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