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