Major check-in of changes for GL_EXT_framebuffer_object extension.
[mesa.git] / src / mesa / drivers / dri / savage / savagestate.c
1 /*
2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4 *
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, sub license,
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:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25
26 #include <stdio.h>
27
28 #include "mtypes.h"
29 #include "buffers.h"
30 #include "enums.h"
31 #include "macros.h"
32 #include "dd.h"
33
34 #include "mm.h"
35 #include "savagedd.h"
36 #include "savagecontext.h"
37
38 #include "savagestate.h"
39 #include "savagetex.h"
40 #include "savagetris.h"
41 #include "savageioctl.h"
42 #include "savage_bci.h"
43
44 #include "swrast/swrast.h"
45 #include "array_cache/acache.h"
46 #include "tnl/tnl.h"
47 #include "swrast_setup/swrast_setup.h"
48
49 #include "xmlpool.h"
50
51 /* Savage4, ProSavage[DDR], SuperSavage watermarks */
52 #define S4_ZRLO 24
53 #define S4_ZRHI 24
54 #define S4_ZWLO 0
55 #define S4_ZWHI 0
56
57 #define S4_DRLO 0
58 #define S4_DRHI 0
59 #define S4_DWLO 0
60 #define S4_DWHI 0
61
62 #define S4_TR 15
63
64 /* Savage3D/MX/IX watermarks */
65 #define S3D_ZRLO 8
66 #define S3D_ZRHI 24
67 #define S3D_ZWLO 0
68 #define S3D_ZWHI 24
69
70 #define S3D_DRLO 0
71 #define S3D_DRHI 0
72 #define S3D_DWLO 0
73 #define S3D_DWHI 0
74
75 #define S3D_TR 15
76
77 static void savageBlendFunc_s4(GLcontext *);
78 static void savageBlendFunc_s3d(GLcontext *);
79
80 static __inline__ GLuint savagePackColor(GLuint format,
81 GLubyte r, GLubyte g,
82 GLubyte b, GLubyte a)
83 {
84 switch (format) {
85 case DV_PF_8888:
86 return SAVAGEPACKCOLOR8888(r,g,b,a);
87 case DV_PF_565:
88 return SAVAGEPACKCOLOR565(r,g,b);
89 default:
90
91 return 0;
92 }
93 }
94
95
96 static void savageDDAlphaFunc_s4(GLcontext *ctx, GLenum func, GLfloat ref)
97 {
98 savageBlendFunc_s4(ctx);
99 }
100 static void savageDDAlphaFunc_s3d(GLcontext *ctx, GLenum func, GLfloat ref)
101 {
102 savageBlendFunc_s3d(ctx);
103 }
104
105 static void savageDDBlendEquationSeparate(GLcontext *ctx,
106 GLenum modeRGB, GLenum modeA)
107 {
108 assert( modeRGB == modeA );
109
110 /* BlendEquation sets ColorLogicOpEnabled in an unexpected
111 * manner.
112 */
113 FALLBACK( ctx, SAVAGE_FALLBACK_LOGICOP,
114 (ctx->Color.ColorLogicOpEnabled &&
115 ctx->Color.LogicOp != GL_COPY));
116
117 /* Can only do blend addition, not min, max, subtract, etc. */
118 FALLBACK( ctx, SAVAGE_FALLBACK_BLEND_EQ,
119 modeRGB != GL_FUNC_ADD);
120 }
121
122
123 static void savageBlendFunc_s4(GLcontext *ctx)
124 {
125 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
126 u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui;
127 u_int32_t drawCtrl0 = imesa->regs.s4.drawCtrl0.ui;
128 u_int32_t drawCtrl1 = imesa->regs.s4.drawCtrl1.ui;
129
130 /* set up draw control register (including blending, alpha
131 * test, and shading model)
132 */
133
134 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_FALSE;
135
136 /*
137 * blend modes
138 */
139 if(ctx->Color.BlendEnabled){
140 switch (ctx->Color.BlendDstRGB)
141 {
142 case GL_ZERO:
143 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_Zero;
144 break;
145
146 case GL_ONE:
147 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_One;
148 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
149 break;
150
151 case GL_SRC_COLOR:
152 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_SrcClr;
153 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
154 break;
155
156 case GL_ONE_MINUS_SRC_COLOR:
157 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_1SrcClr;
158 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
159 break;
160
161 case GL_SRC_ALPHA:
162 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_SrcAlpha;
163 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
164 break;
165
166 case GL_ONE_MINUS_SRC_ALPHA:
167 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_1SrcAlpha;
168 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
169 break;
170
171 case GL_DST_ALPHA:
172 if (imesa->glCtx->Visual.alphaBits == 0)
173 {
174 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_One;
175 }
176 else
177 {
178 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode= DAM_DstAlpha;
179 }
180 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
181 break;
182
183 case GL_ONE_MINUS_DST_ALPHA:
184 if (imesa->glCtx->Visual.alphaBits == 0)
185 {
186 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_Zero;
187 }
188 else
189 {
190 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode=DAM_1DstAlpha;
191 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites= GL_TRUE;
192 }
193 break;
194 }
195
196 switch (ctx->Color.BlendSrcRGB)
197 {
198 case GL_ZERO:
199 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_Zero;
200 break;
201
202 case GL_ONE:
203 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_One;
204 break;
205
206 case GL_DST_COLOR:
207 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_DstClr;
208 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
209 break;
210
211 case GL_ONE_MINUS_DST_COLOR:
212 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_1DstClr;
213 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
214 break;
215
216 case GL_SRC_ALPHA:
217 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_SrcAlpha;
218 break;
219
220 case GL_ONE_MINUS_SRC_ALPHA:
221 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_1SrcAlpha;
222 break;
223
224 case GL_DST_ALPHA:
225 if (imesa->glCtx->Visual.alphaBits == 0)
226 {
227 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_One;
228 }
229 else
230 {
231 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode= SAM_DstAlpha;
232 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites= GL_TRUE;
233 }
234 break;
235
236 case GL_ONE_MINUS_DST_ALPHA:
237 if (imesa->glCtx->Visual.alphaBits == 0)
238 {
239 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_Zero;
240 }
241 else
242 {
243 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode=SAM_1DstAlpha;
244 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites= GL_TRUE;
245 }
246 break;
247 }
248 }
249 else
250 {
251 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_Zero;
252 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_One;
253 }
254
255 /* alpha test*/
256
257 if(ctx->Color.AlphaEnabled)
258 {
259 ACmpFunc a;
260 GLubyte alphaRef;
261
262 CLAMPED_FLOAT_TO_UBYTE(alphaRef,ctx->Color.AlphaRef);
263
264 switch(ctx->Color.AlphaFunc) {
265 case GL_NEVER: a = CF_Never; break;
266 case GL_ALWAYS: a = CF_Always; break;
267 case GL_LESS: a = CF_Less; break;
268 case GL_LEQUAL: a = CF_LessEqual; break;
269 case GL_EQUAL: a = CF_Equal; break;
270 case GL_GREATER: a = CF_Greater; break;
271 case GL_GEQUAL: a = CF_GreaterEqual; break;
272 case GL_NOTEQUAL: a = CF_NotEqual; break;
273 default:return;
274 }
275
276 imesa->regs.s4.drawCtrl1.ni.alphaTestEn = GL_TRUE;
277 imesa->regs.s4.drawCtrl1.ni.alphaTestCmpFunc = a;
278 imesa->regs.s4.drawCtrl0.ni.alphaRefVal = alphaRef;
279 }
280 else
281 {
282 imesa->regs.s4.drawCtrl1.ni.alphaTestEn = GL_FALSE;
283 }
284
285 /* Set/Reset Z-after-alpha*/
286
287 imesa->regs.s4.drawLocalCtrl.ni.wrZafterAlphaTst =
288 imesa->regs.s4.drawCtrl1.ni.alphaTestEn;
289 /*imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn =
290 ~drawLocalCtrl.ni.wrZafterAlphaTst;*/
291
292 if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
293 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
294 if (drawCtrl0 != imesa->regs.s4.drawCtrl0.ui ||
295 drawCtrl1 != imesa->regs.s4.drawCtrl1.ui)
296 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
297 }
298 static void savageBlendFunc_s3d(GLcontext *ctx)
299 {
300 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
301 u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui;
302 u_int32_t zBufCtrl = imesa->regs.s3d.zBufCtrl.ui;
303
304 /* set up draw control register (including blending, alpha
305 * test, dithering, and shading model)
306 */
307
308 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = 0;
309
310 /*
311 * blend modes
312 */
313 if(ctx->Color.BlendEnabled){
314 switch (ctx->Color.BlendDstRGB)
315 {
316 case GL_ZERO:
317 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_Zero;
318 break;
319
320 case GL_ONE:
321 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_One;
322 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
323 break;
324
325 case GL_SRC_COLOR:
326 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_SrcClr;
327 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
328 break;
329
330 case GL_ONE_MINUS_SRC_COLOR:
331 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_1SrcClr;
332 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
333 break;
334
335 case GL_SRC_ALPHA:
336 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_SrcAlpha;
337 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
338 break;
339
340 case GL_ONE_MINUS_SRC_ALPHA:
341 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_1SrcAlpha;
342 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
343 break;
344
345 case GL_DST_ALPHA:
346 if (imesa->glCtx->Visual.alphaBits == 0)
347 {
348 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_One;
349 }
350 else
351 {
352 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_DstAlpha;
353 }
354 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
355 break;
356
357 case GL_ONE_MINUS_DST_ALPHA:
358 if (imesa->glCtx->Visual.alphaBits == 0)
359 {
360 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_Zero;
361 }
362 else
363 {
364 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_1DstAlpha;
365 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
366 }
367 break;
368 }
369
370 switch (ctx->Color.BlendSrcRGB)
371 {
372 case GL_ZERO:
373 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_Zero;
374 break;
375
376 case GL_ONE:
377 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_One;
378 break;
379
380 case GL_DST_COLOR:
381 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_DstClr;
382 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
383 break;
384
385 case GL_ONE_MINUS_DST_COLOR:
386 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_1DstClr;
387 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
388 break;
389
390 case GL_SRC_ALPHA:
391 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_SrcAlpha;
392 break;
393
394 case GL_ONE_MINUS_SRC_ALPHA:
395 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_1SrcAlpha;
396 break;
397
398 case GL_DST_ALPHA:
399 if (imesa->glCtx->Visual.alphaBits == 0)
400 {
401 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_One;
402 }
403 else
404 {
405 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_DstAlpha;
406 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
407 }
408 break;
409
410 case GL_ONE_MINUS_DST_ALPHA:
411 if (imesa->glCtx->Visual.alphaBits == 0)
412 {
413 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_Zero;
414 }
415 else
416 {
417 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_1DstAlpha;
418 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
419 }
420 break;
421 }
422 }
423 else
424 {
425 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_Zero;
426 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_One;
427 }
428
429 /* alpha test*/
430
431 if(ctx->Color.AlphaEnabled)
432 {
433 ACmpFunc a;
434 GLubyte alphaRef;
435
436 CLAMPED_FLOAT_TO_UBYTE(alphaRef,ctx->Color.AlphaRef);
437
438 switch(ctx->Color.AlphaFunc) {
439 case GL_NEVER: a = CF_Never; break;
440 case GL_ALWAYS: a = CF_Always; break;
441 case GL_LESS: a = CF_Less; break;
442 case GL_LEQUAL: a = CF_LessEqual; break;
443 case GL_EQUAL: a = CF_Equal; break;
444 case GL_GREATER: a = CF_Greater; break;
445 case GL_GEQUAL: a = CF_GreaterEqual; break;
446 case GL_NOTEQUAL: a = CF_NotEqual; break;
447 default:return;
448 }
449
450 imesa->regs.s3d.drawCtrl.ni.alphaTestEn = GL_TRUE;
451 imesa->regs.s3d.drawCtrl.ni.alphaTestCmpFunc = a;
452 imesa->regs.s3d.drawCtrl.ni.alphaRefVal = alphaRef;
453 }
454 else
455 {
456 imesa->regs.s3d.drawCtrl.ni.alphaTestEn = GL_FALSE;
457 }
458
459 /* Set/Reset Z-after-alpha*/
460
461 imesa->regs.s3d.zBufCtrl.ni.wrZafterAlphaTst =
462 imesa->regs.s3d.drawCtrl.ni.alphaTestEn;
463
464 if (drawCtrl != imesa->regs.s3d.drawCtrl.ui ||
465 zBufCtrl != imesa->regs.s3d.zBufCtrl.ui)
466 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
467 }
468
469 static void savageDDBlendFuncSeparate_s4( GLcontext *ctx, GLenum sfactorRGB,
470 GLenum dfactorRGB, GLenum sfactorA,
471 GLenum dfactorA )
472 {
473 assert (dfactorRGB == dfactorA && sfactorRGB == sfactorA);
474 savageBlendFunc_s4( ctx );
475 }
476 static void savageDDBlendFuncSeparate_s3d( GLcontext *ctx, GLenum sfactorRGB,
477 GLenum dfactorRGB, GLenum sfactorA,
478 GLenum dfactorA )
479 {
480 assert (dfactorRGB == dfactorA && sfactorRGB == sfactorA);
481 savageBlendFunc_s3d( ctx );
482 }
483
484
485
486 static void savageDDDepthFunc_s4(GLcontext *ctx, GLenum func)
487 {
488 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
489 ZCmpFunc zmode;
490 u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui;
491 u_int32_t zBufCtrl = imesa->regs.s4.zBufCtrl.ui;
492 u_int32_t zWatermarks = imesa->regs.s4.zWatermarks.ui; /* FIXME: in DRM */
493
494 /* set up z-buffer control register (global)
495 * set up z-buffer offset register (global)
496 * set up z read/write watermarks register (global)
497 */
498
499 switch(func) { /* reversed (see savageCalcViewport) */
500 case GL_NEVER: zmode = CF_Never; break;
501 case GL_ALWAYS: zmode = CF_Always; break;
502 case GL_LESS: zmode = CF_Greater; break;
503 case GL_LEQUAL: zmode = CF_GreaterEqual; break;
504 case GL_EQUAL: zmode = CF_Equal; break;
505 case GL_GREATER: zmode = CF_Less; break;
506 case GL_GEQUAL: zmode = CF_LessEqual; break;
507 case GL_NOTEQUAL: zmode = CF_NotEqual; break;
508 default:return;
509 }
510 if (ctx->Depth.Test)
511 {
512
513 imesa->regs.s4.zBufCtrl.ni.zCmpFunc = zmode;
514 imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = ctx->Depth.Mask;
515 imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_TRUE;
516 imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_TRUE;
517 }
518 else if (imesa->glCtx->Stencil.Enabled && imesa->hw_stencil)
519 {
520 /* Need to keep Z on for Stencil. */
521 imesa->regs.s4.zBufCtrl.ni.zCmpFunc = CF_Always;
522 imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_TRUE;
523 imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = GL_FALSE;
524 imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE;
525 }
526 else
527 {
528
529 if (imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn == GL_FALSE)
530 {
531 imesa->regs.s4.zBufCtrl.ni.zCmpFunc = CF_Always;
532 imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_TRUE;
533 }
534 else
535
536 /* DRAWUPDATE_REQUIRES_Z_ENABLED*/
537 {
538 imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_FALSE;
539 }
540 imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = GL_FALSE;
541 imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE;
542 }
543
544 if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
545 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
546 if (zBufCtrl != imesa->regs.s4.zBufCtrl.ui ||
547 zWatermarks != imesa->regs.s4.zWatermarks.ui)
548 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
549 }
550 static void savageDDDepthFunc_s3d(GLcontext *ctx, GLenum func)
551 {
552 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
553 ZCmpFunc zmode;
554 u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui;
555 u_int32_t zBufCtrl = imesa->regs.s3d.zBufCtrl.ui;
556 u_int32_t zWatermarks = imesa->regs.s3d.zWatermarks.ui; /* FIXME: in DRM */
557
558 /* set up z-buffer control register (global)
559 * set up z-buffer offset register (global)
560 * set up z read/write watermarks register (global)
561 */
562 switch(func) { /* reversed (see savageCalcViewport) */
563 case GL_NEVER: zmode = CF_Never; break;
564 case GL_ALWAYS: zmode = CF_Always; break;
565 case GL_LESS: zmode = CF_Greater; break;
566 case GL_LEQUAL: zmode = CF_GreaterEqual; break;
567 case GL_EQUAL: zmode = CF_Equal; break;
568 case GL_GREATER: zmode = CF_Less; break;
569 case GL_GEQUAL: zmode = CF_LessEqual; break;
570 case GL_NOTEQUAL: zmode = CF_NotEqual; break;
571 default:return;
572 }
573 if (ctx->Depth.Test)
574 {
575 imesa->regs.s3d.zBufCtrl.ni.zBufEn = GL_TRUE;
576 imesa->regs.s3d.zBufCtrl.ni.zCmpFunc = zmode;
577 imesa->regs.s3d.zBufCtrl.ni.zUpdateEn = ctx->Depth.Mask;
578
579 imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE;
580 }
581 else
582 {
583 if (imesa->regs.s3d.zBufCtrl.ni.drawUpdateEn == GL_FALSE) {
584 imesa->regs.s3d.zBufCtrl.ni.zCmpFunc = CF_Always;
585 imesa->regs.s3d.zBufCtrl.ni.zBufEn = GL_TRUE;
586 }
587 else
588
589 /* DRAWUPDATE_REQUIRES_Z_ENABLED*/
590 {
591 imesa->regs.s3d.zBufCtrl.ni.zBufEn = GL_FALSE;
592 }
593 imesa->regs.s3d.zBufCtrl.ni.zUpdateEn = GL_FALSE;
594 imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_FALSE;
595 }
596
597 if (drawCtrl != imesa->regs.s3d.drawCtrl.ui ||
598 zBufCtrl != imesa->regs.s3d.zBufCtrl.ui)
599 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
600 if (zWatermarks != imesa->regs.s3d.zWatermarks.ui)
601 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
602 }
603
604 static void savageDDDepthMask_s4(GLcontext *ctx, GLboolean flag)
605 {
606 savageDDDepthFunc_s4(ctx,ctx->Depth.Func);
607 }
608 static void savageDDDepthMask_s3d(GLcontext *ctx, GLboolean flag)
609 {
610 savageDDDepthFunc_s3d(ctx,ctx->Depth.Func);
611 }
612
613
614
615
616 /* =============================================================
617 * Hardware clipping
618 */
619
620
621 static void savageDDScissor( GLcontext *ctx, GLint x, GLint y,
622 GLsizei w, GLsizei h )
623 {
624 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
625
626 /* Emit buffered commands with old scissor state. */
627 FLUSH_BATCH(imesa);
628
629 /* Mirror scissors in private context. */
630 imesa->scissor.enabled = ctx->Scissor.Enabled;
631 imesa->scissor.x = x;
632 imesa->scissor.y = y;
633 imesa->scissor.w = w;
634 imesa->scissor.h = h;
635 }
636
637
638
639 static void savageDDDrawBuffer(GLcontext *ctx, GLenum mode )
640 {
641 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
642 u_int32_t destCtrl = imesa->regs.s4.destCtrl.ui;
643
644 /*
645 * _DrawDestMask is easier to cope with than <mode>.
646 */
647 switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) {
648 case BUFFER_BIT_FRONT_LEFT:
649 imesa->IsDouble = GL_FALSE;
650 imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->frontOffset>>11;
651
652 imesa->NotFirstFrame = GL_FALSE;
653 savageXMesaSetFrontClipRects( imesa );
654 FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_FALSE );
655 break;
656 case BUFFER_BIT_BACK_LEFT:
657 imesa->IsDouble = GL_TRUE;
658 imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->backOffset>>11;
659 imesa->NotFirstFrame = GL_FALSE;
660 savageXMesaSetBackClipRects( imesa );
661 FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_FALSE );
662 break;
663 default:
664 FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_TRUE );
665 return;
666 }
667
668 /* We want to update the s/w rast state too so that r200SetBuffer() (?)
669 * gets called.
670 */
671 _swrast_DrawBuffer(ctx, mode);
672
673 if (destCtrl != imesa->regs.s4.destCtrl.ui)
674 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
675 }
676
677 static void savageDDReadBuffer(GLcontext *ctx, GLenum mode )
678 {
679 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
680 }
681
682 #if 0
683 static void savageDDSetColor(GLcontext *ctx,
684 GLubyte r, GLubyte g,
685 GLubyte b, GLubyte a )
686 {
687 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
688 imesa->MonoColor = savagePackColor( imesa->savageScreen->frontFormat, r, g, b, a );
689 }
690 #endif
691
692 /* =============================================================
693 * Window position and viewport transformation
694 */
695
696 void savageCalcViewport( GLcontext *ctx )
697 {
698 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
699 const GLfloat *v = ctx->Viewport._WindowMap.m;
700 GLfloat *m = imesa->hw_viewport;
701
702 m[MAT_SX] = v[MAT_SX];
703 m[MAT_TX] = v[MAT_TX] + imesa->drawX + SUBPIXEL_X;
704 m[MAT_SY] = - v[MAT_SY];
705 m[MAT_TY] = - v[MAT_TY] + imesa->driDrawable->h + imesa->drawY + SUBPIXEL_Y;
706 /* Depth range is reversed (far: 0, near: 1) so that float depth
707 * compensates for loss of accuracy of far coordinates. */
708 if (imesa->float_depth && imesa->savageScreen->zpp == 2) {
709 /* The Savage 16-bit floating point depth format can't encode
710 * numbers < 2^-16. Make sure all depth values stay greater
711 * than that. */
712 m[MAT_SZ] = - v[MAT_SZ] * imesa->depth_scale * (65535.0/65536.0);
713 m[MAT_TZ] = 1.0 - v[MAT_TZ] * imesa->depth_scale * (65535.0/65536.0);
714 } else {
715 m[MAT_SZ] = - v[MAT_SZ] * imesa->depth_scale;
716 m[MAT_TZ] = 1.0 - v[MAT_TZ] * imesa->depth_scale;
717 }
718
719 imesa->SetupNewInputs = ~0;
720 }
721
722 static void savageViewport( GLcontext *ctx,
723 GLint x, GLint y,
724 GLsizei width, GLsizei height )
725 {
726 /* update size of Mesa/software ancillary buffers */
727 _mesa_ResizeBuffersMESA();
728 savageCalcViewport( ctx );
729 }
730
731 static void savageDepthRange( GLcontext *ctx,
732 GLclampd nearval, GLclampd farval )
733 {
734 savageCalcViewport( ctx );
735 }
736
737
738 /* =============================================================
739 * Miscellaneous
740 */
741
742 static void savageDDClearColor(GLcontext *ctx,
743 const GLfloat color[4] )
744 {
745 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
746 GLubyte c[4];
747 CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
748 CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
749 CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
750 CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
751
752 imesa->ClearColor = savagePackColor( imesa->savageScreen->frontFormat,
753 c[0], c[1], c[2], c[3] );
754 }
755
756 /* Fallback to swrast for select and feedback.
757 */
758 static void savageRenderMode( GLcontext *ctx, GLenum mode )
759 {
760 FALLBACK( ctx, SAVAGE_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
761 }
762
763
764 #if HW_CULL
765
766 /* =============================================================
767 * Culling - the savage isn't quite as clean here as the rest of
768 * its interfaces, but it's not bad.
769 */
770 static void savageDDCullFaceFrontFace(GLcontext *ctx, GLenum unused)
771 {
772 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
773 GLuint cullMode=imesa->LcsCullMode;
774 switch (ctx->Polygon.CullFaceMode)
775 {
776 case GL_FRONT:
777 switch (ctx->Polygon.FrontFace)
778 {
779 case GL_CW:
780 cullMode = BCM_CW;
781 break;
782 case GL_CCW:
783 cullMode = BCM_CCW;
784 break;
785 }
786 break;
787
788 case GL_BACK:
789 switch (ctx->Polygon.FrontFace)
790 {
791 case GL_CW:
792 cullMode = BCM_CCW;
793 break;
794 case GL_CCW:
795 cullMode = BCM_CW;
796 break;
797 }
798 break;
799 }
800 imesa->LcsCullMode = cullMode;
801 imesa->new_state |= SAVAGE_NEW_CULL;
802 }
803 #endif /* end #if HW_CULL */
804
805 static void savageUpdateCull( GLcontext *ctx )
806 {
807 #if HW_CULL
808 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
809 GLuint cullMode;
810 if (ctx->Polygon.CullFlag &&
811 imesa->raster_primitive >= GL_TRIANGLES &&
812 ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK)
813 cullMode = imesa->LcsCullMode;
814 else
815 cullMode = BCM_None;
816 if (imesa->savageScreen->chipset >= S3_SAVAGE4) {
817 if (imesa->regs.s4.drawCtrl1.ni.cullMode != cullMode) {
818 imesa->regs.s4.drawCtrl1.ni.cullMode = cullMode;
819 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
820 }
821 } else {
822 if (imesa->regs.s3d.drawCtrl.ni.cullMode != cullMode) {
823 imesa->regs.s3d.drawCtrl.ni.cullMode = cullMode;
824 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
825 }
826 }
827 #endif /* end #if HW_CULL */
828 }
829
830
831
832 /* =============================================================
833 * Color masks
834 */
835
836 /* Savage4 can disable draw updates when all channels are
837 * masked. Savage3D has a bit called drawUpdateEn, but it doesn't seem
838 * to have any effect. If only some channels are masked we need a
839 * software fallback on all chips.
840 */
841 static void savageDDColorMask_s4(GLcontext *ctx,
842 GLboolean r, GLboolean g,
843 GLboolean b, GLboolean a )
844 {
845 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
846 GLboolean passAny, passAll;
847
848 if (ctx->Visual.alphaBits) {
849 passAny = b || g || r || a;
850 passAll = r && g && b && a;
851 } else {
852 passAny = b || g || r;
853 passAll = r && g && b;
854 }
855
856 if (passAny) {
857 if (!imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn) {
858 imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn = GL_TRUE;
859 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
860 }
861 FALLBACK (ctx, SAVAGE_FALLBACK_COLORMASK, !passAll);
862 } else if (imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn) {
863 imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn = GL_FALSE;
864 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
865 }
866 }
867 static void savageDDColorMask_s3d(GLcontext *ctx,
868 GLboolean r, GLboolean g,
869 GLboolean b, GLboolean a )
870 {
871 if (ctx->Visual.alphaBits)
872 FALLBACK (ctx, SAVAGE_FALLBACK_COLORMASK, !(r && g && b && a));
873 else
874 FALLBACK (ctx, SAVAGE_FALLBACK_COLORMASK, !(r && g && b));
875 }
876
877 /* Seperate specular not fully implemented in hardware... Needs
878 * some interaction with material state? Just punt to software
879 * in all cases?
880 * FK: Don't fall back for now. Let's see the failure cases and
881 * fix them the right way. I don't see how this could be a
882 * hardware limitation.
883 */
884 static void savageUpdateSpecular_s4(GLcontext *ctx) {
885 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
886 u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui;
887
888 if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR &&
889 ctx->Light.Enabled) {
890 imesa->regs.s4.drawLocalCtrl.ni.specShadeEn = GL_TRUE;
891 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_TRUE);*/
892 } else {
893 imesa->regs.s4.drawLocalCtrl.ni.specShadeEn = GL_FALSE;
894 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE);*/
895 }
896
897 if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
898 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
899 }
900 static void savageUpdateSpecular_s3d(GLcontext *ctx) {
901 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
902 u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui;
903
904 if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR &&
905 ctx->Light.Enabled) {
906 imesa->regs.s3d.drawCtrl.ni.specShadeEn = GL_TRUE;
907 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_TRUE);*/
908 } else {
909 imesa->regs.s3d.drawCtrl.ni.specShadeEn = GL_FALSE;
910 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE);*/
911 }
912
913 if (drawCtrl != imesa->regs.s3d.drawCtrl.ui)
914 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
915 }
916
917 static void savageDDLightModelfv_s4(GLcontext *ctx, GLenum pname,
918 const GLfloat *param)
919 {
920 savageUpdateSpecular_s4 (ctx);
921 }
922 static void savageDDLightModelfv_s3d(GLcontext *ctx, GLenum pname,
923 const GLfloat *param)
924 {
925 savageUpdateSpecular_s3d (ctx);
926 }
927
928 static void savageDDShadeModel_s4(GLcontext *ctx, GLuint mod)
929 {
930 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
931 u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui;
932
933 if (mod == GL_SMOOTH)
934 {
935 imesa->regs.s4.drawLocalCtrl.ni.flatShadeEn = GL_FALSE;
936 }
937 else
938 {
939 imesa->regs.s4.drawLocalCtrl.ni.flatShadeEn = GL_TRUE;
940 }
941
942 if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
943 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
944 }
945 static void savageDDShadeModel_s3d(GLcontext *ctx, GLuint mod)
946 {
947 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
948 u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui;
949
950 if (mod == GL_SMOOTH)
951 {
952 imesa->regs.s3d.drawCtrl.ni.flatShadeEn = GL_FALSE;
953 }
954 else
955 {
956 imesa->regs.s3d.drawCtrl.ni.flatShadeEn = GL_TRUE;
957 }
958
959 if (drawCtrl != imesa->regs.s3d.drawCtrl.ui)
960 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
961 }
962
963
964 /* =============================================================
965 * Fog
966 * The fogCtrl register has the same position and the same layout
967 * on savage3d and savage4. No need for two separate functions.
968 */
969
970 static void savageDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
971 {
972 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
973 GLuint fogClr;
974 u_int32_t fogCtrl = imesa->regs.s4.fogCtrl.ui;
975
976 /*if ((ctx->Fog.Enabled) &&(pname == GL_FOG_COLOR))*/
977 if (ctx->Fog.Enabled)
978 {
979 fogClr = (((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) |
980 ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) |
981 ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0));
982 imesa->regs.s4.fogCtrl.ni.fogEn = GL_TRUE;
983 /*cheap fog*/
984 imesa->regs.s4.fogCtrl.ni.fogMode = GL_TRUE;
985 imesa->regs.s4.fogCtrl.ni.fogClr = fogClr;
986 }
987 else
988 {
989 /*No fog*/
990
991 imesa->regs.s4.fogCtrl.ni.fogEn = 0;
992 imesa->regs.s4.fogCtrl.ni.fogMode = 0;
993 }
994
995 if (fogCtrl != imesa->regs.s4.fogCtrl.ui)
996 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
997 }
998
999
1000 static void savageDDStencilFunc(GLcontext *ctx, GLenum func, GLint ref,
1001 GLuint mask)
1002 {
1003 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1004 SCmpFunc a=0;
1005 u_int32_t zBufCtrl = imesa->regs.s4.zBufCtrl.ui;
1006 u_int32_t stencilCtrl = imesa->regs.s4.stencilCtrl.ui;
1007
1008 imesa->regs.s4.zBufCtrl.ni.stencilRefVal = ctx->Stencil.Ref[0];
1009 imesa->regs.s4.stencilCtrl.ni.readMask = ctx->Stencil.ValueMask[0];
1010
1011 switch (ctx->Stencil.Function[0])
1012 {
1013 case GL_NEVER: a = CF_Never; break;
1014 case GL_ALWAYS: a = CF_Always; break;
1015 case GL_LESS: a = CF_Less; break;
1016 case GL_LEQUAL: a = CF_LessEqual; break;
1017 case GL_EQUAL: a = CF_Equal; break;
1018 case GL_GREATER: a = CF_Greater; break;
1019 case GL_GEQUAL: a = CF_GreaterEqual; break;
1020 case GL_NOTEQUAL: a = CF_NotEqual; break;
1021 default:
1022 break;
1023 }
1024
1025 imesa->regs.s4.stencilCtrl.ni.cmpFunc = a;
1026
1027 if (zBufCtrl != imesa->regs.s4.zBufCtrl.ui ||
1028 stencilCtrl != imesa->regs.s4.stencilCtrl.ui)
1029 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
1030 }
1031
1032 static void savageDDStencilMask(GLcontext *ctx, GLuint mask)
1033 {
1034 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1035
1036 if (imesa->regs.s4.stencilCtrl.ni.writeMask != ctx->Stencil.WriteMask[0]) {
1037 imesa->regs.s4.stencilCtrl.ni.writeMask = ctx->Stencil.WriteMask[0];
1038 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
1039 }
1040 }
1041
1042 static void savageDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail,
1043 GLenum zpass)
1044 {
1045 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1046 u_int32_t stencilCtrl = imesa->regs.s4.stencilCtrl.ui;
1047
1048 switch (ctx->Stencil.FailFunc[0])
1049 {
1050 case GL_KEEP:
1051 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Keep;
1052 break;
1053 case GL_ZERO:
1054 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Zero;
1055 break;
1056 case GL_REPLACE:
1057 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Equal;
1058 break;
1059 case GL_INCR:
1060 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_IncClamp;
1061 break;
1062 case GL_DECR:
1063 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_DecClamp;
1064 break;
1065 case GL_INVERT:
1066 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Invert;
1067 break;
1068 case GL_INCR_WRAP_EXT:
1069 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Inc;
1070 break;
1071 case GL_DECR_WRAP_EXT:
1072 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Dec;
1073 break;
1074 }
1075
1076
1077 switch (ctx->Stencil.ZFailFunc[0])
1078 {
1079 case GL_KEEP:
1080 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Keep;
1081 break;
1082 case GL_ZERO:
1083 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Zero;
1084 break;
1085 case GL_REPLACE:
1086 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Equal;
1087 break;
1088 case GL_INCR:
1089 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_IncClamp;
1090 break;
1091 case GL_DECR:
1092 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_DecClamp;
1093 break;
1094 case GL_INVERT:
1095 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Invert;
1096 break;
1097 case GL_INCR_WRAP_EXT:
1098 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Inc;
1099 break;
1100 case GL_DECR_WRAP_EXT:
1101 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Dec;
1102 break;
1103 }
1104
1105 switch (ctx->Stencil.ZPassFunc[0])
1106 {
1107 case GL_KEEP:
1108 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Keep;
1109 break;
1110 case GL_ZERO:
1111 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Zero;
1112 break;
1113 case GL_REPLACE:
1114 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Equal;
1115 break;
1116 case GL_INCR:
1117 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_IncClamp;
1118 break;
1119 case GL_DECR:
1120 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_DecClamp;
1121 break;
1122 case GL_INVERT:
1123 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Invert;
1124 break;
1125 case GL_INCR_WRAP_EXT:
1126 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Inc;
1127 break;
1128 case GL_DECR_WRAP_EXT:
1129 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Dec;
1130 break;
1131 }
1132
1133 if (stencilCtrl != imesa->regs.s4.stencilCtrl.ui)
1134 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
1135 }
1136
1137
1138 /* =============================================================
1139 */
1140
1141 static void savageDDEnable_s4(GLcontext *ctx, GLenum cap, GLboolean state)
1142 {
1143
1144 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1145 switch(cap) {
1146 case GL_ALPHA_TEST:
1147 /* we should consider the disable case*/
1148 savageBlendFunc_s4(ctx);
1149 break;
1150 case GL_BLEND:
1151 /*add the savageBlendFunc 2001/11/25
1152 * if call no such function, then glDisable(GL_BLEND) will do noting,
1153 *our chip has no disable bit
1154 */
1155 savageBlendFunc_s4(ctx);
1156 case GL_COLOR_LOGIC_OP:
1157 /* Fall through:
1158 * For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
1159 */
1160 FALLBACK (ctx, SAVAGE_FALLBACK_LOGICOP,
1161 (ctx->Color.ColorLogicOpEnabled &&
1162 ctx->Color.LogicOp != GL_COPY));
1163 break;
1164 case GL_DEPTH_TEST:
1165 savageDDDepthFunc_s4(ctx,ctx->Depth.Func);
1166 break;
1167 case GL_SCISSOR_TEST:
1168 savageDDScissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
1169 ctx->Scissor.Width, ctx->Scissor.Height);
1170 break;
1171 case GL_STENCIL_TEST:
1172 if (!imesa->hw_stencil)
1173 FALLBACK (ctx, SAVAGE_FALLBACK_STENCIL, state);
1174 else {
1175 imesa->regs.s4.stencilCtrl.ni.stencilEn = state;
1176 if (ctx->Stencil.Enabled &&
1177 imesa->regs.s4.zBufCtrl.ni.zBufEn != GL_TRUE)
1178 {
1179 /* Stencil buffer requires Z enabled. */
1180 imesa->regs.s4.zBufCtrl.ni.zCmpFunc = CF_Always;
1181 imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_TRUE;
1182 imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = GL_FALSE;
1183 }
1184 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL | SAVAGE_UPLOAD_LOCAL;
1185 }
1186 break;
1187 case GL_FOG:
1188 savageDDFogfv(ctx,0,0);
1189 break;
1190 case GL_CULL_FACE:
1191 #if HW_CULL
1192 if (state)
1193 {
1194 savageDDCullFaceFrontFace(ctx,0);
1195 }
1196 else
1197 {
1198 imesa->LcsCullMode = BCM_None;
1199 imesa->new_state |= SAVAGE_NEW_CULL;
1200 }
1201 #endif
1202 break;
1203 case GL_DITHER:
1204 if (state)
1205 {
1206 if ( ctx->Color.DitherFlag )
1207 {
1208 imesa->regs.s4.drawCtrl1.ni.ditherEn=GL_TRUE;
1209 }
1210 }
1211 if (!ctx->Color.DitherFlag )
1212 {
1213 imesa->regs.s4.drawCtrl1.ni.ditherEn=GL_FALSE;
1214 }
1215 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
1216 break;
1217
1218 case GL_LIGHTING:
1219 savageUpdateSpecular_s4 (ctx);
1220 break;
1221 case GL_TEXTURE_1D:
1222 case GL_TEXTURE_3D:
1223 imesa->new_state |= SAVAGE_NEW_TEXTURE;
1224 break;
1225 case GL_TEXTURE_2D:
1226 imesa->new_state |= SAVAGE_NEW_TEXTURE;
1227 break;
1228 default:
1229 ;
1230 }
1231 }
1232 static void savageDDEnable_s3d(GLcontext *ctx, GLenum cap, GLboolean state)
1233 {
1234
1235 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1236 switch(cap) {
1237 case GL_ALPHA_TEST:
1238 /* we should consider the disable case*/
1239 savageBlendFunc_s3d(ctx);
1240 break;
1241 case GL_BLEND:
1242 /*add the savageBlendFunc 2001/11/25
1243 * if call no such function, then glDisable(GL_BLEND) will do noting,
1244 *our chip has no disable bit
1245 */
1246 savageBlendFunc_s3d(ctx);
1247 case GL_COLOR_LOGIC_OP:
1248 /* Fall through:
1249 * For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
1250 */
1251 FALLBACK (ctx, SAVAGE_FALLBACK_LOGICOP,
1252 (ctx->Color.ColorLogicOpEnabled &&
1253 ctx->Color.LogicOp != GL_COPY));
1254 break;
1255 case GL_DEPTH_TEST:
1256 savageDDDepthFunc_s3d(ctx,ctx->Depth.Func);
1257 break;
1258 case GL_SCISSOR_TEST:
1259 savageDDScissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
1260 ctx->Scissor.Width, ctx->Scissor.Height);
1261 break;
1262 case GL_STENCIL_TEST:
1263 FALLBACK (ctx, SAVAGE_FALLBACK_STENCIL, state);
1264 break;
1265 case GL_FOG:
1266 savageDDFogfv(ctx,0,0);
1267 break;
1268 case GL_CULL_FACE:
1269 #if HW_CULL
1270 if (state)
1271 {
1272 savageDDCullFaceFrontFace(ctx,0);
1273 }
1274 else
1275 {
1276 imesa->LcsCullMode = BCM_None;
1277 imesa->new_state |= SAVAGE_NEW_CULL;
1278 }
1279 #endif
1280 break;
1281 case GL_DITHER:
1282 if (state)
1283 {
1284 if ( ctx->Color.DitherFlag )
1285 {
1286 imesa->regs.s3d.drawCtrl.ni.ditherEn=GL_TRUE;
1287 }
1288 }
1289 if (!ctx->Color.DitherFlag )
1290 {
1291 imesa->regs.s3d.drawCtrl.ni.ditherEn=GL_FALSE;
1292 }
1293 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
1294 break;
1295
1296 case GL_LIGHTING:
1297 savageUpdateSpecular_s3d (ctx);
1298 break;
1299 case GL_TEXTURE_1D:
1300 case GL_TEXTURE_3D:
1301 imesa->new_state |= SAVAGE_NEW_TEXTURE;
1302 break;
1303 case GL_TEXTURE_2D:
1304 imesa->new_state |= SAVAGE_NEW_TEXTURE;
1305 break;
1306 default:
1307 ;
1308 }
1309 }
1310
1311 void savageDDUpdateHwState( GLcontext *ctx )
1312 {
1313 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1314
1315 if (imesa->new_state) {
1316 savageFlushVertices(imesa);
1317 if (imesa->new_state & SAVAGE_NEW_TEXTURE) {
1318 savageUpdateTextureState( ctx );
1319 }
1320 if ((imesa->new_state & SAVAGE_NEW_CULL)) {
1321 savageUpdateCull(ctx);
1322 }
1323 imesa->new_state = 0;
1324 }
1325 }
1326
1327
1328 static void savageDDPrintDirty( const char *msg, GLuint state )
1329 {
1330 fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s\n",
1331 msg,
1332 (unsigned int) state,
1333 (state & SAVAGE_UPLOAD_LOCAL) ? "upload-local, " : "",
1334 (state & SAVAGE_UPLOAD_TEX0) ? "upload-tex0, " : "",
1335 (state & SAVAGE_UPLOAD_TEX1) ? "upload-tex1, " : "",
1336 (state & SAVAGE_UPLOAD_FOGTBL) ? "upload-fogtbl, " : "",
1337 (state & SAVAGE_UPLOAD_GLOBAL) ? "upload-global, " : "",
1338 (state & SAVAGE_UPLOAD_TEXGLOBAL) ? "upload-texglobal, " : ""
1339 );
1340 }
1341
1342
1343 /**
1344 * Check if global registers were changed
1345 */
1346 static GLboolean savageGlobalRegChanged (savageContextPtr imesa,
1347 GLuint first, GLuint last) {
1348 GLuint i;
1349 for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i) {
1350 if (((imesa->oldRegs.ui[i] ^ imesa->regs.ui[i]) &
1351 imesa->globalRegMask.ui[i]) != 0)
1352 return GL_TRUE;
1353 }
1354 return GL_FALSE;
1355 }
1356 static void savageEmitOldRegs (savageContextPtr imesa,
1357 GLuint first, GLuint last, GLboolean global) {
1358 GLuint n = last-first+1;
1359 drm_savage_cmd_header_t *cmd = savageAllocCmdBuf(imesa, n*4);
1360 cmd->state.cmd = SAVAGE_CMD_STATE;
1361 cmd->state.global = global;
1362 cmd->state.count = n;
1363 cmd->state.start = first;
1364 memcpy(cmd+1, &imesa->oldRegs.ui[first-SAVAGE_FIRST_REG], n*4);
1365 }
1366 static void savageEmitContiguousRegs (savageContextPtr imesa,
1367 GLuint first, GLuint last) {
1368 GLuint i;
1369 GLuint n = last-first+1;
1370 drm_savage_cmd_header_t *cmd = savageAllocCmdBuf(imesa, n*4);
1371 cmd->state.cmd = SAVAGE_CMD_STATE;
1372 cmd->state.global = savageGlobalRegChanged(imesa, first, last);
1373 cmd->state.count = n;
1374 cmd->state.start = first;
1375 memcpy(cmd+1, &imesa->regs.ui[first-SAVAGE_FIRST_REG], n*4);
1376 /* savageAllocCmdBuf may need to flush the cmd buffer and backup
1377 * the current hardware state. It should see the "old" (current)
1378 * state that has actually been emitted to the hardware. Therefore
1379 * this update is done *after* savageAllocCmdBuf. */
1380 for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i)
1381 imesa->oldRegs.ui[i] = imesa->regs.ui[i];
1382 if (SAVAGE_DEBUG & DEBUG_STATE)
1383 fprintf (stderr, "Emitting regs 0x%02x-0x%02x\n", first, last);
1384 }
1385 static void savageEmitChangedRegs (savageContextPtr imesa,
1386 GLuint first, GLuint last) {
1387 GLuint i, firstChanged;
1388 firstChanged = SAVAGE_NR_REGS;
1389 for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i) {
1390 if (imesa->oldRegs.ui[i] != imesa->regs.ui[i]) {
1391 if (firstChanged == SAVAGE_NR_REGS)
1392 firstChanged = i;
1393 } else {
1394 if (firstChanged != SAVAGE_NR_REGS) {
1395 savageEmitContiguousRegs (imesa, firstChanged+SAVAGE_FIRST_REG,
1396 i-1+SAVAGE_FIRST_REG);
1397 firstChanged = SAVAGE_NR_REGS;
1398 }
1399 }
1400 }
1401 if (firstChanged != SAVAGE_NR_REGS)
1402 savageEmitContiguousRegs (imesa, firstChanged+SAVAGE_FIRST_REG,
1403 last);
1404 }
1405 static void savageEmitChangedRegChunk (savageContextPtr imesa,
1406 GLuint first, GLuint last) {
1407 GLuint i;
1408 for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i) {
1409 if (imesa->oldRegs.ui[i] != imesa->regs.ui[i]) {
1410 savageEmitContiguousRegs (imesa, first, last);
1411 break;
1412 }
1413 }
1414 }
1415 static void savageUpdateRegister_s4(savageContextPtr imesa)
1416 {
1417 /* In case the texture image was changed without changing the
1418 * texture address as well, we need to force emitting the texture
1419 * address in order to flush texture cashes. */
1420 if ((imesa->dirty & SAVAGE_UPLOAD_TEX0) &&
1421 imesa->oldRegs.s4.texAddr[0].ui == imesa->regs.s4.texAddr[0].ui)
1422 imesa->oldRegs.s4.texAddr[0].ui = 0xffffffff;
1423 if ((imesa->dirty & SAVAGE_UPLOAD_TEX1) &&
1424 imesa->oldRegs.s4.texAddr[1].ui == imesa->regs.s4.texAddr[1].ui)
1425 imesa->oldRegs.s4.texAddr[1].ui = 0xffffffff;
1426
1427 /* Fix up watermarks */
1428 if (imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites) {
1429 imesa->regs.s4.destTexWatermarks.ni.destWriteLow = 0;
1430 imesa->regs.s4.destTexWatermarks.ni.destFlush = 1;
1431 } else
1432 imesa->regs.s4.destTexWatermarks.ni.destWriteLow = S4_DWLO;
1433 if (imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites)
1434 imesa->regs.s4.zWatermarks.ni.wLow = 0;
1435 else
1436 imesa->regs.s4.zWatermarks.ni.wLow = S4_ZWLO;
1437
1438 savageEmitChangedRegs (imesa, 0x1e, 0x39);
1439
1440 imesa->dirty=0;
1441 }
1442 static void savageUpdateRegister_s3d(savageContextPtr imesa)
1443 {
1444 /* In case the texture image was changed without changing the
1445 * texture address as well, we need to force emitting the texture
1446 * address in order to flush texture cashes. */
1447 if ((imesa->dirty & SAVAGE_UPLOAD_TEX0) &&
1448 imesa->oldRegs.s3d.texAddr.ui == imesa->regs.s3d.texAddr.ui)
1449 imesa->oldRegs.s3d.texAddr.ui = 0xffffffff;
1450
1451 /* Fix up watermarks */
1452 if (imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites) {
1453 imesa->regs.s3d.destTexWatermarks.ni.destWriteLow = 0;
1454 imesa->regs.s3d.destTexWatermarks.ni.destFlush = 1;
1455 } else
1456 imesa->regs.s3d.destTexWatermarks.ni.destWriteLow = S3D_DWLO;
1457 if (imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites)
1458 imesa->regs.s3d.zWatermarks.ni.wLow = 0;
1459 else
1460 imesa->regs.s3d.zWatermarks.ni.wLow = S3D_ZWLO;
1461
1462
1463 /* the savage3d uses two contiguous ranges of BCI registers:
1464 * 0x18-0x1c and 0x20-0x38. Some texture registers need to be
1465 * emitted in one chunk or we get some funky rendering errors. */
1466 savageEmitChangedRegs (imesa, 0x18, 0x19);
1467 savageEmitChangedRegChunk (imesa, 0x1a, 0x1c);
1468 savageEmitChangedRegs (imesa, 0x20, 0x38);
1469
1470 imesa->dirty=0;
1471 }
1472
1473
1474 void savageEmitOldState( savageContextPtr imesa )
1475 {
1476 assert(imesa->cmdBuf.write == imesa->cmdBuf.base);
1477 if (imesa->savageScreen->chipset >= S3_SAVAGE4) {
1478 savageEmitOldRegs (imesa, 0x1e, 0x39, GL_TRUE);
1479 } else {
1480 savageEmitOldRegs (imesa, 0x18, 0x1c, GL_TRUE);
1481 savageEmitOldRegs (imesa, 0x20, 0x38, GL_FALSE);
1482 }
1483 }
1484
1485
1486 /* Push the state into the sarea and/or texture memory.
1487 */
1488 void savageEmitChangedState( savageContextPtr imesa )
1489 {
1490 if (SAVAGE_DEBUG & DEBUG_VERBOSE_API)
1491 savageDDPrintDirty( "\n\n\nsavageEmitHwStateLocked", imesa->dirty );
1492
1493 if (imesa->dirty)
1494 {
1495 if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
1496 fprintf (stderr, "... emitting state\n");
1497 if (imesa->savageScreen->chipset >= S3_SAVAGE4)
1498 savageUpdateRegister_s4(imesa);
1499 else
1500 savageUpdateRegister_s3d(imesa);
1501 }
1502
1503 imesa->dirty = 0;
1504 }
1505
1506
1507 static void savageDDInitState_s4( savageContextPtr imesa )
1508 {
1509 #if 1
1510 imesa->regs.s4.destCtrl.ui = 1<<7;
1511 #endif
1512
1513 imesa->regs.s4.zBufCtrl.ni.zCmpFunc = CF_Less;
1514 imesa->regs.s4.zBufCtrl.ni.wToZEn = GL_TRUE;
1515 if (imesa->float_depth) {
1516 imesa->regs.s4.zBufCtrl.ni.zExpOffset =
1517 imesa->savageScreen->zpp == 2 ? 16 : 32;
1518 imesa->regs.s4.zBufCtrl.ni.floatZEn = GL_TRUE;
1519 } else {
1520 imesa->regs.s4.zBufCtrl.ni.zExpOffset = 0;
1521 imesa->regs.s4.zBufCtrl.ni.floatZEn = GL_FALSE;
1522 }
1523 imesa->regs.s4.texBlendCtrl[0].ui = TBC_NoTexMap;
1524 imesa->regs.s4.texBlendCtrl[1].ui = TBC_NoTexMap1;
1525 imesa->regs.s4.drawCtrl0.ui = 0;
1526 #if 0
1527 imesa->regs.s4.drawCtrl1.ni.xyOffsetEn = 1;
1528 #endif
1529
1530 /* Set DestTexWatermarks_31,30 to 01 always.
1531 *Has no effect if dest. flush is disabled.
1532 */
1533 #if 0
1534 imesa->regs.s4.zWatermarks.ui = 0x12000C04;
1535 imesa->regs.s4.destTexWatermarks.ui = 0x40200400;
1536 #else
1537 /*imesa->regs.s4.zWatermarks.ui = 0x16001808;*/
1538 imesa->regs.s4.zWatermarks.ni.rLow = S4_ZRLO;
1539 imesa->regs.s4.zWatermarks.ni.rHigh = S4_ZRHI;
1540 imesa->regs.s4.zWatermarks.ni.wLow = S4_ZWLO;
1541 imesa->regs.s4.zWatermarks.ni.wHigh = S4_ZWHI;
1542 /*imesa->regs.s4.destTexWatermarks.ui = 0x4f000000;*/
1543 imesa->regs.s4.destTexWatermarks.ni.destReadLow = S4_DRLO;
1544 imesa->regs.s4.destTexWatermarks.ni.destReadHigh = S4_DRHI;
1545 imesa->regs.s4.destTexWatermarks.ni.destWriteLow = S4_DWLO;
1546 imesa->regs.s4.destTexWatermarks.ni.destWriteHigh = S4_DWHI;
1547 imesa->regs.s4.destTexWatermarks.ni.texRead = S4_TR;
1548 imesa->regs.s4.destTexWatermarks.ni.destFlush = 1;
1549 #endif
1550 imesa->regs.s4.drawCtrl0.ni.dPerfAccelEn = GL_TRUE;
1551
1552 /* clrCmpAlphaBlendCtrl is needed to get alphatest and
1553 * alpha blending working properly
1554 */
1555
1556 imesa->regs.s4.texCtrl[0].ni.dBias = 0x08;
1557 imesa->regs.s4.texCtrl[1].ni.dBias = 0x08;
1558 imesa->regs.s4.texCtrl[0].ni.texXprEn = GL_TRUE;
1559 imesa->regs.s4.texCtrl[1].ni.texXprEn = GL_TRUE;
1560 imesa->regs.s4.texCtrl[0].ni.dMax = 0x0f;
1561 imesa->regs.s4.texCtrl[1].ni.dMax = 0x0f;
1562 /* programm a valid tex address, in case texture state is emitted
1563 * in wrong order. */
1564 if (imesa->lastTexHeap == 2 && imesa->savageScreen->textureSize[1]) {
1565 /* AGP textures available */
1566 imesa->regs.s4.texAddr[0].ui = imesa->savageScreen->textureOffset[1]|3;
1567 imesa->regs.s4.texAddr[1].ui = imesa->savageScreen->textureOffset[1]|3;
1568 } else {
1569 /* no AGP textures available, use local */
1570 imesa->regs.s4.texAddr[0].ui = imesa->savageScreen->textureOffset[0]|2;
1571 imesa->regs.s4.texAddr[1].ui = imesa->savageScreen->textureOffset[0]|2;
1572 }
1573 imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn = GL_TRUE;
1574 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_One;
1575 imesa->regs.s4.drawLocalCtrl.ni.wrZafterAlphaTst = GL_FALSE;
1576 imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites= GL_TRUE;
1577 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites= GL_TRUE;
1578
1579 imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn= GL_TRUE;
1580 imesa->regs.s4.drawCtrl1.ni.ditherEn = (
1581 driQueryOptioni(&imesa->optionCache, "color_reduction") ==
1582 DRI_CONF_COLOR_REDUCTION_DITHER) ? GL_TRUE : GL_FALSE;
1583 imesa->regs.s4.drawCtrl1.ni.cullMode = BCM_None;
1584
1585 imesa->regs.s4.zBufCtrl.ni.stencilRefVal = 0x00;
1586
1587 imesa->regs.s4.stencilCtrl.ni.stencilEn = GL_FALSE;
1588 imesa->regs.s4.stencilCtrl.ni.cmpFunc = CF_Always;
1589 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Keep;
1590 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Keep;
1591 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Keep;
1592 imesa->regs.s4.stencilCtrl.ni.writeMask = 0xff;
1593 imesa->regs.s4.stencilCtrl.ni.readMask = 0xff;
1594
1595 imesa->LcsCullMode=BCM_None;
1596 imesa->regs.s4.texDescr.ni.palSize = TPS_256;
1597
1598 /* clear the local registers in the global reg mask */
1599 imesa->globalRegMask.s4.drawLocalCtrl.ui = 0;
1600 imesa->globalRegMask.s4.texPalAddr.ui = 0;
1601 imesa->globalRegMask.s4.texCtrl[0].ui = 0;
1602 imesa->globalRegMask.s4.texCtrl[1].ui = 0;
1603 imesa->globalRegMask.s4.texAddr[0].ui = 0;
1604 imesa->globalRegMask.s4.texAddr[1].ui = 0;
1605 imesa->globalRegMask.s4.texBlendCtrl[0].ui = 0;
1606 imesa->globalRegMask.s4.texBlendCtrl[1].ui = 0;
1607 imesa->globalRegMask.s4.texXprClr.ui = 0;
1608 imesa->globalRegMask.s4.texDescr.ui = 0;
1609 }
1610 static void savageDDInitState_s3d( savageContextPtr imesa )
1611 {
1612 #if 1
1613 imesa->regs.s3d.destCtrl.ui = 1<<7;
1614 #endif
1615
1616 imesa->regs.s3d.zBufCtrl.ni.zCmpFunc = CF_Less;
1617 #if 0
1618 imesa->regs.s3d.drawCtrl.ni.xyOffsetEn = 1;
1619 #endif
1620
1621 /* Set DestTexWatermarks_31,30 to 01 always.
1622 *Has no effect if dest. flush is disabled.
1623 */
1624 #if 0
1625 imesa->regs.s3d.zWatermarks.ui = 0x12000C04;
1626 imesa->regs.s3d.destTexWatermarks.ui = 0x40200400;
1627 #else
1628 /*imesa->regs.s3d.zWatermarks.ui = 0x16001808;*/
1629 imesa->regs.s3d.zWatermarks.ni.rLow = S3D_ZRLO;
1630 imesa->regs.s3d.zWatermarks.ni.rHigh = S3D_ZRHI;
1631 imesa->regs.s3d.zWatermarks.ni.wLow = S3D_ZWLO;
1632 imesa->regs.s3d.zWatermarks.ni.wHigh = S3D_ZWHI;
1633 /*imesa->regs.s3d.destTexWatermarks.ui = 0x4f000000;*/
1634 imesa->regs.s3d.destTexWatermarks.ni.destReadLow = S3D_DRLO;
1635 imesa->regs.s3d.destTexWatermarks.ni.destReadHigh = S3D_DRHI;
1636 imesa->regs.s3d.destTexWatermarks.ni.destWriteLow = S3D_DWLO;
1637 imesa->regs.s3d.destTexWatermarks.ni.destWriteHigh = S3D_DWHI;
1638 imesa->regs.s3d.destTexWatermarks.ni.texRead = S3D_TR;
1639 imesa->regs.s3d.destTexWatermarks.ni.destFlush = 1;
1640 #endif
1641
1642 imesa->regs.s3d.texCtrl.ni.dBias = 0x08;
1643 imesa->regs.s3d.texCtrl.ni.texXprEn = GL_TRUE;
1644 /* texXprEn is needed to get alphatest and alpha blending working
1645 * properly. However, this makes texels with color texXprClr
1646 * completely transparent in some texture environment modes. I
1647 * couldn't find a way to disable this. So choose an arbitrary and
1648 * improbable color. (0 is a bad choice, makes all black texels
1649 * transparent.) */
1650 imesa->regs.s3d.texXprClr.ui = 0x26ae26ae;
1651 /* programm a valid tex address, in case texture state is emitted
1652 * in wrong order. */
1653 if (imesa->lastTexHeap == 2 && imesa->savageScreen->textureSize[1]) {
1654 /* AGP textures available */
1655 imesa->regs.s3d.texAddr.ui = imesa->savageScreen->textureOffset[1]|3;
1656 } else {
1657 /* no AGP textures available, use local */
1658 imesa->regs.s3d.texAddr.ui = imesa->savageScreen->textureOffset[0]|2;
1659 }
1660
1661 imesa->regs.s3d.zBufCtrl.ni.drawUpdateEn = GL_TRUE;
1662 imesa->regs.s3d.zBufCtrl.ni.wrZafterAlphaTst = GL_FALSE;
1663 imesa->regs.s3d.zBufCtrl.ni.zUpdateEn = GL_TRUE;
1664
1665 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_One;
1666 imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE;
1667 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
1668
1669 imesa->regs.s3d.drawCtrl.ni.ditherEn = (
1670 driQueryOptioni(&imesa->optionCache, "color_reduction") ==
1671 DRI_CONF_COLOR_REDUCTION_DITHER) ? GL_TRUE : GL_FALSE;
1672 imesa->regs.s3d.drawCtrl.ni.cullMode = BCM_None;
1673
1674 imesa->LcsCullMode = BCM_None;
1675 imesa->regs.s3d.texDescr.ni.palSize = TPS_256;
1676
1677 /* clear the local registers in the global reg mask */
1678 imesa->globalRegMask.s3d.texPalAddr.ui = 0;
1679 imesa->globalRegMask.s3d.texXprClr.ui = 0;
1680 imesa->globalRegMask.s3d.texAddr.ui = 0;
1681 imesa->globalRegMask.s3d.texDescr.ui = 0;
1682 imesa->globalRegMask.s3d.texCtrl.ui = 0;
1683
1684 imesa->globalRegMask.s3d.fogCtrl.ui = 0;
1685
1686 /* drawCtrl is local with some exceptions */
1687 imesa->globalRegMask.s3d.drawCtrl.ui = 0;
1688 imesa->globalRegMask.s3d.drawCtrl.ni.cullMode = 0x3;
1689 imesa->globalRegMask.s3d.drawCtrl.ni.alphaTestCmpFunc = 0x7;
1690 imesa->globalRegMask.s3d.drawCtrl.ni.alphaTestEn = 0x1;
1691 imesa->globalRegMask.s3d.drawCtrl.ni.alphaRefVal = 0xff;
1692
1693 /* zBufCtrl is local with some exceptions */
1694 imesa->globalRegMask.s3d.zBufCtrl.ui = 0;
1695 imesa->globalRegMask.s3d.zBufCtrl.ni.zCmpFunc = 0x7;
1696 imesa->globalRegMask.s3d.zBufCtrl.ni.zBufEn = 0x1;
1697 }
1698 void savageDDInitState( savageContextPtr imesa ) {
1699 memset (imesa->regs.ui, 0, SAVAGE_NR_REGS*sizeof(u_int32_t));
1700 memset (imesa->globalRegMask.ui, 0xff, SAVAGE_NR_REGS*sizeof(u_int32_t));
1701 if (imesa->savageScreen->chipset >= S3_SAVAGE4)
1702 savageDDInitState_s4 (imesa);
1703 else
1704 savageDDInitState_s3d (imesa);
1705
1706 /*fprintf(stderr,"DBflag:%d\n",imesa->glCtx->Visual->DBflag);*/
1707 /* zbufoffset and destctrl have the same position and layout on
1708 * savage4 and savage3d. */
1709 if (imesa->glCtx->Visual.doubleBufferMode) {
1710 imesa->IsDouble = GL_TRUE;
1711 imesa->toggle = TARGET_BACK;
1712 imesa->regs.s4.destCtrl.ni.offset =
1713 imesa->savageScreen->backOffset>>11;
1714 } else {
1715 imesa->IsDouble = GL_FALSE;
1716 imesa->toggle = TARGET_FRONT;
1717 imesa->regs.s4.destCtrl.ni.offset =
1718 imesa->savageScreen->frontOffset>>11;
1719 }
1720 if(imesa->savageScreen->cpp == 2) {
1721 imesa->regs.s4.destCtrl.ni.dstPixFmt = 0;
1722 imesa->regs.s4.destCtrl.ni.dstWidthInTile =
1723 (imesa->savageScreen->width+63)>>6;
1724 } else {
1725 imesa->regs.s4.destCtrl.ni.dstPixFmt = 1;
1726 imesa->regs.s4.destCtrl.ni.dstWidthInTile =
1727 (imesa->savageScreen->width+31)>>5;
1728 }
1729 imesa->drawMap = imesa->apertureBase[imesa->toggle];
1730 imesa->readMap = imesa->apertureBase[imesa->toggle];
1731 imesa->NotFirstFrame = GL_FALSE;
1732
1733 imesa->regs.s4.zBufOffset.ni.offset=imesa->savageScreen->depthOffset>>11;
1734 if(imesa->savageScreen->zpp == 2) {
1735 imesa->regs.s4.zBufOffset.ni.zBufWidthInTiles =
1736 (imesa->savageScreen->width+63)>>6;
1737 imesa->regs.s4.zBufOffset.ni.zDepthSelect = 0;
1738 } else {
1739 imesa->regs.s4.zBufOffset.ni.zBufWidthInTiles =
1740 (imesa->savageScreen->width+31)>>5;
1741 imesa->regs.s4.zBufOffset.ni.zDepthSelect = 1;
1742 }
1743
1744 memcpy (imesa->oldRegs.ui, imesa->regs.ui, SAVAGE_NR_REGS*sizeof(u_int32_t));
1745
1746 /* Emit the initial state to the (empty) command buffer. */
1747 assert (imesa->cmdBuf.write == imesa->cmdBuf.base);
1748 savageEmitOldState(imesa);
1749 imesa->cmdBuf.start = imesa->cmdBuf.write;
1750 }
1751
1752
1753 #define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\
1754 NEW_TEXTURE_MATRIX|\
1755 NEW_USER_CLIP|NEW_CLIENT_STATE))
1756
1757 static void savageDDInvalidateState( GLcontext *ctx, GLuint new_state )
1758 {
1759 _swrast_InvalidateState( ctx, new_state );
1760 _swsetup_InvalidateState( ctx, new_state );
1761 _ac_InvalidateState( ctx, new_state );
1762 _tnl_InvalidateState( ctx, new_state );
1763 SAVAGE_CONTEXT(ctx)->new_gl_state |= new_state;
1764 }
1765
1766
1767 void savageDDInitStateFuncs(GLcontext *ctx)
1768 {
1769 ctx->Driver.UpdateState = savageDDInvalidateState;
1770 ctx->Driver.BlendEquationSeparate = savageDDBlendEquationSeparate;
1771 ctx->Driver.Fogfv = savageDDFogfv;
1772 ctx->Driver.Scissor = savageDDScissor;
1773 #if HW_CULL
1774 ctx->Driver.CullFace = savageDDCullFaceFrontFace;
1775 ctx->Driver.FrontFace = savageDDCullFaceFrontFace;
1776 #else
1777 ctx->Driver.CullFace = 0;
1778 ctx->Driver.FrontFace = 0;
1779 #endif /* end #if HW_CULL */
1780 ctx->Driver.PolygonMode=NULL;
1781 ctx->Driver.PolygonStipple = 0;
1782 ctx->Driver.LineStipple = 0;
1783 ctx->Driver.LineWidth = 0;
1784 ctx->Driver.LogicOpcode = 0;
1785 ctx->Driver.DrawBuffer = savageDDDrawBuffer;
1786 ctx->Driver.ReadBuffer = savageDDReadBuffer;
1787 ctx->Driver.ClearColor = savageDDClearColor;
1788
1789 ctx->Driver.DepthRange = savageDepthRange;
1790 ctx->Driver.Viewport = savageViewport;
1791 ctx->Driver.RenderMode = savageRenderMode;
1792
1793 ctx->Driver.ClearIndex = 0;
1794 ctx->Driver.IndexMask = 0;
1795
1796 if (SAVAGE_CONTEXT( ctx )->savageScreen->chipset >= S3_SAVAGE4) {
1797 ctx->Driver.Enable = savageDDEnable_s4;
1798 ctx->Driver.AlphaFunc = savageDDAlphaFunc_s4;
1799 ctx->Driver.DepthFunc = savageDDDepthFunc_s4;
1800 ctx->Driver.DepthMask = savageDDDepthMask_s4;
1801 ctx->Driver.BlendFuncSeparate = savageDDBlendFuncSeparate_s4;
1802 ctx->Driver.ColorMask = savageDDColorMask_s4;
1803 ctx->Driver.ShadeModel = savageDDShadeModel_s4;
1804 ctx->Driver.LightModelfv = savageDDLightModelfv_s4;
1805 ctx->Driver.StencilFunc = savageDDStencilFunc;
1806 ctx->Driver.StencilMask = savageDDStencilMask;
1807 ctx->Driver.StencilOp = savageDDStencilOp;
1808 } else {
1809 ctx->Driver.Enable = savageDDEnable_s3d;
1810 ctx->Driver.AlphaFunc = savageDDAlphaFunc_s3d;
1811 ctx->Driver.DepthFunc = savageDDDepthFunc_s3d;
1812 ctx->Driver.DepthMask = savageDDDepthMask_s3d;
1813 ctx->Driver.BlendFuncSeparate = savageDDBlendFuncSeparate_s3d;
1814 ctx->Driver.ColorMask = savageDDColorMask_s3d;
1815 ctx->Driver.ShadeModel = savageDDShadeModel_s3d;
1816 ctx->Driver.LightModelfv = savageDDLightModelfv_s3d;
1817 ctx->Driver.StencilFunc = 0;
1818 ctx->Driver.StencilMask = 0;
1819 ctx->Driver.StencilOp = 0;
1820 }
1821
1822 /* Swrast hooks for imaging extensions:
1823 */
1824 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
1825 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
1826 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
1827 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
1828 }