OSDN Git Service

Merge branch 'mesa_7_7_branch'
[android-x86/external-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 }