2
* GLX Hardware Device Driver for Intel i810
3
* Copyright (C) 1999 Keith Whitwell
5
* Permission is hereby granted, free of charge, to any person obtaining a
6
* copy of this software and associated documentation files (the "Software"),
7
* to deal in the Software without restriction, including without limitation
8
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
* and/or sell copies of the Software, and to permit persons to whom the
10
* Software is furnished to do so, subject to the following conditions:
12
* The above copyright notice and this permission notice shall be included
13
* in all copies or substantial portions of the Software.
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
19
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
21
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
* Adapted for use on the I830M:
24
* Jeff Hartmann <jhartmann@2d3d.com>
26
/* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_vb.c,v 1.5 2002/12/10 01:26:54 dawes Exp $ */
35
#include "swrast_setup/swrast_setup.h"
36
#include "tnl/t_context.h"
38
#include "i830_screen.h"
41
#include "i830_context.h"
43
#include "i830_ioctl.h"
44
#include "i830_tris.h"
45
#include "i830_state.h"
47
#define I830_TEX1_BIT 0x1
48
#define I830_TEX0_BIT 0x2
49
#define I830_RGBA_BIT 0x4
50
#define I830_SPEC_BIT 0x8
51
#define I830_FOG_BIT 0x10
52
#define I830_XYZW_BIT 0x20
53
#define I830_PTEX_BIT 0x40
54
#define I830_MAX_SETUP 0x80
57
void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint );
60
GLboolean (*check_tex_sizes)( GLcontext *ctx );
62
GLuint vertex_stride_shift;
64
} setup_tab[I830_MAX_SETUP];
66
#define TINY_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \
67
VRTX_TEX_COORD_COUNT(0) | \
71
#define NOTEX_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \
72
VRTX_TEX_COORD_COUNT(0) | \
77
#define TEX0_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \
78
VRTX_TEX_COORD_COUNT(1) | \
83
#define TEX1_VERTEX_FORMAT (STATE3D_VERTEX_FORMAT_CMD | \
84
VRTX_TEX_COORD_COUNT(2) | \
90
/* I'm cheating here hardcore : if bit 31 is set I know to emit
91
* a vf2 state == TEXCOORDFMT_3D. We never mix 2d/3d texcoords,
92
* so this solution works for now.
95
#define PROJ_TEX1_VERTEX_FORMAT ((1<<31) | \
96
STATE3D_VERTEX_FORMAT_CMD | \
97
VRTX_TEX_COORD_COUNT(2) | \
102
/* Might want to do these later */
103
#define TEX2_VERTEX_FORMAT 0
104
#define TEX3_VERTEX_FORMAT 0
105
#define PROJ_TEX3_VERTEX_FORMAT 0
107
#define DO_XYZW (IND & I830_XYZW_BIT)
108
#define DO_RGBA (IND & I830_RGBA_BIT)
109
#define DO_SPEC (IND & I830_SPEC_BIT)
110
#define DO_FOG (IND & I830_FOG_BIT)
111
#define DO_TEX0 (IND & I830_TEX0_BIT)
112
#define DO_TEX1 (IND & I830_TEX1_BIT)
115
#define DO_PTEX (IND & I830_PTEX_BIT)
117
#define VERTEX i830Vertex
118
#define VERTEX_COLOR i830_color_t
119
#define GET_VIEWPORT_MAT() I830_CONTEXT(ctx)->ViewportMatrix.m
120
#define GET_TEXSOURCE(n) n
121
#define GET_VERTEX_FORMAT() I830_CONTEXT(ctx)->vertex_format
122
#define GET_VERTEX_STORE() ((GLubyte *)I830_CONTEXT(ctx)->verts)
123
#define GET_VERTEX_STRIDE_SHIFT() I830_CONTEXT(ctx)->vertex_stride_shift
124
#define GET_UBYTE_COLOR_STORE() &I830_CONTEXT(ctx)->UbyteColor
125
#define GET_UBYTE_SPEC_COLOR_STORE() &I830_CONTEXT(ctx)->UbyteSecondaryColor
126
#define INVALIDATE_STORED_VERTICES()
128
#define HAVE_HW_VIEWPORT 0
129
#define HAVE_HW_DIVIDE 0
130
#define HAVE_RGBA_COLOR 0
131
#define HAVE_TINY_VERTICES 1
132
#define HAVE_NOTEX_VERTICES 1
133
#define HAVE_TEX0_VERTICES 1
134
#define HAVE_TEX1_VERTICES 1
135
#define HAVE_TEX2_VERTICES 0
136
#define HAVE_TEX3_VERTICES 0
137
#define HAVE_PTEX_VERTICES 1
139
#define UNVIEWPORT_VARS GLfloat h = I830_CONTEXT(ctx)->driDrawable->h
140
#define UNVIEWPORT_X(x) x - SUBPIXEL_X
141
#define UNVIEWPORT_Y(y) - y + h + SUBPIXEL_Y
142
#define UNVIEWPORT_Z(z) z * (float)I830_CONTEXT(ctx)->ClearDepth
144
#define PTEX_FALLBACK() FALLBACK(I830_CONTEXT(ctx), I830_FALLBACK_TEXTURE, 1)
146
#define IMPORT_FLOAT_COLORS i830_import_float_colors
147
#define IMPORT_FLOAT_SPEC_COLORS i830_import_float_spec_colors
149
#define INTERP_VERTEX setup_tab[I830_CONTEXT(ctx)->SetupIndex].interp
150
#define COPY_PV_VERTEX setup_tab[I830_CONTEXT(ctx)->SetupIndex].copy_pv
153
/***********************************************************************
154
* Generate pv-copying and translation functions *
155
***********************************************************************/
157
#define TAG(x) i830_##x
158
#include "tnl_dd/t_dd_vb.c"
160
/***********************************************************************
161
* Generate vertex emit and interp functions *
162
***********************************************************************/
164
#define IND (I830_XYZW_BIT|I830_RGBA_BIT)
165
#define TAG(x) x##_wg
166
#include "tnl_dd/t_dd_vbtmp.h"
168
#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT)
169
#define TAG(x) x##_wgs
170
#include "tnl_dd/t_dd_vbtmp.h"
172
#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT)
173
#define TAG(x) x##_wgt0
174
#include "tnl_dd/t_dd_vbtmp.h"
176
#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT|I830_TEX1_BIT)
177
#define TAG(x) x##_wgt0t1
178
#include "tnl_dd/t_dd_vbtmp.h"
180
#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT|I830_PTEX_BIT)
181
#define TAG(x) x##_wgpt0
182
#include "tnl_dd/t_dd_vbtmp.h"
184
#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT)
185
#define TAG(x) x##_wgst0
186
#include "tnl_dd/t_dd_vbtmp.h"
188
#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\
190
#define TAG(x) x##_wgst0t1
191
#include "tnl_dd/t_dd_vbtmp.h"
193
#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\
195
#define TAG(x) x##_wgspt0
196
#include "tnl_dd/t_dd_vbtmp.h"
198
#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT)
199
#define TAG(x) x##_wgf
200
#include "tnl_dd/t_dd_vbtmp.h"
202
#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT)
203
#define TAG(x) x##_wgfs
204
#include "tnl_dd/t_dd_vbtmp.h"
206
#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT)
207
#define TAG(x) x##_wgft0
208
#include "tnl_dd/t_dd_vbtmp.h"
210
#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|\
212
#define TAG(x) x##_wgft0t1
213
#include "tnl_dd/t_dd_vbtmp.h"
215
#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|\
217
#define TAG(x) x##_wgfpt0
218
#include "tnl_dd/t_dd_vbtmp.h"
220
#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\
222
#define TAG(x) x##_wgfst0
223
#include "tnl_dd/t_dd_vbtmp.h"
225
#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\
226
I830_TEX0_BIT|I830_TEX1_BIT)
227
#define TAG(x) x##_wgfst0t1
228
#include "tnl_dd/t_dd_vbtmp.h"
230
#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\
231
I830_TEX0_BIT|I830_PTEX_BIT)
232
#define TAG(x) x##_wgfspt0
233
#include "tnl_dd/t_dd_vbtmp.h"
235
#define IND (I830_TEX0_BIT)
236
#define TAG(x) x##_t0
237
#include "tnl_dd/t_dd_vbtmp.h"
239
#define IND (I830_TEX0_BIT|I830_TEX1_BIT)
240
#define TAG(x) x##_t0t1
241
#include "tnl_dd/t_dd_vbtmp.h"
243
#define IND (I830_FOG_BIT)
245
#include "tnl_dd/t_dd_vbtmp.h"
247
#define IND (I830_FOG_BIT|I830_TEX0_BIT)
248
#define TAG(x) x##_ft0
249
#include "tnl_dd/t_dd_vbtmp.h"
251
#define IND (I830_FOG_BIT|I830_TEX0_BIT|I830_TEX1_BIT)
252
#define TAG(x) x##_ft0t1
253
#include "tnl_dd/t_dd_vbtmp.h"
255
#define IND (I830_RGBA_BIT)
257
#include "tnl_dd/t_dd_vbtmp.h"
259
#define IND (I830_RGBA_BIT|I830_SPEC_BIT)
260
#define TAG(x) x##_gs
261
#include "tnl_dd/t_dd_vbtmp.h"
263
#define IND (I830_RGBA_BIT|I830_TEX0_BIT)
264
#define TAG(x) x##_gt0
265
#include "tnl_dd/t_dd_vbtmp.h"
267
#define IND (I830_RGBA_BIT|I830_TEX0_BIT|I830_TEX1_BIT)
268
#define TAG(x) x##_gt0t1
269
#include "tnl_dd/t_dd_vbtmp.h"
271
#define IND (I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT)
272
#define TAG(x) x##_gst0
273
#include "tnl_dd/t_dd_vbtmp.h"
275
#define IND (I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|I830_TEX1_BIT)
276
#define TAG(x) x##_gst0t1
277
#include "tnl_dd/t_dd_vbtmp.h"
279
#define IND (I830_RGBA_BIT|I830_FOG_BIT)
280
#define TAG(x) x##_gf
281
#include "tnl_dd/t_dd_vbtmp.h"
283
#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT)
284
#define TAG(x) x##_gfs
285
#include "tnl_dd/t_dd_vbtmp.h"
287
#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT)
288
#define TAG(x) x##_gft0
289
#include "tnl_dd/t_dd_vbtmp.h"
291
#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|I830_TEX1_BIT)
292
#define TAG(x) x##_gft0t1
293
#include "tnl_dd/t_dd_vbtmp.h"
295
#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|I830_TEX0_BIT)
296
#define TAG(x) x##_gfst0
297
#include "tnl_dd/t_dd_vbtmp.h"
299
#define IND (I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\
301
#define TAG(x) x##_gfst0t1
302
#include "tnl_dd/t_dd_vbtmp.h"
304
/* Add functions for proj texturing for t0 and t1 */
305
#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_TEX0_BIT|I830_TEX1_BIT|\
307
#define TAG(x) x##_wgpt0t1
308
#include "tnl_dd/t_dd_vbtmp.h"
310
#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_SPEC_BIT|I830_TEX0_BIT|\
311
I830_TEX1_BIT|I830_PTEX_BIT)
312
#define TAG(x) x##_wgspt0t1
313
#include "tnl_dd/t_dd_vbtmp.h"
315
#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_TEX0_BIT|\
316
I830_TEX1_BIT|I830_PTEX_BIT)
317
#define TAG(x) x##_wgfpt0t1
318
#include "tnl_dd/t_dd_vbtmp.h"
320
#define IND (I830_XYZW_BIT|I830_RGBA_BIT|I830_FOG_BIT|I830_SPEC_BIT|\
321
I830_TEX1_BIT|I830_TEX0_BIT|I830_PTEX_BIT)
322
#define TAG(x) x##_wgfspt0t1
323
#include "tnl_dd/t_dd_vbtmp.h"
326
static void init_setup_tab( void )
361
/* Add proj texturing on t1 */
370
void i830PrintSetupFlags(char *msg, GLuint flags )
372
fprintf(stderr, "%s(%x): %s%s%s%s%s%s%s\n",
375
(flags & I830_XYZW_BIT) ? " xyzw," : "",
376
(flags & I830_RGBA_BIT) ? " rgba," : "",
377
(flags & I830_SPEC_BIT) ? " spec," : "",
378
(flags & I830_FOG_BIT) ? " fog," : "",
379
(flags & I830_TEX0_BIT) ? " tex-0," : "",
380
(flags & I830_TEX1_BIT) ? " tex-1," : "",
381
(flags & I830_PTEX_BIT) ? " ptex," : "");
384
void i830CheckTexSizes( GLcontext *ctx )
386
TNLcontext *tnl = TNL_CONTEXT(ctx);
387
i830ContextPtr imesa = I830_CONTEXT( ctx );
389
if (!setup_tab[imesa->SetupIndex].check_tex_sizes(ctx)) {
390
int ind = imesa->SetupIndex |= I830_PTEX_BIT;
392
if(setup_tab[ind].vertex_format != imesa->vertex_format) {
393
int vfmt = setup_tab[ind].vertex_format;
395
I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
396
imesa->Setup[I830_CTXREG_VF] = ~(1<<31) & vfmt;
398
if (vfmt & (1<<31)) {
400
imesa->Setup[I830_CTXREG_VF2] = (STATE3D_VERTEX_FORMAT_2_CMD |
401
VRTX_TEX_SET_0_FMT(TEXCOORDFMT_3D) |
402
VRTX_TEX_SET_1_FMT(TEXCOORDFMT_3D) |
403
VRTX_TEX_SET_2_FMT(TEXCOORDFMT_3D) |
404
VRTX_TEX_SET_3_FMT(TEXCOORDFMT_3D));
405
i830UpdateTexUnitProj( ctx, 0, GL_TRUE );
406
i830UpdateTexUnitProj( ctx, 1, GL_TRUE );
409
/* Normal texturing */
410
imesa->Setup[I830_CTXREG_VF2] = (STATE3D_VERTEX_FORMAT_2_CMD |
411
VRTX_TEX_SET_0_FMT(TEXCOORDFMT_2D) |
412
VRTX_TEX_SET_1_FMT(TEXCOORDFMT_2D) |
413
VRTX_TEX_SET_2_FMT(TEXCOORDFMT_2D) |
414
VRTX_TEX_SET_3_FMT(TEXCOORDFMT_2D));
415
i830UpdateTexUnitProj( ctx, 0, GL_FALSE );
416
i830UpdateTexUnitProj( ctx, 1, GL_FALSE );
418
imesa->vertex_format = vfmt;
419
imesa->vertex_size = setup_tab[ind].vertex_size;
420
imesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift;
423
if (!imesa->Fallback &&
424
!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
425
tnl->Driver.Render.Interp = setup_tab[imesa->SetupIndex].interp;
426
tnl->Driver.Render.CopyPV = setup_tab[imesa->SetupIndex].copy_pv;
431
void i830BuildVertices( GLcontext *ctx,
436
i830ContextPtr imesa = I830_CONTEXT( ctx );
437
GLubyte *v = ((GLubyte *)
438
imesa->verts + (start<<imesa->vertex_stride_shift));
439
GLuint stride = 1<<imesa->vertex_stride_shift;
441
if (0) fprintf(stderr, "%s\n", __FUNCTION__);
443
newinputs |= imesa->SetupNewInputs;
444
imesa->SetupNewInputs = 0;
449
if (newinputs & VERT_CLIP) {
450
setup_tab[imesa->SetupIndex].emit( ctx, start, count, v, stride );
454
if (newinputs & VERT_RGBA)
455
ind |= I830_RGBA_BIT;
457
if (newinputs & VERT_SPEC_RGB)
458
ind |= I830_SPEC_BIT;
460
if (newinputs & VERT_TEX0)
461
ind |= I830_TEX0_BIT;
463
if (newinputs & VERT_TEX1)
464
ind |= I830_TEX1_BIT;
466
if (newinputs & VERT_FOG_COORD)
470
if (imesa->SetupIndex & I830_PTEX_BIT)
474
ind &= imesa->SetupIndex;
477
setup_tab[ind].emit( ctx, start, count, v, stride );
482
void i830ChooseVertexState( GLcontext *ctx )
484
TNLcontext *tnl = TNL_CONTEXT(ctx);
485
i830ContextPtr imesa = I830_CONTEXT( ctx );
486
GLuint ind = I830_XYZW_BIT|I830_RGBA_BIT;
488
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
489
ind |= I830_SPEC_BIT;
491
if (ctx->Fog.Enabled)
495
if (ctx->Texture._ReallyEnabled & TEXTURE1_ANY)
496
ind |= I830_TEX1_BIT|I830_TEX0_BIT;
498
else if (ctx->Texture._ReallyEnabled & TEXTURE0_ANY)
499
ind |= I830_TEX0_BIT;
501
imesa->SetupIndex = ind;
503
if (I830_DEBUG & (DEBUG_VERTS|DEBUG_STATE))
504
i830PrintSetupFlags( __FUNCTION__, ind );
506
if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
507
tnl->Driver.Render.Interp = i830_interp_extras;
508
tnl->Driver.Render.CopyPV = i830_copy_pv_extras;
510
tnl->Driver.Render.Interp = setup_tab[ind].interp;
511
tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
514
if (setup_tab[ind].vertex_format != imesa->vertex_format) {
515
int vfmt = setup_tab[ind].vertex_format;
517
I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
518
imesa->Setup[I830_CTXREG_VF] = ~(1<<31) & vfmt;
520
if (vfmt & (1<<31)) {
522
imesa->Setup[I830_CTXREG_VF2] = (STATE3D_VERTEX_FORMAT_2_CMD |
523
VRTX_TEX_SET_0_FMT(TEXCOORDFMT_3D) |
524
VRTX_TEX_SET_1_FMT(TEXCOORDFMT_3D) |
525
VRTX_TEX_SET_2_FMT(TEXCOORDFMT_3D) |
526
VRTX_TEX_SET_3_FMT(TEXCOORDFMT_3D));
527
i830UpdateTexUnitProj( ctx, 0, GL_TRUE );
528
i830UpdateTexUnitProj( ctx, 1, GL_TRUE );
530
/* Normal texturing */
531
imesa->Setup[I830_CTXREG_VF2] = (STATE3D_VERTEX_FORMAT_2_CMD |
532
VRTX_TEX_SET_0_FMT(TEXCOORDFMT_2D) |
533
VRTX_TEX_SET_1_FMT(TEXCOORDFMT_2D) |
534
VRTX_TEX_SET_2_FMT(TEXCOORDFMT_2D) |
535
VRTX_TEX_SET_3_FMT(TEXCOORDFMT_2D));
536
i830UpdateTexUnitProj( ctx, 0, GL_FALSE );
537
i830UpdateTexUnitProj( ctx, 1, GL_FALSE );
539
imesa->vertex_format = vfmt;
540
imesa->vertex_size = setup_tab[ind].vertex_size;
541
imesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift;
547
void i830_emit_contiguous_verts( GLcontext *ctx,
551
i830ContextPtr imesa = I830_CONTEXT(ctx);
552
GLuint vertex_size = imesa->vertex_size * 4;
553
GLuint *dest = i830AllocDmaLow( imesa, (count-start) * vertex_size);
554
setup_tab[imesa->SetupIndex].emit( ctx, start, count, dest, vertex_size );
559
void i830InitVB( GLcontext *ctx )
561
i830ContextPtr imesa = I830_CONTEXT(ctx);
562
GLuint size = TNL_CONTEXT(ctx)->vb.Size;
564
imesa->verts = (char *)ALIGN_MALLOC(size * 4 * 16, 32);
567
static int firsttime = 1;
576
void i830FreeVB( GLcontext *ctx )
578
i830ContextPtr imesa = I830_CONTEXT(ctx);
580
ALIGN_FREE(imesa->verts);
584
if (imesa->UbyteSecondaryColor.Ptr) {
585
ALIGN_FREE(imesa->UbyteSecondaryColor.Ptr);
586
imesa->UbyteSecondaryColor.Ptr = 0;
589
if (imesa->UbyteColor.Ptr) {
590
ALIGN_FREE(imesa->UbyteColor.Ptr);
591
imesa->UbyteColor.Ptr = 0;