Merge branch 'nouveau-import'
[mesa.git] / src / mesa / drivers / dri / sis / sis_texstate.c
1 /**************************************************************************
2
3 Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
4 Copyright 2003 Eric Anholt
5 All Rights Reserved.
6
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the "Software"),
9 to deal in the Software without restriction, including without limitation
10 on the rights to use, copy, modify, merge, publish, distribute, sub
11 license, and/or sell copies of the Software, and to permit persons to whom
12 the Software is furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice (including the next
15 paragraph) shall be included in all copies or substantial portions of the
16 Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM,
22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **************************************************************************/
27 /* $XFree86$ */
28
29 /*
30 * Authors:
31 * Sung-Ching Lin <sclin@sis.com.tw>
32 * Eric Anholt <anholt@FreeBSD.org>
33 */
34
35 #include "glheader.h"
36 #include "imports.h"
37 #include "colormac.h"
38 #include "context.h"
39 #include "macros.h"
40 #include "texformat.h"
41
42 #include "sis_context.h"
43 #include "sis_state.h"
44 #include "sis_tex.h"
45 #include "sis_tris.h"
46 #include "sis_alloc.h"
47
48 static GLint TransferTexturePitch (GLint dwPitch);
49
50 /* Handle texenv stuff, called from validate_texture (renderstart) */
51 static void
52 sis_set_texture_env0( GLcontext *ctx, struct gl_texture_object *texObj,
53 int unit )
54 {
55 sisContextPtr smesa = SIS_CONTEXT(ctx);
56 GLubyte c[4];
57
58 __GLSiSHardware *prev = &smesa->prev;
59 __GLSiSHardware *current = &smesa->current;
60
61 struct gl_texture_unit *texture_unit = &ctx->Texture.Unit[unit];
62
63 sisTexObjPtr t = texObj->DriverData;
64
65 switch (texture_unit->EnvMode)
66 {
67 case GL_REPLACE:
68 switch (t->format)
69 {
70 case GL_ALPHA:
71 current->hwTexBlendColor0 = STAGE0_C_CF;
72 current->hwTexBlendAlpha0 = STAGE0_A_AS;
73 break;
74 case GL_LUMINANCE:
75 case GL_RGB:
76 case GL_YCBCR_MESA:
77 current->hwTexBlendColor0 = STAGE0_C_CS;
78 current->hwTexBlendAlpha0 = STAGE0_A_AF;
79 break;
80 case GL_INTENSITY:
81 case GL_LUMINANCE_ALPHA:
82 case GL_RGBA:
83 current->hwTexBlendColor0 = STAGE0_C_CS;
84 current->hwTexBlendAlpha0 = STAGE0_A_AS;
85 break;
86 default:
87 sis_fatal_error("unknown base format 0x%x\n", t->format);
88 }
89 break;
90
91 case GL_MODULATE:
92 switch (t->format)
93 {
94 case GL_ALPHA:
95 current->hwTexBlendColor0 = STAGE0_C_CF;
96 current->hwTexBlendAlpha0 = STAGE0_A_AFAS;
97 break;
98 case GL_LUMINANCE:
99 case GL_RGB:
100 case GL_YCBCR_MESA:
101 current->hwTexBlendColor0 = STAGE0_C_CFCS;
102 current->hwTexBlendAlpha0 = STAGE0_A_AF;
103 break;
104 case GL_INTENSITY:
105 case GL_LUMINANCE_ALPHA:
106 case GL_RGBA:
107 current->hwTexBlendColor0 = STAGE0_C_CFCS;
108 current->hwTexBlendAlpha0 = STAGE0_A_AFAS;
109 break;
110 default:
111 sis_fatal_error("unknown base format 0x%x\n", t->format);
112 }
113 break;
114
115 case GL_DECAL:
116 switch (t->format)
117 {
118 case GL_RGB:
119 case GL_YCBCR_MESA:
120 current->hwTexBlendColor0 = STAGE0_C_CS;
121 current->hwTexBlendAlpha0 = STAGE0_A_AF;
122 break;
123 case GL_RGBA:
124 current->hwTexBlendColor0 = STAGE0_C_CFOMAS_CSAS;
125 current->hwTexBlendAlpha0 = STAGE0_A_AF;
126 break;
127 case GL_ALPHA:
128 case GL_LUMINANCE:
129 case GL_INTENSITY:
130 case GL_LUMINANCE_ALPHA:
131 current->hwTexBlendColor0 = STAGE0_C_CF;
132 current->hwTexBlendAlpha0 = STAGE0_A_AF;
133 break;
134 default:
135 sis_fatal_error("unknown base format 0x%x\n", t->format);
136 }
137 break;
138
139 case GL_BLEND:
140 UNCLAMPED_FLOAT_TO_RGBA_CHAN(c, texture_unit->EnvColor);
141 current->hwTexEnvColor = ((GLint) (c[3])) << 24 |
142 ((GLint) (c[0])) << 16 |
143 ((GLint) (c[1])) << 8 |
144 ((GLint) (c[2]));
145 switch (t->format)
146 {
147 case GL_ALPHA:
148 current->hwTexBlendColor0 = STAGE0_C_CF;
149 current->hwTexBlendAlpha0 = STAGE0_A_AFAS;
150 break;
151 case GL_LUMINANCE:
152 case GL_RGB:
153 case GL_YCBCR_MESA:
154 current->hwTexBlendColor0 = STAGE0_C_CFOMCS_CCCS;
155 current->hwTexBlendAlpha0 = STAGE0_A_AF;
156 break;
157 case GL_INTENSITY:
158 current->hwTexBlendColor0 = STAGE0_C_CFOMCS_CCCS;
159 current->hwTexBlendAlpha0 = STAGE0_A_AFOMAS_ACAS;
160 break;
161 case GL_LUMINANCE_ALPHA:
162 case GL_RGBA:
163 current->hwTexBlendColor0 = STAGE0_C_CFOMCS_CCCS;
164 current->hwTexBlendAlpha0 = STAGE0_A_AFAS;
165 break;
166 default:
167 sis_fatal_error("unknown base format 0x%x\n", t->format);
168 }
169 break;
170
171 default:
172 sis_fatal_error("unknown env mode 0x%x\n", texture_unit->EnvMode);
173 }
174
175 if ((current->hwTexBlendColor0 != prev->hwTexBlendColor0) ||
176 (current->hwTexBlendAlpha0 != prev->hwTexBlendAlpha0) ||
177 (current->hwTexEnvColor != prev->hwTexEnvColor))
178 {
179 prev->hwTexEnvColor = current->hwTexEnvColor;
180 prev->hwTexBlendColor0 = current->hwTexBlendColor0;
181 prev->hwTexBlendAlpha0 = current->hwTexBlendAlpha0;
182 smesa->GlobalFlag |= GFLAG_TEXTUREENV;
183 }
184 }
185
186 /* Handle texenv stuff, called from validate_texture (renderstart) */
187 static void
188 sis_set_texture_env1( GLcontext *ctx, struct gl_texture_object *texObj,
189 int unit)
190 {
191 sisContextPtr smesa = SIS_CONTEXT(ctx);
192 GLubyte c[4];
193
194 __GLSiSHardware *prev = &smesa->prev;
195 __GLSiSHardware *current = &smesa->current;
196
197 struct gl_texture_unit *texture_unit = &ctx->Texture.Unit[unit];
198
199 sisTexObjPtr t = texObj->DriverData;
200
201 switch (texture_unit->EnvMode)
202 {
203 case GL_REPLACE:
204 switch (t->format)
205 {
206 case GL_ALPHA:
207 current->hwTexBlendColor1 = STAGE1_C_CF;
208 current->hwTexBlendAlpha1 = STAGE1_A_AS;
209 break;
210 case GL_LUMINANCE:
211 case GL_RGB:
212 case GL_YCBCR_MESA:
213 current->hwTexBlendColor1 = STAGE1_C_CS;
214 current->hwTexBlendAlpha1 = STAGE1_A_AF;
215 break;
216 case GL_INTENSITY:
217 case GL_LUMINANCE_ALPHA:
218 case GL_RGBA:
219 current->hwTexBlendColor1 = STAGE1_C_CS;
220 current->hwTexBlendAlpha1 = STAGE1_A_AS;
221 break;
222 default:
223 sis_fatal_error("unknown base format 0x%x\n", t->format);
224 }
225 break;
226
227 case GL_MODULATE:
228 switch (t->format)
229 {
230 case GL_ALPHA:
231 current->hwTexBlendColor1 = STAGE1_C_CF;
232 current->hwTexBlendAlpha1 = STAGE1_A_AFAS;
233 break;
234 case GL_LUMINANCE:
235 case GL_RGB:
236 case GL_YCBCR_MESA:
237 current->hwTexBlendColor1 = STAGE1_C_CFCS;
238 current->hwTexBlendAlpha1 = STAGE1_A_AF;
239 break;
240 case GL_INTENSITY:
241 case GL_LUMINANCE_ALPHA:
242 case GL_RGBA:
243 current->hwTexBlendColor1 = STAGE1_C_CFCS;
244 current->hwTexBlendAlpha1 = STAGE1_A_AFAS;
245 break;
246 default:
247 sis_fatal_error("unknown base format 0x%x\n", t->format);
248 }
249 break;
250
251 case GL_DECAL:
252 switch (t->format)
253 {
254 case GL_RGB:
255 case GL_YCBCR_MESA:
256 current->hwTexBlendColor1 = STAGE1_C_CS;
257 current->hwTexBlendAlpha1 = STAGE1_A_AF;
258 break;
259 case GL_RGBA:
260 current->hwTexBlendColor1 = STAGE1_C_CFOMAS_CSAS;
261 current->hwTexBlendAlpha1 = STAGE1_A_AF;
262 break;
263 case GL_ALPHA:
264 case GL_LUMINANCE:
265 case GL_INTENSITY:
266 case GL_LUMINANCE_ALPHA:
267 current->hwTexBlendColor1 = STAGE1_C_CF;
268 current->hwTexBlendAlpha1 = STAGE1_A_AF;
269 break;
270 default:
271 sis_fatal_error("unknown base format 0x%x\n", t->format);
272 }
273 break;
274
275 case GL_BLEND:
276 UNCLAMPED_FLOAT_TO_RGBA_CHAN(c, texture_unit->EnvColor);
277 current->hwTexEnvColor = ((GLint) (c[3])) << 24 |
278 ((GLint) (c[0])) << 16 |
279 ((GLint) (c[1])) << 8 |
280 ((GLint) (c[2]));
281 switch (t->format)
282 {
283 case GL_ALPHA:
284 current->hwTexBlendColor1 = STAGE1_C_CF;
285 current->hwTexBlendAlpha1 = STAGE1_A_AFAS;
286 break;
287 case GL_LUMINANCE:
288 case GL_RGB:
289 case GL_YCBCR_MESA:
290 current->hwTexBlendColor1 = STAGE1_C_CFOMCS_CCCS;
291 current->hwTexBlendAlpha1 = STAGE1_A_AF;
292 break;
293 case GL_INTENSITY:
294 current->hwTexBlendColor1 = STAGE1_C_CFOMCS_CCCS;
295 current->hwTexBlendAlpha1 = STAGE1_A_AFOMAS_ACAS;
296 break;
297 case GL_LUMINANCE_ALPHA:
298 case GL_RGBA:
299 current->hwTexBlendColor1 = STAGE1_C_CFOMCS_CCCS;
300 current->hwTexBlendAlpha1 = STAGE1_A_AFAS;
301 break;
302 default:
303 sis_fatal_error("unknown base format 0x%x\n", t->format);
304 }
305 break;
306
307 default:
308 sis_fatal_error("unknown env mode 0x%x\n", texture_unit->EnvMode);
309 }
310
311 if ((current->hwTexBlendColor1 != prev->hwTexBlendColor1) ||
312 (current->hwTexBlendAlpha1 != prev->hwTexBlendAlpha1) ||
313 (current->hwTexEnvColor != prev->hwTexEnvColor))
314 {
315 prev->hwTexBlendColor1 = current->hwTexBlendColor1;
316 prev->hwTexBlendAlpha1 = current->hwTexBlendAlpha1;
317 prev->hwTexEnvColor = current->hwTexEnvColor;
318 smesa->GlobalFlag |= GFLAG_TEXTUREENV_1;
319 }
320 }
321
322 /* Returns 0 if a software fallback is necessary */
323 static GLboolean
324 sis_set_texobj_parm( GLcontext *ctx, struct gl_texture_object *texObj,
325 int hw_unit )
326 {
327 sisContextPtr smesa = SIS_CONTEXT(ctx);
328 int ok = 1;
329
330 __GLSiSHardware *prev = &smesa->prev;
331 __GLSiSHardware *current = &smesa->current;
332
333 sisTexObjPtr t = texObj->DriverData;
334
335 GLint firstLevel, lastLevel;
336 GLint i;
337
338 current->texture[hw_unit].hwTextureMip = 0UL;
339 current->texture[hw_unit].hwTextureSet = t->hwformat;
340
341 if ((texObj->MinFilter == GL_NEAREST) || (texObj->MinFilter == GL_LINEAR)) {
342 firstLevel = lastLevel = texObj->BaseLevel;
343 } else {
344 /* Compute which mipmap levels we really want to send to the hardware.
345 * This depends on the base image size, GL_TEXTURE_MIN_LOD,
346 * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL and GL_TEXTURE_MAX_LEVEL.
347 * Yes, this looks overly complicated, but it's all needed.
348 */
349
350 firstLevel = texObj->BaseLevel + (GLint)(texObj->MinLod + 0.5);
351 firstLevel = MAX2(firstLevel, texObj->BaseLevel);
352 lastLevel = texObj->BaseLevel + (GLint)(texObj->MaxLod + 0.5);
353 lastLevel = MAX2(lastLevel, texObj->BaseLevel);
354 lastLevel = MIN2(lastLevel, texObj->BaseLevel +
355 texObj->Image[0][texObj->BaseLevel]->MaxLog2);
356 lastLevel = MIN2(lastLevel, texObj->MaxLevel);
357 lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
358 }
359
360 current->texture[hw_unit].hwTextureSet |= (lastLevel << 8);
361
362 switch (texObj->MagFilter)
363 {
364 case GL_NEAREST:
365 current->texture[hw_unit].hwTextureMip |= TEXTURE_FILTER_NEAREST;
366 break;
367 case GL_LINEAR:
368 current->texture[hw_unit].hwTextureMip |= (TEXTURE_FILTER_LINEAR << 3);
369 break;
370 }
371
372 {
373 GLint b;
374
375 /* The mipmap lod biasing is based on experiment. It seems there's a
376 * limit of around +4/-4 to the bias value; we're being conservative.
377 */
378 b = (GLint) (ctx->Texture.Unit[hw_unit].LodBias * 32.0);
379 if (b > 127)
380 b = 127;
381 else if (b < -128)
382 b = -128;
383
384 current->texture[hw_unit].hwTextureMip |= ((b << 4) &
385 MASK_TextureMipmapLodBias);
386 }
387
388 switch (texObj->MinFilter)
389 {
390 case GL_NEAREST:
391 current->texture[hw_unit].hwTextureMip |= TEXTURE_FILTER_NEAREST;
392 break;
393 case GL_LINEAR:
394 current->texture[hw_unit].hwTextureMip |= TEXTURE_FILTER_LINEAR;
395 break;
396 case GL_NEAREST_MIPMAP_NEAREST:
397 current->texture[hw_unit].hwTextureMip |=
398 TEXTURE_FILTER_NEAREST_MIP_NEAREST;
399 break;
400 case GL_NEAREST_MIPMAP_LINEAR:
401 current->texture[hw_unit].hwTextureMip |=
402 TEXTURE_FILTER_NEAREST_MIP_LINEAR;
403 break;
404 case GL_LINEAR_MIPMAP_NEAREST:
405 current->texture[hw_unit].hwTextureMip |=
406 TEXTURE_FILTER_LINEAR_MIP_NEAREST;
407 break;
408 case GL_LINEAR_MIPMAP_LINEAR:
409 current->texture[hw_unit].hwTextureMip |=
410 TEXTURE_FILTER_LINEAR_MIP_LINEAR;
411 break;
412 }
413
414 switch (texObj->WrapS)
415 {
416 case GL_REPEAT:
417 current->texture[hw_unit].hwTextureSet |= MASK_TextureWrapU;
418 break;
419 case GL_MIRRORED_REPEAT:
420 current->texture[hw_unit].hwTextureSet |= MASK_TextureMirrorU;
421 break;
422 case GL_CLAMP:
423 current->texture[hw_unit].hwTextureSet |= MASK_TextureClampU;
424 /* XXX: GL_CLAMP isn't conformant, but falling back makes the situation
425 * worse in other programs at the moment.
426 */
427 /*ok = 0;*/
428 break;
429 case GL_CLAMP_TO_EDGE:
430 current->texture[hw_unit].hwTextureSet |= MASK_TextureClampU;
431 break;
432 case GL_CLAMP_TO_BORDER:
433 current->texture[hw_unit].hwTextureSet |= MASK_TextureBorderU;
434 break;
435 }
436
437 switch (texObj->WrapT)
438 {
439 case GL_REPEAT:
440 current->texture[hw_unit].hwTextureSet |= MASK_TextureWrapV;
441 break;
442 case GL_MIRRORED_REPEAT:
443 current->texture[hw_unit].hwTextureSet |= MASK_TextureMirrorV;
444 break;
445 case GL_CLAMP:
446 current->texture[hw_unit].hwTextureSet |= MASK_TextureClampV;
447 /* XXX: GL_CLAMP isn't conformant, but falling back makes the situation
448 * worse in other programs at the moment.
449 */
450 /*ok = 0;*/
451 break;
452 case GL_CLAMP_TO_EDGE:
453 current->texture[hw_unit].hwTextureSet |= MASK_TextureClampV;
454 break;
455 case GL_CLAMP_TO_BORDER:
456 current->texture[hw_unit].hwTextureSet |= MASK_TextureBorderV;
457 break;
458 }
459
460 current->texture[hw_unit].hwTextureBorderColor =
461 ((GLuint) texObj->_BorderChan[3] << 24) +
462 ((GLuint) texObj->_BorderChan[0] << 16) +
463 ((GLuint) texObj->_BorderChan[1] << 8) +
464 ((GLuint) texObj->_BorderChan[2]);
465
466 if (current->texture[hw_unit].hwTextureBorderColor !=
467 prev->texture[hw_unit].hwTextureBorderColor)
468 {
469 prev->texture[hw_unit].hwTextureBorderColor =
470 current->texture[hw_unit].hwTextureBorderColor;
471 if (hw_unit == 1)
472 smesa->GlobalFlag |= GFLAG_TEXBORDERCOLOR_1;
473 else
474 smesa->GlobalFlag |= GFLAG_TEXBORDERCOLOR;
475 }
476
477 current->texture[hw_unit].hwTextureSet |=
478 texObj->Image[0][firstLevel]->WidthLog2 << 4;
479 current->texture[hw_unit].hwTextureSet |=
480 texObj->Image[0][firstLevel]->HeightLog2;
481
482 if (hw_unit == 0)
483 smesa->GlobalFlag |= GFLAG_TEXTUREADDRESS;
484 else
485 smesa->GlobalFlag |= GFLAG_TEXTUREADDRESS_1;
486
487 for (i = firstLevel; i <= lastLevel; i++)
488 {
489 GLuint texOffset = 0;
490 GLuint texPitch = TransferTexturePitch( t->image[i].pitch );
491
492 switch (t->image[i].memType)
493 {
494 case VIDEO_TYPE:
495 texOffset = ((unsigned long)t->image[i].Data - (unsigned long)smesa->FbBase);
496 break;
497 case AGP_TYPE:
498 texOffset = ((unsigned long)t->image[i].Data - (unsigned long)smesa->AGPBase) +
499 (unsigned long) smesa->AGPAddr;
500 current->texture[hw_unit].hwTextureMip |=
501 (MASK_TextureLevel0InSystem << i);
502 break;
503 }
504
505 switch (i)
506 {
507 case 0:
508 prev->texture[hw_unit].texOffset0 = texOffset;
509 prev->texture[hw_unit].texPitch01 = texPitch << 16;
510 break;
511 case 1:
512 prev->texture[hw_unit].texOffset1 = texOffset;
513 prev->texture[hw_unit].texPitch01 |= texPitch;
514 break;
515 case 2:
516 prev->texture[hw_unit].texOffset2 = texOffset;
517 prev->texture[hw_unit].texPitch23 = texPitch << 16;
518 break;
519 case 3:
520 prev->texture[hw_unit].texOffset3 = texOffset;
521 prev->texture[hw_unit].texPitch23 |= texPitch;
522 break;
523 case 4:
524 prev->texture[hw_unit].texOffset4 = texOffset;
525 prev->texture[hw_unit].texPitch45 = texPitch << 16;
526 break;
527 case 5:
528 prev->texture[hw_unit].texOffset5 = texOffset;
529 prev->texture[hw_unit].texPitch45 |= texPitch;
530 break;
531 case 6:
532 prev->texture[hw_unit].texOffset6 = texOffset;
533 prev->texture[hw_unit].texPitch67 = texPitch << 16;
534 break;
535 case 7:
536 prev->texture[hw_unit].texOffset7 = texOffset;
537 prev->texture[hw_unit].texPitch67 |= texPitch;
538 break;
539 case 8:
540 prev->texture[hw_unit].texOffset8 = texOffset;
541 prev->texture[hw_unit].texPitch89 = texPitch << 16;
542 break;
543 case 9:
544 prev->texture[hw_unit].texOffset9 = texOffset;
545 prev->texture[hw_unit].texPitch89 |= texPitch;
546 break;
547 case 10:
548 prev->texture[hw_unit].texOffset10 = texOffset;
549 prev->texture[hw_unit].texPitch10 = texPitch << 16;
550 break;
551 case 11:
552 prev->texture[hw_unit].texOffset11 = texOffset;
553 prev->texture[hw_unit].texPitch10 |= texPitch;
554 break;
555 }
556 }
557
558 if (current->texture[hw_unit].hwTextureSet !=
559 prev->texture[hw_unit].hwTextureSet)
560 {
561 prev->texture[hw_unit].hwTextureSet =
562 current->texture[hw_unit].hwTextureSet;
563 if (hw_unit == 1)
564 smesa->GlobalFlag |= CFLAG_TEXTURERESET_1;
565 else
566 smesa->GlobalFlag |= CFLAG_TEXTURERESET;
567 }
568 if (current->texture[hw_unit].hwTextureMip !=
569 prev->texture[hw_unit].hwTextureMip)
570 {
571 prev->texture[hw_unit].hwTextureMip =
572 current->texture[hw_unit].hwTextureMip;
573 if (hw_unit == 1)
574 smesa->GlobalFlag |= GFLAG_TEXTUREMIPMAP_1;
575 else
576 smesa->GlobalFlag |= GFLAG_TEXTUREMIPMAP;
577 }
578
579 return ok;
580 }
581
582 /* Disable a texture unit, called from validate_texture */
583 static void
584 sis_reset_texture_env (GLcontext *ctx, int hw_unit)
585 {
586 sisContextPtr smesa = SIS_CONTEXT(ctx);
587
588 __GLSiSHardware *prev = &smesa->prev;
589 __GLSiSHardware *current = &smesa->current;
590
591 if (hw_unit == 1)
592 {
593 current->hwTexBlendColor1 = STAGE1_C_CF;
594 current->hwTexBlendAlpha1 = STAGE1_A_AF;
595
596 if ((current->hwTexBlendColor1 != prev->hwTexBlendColor1) ||
597 (current->hwTexBlendAlpha1 != prev->hwTexBlendAlpha1) ||
598 (current->hwTexEnvColor != prev->hwTexEnvColor))
599 {
600 prev->hwTexBlendColor1 = current->hwTexBlendColor1;
601 prev->hwTexBlendAlpha1 = current->hwTexBlendAlpha1;
602 prev->hwTexEnvColor = current->hwTexEnvColor;
603 smesa->GlobalFlag |= GFLAG_TEXTUREENV_1;
604 }
605 } else {
606 current->hwTexBlendColor0 = STAGE0_C_CF;
607 current->hwTexBlendAlpha0 = STAGE0_A_AF;
608
609 if ((current->hwTexBlendColor0 != prev->hwTexBlendColor0) ||
610 (current->hwTexBlendAlpha0 != prev->hwTexBlendAlpha0) ||
611 (current->hwTexEnvColor != prev->hwTexEnvColor))
612 {
613 prev->hwTexBlendColor0 = current->hwTexBlendColor0;
614 prev->hwTexBlendAlpha0 = current->hwTexBlendAlpha0;
615 prev->hwTexEnvColor = current->hwTexEnvColor;
616 smesa->GlobalFlag |= GFLAG_TEXTUREENV;
617 }
618 }
619 }
620
621 static void updateTextureUnit( GLcontext *ctx, int unit )
622 {
623 sisContextPtr smesa = SIS_CONTEXT( ctx );
624 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
625 struct gl_texture_object *texObj = texUnit->_Current;
626 GLint fallbackbit;
627
628 if (unit == 0)
629 fallbackbit = SIS_FALLBACK_TEXTURE0;
630 else
631 fallbackbit = SIS_FALLBACK_TEXTURE1;
632
633 if (texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) {
634 if (smesa->TexStates[unit] & NEW_TEXTURING) {
635 GLboolean ok;
636
637 ok = sis_set_texobj_parm (ctx, texObj, unit);
638 FALLBACK( smesa, fallbackbit, !ok );
639 }
640 if (smesa->TexStates[unit] & NEW_TEXTURE_ENV) {
641 if (unit == 0)
642 sis_set_texture_env0( ctx, texObj, unit );
643 else
644 sis_set_texture_env1( ctx, texObj, unit );
645 }
646 smesa->TexStates[unit] = 0;
647 } else if ( texUnit->_ReallyEnabled ) {
648 /* fallback */
649 FALLBACK( smesa, fallbackbit, 1 );
650 } else {
651 sis_reset_texture_env( ctx, unit );
652 FALLBACK( smesa, fallbackbit, 0 );
653 }
654 }
655
656
657 void sisUpdateTextureState( GLcontext *ctx )
658 {
659 sisContextPtr smesa = SIS_CONTEXT( ctx );
660 int i;
661 __GLSiSHardware *current = &smesa->current;
662
663 #if 1
664 /* TODO : if unmark these, error in multitexture */ /* XXX */
665 for (i = 0; i < SIS_MAX_TEXTURES; i++)
666 smesa->TexStates[i] |= (NEW_TEXTURING | NEW_TEXTURE_ENV);
667 #endif
668
669 updateTextureUnit( ctx, 0 );
670 updateTextureUnit( ctx, 1 );
671
672 /* XXX Issues with the 2nd unit but not the first being enabled? */
673 if ( ctx->Texture.Unit[0]._ReallyEnabled &
674 (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ||
675 ctx->Texture.Unit[1]._ReallyEnabled &
676 (TEXTURE_1D_BIT | TEXTURE_2D_BIT) )
677 {
678 current->hwCapEnable |= MASK_TextureEnable;
679 current->hwCapEnable &= ~MASK_TextureNumUsed;
680 if (ctx->Texture.Unit[1]._ReallyEnabled)
681 current->hwCapEnable |= 0x00002000;
682 else
683 current->hwCapEnable |= 0x00001000;
684 } else {
685 current->hwCapEnable &= ~MASK_TextureEnable;
686 }
687 }
688
689 static GLint
690 BitScanForward( GLshort w )
691 {
692 GLint i;
693
694 for (i = 0; i < 16; i++) {
695 if (w & (1 << i))
696 break;
697 }
698 return i;
699 }
700
701 static GLint
702 TransferTexturePitch( GLint dwPitch )
703 {
704 GLint dwRet, i;
705
706 i = BitScanForward( (GLshort)dwPitch );
707 dwRet = dwPitch >> i;
708 dwRet |= i << 9;
709 return dwRet;
710 }