Small optimization for big-endian (e.g., PowerPC) systems.
[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 && imesa->hw_stencil)
487 {
488 /* Need to keep Z on for Stencil. */
489 imesa->regs.s4.zBufCtrl.ni.zCmpFunc = CF_Always;
490 imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_TRUE;
491 imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = GL_FALSE;
492 imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE;
493 imesa->regs.s4.zWatermarks.ni.wLow = 8;
494 }
495 else
496 {
497
498 if (imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn == GL_FALSE)
499 {
500 imesa->regs.s4.zBufCtrl.ni.zCmpFunc = CF_Always;
501 imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_TRUE;
502 }
503 else
504
505 /* DRAWUPDATE_REQUIRES_Z_ENABLED*/
506 {
507 imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_FALSE;
508 }
509 imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = GL_FALSE;
510 imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE;
511 imesa->regs.s4.zWatermarks.ni.wLow = 8;
512 }
513
514 imesa->dirty |= SAVAGE_UPLOAD_CTX;
515 }
516 static void savageDDDepthFunc_s3d(GLcontext *ctx, GLenum func)
517 {
518 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
519 ZCmpFunc zmode;
520 #define depthIndex 0
521
522 /* set up z-buffer control register (global)
523 * set up z-buffer offset register (global)
524 * set up z read/write watermarks register (global)
525 */
526 switch(func) {
527 case GL_NEVER: zmode = CF_Never; break;
528 case GL_ALWAYS: zmode = CF_Always; break;
529 case GL_LESS: zmode = CF_Less; break;
530 case GL_LEQUAL: zmode = CF_LessEqual; break;
531 case GL_EQUAL: zmode = CF_Equal; break;
532 case GL_GREATER: zmode = CF_Greater; break;
533 case GL_GEQUAL: zmode = CF_GreaterEqual; break;
534 case GL_NOTEQUAL: zmode = CF_NotEqual; break;
535 default:return;
536 }
537 if (ctx->Depth.Test)
538 {
539 imesa->regs.s3d.zBufCtrl.ni.zBufEn = GL_TRUE;
540 imesa->regs.s3d.zBufCtrl.ni.zCmpFunc = zmode;
541 imesa->regs.s3d.zBufCtrl.ni.zUpdateEn = ctx->Depth.Mask;
542
543 imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE;
544 #if 1
545 imesa->regs.s3d.zWatermarks.ni.wLow = 0;
546 #endif
547 }
548 else
549 {
550 if (imesa->regs.s3d.zBufCtrl.ni.drawUpdateEn == GL_FALSE) {
551 imesa->regs.s3d.zBufCtrl.ni.zCmpFunc = CF_Always;
552 imesa->regs.s3d.zBufCtrl.ni.zBufEn = GL_TRUE;
553 }
554 else
555
556 /* DRAWUPDATE_REQUIRES_Z_ENABLED*/
557 {
558 imesa->regs.s3d.zBufCtrl.ni.zBufEn = GL_FALSE;
559 }
560 imesa->regs.s3d.zBufCtrl.ni.zUpdateEn = GL_FALSE;
561 imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_FALSE;
562 imesa->regs.s3d.zWatermarks.ni.wLow = 8;
563 }
564
565 imesa->dirty |= SAVAGE_UPLOAD_CTX;
566 }
567
568 static void savageDDDepthMask_s4(GLcontext *ctx, GLboolean flag)
569 {
570 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
571
572 imesa->dirty |= SAVAGE_UPLOAD_CTX;
573 if (flag)
574 {
575 imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_TRUE;
576 }
577 else
578 {
579 imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE;
580 }
581 savageDDDepthFunc_s4(ctx,ctx->Depth.Func);
582 }
583 static void savageDDDepthMask_s3d(GLcontext *ctx, GLboolean flag)
584 {
585 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
586
587 imesa->dirty |= SAVAGE_UPLOAD_CTX;
588 if (flag)
589 {
590 imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE;
591 }
592 else
593 {
594 imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_FALSE;
595 }
596 savageDDDepthFunc_s3d(ctx,ctx->Depth.Func);
597 }
598
599
600
601
602 /* =============================================================
603 * Hardware clipping
604 */
605
606
607 static void savageDDScissor( GLcontext *ctx, GLint x, GLint y,
608 GLsizei w, GLsizei h )
609 {
610 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
611 imesa->scissor_rect.x1 = MAX2(imesa->drawX+x,imesa->draw_rect.x1);
612 imesa->scissor_rect.y1 = MAX2(imesa->drawY+imesa->driDrawable->h -(y+h),
613 imesa->draw_rect.y1);
614 imesa->scissor_rect.x2 = MIN2(imesa->drawX+x+w,imesa->draw_rect.x2);
615 imesa->scissor_rect.y2 = MIN2(imesa->drawY+imesa->driDrawable->h - y,
616 imesa->draw_rect.y2);
617
618
619 imesa->scissorChanged=GL_TRUE;
620
621 imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS;
622 }
623
624
625
626 static void savageDDDrawBuffer(GLcontext *ctx, GLenum mode )
627 {
628 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
629
630 /*
631 * _DrawDestMask is easier to cope with than <mode>.
632 */
633 switch ( ctx->Color._DrawDestMask[0] ) {
634 case DD_FRONT_LEFT_BIT:
635 imesa->IsDouble = GL_FALSE;
636
637 imesa->drawMap = (char *)imesa->apertureBase[TARGET_FRONT];
638 imesa->readMap = (char *)imesa->apertureBase[TARGET_FRONT];
639 imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->frontOffset>>11;
640 imesa->NotFirstFrame = GL_FALSE;
641 imesa->dirty |= SAVAGE_UPLOAD_BUFFERS | SAVAGE_UPLOAD_CTX;
642 savageXMesaSetFrontClipRects( imesa );
643 FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_FALSE );
644 break;
645 case DD_BACK_LEFT_BIT:
646 imesa->IsDouble = GL_TRUE;
647 imesa->drawMap = (char *)imesa->apertureBase[TARGET_BACK];
648 imesa->readMap = (char *)imesa->apertureBase[TARGET_BACK];
649 imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->backOffset>>11;
650 imesa->NotFirstFrame = GL_FALSE;
651 imesa->dirty |= SAVAGE_UPLOAD_BUFFERS | SAVAGE_UPLOAD_CTX;
652 savageXMesaSetBackClipRects( imesa );
653 FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_FALSE );
654 break;
655 default:
656 FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_TRUE );
657 return;
658 }
659
660 /* We want to update the s/w rast state too so that r200SetBuffer() (?)
661 * gets called.
662 */
663 _swrast_DrawBuffer(ctx, mode);
664 }
665
666 static void savageDDReadBuffer(GLcontext *ctx, GLenum mode )
667 {
668 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
669 }
670
671 #if 0
672 static void savageDDSetColor(GLcontext *ctx,
673 GLubyte r, GLubyte g,
674 GLubyte b, GLubyte a )
675 {
676 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
677 imesa->MonoColor = savagePackColor( imesa->savageScreen->frontFormat, r, g, b, a );
678 }
679 #endif
680
681 /* =============================================================
682 * Window position and viewport transformation
683 */
684
685 static void savageCalcViewport( GLcontext *ctx )
686 {
687 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
688 const GLfloat *v = ctx->Viewport._WindowMap.m;
689 GLfloat *m = imesa->hw_viewport;
690
691 /* See also mga_translate_vertex.
692 */
693 m[MAT_SX] = v[MAT_SX];
694 m[MAT_TX] = v[MAT_TX] + imesa->drawX + SUBPIXEL_X;
695 m[MAT_SY] = - v[MAT_SY];
696 m[MAT_TY] = - v[MAT_TY] + imesa->driDrawable->h + imesa->drawY + SUBPIXEL_Y;
697 m[MAT_SZ] = v[MAT_SZ] * imesa->depth_scale;
698 m[MAT_TZ] = v[MAT_TZ] * imesa->depth_scale;
699
700 imesa->SetupNewInputs = ~0;
701 }
702
703 static void savageViewport( GLcontext *ctx,
704 GLint x, GLint y,
705 GLsizei width, GLsizei height )
706 {
707 savageCalcViewport( ctx );
708 }
709
710 static void savageDepthRange( GLcontext *ctx,
711 GLclampd nearval, GLclampd farval )
712 {
713 savageCalcViewport( ctx );
714 }
715
716
717 /* =============================================================
718 * Miscellaneous
719 */
720
721 static void savageDDClearColor(GLcontext *ctx,
722 const GLfloat color[4] )
723 {
724 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
725 GLubyte c[4];
726 CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
727 CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
728 CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
729 CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
730
731 imesa->ClearColor = savagePackColor( imesa->savageScreen->frontFormat,
732 c[0], c[1], c[2], c[3] );
733 }
734
735 /* Fallback to swrast for select and feedback.
736 */
737 static void savageRenderMode( GLcontext *ctx, GLenum mode )
738 {
739 FALLBACK( ctx, SAVAGE_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
740 }
741
742
743 #if HW_CULL
744
745 /* =============================================================
746 * Culling - the savage isn't quite as clean here as the rest of
747 * its interfaces, but it's not bad.
748 */
749 static void savageDDCullFaceFrontFace(GLcontext *ctx, GLenum unused)
750 {
751 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
752 GLuint cullMode=imesa->LcsCullMode;
753 switch (ctx->Polygon.CullFaceMode)
754 {
755 case GL_FRONT:
756 switch (ctx->Polygon.FrontFace)
757 {
758 case GL_CW:
759 cullMode = BCM_CW;
760 break;
761 case GL_CCW:
762 cullMode = BCM_CCW;
763 break;
764 }
765 break;
766
767 case GL_BACK:
768 switch (ctx->Polygon.FrontFace)
769 {
770 case GL_CW:
771 cullMode = BCM_CCW;
772 break;
773 case GL_CCW:
774 cullMode = BCM_CW;
775 break;
776 }
777 break;
778 }
779 imesa->LcsCullMode = cullMode;
780 imesa->new_state |= SAVAGE_NEW_CULL;
781 }
782 #endif /* end #if HW_CULL */
783
784 static void savageUpdateCull( GLcontext *ctx )
785 {
786 #if HW_CULL
787 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
788 GLuint cullMode;
789 if (ctx->Polygon.CullFlag &&
790 imesa->raster_primitive == GL_TRIANGLES &&
791 ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK)
792 cullMode = imesa->LcsCullMode;
793 else
794 cullMode = BCM_None;
795 if (imesa->savageScreen->chipset >= S3_SAVAGE4) {
796 if (imesa->regs.s4.drawCtrl1.ni.cullMode != cullMode) {
797 imesa->regs.s4.drawCtrl1.ni.cullMode = cullMode;
798 imesa->dirty |= SAVAGE_UPLOAD_CTX;
799 }
800 } else {
801 if (imesa->regs.s3d.drawCtrl.ni.cullMode != cullMode) {
802 imesa->regs.s3d.drawCtrl.ni.cullMode = cullMode;
803 imesa->dirty |= SAVAGE_UPLOAD_CTX;
804 }
805 }
806 #endif /* end #if HW_CULL */
807 }
808
809
810
811 /* =============================================================
812 * Color masks
813 */
814
815 /* Mesa calls this from the wrong place - it is called a very large
816 * number of redundant times.
817 *
818 * Colormask can be simulated by multipass or multitexture techniques.
819 */
820 static void savageDDColorMask_s4(GLcontext *ctx,
821 GLboolean r, GLboolean g,
822 GLboolean b, GLboolean a )
823 {
824 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
825 GLuint enable;
826
827 if (ctx->Visual.alphaBits)
828 {
829 enable = b | g | r | a;
830 }
831 else
832 {
833 enable = b | g | r;
834 }
835
836 if (enable)
837 {
838 imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn = GL_TRUE;
839 }
840 else
841 {
842 imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn = GL_FALSE;
843 }
844 imesa->dirty |= SAVAGE_UPLOAD_CTX;
845 /* TODO: need a software fallback */
846 }
847 static void savageDDColorMask_s3d(GLcontext *ctx,
848 GLboolean r, GLboolean g,
849 GLboolean b, GLboolean a )
850 {
851 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
852 GLuint enable;
853
854 if (ctx->Visual.alphaBits)
855 {
856 enable = b | g | r | a;
857 }
858 else
859 {
860 enable = b | g | r;
861 }
862
863 if (enable)
864 {
865 imesa->regs.s3d.zBufCtrl.ni.drawUpdateEn = GL_TRUE;
866 }
867 else
868 {
869 imesa->regs.s3d.zBufCtrl.ni.drawUpdateEn = GL_FALSE;
870 }
871 imesa->dirty |= SAVAGE_UPLOAD_CTX;
872 /* TODO: need a software fallback */
873 }
874
875 /* Seperate specular not fully implemented in hardware... Needs
876 * some interaction with material state? Just punt to software
877 * in all cases?
878 * FK: Don't fall back for now. Let's see the failure cases and
879 * fix them the right way. I don't see how this could be a
880 * hardware limitation.
881 */
882 static void savageUpdateSpecular_s4(GLcontext *ctx) {
883 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
884
885 if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR &&
886 ctx->Light.Enabled) {
887 imesa->regs.s4.drawLocalCtrl.ni.specShadeEn = GL_TRUE;
888 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_TRUE);*/
889 } else {
890 imesa->regs.s4.drawLocalCtrl.ni.specShadeEn = GL_FALSE;
891 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE);*/
892 }
893 imesa->dirty |= SAVAGE_UPLOAD_CTX;
894 }
895 static void savageUpdateSpecular_s3d(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.s3d.drawCtrl.ni.specShadeEn = GL_TRUE;
901 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_TRUE);*/
902 } else {
903 imesa->regs.s3d.drawCtrl.ni.specShadeEn = GL_FALSE;
904 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE);*/
905 }
906 imesa->dirty |= SAVAGE_UPLOAD_CTX;
907 }
908
909 static void savageDDLightModelfv_s4(GLcontext *ctx, GLenum pname,
910 const GLfloat *param)
911 {
912 savageUpdateSpecular_s4 (ctx);
913 }
914 static void savageDDLightModelfv_s3d(GLcontext *ctx, GLenum pname,
915 const GLfloat *param)
916 {
917 savageUpdateSpecular_s3d (ctx);
918 }
919
920 static void savageDDShadeModel_s4(GLcontext *ctx, GLuint mod)
921 {
922 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
923
924 if (mod == GL_SMOOTH)
925 {
926 imesa->regs.s4.drawLocalCtrl.ni.flatShadeEn = GL_FALSE;
927 }
928 else
929 {
930 imesa->regs.s4.drawLocalCtrl.ni.flatShadeEn = GL_TRUE;
931 }
932 imesa->dirty |= SAVAGE_UPLOAD_CTX;
933 }
934 static void savageDDShadeModel_s3d(GLcontext *ctx, GLuint mod)
935 {
936 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
937
938 if (mod == GL_SMOOTH)
939 {
940 imesa->regs.s3d.drawCtrl.ni.flatShadeEn = GL_FALSE;
941 }
942 else
943 {
944 imesa->regs.s3d.drawCtrl.ni.flatShadeEn = GL_TRUE;
945 }
946 imesa->dirty |= SAVAGE_UPLOAD_CTX;
947 }
948
949
950 /* =============================================================
951 * Fog
952 * The fogCtrl register has the same position and the same layout
953 * on savage3d and savage4. No need for two separate functions.
954 */
955
956 static void savageDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
957 {
958 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
959 GLuint fogClr;
960
961 /*if ((ctx->Fog.Enabled) &&(pname == GL_FOG_COLOR))*/
962 if (ctx->Fog.Enabled)
963 {
964 fogClr = (((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) |
965 ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) |
966 ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0));
967 imesa->regs.s4.fogCtrl.ni.fogEn = GL_TRUE;
968 /*cheap fog*/
969 imesa->regs.s4.fogCtrl.ni.fogMode = GL_TRUE;
970 imesa->regs.s4.fogCtrl.ni.fogClr = fogClr;
971 }
972 else
973 {
974 /*No fog*/
975
976 imesa->regs.s4.fogCtrl.ni.fogEn = 0;
977 imesa->regs.s4.fogCtrl.ni.fogMode = 0;
978 }
979 imesa->dirty |= SAVAGE_UPLOAD_CTX;
980 }
981
982
983 static void savageStencilFunc(GLcontext *);
984
985 static void savageDDStencilFunc(GLcontext *ctx, GLenum func, GLint ref,
986 GLuint mask)
987 {
988 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
989 SCmpFunc a=0;
990
991 imesa->regs.s4.zBufCtrl.ni.stencilRefVal = ctx->Stencil.Ref[0];
992 imesa->regs.s4.stencilCtrl.ni.readMask = ctx->Stencil.ValueMask[0];
993
994 switch (ctx->Stencil.Function[0])
995 {
996 case GL_NEVER: a = CF_Never; break;
997 case GL_ALWAYS: a = CF_Always; break;
998 case GL_LESS: a = CF_Less; break;
999 case GL_LEQUAL: a = CF_LessEqual; break;
1000 case GL_EQUAL: a = CF_Equal; break;
1001 case GL_GREATER: a = CF_Greater; break;
1002 case GL_GEQUAL: a = CF_GreaterEqual; break;
1003 case GL_NOTEQUAL: a = CF_NotEqual; break;
1004 default:
1005 break;
1006 }
1007
1008 imesa->regs.s4.stencilCtrl.ni.cmpFunc = a;
1009
1010 imesa->dirty |= SAVAGE_UPLOAD_CTX;
1011 }
1012
1013 static void savageDDStencilMask(GLcontext *ctx, GLuint mask)
1014 {
1015 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1016
1017 imesa->regs.s4.stencilCtrl.ni.writeMask = ctx->Stencil.WriteMask[0];
1018
1019 imesa->dirty |= SAVAGE_UPLOAD_CTX;
1020 }
1021
1022 static void savageDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail,
1023 GLenum zpass)
1024 {
1025 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1026
1027 switch (ctx->Stencil.FailFunc[0])
1028 {
1029 case GL_KEEP:
1030 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Keep;
1031 break;
1032 case GL_ZERO:
1033 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Zero;
1034 break;
1035 case GL_REPLACE:
1036 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Equal;
1037 break;
1038 case GL_INCR:
1039 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_IncClamp;
1040 break;
1041 case GL_DECR:
1042 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_DecClamp;
1043 break;
1044 case GL_INVERT:
1045 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Invert;
1046 break;
1047 case GL_INCR_WRAP_EXT:
1048 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Inc;
1049 break;
1050 case GL_DECR_WRAP_EXT:
1051 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Dec;
1052 break;
1053 }
1054
1055
1056 switch (ctx->Stencil.ZFailFunc[0])
1057 {
1058 case GL_KEEP:
1059 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Keep;
1060 break;
1061 case GL_ZERO:
1062 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Zero;
1063 break;
1064 case GL_REPLACE:
1065 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Equal;
1066 break;
1067 case GL_INCR:
1068 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_IncClamp;
1069 break;
1070 case GL_DECR:
1071 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_DecClamp;
1072 break;
1073 case GL_INVERT:
1074 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Invert;
1075 break;
1076 case GL_INCR_WRAP_EXT:
1077 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Inc;
1078 break;
1079 case GL_DECR_WRAP_EXT:
1080 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Dec;
1081 break;
1082 }
1083
1084 switch (ctx->Stencil.ZPassFunc[0])
1085 {
1086 case GL_KEEP:
1087 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Keep;
1088 break;
1089 case GL_ZERO:
1090 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Zero;
1091 break;
1092 case GL_REPLACE:
1093 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Equal;
1094 break;
1095 case GL_INCR:
1096 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_IncClamp;
1097 break;
1098 case GL_DECR:
1099 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_DecClamp;
1100 break;
1101 case GL_INVERT:
1102 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Invert;
1103 break;
1104 case GL_INCR_WRAP_EXT:
1105 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Inc;
1106 break;
1107 case GL_DECR_WRAP_EXT:
1108 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Dec;
1109 break;
1110 }
1111
1112 imesa->dirty |= SAVAGE_UPLOAD_CTX;
1113 }
1114
1115
1116 /* =============================================================
1117 */
1118
1119 static void savageDDEnable_s4(GLcontext *ctx, GLenum cap, GLboolean state)
1120 {
1121
1122 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1123 switch(cap) {
1124 case GL_ALPHA_TEST:
1125 /* we should consider the disable case*/
1126 imesa->dirty |= SAVAGE_UPLOAD_CTX;
1127 savageBlendFunc_s4(ctx);
1128 break;
1129 case GL_BLEND:
1130 imesa->dirty |= SAVAGE_UPLOAD_CTX;
1131 /*Can't find Enable bit in the 3D registers.*/
1132 /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
1133 */
1134 FALLBACK (ctx, SAVAGE_FALLBACK_LOGICOP,
1135 (ctx->Color.ColorLogicOpEnabled &&
1136 ctx->Color.LogicOp != GL_COPY));
1137 /*add the savageBlendFunc 2001/11/25
1138 * if call no such function, then glDisable(GL_BLEND) will do noting,
1139 *our chip has no disable bit
1140 */
1141 savageBlendFunc_s4(ctx);
1142 break;
1143 case GL_DEPTH_TEST:
1144 imesa->dirty |= SAVAGE_UPLOAD_CTX;
1145 savageDDDepthFunc_s4(ctx,ctx->Depth.Func);
1146 break;
1147 case GL_SCISSOR_TEST:
1148 imesa->scissor = state;
1149 imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS;
1150 break;
1151 case GL_STENCIL_TEST:
1152 imesa->dirty |= SAVAGE_UPLOAD_CTX;
1153 if (!imesa->hw_stencil)
1154 FALLBACK (ctx, SAVAGE_FALLBACK_STENCIL, state);
1155 else {
1156 imesa->regs.s4.stencilCtrl.ni.stencilEn = state;
1157 if (ctx->Stencil.Enabled &&
1158 imesa->regs.s4.zBufCtrl.ni.zBufEn != GL_TRUE)
1159 {
1160 /* Stencil buffer requires Z enabled. */
1161 imesa->regs.s4.zBufCtrl.ni.zCmpFunc = CF_Always;
1162 imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_TRUE;
1163 imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = GL_FALSE;
1164 }
1165 imesa->dirty |= SAVAGE_UPLOAD_CTX;
1166 }
1167 break;
1168 case GL_FOG:
1169 imesa->dirty |= SAVAGE_UPLOAD_CTX;
1170 savageDDFogfv(ctx,0,0);
1171 break;
1172 case GL_CULL_FACE:
1173 #if HW_CULL
1174 if (state)
1175 {
1176 savageDDCullFaceFrontFace(ctx,0);
1177 }
1178 else
1179 {
1180 imesa->LcsCullMode = BCM_None;
1181 imesa->new_state |= SAVAGE_NEW_CULL;
1182 }
1183 #endif
1184 break;
1185 case GL_DITHER:
1186 imesa->dirty |= SAVAGE_UPLOAD_CTX;
1187 if (state)
1188 {
1189 if ( ctx->Color.DitherFlag )
1190 {
1191 imesa->regs.s4.drawCtrl1.ni.ditherEn=GL_TRUE;
1192 }
1193 }
1194 if (!ctx->Color.DitherFlag )
1195 {
1196 imesa->regs.s4.drawCtrl1.ni.ditherEn=GL_FALSE;
1197 }
1198 break;
1199
1200 case GL_LIGHTING:
1201 savageUpdateSpecular_s4 (ctx);
1202 break;
1203 case GL_TEXTURE_1D:
1204 case GL_TEXTURE_3D:
1205 imesa->new_state |= SAVAGE_NEW_TEXTURE;
1206 break;
1207 case GL_TEXTURE_2D:
1208 imesa->new_state |= SAVAGE_NEW_TEXTURE;
1209 break;
1210 default:
1211 ;
1212 }
1213 }
1214 static void savageDDEnable_s3d(GLcontext *ctx, GLenum cap, GLboolean state)
1215 {
1216
1217 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1218 switch(cap) {
1219 case GL_ALPHA_TEST:
1220 /* we should consider the disable case*/
1221 imesa->dirty |= SAVAGE_UPLOAD_CTX;
1222 savageBlendFunc_s3d(ctx);
1223 break;
1224 case GL_BLEND:
1225 imesa->dirty |= SAVAGE_UPLOAD_CTX;
1226 /*Can't find Enable bit in the 3D registers.*/
1227 /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
1228 */
1229 FALLBACK (ctx, SAVAGE_FALLBACK_LOGICOP,
1230 (ctx->Color.ColorLogicOpEnabled &&
1231 ctx->Color.LogicOp != GL_COPY));
1232 /*add the savageBlendFunc 2001/11/25
1233 * if call no such function, then glDisable(GL_BLEND) will do noting,
1234 *our chip has no disable bit
1235 */
1236 savageBlendFunc_s3d(ctx);
1237 break;
1238 case GL_DEPTH_TEST:
1239 imesa->dirty |= SAVAGE_UPLOAD_CTX;
1240 savageDDDepthFunc_s3d(ctx,ctx->Depth.Func);
1241 break;
1242 case GL_SCISSOR_TEST:
1243 imesa->scissor = state;
1244 imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS;
1245 break;
1246 case GL_STENCIL_TEST:
1247 FALLBACK (ctx, SAVAGE_FALLBACK_STENCIL, state);
1248 break;
1249 case GL_FOG:
1250 imesa->dirty |= SAVAGE_UPLOAD_CTX;
1251 savageDDFogfv(ctx,0,0);
1252 break;
1253 case GL_CULL_FACE:
1254 #if HW_CULL
1255 if (state)
1256 {
1257 savageDDCullFaceFrontFace(ctx,0);
1258 }
1259 else
1260 {
1261 imesa->LcsCullMode = BCM_None;
1262 imesa->new_state |= SAVAGE_NEW_CULL;
1263 }
1264 #endif
1265 break;
1266 case GL_DITHER:
1267 imesa->dirty |= SAVAGE_UPLOAD_CTX;
1268 if (state)
1269 {
1270 if ( ctx->Color.DitherFlag )
1271 {
1272 imesa->regs.s3d.drawCtrl.ni.ditherEn=GL_TRUE;
1273 }
1274 }
1275 if (!ctx->Color.DitherFlag )
1276 {
1277 imesa->regs.s3d.drawCtrl.ni.ditherEn=GL_FALSE;
1278 }
1279 break;
1280
1281 case GL_LIGHTING:
1282 savageUpdateSpecular_s3d (ctx);
1283 break;
1284 case GL_TEXTURE_1D:
1285 case GL_TEXTURE_3D:
1286 imesa->new_state |= SAVAGE_NEW_TEXTURE;
1287 break;
1288 case GL_TEXTURE_2D:
1289 imesa->new_state |= SAVAGE_NEW_TEXTURE;
1290 break;
1291 default:
1292 ;
1293 }
1294 }
1295
1296 void savageDDUpdateHwState( GLcontext *ctx )
1297 {
1298 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1299
1300 if (imesa->new_state) {
1301 FLUSH_BATCH(imesa);
1302
1303 if (imesa->new_state & SAVAGE_NEW_TEXTURE) {
1304 savageUpdateTextureState( ctx );
1305 }
1306 if ((imesa->new_state & SAVAGE_NEW_CULL)) {
1307 savageUpdateCull(ctx);
1308 }
1309 imesa->new_state = 0;
1310 }
1311 }
1312
1313
1314 void savageEmitDrawingRectangle( savageContextPtr imesa )
1315 {
1316 __DRIdrawablePrivate *dPriv = imesa->driDrawable;
1317 savageScreenPrivate *savageScreen = imesa->savageScreen;
1318 drm_clip_rect_t *pbox;
1319 int nbox;
1320
1321
1322 int x0 = imesa->drawX;
1323 int y0 = imesa->drawY;
1324 int x1 = x0 + dPriv->w;
1325 int y1 = y0 + dPriv->h;
1326
1327 pbox = dPriv->pClipRects;
1328 nbox = dPriv->numClipRects;
1329
1330
1331
1332 /* Coordinate origin of the window - may be offscreen.
1333 */
1334 /* imesa->BufferSetup[SAVAGE_DESTREG_DR4] = ((y0<<16) |
1335 (((unsigned)x0)&0xFFFF));*/
1336
1337 /* Clip to screen.
1338 */
1339 if (x0 < 0) x0 = 0;
1340 if (y0 < 0) y0 = 0;
1341 if (x1 > savageScreen->width) x1 = savageScreen->width;
1342 if (y1 > savageScreen->height) y1 = savageScreen->height;
1343
1344
1345 if(nbox == 1)
1346 {
1347 imesa->draw_rect.x1 = MAX2(x0,pbox->x1);
1348 imesa->draw_rect.y1 = MAX2(y0,pbox->y1);
1349 imesa->draw_rect.x2 = MIN2(x1,pbox->x2);
1350 imesa->draw_rect.y2 = MIN2(y1,pbox->y2);
1351 }
1352 else
1353 {
1354 imesa->draw_rect.x1 = x0;
1355 imesa->draw_rect.y1 = y0;
1356 imesa->draw_rect.x2 = x1;
1357 imesa->draw_rect.y2 = y1;
1358 }
1359
1360 imesa->scissorChanged = GL_TRUE;
1361
1362 /* imesa->regs.ni.changed.ni.fDrawCtrl0Changed=GL_TRUE;
1363 imesa->regs.ni.changed.ni.fDrawCtrl1Changed=GL_TRUE;*/
1364
1365 savageCalcViewport (imesa->glCtx);
1366
1367 imesa->dirty |= SAVAGE_UPLOAD_BUFFERS;
1368 }
1369
1370
1371 static void savageDDPrintDirty( const char *msg, GLuint state )
1372 {
1373 fprintf(stderr, "%s (0x%x): %s%s%s%s%s\n",
1374 msg,
1375 (unsigned int) state,
1376 (state & SAVAGE_UPLOAD_TEX0IMAGE) ? "upload-tex0, " : "",
1377 (state & SAVAGE_UPLOAD_TEX1IMAGE) ? "upload-tex1, " : "",
1378 (state & SAVAGE_UPLOAD_CTX) ? "upload-ctx, " : "",
1379 (state & SAVAGE_UPLOAD_BUFFERS) ? "upload-bufs, " : "",
1380 (state & SAVAGE_UPLOAD_CLIPRECTS) ? "upload-cliprects, " : ""
1381 );
1382 }
1383
1384
1385 /**
1386 * Check if global registers were changed
1387 */
1388 static GLboolean savageGlobalRegChanged (savageContextPtr imesa,
1389 GLuint first, GLuint last) {
1390 GLuint i;
1391 for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i) {
1392 if (((imesa->oldRegs.ui[i] ^ imesa->regs.ui[i]) &
1393 imesa->globalRegMask.ui[i]) != 0)
1394 return GL_TRUE;
1395 }
1396 return GL_FALSE;
1397 }
1398 static void savageEmitContiguousRegs (savageContextPtr imesa,
1399 GLuint first, GLuint last) {
1400 GLuint i;
1401 uint32_t *pBCIBase;
1402 pBCIBase = savageDMAAlloc (imesa, last - first + 2);
1403 WRITE_CMD (pBCIBase, SET_REGISTER(first, last - first + 1), uint32_t);
1404
1405 for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i) {
1406 WRITE_CMD (pBCIBase, imesa->regs.ui[i], uint32_t);
1407 imesa->oldRegs.ui[i] = imesa->regs.ui[i];
1408 }
1409 savageDMACommit (imesa, pBCIBase);
1410 }
1411 static void savageEmitChangedRegs (savageContextPtr imesa,
1412 GLuint first, GLuint last) {
1413 GLuint i, firstChanged;
1414 firstChanged = SAVAGE_NR_REGS;
1415 for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i) {
1416 if (imesa->oldRegs.ui[i] != imesa->regs.ui[i]) {
1417 if (firstChanged == SAVAGE_NR_REGS)
1418 firstChanged = i;
1419 } else {
1420 if (firstChanged != SAVAGE_NR_REGS) {
1421 savageEmitContiguousRegs (imesa, firstChanged+SAVAGE_FIRST_REG,
1422 i-1+SAVAGE_FIRST_REG);
1423 firstChanged = SAVAGE_NR_REGS;
1424 }
1425 }
1426 }
1427 if (firstChanged != SAVAGE_NR_REGS)
1428 savageEmitContiguousRegs (imesa, firstChanged+SAVAGE_FIRST_REG,
1429 last);
1430 }
1431 static void savageEmitChangedRegChunk (savageContextPtr imesa,
1432 GLuint first, GLuint last) {
1433 GLuint i;
1434 for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i) {
1435 if (imesa->oldRegs.ui[i] != imesa->regs.ui[i]) {
1436 savageEmitContiguousRegs (imesa, first, last);
1437 break;
1438 }
1439 }
1440 }
1441 static void savageUpdateRegister_s4(savageContextPtr imesa)
1442 {
1443 uint32_t *pBCIBase;
1444
1445 /*
1446 * Scissors updates drawctrl0 and drawctrl 1
1447 */
1448 if (imesa->scissorChanged)
1449 {
1450 if(imesa->scissor)
1451 {
1452 imesa->regs.s4.drawCtrl0.ni.scissorXStart = imesa->scissor_rect.x1;
1453 imesa->regs.s4.drawCtrl0.ni.scissorYStart = imesa->scissor_rect.y1;
1454 imesa->regs.s4.drawCtrl1.ni.scissorXEnd = imesa->scissor_rect.x2-1;
1455 imesa->regs.s4.drawCtrl1.ni.scissorYEnd = imesa->scissor_rect.y2-1;
1456 }
1457 else
1458 {
1459 imesa->regs.s4.drawCtrl0.ni.scissorXStart = imesa->draw_rect.x1;
1460 imesa->regs.s4.drawCtrl0.ni.scissorYStart = imesa->draw_rect.y1;
1461 imesa->regs.s4.drawCtrl1.ni.scissorXEnd = imesa->draw_rect.x2-1;
1462 imesa->regs.s4.drawCtrl1.ni.scissorYEnd = imesa->draw_rect.y2-1;
1463 }
1464 }
1465
1466 /* the savage4 uses the contiguous range of BCI registers 0x1e-0x39
1467 * 0x1e-0x27 are local, no need to check them for global changes */
1468 if (imesa->lostContext || savageGlobalRegChanged (imesa, 0x28, 0x39)) {
1469 pBCIBase = savageDMAAlloc (imesa, 1);
1470 WRITE_CMD (pBCIBase, WAIT_3D_IDLE, uint32_t);
1471 savageDMACommit (imesa, pBCIBase);
1472 }
1473 if (imesa->lostContext)
1474 savageEmitContiguousRegs (imesa, 0x1e, 0x39);
1475 else
1476 savageEmitChangedRegs (imesa, 0x1e, 0x39);
1477
1478 imesa->dirty=0;
1479 imesa->lostContext = GL_FALSE;
1480 }
1481 static void savageUpdateRegister_s3d(savageContextPtr imesa)
1482 {
1483 uint32_t *pBCIBase;
1484
1485 if (imesa->scissorChanged)
1486 {
1487 if(imesa->scissor)
1488 {
1489 imesa->regs.s3d.scissorsStart.ni.scissorXStart =
1490 imesa->scissor_rect.x1;
1491 imesa->regs.s3d.scissorsStart.ni.scissorYStart =
1492 imesa->scissor_rect.y1;
1493 imesa->regs.s3d.scissorsEnd.ni.scissorXEnd =
1494 imesa->scissor_rect.x2-1;
1495 imesa->regs.s3d.scissorsEnd.ni.scissorYEnd =
1496 imesa->scissor_rect.y2-1;
1497 }
1498 else
1499 {
1500 imesa->regs.s3d.scissorsStart.ni.scissorXStart =
1501 imesa->draw_rect.x1;
1502 imesa->regs.s3d.scissorsStart.ni.scissorYStart =
1503 imesa->draw_rect.y1;
1504 imesa->regs.s3d.scissorsEnd.ni.scissorXEnd =
1505 imesa->draw_rect.x2-1;
1506 imesa->regs.s3d.scissorsEnd.ni.scissorYEnd =
1507 imesa->draw_rect.y2-1;
1508 }
1509 }
1510
1511 /* Some temporary hacks to workaround lockups. Not sure if they are
1512 * still needed. But they work for now. */
1513 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
1514 imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE;
1515
1516 /* the savage3d uses two contiguous ranges of BCI registers:
1517 * 0x18-0x1c and 0x20-0x38. The first range is local. */
1518 if (imesa->lostContext || savageGlobalRegChanged (imesa, 0x20, 0x38)) {
1519 pBCIBase = savageDMAAlloc (imesa, 1);
1520 WRITE_CMD (pBCIBase, WAIT_3D_IDLE, uint32_t);
1521 savageDMACommit (imesa, pBCIBase);
1522 }
1523 /* FIXME: watermark registers aren't programmed correctly ATM */
1524 if (imesa->lostContext) {
1525 savageEmitContiguousRegs (imesa, 0x18, 0x1c);
1526 savageEmitContiguousRegs (imesa, 0x20, 0x36);
1527 } else {
1528 /* On the Savage IX texture registers (at least some of them)
1529 * have to be emitted as one chunk. */
1530 savageEmitChangedRegs (imesa, 0x18, 0x19);
1531 savageEmitChangedRegChunk (imesa, 0x1a, 0x1c);
1532 savageEmitChangedRegs (imesa, 0x20, 0x36);
1533 }
1534
1535 imesa->dirty=0;
1536 imesa->lostContext = GL_FALSE;
1537 }
1538
1539
1540
1541 /* Push the state into the sarea and/or texture memory.
1542 */
1543 void savageEmitHwStateLocked( savageContextPtr imesa )
1544 {
1545 if (SAVAGE_DEBUG & DEBUG_VERBOSE_API)
1546 savageDDPrintDirty( "\n\n\nsavageEmitHwStateLocked", imesa->dirty );
1547
1548 if (imesa->dirty & ~SAVAGE_UPLOAD_CLIPRECTS)
1549 {
1550 if (imesa->dirty & (SAVAGE_UPLOAD_CTX | SAVAGE_UPLOAD_TEX0 | \
1551 SAVAGE_UPLOAD_TEX1 | SAVAGE_UPLOAD_BUFFERS))
1552 {
1553
1554 /*SAVAGE_STATE_COPY(imesa);*/
1555 /* update state to hw*/
1556 if (imesa->driDrawable &&imesa->driDrawable->numClipRects ==0 )
1557 {
1558 return ;
1559 }
1560 if (imesa->savageScreen->chipset >= S3_SAVAGE4)
1561 savageUpdateRegister_s4(imesa);
1562 else
1563 savageUpdateRegister_s3d(imesa);
1564 }
1565
1566 imesa->sarea->dirty |= (imesa->dirty &
1567 ~(SAVAGE_UPLOAD_TEX1|SAVAGE_UPLOAD_TEX0));
1568 imesa->dirty &= SAVAGE_UPLOAD_CLIPRECTS;
1569 }
1570 }
1571
1572
1573
1574 static void savageDDInitState_s4( savageContextPtr imesa )
1575 {
1576 #if 1
1577 imesa->regs.s4.destCtrl.ui = 1<<7;
1578 #endif
1579
1580 imesa->regs.s4.zBufCtrl.ni.zCmpFunc = CF_Less;
1581 imesa->regs.s4.zBufCtrl.ni.wToZEn = GL_TRUE;
1582 /*imesa->regs.s4.ZBufCtrl.ni.floatZEn = GL_TRUE;*/
1583 imesa->regs.s4.texBlendCtrl[0].ui = TBC_NoTexMap;
1584 imesa->regs.s4.texBlendCtrl[1].ui = TBC_NoTexMap1;
1585 imesa->regs.s4.drawCtrl0.ui = 0;
1586 #if 0
1587 imesa->regs.s4.drawCtrl1.ni.xyOffsetEn = 1;
1588 #endif
1589
1590 /* Set DestTexWatermarks_31,30 to 01 always.
1591 *Has no effect if dest. flush is disabled.
1592 */
1593 #if 0
1594 imesa->regs.s4.zWatermarks.ui = 0x12000C04;
1595 imesa->regs.s4.destTexWatermarks.ui = 0x40200400;
1596 #else
1597 imesa->regs.s4.zWatermarks.ui = 0x16001808;
1598 imesa->regs.s4.destTexWatermarks.ui = 0x4f000000;
1599 #endif
1600 imesa->regs.s4.drawCtrl0.ni.dPerfAccelEn = GL_TRUE;
1601
1602 /* clrCmpAlphaBlendCtrl is needed to get alphatest and
1603 * alpha blending working properly
1604 */
1605
1606 imesa->regs.s4.texCtrl[0].ni.dBias = 0x08;
1607 imesa->regs.s4.texCtrl[1].ni.dBias = 0x08;
1608 imesa->regs.s4.texCtrl[0].ni.texXprEn = GL_TRUE;
1609 imesa->regs.s4.texCtrl[1].ni.texXprEn = GL_TRUE;
1610 imesa->regs.s4.texCtrl[0].ni.dMax = 0x0f;
1611 imesa->regs.s4.texCtrl[1].ni.dMax = 0x0f;
1612 imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn = GL_TRUE;
1613 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_One;
1614 imesa->regs.s4.drawLocalCtrl.ni.wrZafterAlphaTst = GL_FALSE;
1615 imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites= GL_TRUE;
1616 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites= GL_TRUE;
1617
1618 imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn= GL_TRUE;
1619 imesa->regs.s4.drawCtrl1.ni.ditherEn=GL_TRUE;
1620 imesa->regs.s4.drawCtrl1.ni.cullMode = BCM_None;
1621
1622 imesa->LcsCullMode=BCM_None;
1623 imesa->regs.s4.texDescr.ni.palSize = TPS_256;
1624
1625 /* clear the local registers in the global reg mask */
1626 imesa->globalRegMask.s4.drawLocalCtrl.ui = 0;
1627 imesa->globalRegMask.s4.texPalAddr.ui = 0;
1628 imesa->globalRegMask.s4.texCtrl[0].ui = 0;
1629 imesa->globalRegMask.s4.texCtrl[1].ui = 0;
1630 imesa->globalRegMask.s4.texAddr[0].ui = 0;
1631 imesa->globalRegMask.s4.texAddr[1].ui = 0;
1632 imesa->globalRegMask.s4.texBlendCtrl[0].ui = 0;
1633 imesa->globalRegMask.s4.texBlendCtrl[1].ui = 0;
1634 imesa->globalRegMask.s4.texXprClr.ui = 0;
1635 imesa->globalRegMask.s4.texDescr.ui = 0;
1636 }
1637 static void savageDDInitState_s3d( savageContextPtr imesa )
1638 {
1639 #if 1
1640 imesa->regs.s3d.destCtrl.ui = 1<<7;
1641 #endif
1642
1643 imesa->regs.s3d.zBufCtrl.ni.zCmpFunc = CF_Less;
1644 #if 0
1645 imesa->regs.s3d.drawCtrl.ni.xyOffsetEn = 1;
1646 #endif
1647
1648 /* Set DestTexWatermarks_31,30 to 01 always.
1649 *Has no effect if dest. flush is disabled.
1650 */
1651 #if 0
1652 imesa->regs.s3d.zWatermarks.ui = 0x12000C04;
1653 imesa->regs.s3d.destTexWatermarks.ui = 0x40200400;
1654 #else
1655 imesa->regs.s3d.zWatermarks.ui = 0x16001808;
1656 imesa->regs.s3d.destTexWatermarks.ui = 0x4f000000;
1657 #endif
1658
1659 /* clrCmpAlphaBlendCtrl is needed to get alphatest and
1660 * alpha blending working properly
1661 */
1662
1663 imesa->regs.s3d.texCtrl.ni.dBias = 0x08;
1664 imesa->regs.s3d.texCtrl.ni.texXprEn = GL_TRUE;
1665
1666 imesa->regs.s3d.zBufCtrl.ni.drawUpdateEn = GL_TRUE;
1667 imesa->regs.s3d.zBufCtrl.ni.wrZafterAlphaTst = GL_FALSE;
1668 imesa->regs.s3d.zBufCtrl.ni.zUpdateEn = GL_TRUE;
1669 imesa->regs.s4.zBufCtrl.ni.stencilRefVal = 0x00;
1670
1671 imesa->regs.s4.stencilCtrl.ni.stencilEn = GL_FALSE;
1672 imesa->regs.s4.stencilCtrl.ni.cmpFunc = CF_Always;
1673 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Keep;
1674 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Keep;
1675 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Keep;
1676 imesa->regs.s4.stencilCtrl.ni.writeMask = 0xff;
1677 imesa->regs.s4.stencilCtrl.ni.readMask = 0xff;
1678
1679 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_One;
1680 imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE;
1681 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
1682
1683 imesa->regs.s3d.drawCtrl.ni.ditherEn = GL_TRUE;
1684 imesa->regs.s3d.drawCtrl.ni.cullMode = BCM_None;
1685
1686 imesa->LcsCullMode = BCM_None;
1687 imesa->regs.s3d.texDescr.ni.palSize = TPS_256;
1688
1689 /* clear the local registers in the global reg mask */
1690 imesa->globalRegMask.s3d.texPalAddr.ui = 0;
1691 imesa->globalRegMask.s3d.texXprClr.ui = 0;
1692 imesa->globalRegMask.s3d.texAddr.ui = 0;
1693 imesa->globalRegMask.s3d.texDescr.ui = 0;
1694 imesa->globalRegMask.s3d.texCtrl.ui = 0;
1695
1696 imesa->globalRegMask.s3d.fogCtrl.ui = 0;
1697
1698 /* drawCtrl is local with some exceptions */
1699 imesa->globalRegMask.s3d.drawCtrl.ui = 0;
1700 imesa->globalRegMask.s3d.drawCtrl.ni.cullMode = 0x3;
1701 imesa->globalRegMask.s3d.drawCtrl.ni.alphaTestCmpFunc = 0x7;
1702 imesa->globalRegMask.s3d.drawCtrl.ni.alphaTestEn = 0x1;
1703 imesa->globalRegMask.s3d.drawCtrl.ni.alphaRefVal = 0xff;
1704
1705 /* zBufCtrl is local with some exceptions */
1706 imesa->globalRegMask.s3d.zBufCtrl.ui = 0;
1707 imesa->globalRegMask.s3d.zBufCtrl.ni.zCmpFunc = 0x7;
1708 imesa->globalRegMask.s3d.zBufCtrl.ni.zBufEn = 0x1;
1709 }
1710 void savageDDInitState( savageContextPtr imesa ) {
1711 memset (imesa->regs.ui, 0, SAVAGE_NR_REGS*sizeof(uint32_t));
1712 memset (imesa->oldRegs.ui, 0, SAVAGE_NR_REGS*sizeof(uint32_t));
1713 memset (imesa->globalRegMask.ui, 0xff, SAVAGE_NR_REGS*sizeof(uint32_t));
1714 if (imesa->savageScreen->chipset >= S3_SAVAGE4)
1715 savageDDInitState_s4 (imesa);
1716 else
1717 savageDDInitState_s3d (imesa);
1718
1719 /*fprintf(stderr,"DBflag:%d\n",imesa->glCtx->Visual->DBflag);*/
1720 /* zbufoffset and destctrl have the same position and layout on
1721 * savage4 and savage3d. */
1722 imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->backOffset>>11;
1723 if(imesa->savageScreen->cpp == 2)
1724 {
1725 imesa->regs.s4.destCtrl.ni.dstPixFmt = 0;
1726 imesa->regs.s4.destCtrl.ni.dstWidthInTile =
1727 (imesa->savageScreen->width+63)>>6;
1728 }
1729 else
1730 {
1731 imesa->regs.s4.destCtrl.ni.dstPixFmt = 1;
1732 imesa->regs.s4.destCtrl.ni.dstWidthInTile =
1733 (imesa->savageScreen->width+31)>>5;
1734 }
1735
1736 imesa->IsDouble = GL_TRUE;
1737
1738 imesa->NotFirstFrame = GL_FALSE;
1739 imesa->regs.s4.zBufOffset.ni.offset=imesa->savageScreen->depthOffset>>11;
1740 if(imesa->savageScreen->zpp == 2)
1741 {
1742 imesa->regs.s4.zBufOffset.ni.zBufWidthInTiles =
1743 (imesa->savageScreen->width+63)>>6;
1744 imesa->regs.s4.zBufOffset.ni.zDepthSelect = 0;
1745 }
1746 else
1747 {
1748 imesa->regs.s4.zBufOffset.ni.zBufWidthInTiles =
1749 (imesa->savageScreen->width+31)>>5;
1750 imesa->regs.s4.zBufOffset.ni.zDepthSelect = 1;
1751 }
1752
1753 if (imesa->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) {
1754 if(imesa->IsFullScreen)
1755 {
1756 imesa->toggle = TARGET_BACK;
1757
1758 imesa->drawMap = (char *)imesa->apertureBase[imesa->toggle];
1759 imesa->readMap = (char *)imesa->apertureBase[imesa->toggle];
1760 }
1761 else
1762 {
1763 imesa->drawMap = (char *)imesa->apertureBase[TARGET_BACK];
1764 imesa->readMap = (char *)imesa->apertureBase[TARGET_BACK];
1765 }
1766
1767 } else {
1768
1769 if(imesa->IsFullScreen)
1770 {
1771 imesa->toggle = TARGET_BACK;
1772
1773 imesa->drawMap = (char *)imesa->apertureBase[imesa->toggle];
1774 imesa->readMap = (char *)imesa->apertureBase[imesa->toggle];
1775 }
1776 else
1777 {
1778 imesa->drawMap = (char *)imesa->apertureBase[TARGET_BACK];
1779 imesa->readMap = (char *)imesa->apertureBase[TARGET_BACK];
1780 }
1781 }
1782 }
1783
1784
1785 #define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\
1786 NEW_TEXTURE_MATRIX|\
1787 NEW_USER_CLIP|NEW_CLIENT_STATE))
1788
1789 void savageDDRenderStart(GLcontext *ctx)
1790 {
1791 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
1792 __DRIdrawablePrivate *dPriv = imesa->driDrawable;
1793 drm_clip_rect_t *pbox;
1794 GLint nbox;
1795
1796 /* if the screen is overrided by other application. set the scissor.
1797 * In MulitPass, re-render the screen.
1798 */
1799 pbox = dPriv->pClipRects;
1800 nbox = dPriv->numClipRects;
1801 if (nbox)
1802 {
1803 imesa->currentClip = nbox;
1804 /* set scissor to the first clip box*/
1805 savageDDScissor(ctx,pbox->x1,pbox->y1,pbox->x2,pbox->y2);
1806
1807 /*savageDDUpdateHwState(ctx);*/ /* update to hardware register*/
1808 }
1809 else /* need not render at all*/
1810 {
1811 /*ctx->VB->CopyStart = ctx->VB->Count;*/
1812 }
1813 }
1814
1815
1816 void savageDDRenderEnd(GLcontext *ctx)
1817 {
1818 }
1819
1820 static void savageDDInvalidateState( GLcontext *ctx, GLuint new_state )
1821 {
1822 _swrast_InvalidateState( ctx, new_state );
1823 _swsetup_InvalidateState( ctx, new_state );
1824 _ac_InvalidateState( ctx, new_state );
1825 _tnl_InvalidateState( ctx, new_state );
1826 SAVAGE_CONTEXT(ctx)->new_gl_state |= new_state;
1827 }
1828
1829
1830 void savageDDInitStateFuncs(GLcontext *ctx)
1831 {
1832 ctx->Driver.UpdateState = savageDDInvalidateState;
1833 ctx->Driver.BlendEquationSeparate = savageDDBlendEquationSeparate;
1834 ctx->Driver.Fogfv = savageDDFogfv;
1835 ctx->Driver.Scissor = savageDDScissor;
1836 #if HW_CULL
1837 ctx->Driver.CullFace = savageDDCullFaceFrontFace;
1838 ctx->Driver.FrontFace = savageDDCullFaceFrontFace;
1839 #else
1840 ctx->Driver.CullFace = 0;
1841 ctx->Driver.FrontFace = 0;
1842 #endif /* end #if HW_CULL */
1843 ctx->Driver.PolygonMode=NULL;
1844 ctx->Driver.PolygonStipple = 0;
1845 ctx->Driver.LineStipple = 0;
1846 ctx->Driver.LineWidth = 0;
1847 ctx->Driver.LogicOpcode = 0;
1848 ctx->Driver.DrawBuffer = savageDDDrawBuffer;
1849 ctx->Driver.ReadBuffer = savageDDReadBuffer;
1850 ctx->Driver.ClearColor = savageDDClearColor;
1851
1852 ctx->Driver.DepthRange = savageDepthRange;
1853 ctx->Driver.Viewport = savageViewport;
1854 ctx->Driver.RenderMode = savageRenderMode;
1855
1856 ctx->Driver.ClearIndex = 0;
1857 ctx->Driver.IndexMask = 0;
1858
1859 if (SAVAGE_CONTEXT( ctx )->savageScreen->chipset >= S3_SAVAGE4) {
1860 ctx->Driver.Enable = savageDDEnable_s4;
1861 ctx->Driver.AlphaFunc = savageDDAlphaFunc_s4;
1862 ctx->Driver.DepthFunc = savageDDDepthFunc_s4;
1863 ctx->Driver.DepthMask = savageDDDepthMask_s4;
1864 ctx->Driver.BlendFuncSeparate = savageDDBlendFuncSeparate_s4;
1865 ctx->Driver.ColorMask = savageDDColorMask_s4;
1866 ctx->Driver.ShadeModel = savageDDShadeModel_s4;
1867 ctx->Driver.LightModelfv = savageDDLightModelfv_s4;
1868 ctx->Driver.StencilFunc = savageDDStencilFunc;
1869 ctx->Driver.StencilMask = savageDDStencilMask;
1870 ctx->Driver.StencilOp = savageDDStencilOp;
1871 } else {
1872 ctx->Driver.Enable = savageDDEnable_s3d;
1873 ctx->Driver.AlphaFunc = savageDDAlphaFunc_s3d;
1874 ctx->Driver.DepthFunc = savageDDDepthFunc_s3d;
1875 ctx->Driver.DepthMask = savageDDDepthMask_s3d;
1876 ctx->Driver.BlendFuncSeparate = savageDDBlendFuncSeparate_s3d;
1877 ctx->Driver.ColorMask = savageDDColorMask_s3d;
1878 ctx->Driver.ShadeModel = savageDDShadeModel_s3d;
1879 ctx->Driver.LightModelfv = savageDDLightModelfv_s3d;
1880 ctx->Driver.StencilFunc = 0;
1881 ctx->Driver.StencilMask = 0;
1882 ctx->Driver.StencilOp = 0;
1883 }
1884
1885 /* Swrast hooks for imaging extensions:
1886 */
1887 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
1888 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
1889 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
1890 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
1891 }