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