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