1
/**************************************************************************
3
Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
4
Copyright 2003 Eric Anholt
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:
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
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.
26
**************************************************************************/
30
* Sung-Ching Lin <sclin@sis.com.tw>
31
* Eric Anholt <anholt@FreeBSD.org>
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"
40
#include "sis_context.h"
43
#include "sis_alloc.h"
45
static GLint TransferTexturePitch (GLint dwPitch);
47
/* Handle texenv stuff, called from validate_texture (renderstart) */
49
sis_set_texture_env0( struct gl_context *ctx, struct gl_texture_object *texObj,
52
sisContextPtr smesa = SIS_CONTEXT(ctx);
55
__GLSiSHardware *prev = &smesa->prev;
56
__GLSiSHardware *current = &smesa->current;
58
struct gl_texture_unit *texture_unit = &ctx->Texture.Unit[unit];
60
sisTexObjPtr t = texObj->DriverData;
62
switch (texture_unit->EnvMode)
68
current->hwTexBlendColor0 = STAGE0_C_CF;
69
current->hwTexBlendAlpha0 = STAGE0_A_AS;
74
current->hwTexBlendColor0 = STAGE0_C_CS;
75
current->hwTexBlendAlpha0 = STAGE0_A_AF;
78
case GL_LUMINANCE_ALPHA:
80
current->hwTexBlendColor0 = STAGE0_C_CS;
81
current->hwTexBlendAlpha0 = STAGE0_A_AS;
84
sis_fatal_error("unknown base format 0x%x\n", t->format);
92
current->hwTexBlendColor0 = STAGE0_C_CF;
93
current->hwTexBlendAlpha0 = STAGE0_A_AFAS;
98
current->hwTexBlendColor0 = STAGE0_C_CFCS;
99
current->hwTexBlendAlpha0 = STAGE0_A_AF;
102
case GL_LUMINANCE_ALPHA:
104
current->hwTexBlendColor0 = STAGE0_C_CFCS;
105
current->hwTexBlendAlpha0 = STAGE0_A_AFAS;
108
sis_fatal_error("unknown base format 0x%x\n", t->format);
117
current->hwTexBlendColor0 = STAGE0_C_CS;
118
current->hwTexBlendAlpha0 = STAGE0_A_AF;
121
current->hwTexBlendColor0 = STAGE0_C_CFOMAS_CSAS;
122
current->hwTexBlendAlpha0 = STAGE0_A_AF;
127
case GL_LUMINANCE_ALPHA:
128
current->hwTexBlendColor0 = STAGE0_C_CF;
129
current->hwTexBlendAlpha0 = STAGE0_A_AF;
132
sis_fatal_error("unknown base format 0x%x\n", t->format);
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 |
145
current->hwTexBlendColor0 = STAGE0_C_CF;
146
current->hwTexBlendAlpha0 = STAGE0_A_AFAS;
151
current->hwTexBlendColor0 = STAGE0_C_CFOMCS_CCCS;
152
current->hwTexBlendAlpha0 = STAGE0_A_AF;
155
current->hwTexBlendColor0 = STAGE0_C_CFOMCS_CCCS;
156
current->hwTexBlendAlpha0 = STAGE0_A_AFOMAS_ACAS;
158
case GL_LUMINANCE_ALPHA:
160
current->hwTexBlendColor0 = STAGE0_C_CFOMCS_CCCS;
161
current->hwTexBlendAlpha0 = STAGE0_A_AFAS;
164
sis_fatal_error("unknown base format 0x%x\n", t->format);
169
sis_fatal_error("unknown env mode 0x%x\n", texture_unit->EnvMode);
172
if ((current->hwTexBlendColor0 != prev->hwTexBlendColor0) ||
173
(current->hwTexBlendAlpha0 != prev->hwTexBlendAlpha0) ||
174
(current->hwTexEnvColor != prev->hwTexEnvColor))
176
prev->hwTexEnvColor = current->hwTexEnvColor;
177
prev->hwTexBlendColor0 = current->hwTexBlendColor0;
178
prev->hwTexBlendAlpha0 = current->hwTexBlendAlpha0;
179
smesa->GlobalFlag |= GFLAG_TEXTUREENV;
183
/* Handle texenv stuff, called from validate_texture (renderstart) */
185
sis_set_texture_env1( struct gl_context *ctx, struct gl_texture_object *texObj,
188
sisContextPtr smesa = SIS_CONTEXT(ctx);
191
__GLSiSHardware *prev = &smesa->prev;
192
__GLSiSHardware *current = &smesa->current;
194
struct gl_texture_unit *texture_unit = &ctx->Texture.Unit[unit];
196
sisTexObjPtr t = texObj->DriverData;
198
switch (texture_unit->EnvMode)
204
current->hwTexBlendColor1 = STAGE1_C_CF;
205
current->hwTexBlendAlpha1 = STAGE1_A_AS;
210
current->hwTexBlendColor1 = STAGE1_C_CS;
211
current->hwTexBlendAlpha1 = STAGE1_A_AF;
214
case GL_LUMINANCE_ALPHA:
216
current->hwTexBlendColor1 = STAGE1_C_CS;
217
current->hwTexBlendAlpha1 = STAGE1_A_AS;
220
sis_fatal_error("unknown base format 0x%x\n", t->format);
228
current->hwTexBlendColor1 = STAGE1_C_CF;
229
current->hwTexBlendAlpha1 = STAGE1_A_AFAS;
234
current->hwTexBlendColor1 = STAGE1_C_CFCS;
235
current->hwTexBlendAlpha1 = STAGE1_A_AF;
238
case GL_LUMINANCE_ALPHA:
240
current->hwTexBlendColor1 = STAGE1_C_CFCS;
241
current->hwTexBlendAlpha1 = STAGE1_A_AFAS;
244
sis_fatal_error("unknown base format 0x%x\n", t->format);
253
current->hwTexBlendColor1 = STAGE1_C_CS;
254
current->hwTexBlendAlpha1 = STAGE1_A_AF;
257
current->hwTexBlendColor1 = STAGE1_C_CFOMAS_CSAS;
258
current->hwTexBlendAlpha1 = STAGE1_A_AF;
263
case GL_LUMINANCE_ALPHA:
264
current->hwTexBlendColor1 = STAGE1_C_CF;
265
current->hwTexBlendAlpha1 = STAGE1_A_AF;
268
sis_fatal_error("unknown base format 0x%x\n", t->format);
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 |
281
current->hwTexBlendColor1 = STAGE1_C_CF;
282
current->hwTexBlendAlpha1 = STAGE1_A_AFAS;
287
current->hwTexBlendColor1 = STAGE1_C_CFOMCS_CCCS;
288
current->hwTexBlendAlpha1 = STAGE1_A_AF;
291
current->hwTexBlendColor1 = STAGE1_C_CFOMCS_CCCS;
292
current->hwTexBlendAlpha1 = STAGE1_A_AFOMAS_ACAS;
294
case GL_LUMINANCE_ALPHA:
296
current->hwTexBlendColor1 = STAGE1_C_CFOMCS_CCCS;
297
current->hwTexBlendAlpha1 = STAGE1_A_AFAS;
300
sis_fatal_error("unknown base format 0x%x\n", t->format);
305
sis_fatal_error("unknown env mode 0x%x\n", texture_unit->EnvMode);
308
if ((current->hwTexBlendColor1 != prev->hwTexBlendColor1) ||
309
(current->hwTexBlendAlpha1 != prev->hwTexBlendAlpha1) ||
310
(current->hwTexEnvColor != prev->hwTexEnvColor))
312
prev->hwTexBlendColor1 = current->hwTexBlendColor1;
313
prev->hwTexBlendAlpha1 = current->hwTexBlendAlpha1;
314
prev->hwTexEnvColor = current->hwTexEnvColor;
315
smesa->GlobalFlag |= GFLAG_TEXTUREENV_1;
319
/* Returns 0 if a software fallback is necessary */
321
sis_set_texobj_parm( struct gl_context *ctx, struct gl_texture_object *texObj,
324
sisContextPtr smesa = SIS_CONTEXT(ctx);
327
__GLSiSHardware *prev = &smesa->prev;
328
__GLSiSHardware *current = &smesa->current;
330
sisTexObjPtr t = texObj->DriverData;
332
GLint firstLevel, lastLevel;
335
current->texture[hw_unit].hwTextureMip = 0UL;
336
current->texture[hw_unit].hwTextureSet = t->hwformat;
338
if ((texObj->Sampler.MinFilter == GL_NEAREST) || (texObj->Sampler.MinFilter == GL_LINEAR)) {
339
firstLevel = lastLevel = texObj->BaseLevel;
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.
347
firstLevel = texObj->BaseLevel + (GLint)(texObj->Sampler.MinLod + 0.5);
348
firstLevel = MAX2(firstLevel, texObj->BaseLevel);
349
lastLevel = texObj->BaseLevel + (GLint)(texObj->Sampler.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 */
357
current->texture[hw_unit].hwTextureSet |= (lastLevel << 8);
359
switch (texObj->Sampler.MagFilter)
362
current->texture[hw_unit].hwTextureMip |= TEXTURE_FILTER_NEAREST;
365
current->texture[hw_unit].hwTextureMip |= (TEXTURE_FILTER_LINEAR << 3);
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.
375
b = (GLint) (ctx->Texture.Unit[hw_unit].LodBias * 32.0);
381
current->texture[hw_unit].hwTextureMip |= ((b << 4) &
382
MASK_TextureMipmapLodBias);
385
switch (texObj->Sampler.MinFilter)
388
current->texture[hw_unit].hwTextureMip |= TEXTURE_FILTER_NEAREST;
391
current->texture[hw_unit].hwTextureMip |= TEXTURE_FILTER_LINEAR;
393
case GL_NEAREST_MIPMAP_NEAREST:
394
current->texture[hw_unit].hwTextureMip |=
395
TEXTURE_FILTER_NEAREST_MIP_NEAREST;
397
case GL_NEAREST_MIPMAP_LINEAR:
398
current->texture[hw_unit].hwTextureMip |=
399
TEXTURE_FILTER_NEAREST_MIP_LINEAR;
401
case GL_LINEAR_MIPMAP_NEAREST:
402
current->texture[hw_unit].hwTextureMip |=
403
TEXTURE_FILTER_LINEAR_MIP_NEAREST;
405
case GL_LINEAR_MIPMAP_LINEAR:
406
current->texture[hw_unit].hwTextureMip |=
407
TEXTURE_FILTER_LINEAR_MIP_LINEAR;
411
switch (texObj->Sampler.WrapS)
414
current->texture[hw_unit].hwTextureSet |= MASK_TextureWrapU;
416
case GL_MIRRORED_REPEAT:
417
current->texture[hw_unit].hwTextureSet |= MASK_TextureMirrorU;
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.
426
case GL_CLAMP_TO_EDGE:
427
current->texture[hw_unit].hwTextureSet |= MASK_TextureClampU;
429
case GL_CLAMP_TO_BORDER:
430
current->texture[hw_unit].hwTextureSet |= MASK_TextureBorderU;
434
switch (texObj->Sampler.WrapT)
437
current->texture[hw_unit].hwTextureSet |= MASK_TextureWrapV;
439
case GL_MIRRORED_REPEAT:
440
current->texture[hw_unit].hwTextureSet |= MASK_TextureMirrorV;
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.
449
case GL_CLAMP_TO_EDGE:
450
current->texture[hw_unit].hwTextureSet |= MASK_TextureClampV;
452
case GL_CLAMP_TO_BORDER:
453
current->texture[hw_unit].hwTextureSet |= MASK_TextureBorderV;
459
CLAMPED_FLOAT_TO_UBYTE(c[0], texObj->Sampler.BorderColor.f[0]);
460
CLAMPED_FLOAT_TO_UBYTE(c[1], texObj->Sampler.BorderColor.f[1]);
461
CLAMPED_FLOAT_TO_UBYTE(c[2], texObj->Sampler.BorderColor.f[2]);
462
CLAMPED_FLOAT_TO_UBYTE(c[3], texObj->Sampler.BorderColor.f[3]);
464
current->texture[hw_unit].hwTextureBorderColor =
465
PACK_COLOR_8888(c[3], c[0], c[1], c[2]);
468
if (current->texture[hw_unit].hwTextureBorderColor !=
469
prev->texture[hw_unit].hwTextureBorderColor)
471
prev->texture[hw_unit].hwTextureBorderColor =
472
current->texture[hw_unit].hwTextureBorderColor;
474
smesa->GlobalFlag |= GFLAG_TEXBORDERCOLOR_1;
476
smesa->GlobalFlag |= GFLAG_TEXBORDERCOLOR;
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;
485
smesa->GlobalFlag |= GFLAG_TEXTUREADDRESS;
487
smesa->GlobalFlag |= GFLAG_TEXTUREADDRESS_1;
489
for (i = firstLevel; i <= lastLevel; i++)
491
GLuint texOffset = 0;
492
GLuint texPitch = TransferTexturePitch( t->image[i].pitch );
494
switch (t->image[i].memType)
497
texOffset = ((unsigned long)t->image[i].Data - (unsigned long)smesa->FbBase);
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);
510
prev->texture[hw_unit].texOffset0 = texOffset;
511
prev->texture[hw_unit].texPitch01 = texPitch << 16;
514
prev->texture[hw_unit].texOffset1 = texOffset;
515
prev->texture[hw_unit].texPitch01 |= texPitch;
518
prev->texture[hw_unit].texOffset2 = texOffset;
519
prev->texture[hw_unit].texPitch23 = texPitch << 16;
522
prev->texture[hw_unit].texOffset3 = texOffset;
523
prev->texture[hw_unit].texPitch23 |= texPitch;
526
prev->texture[hw_unit].texOffset4 = texOffset;
527
prev->texture[hw_unit].texPitch45 = texPitch << 16;
530
prev->texture[hw_unit].texOffset5 = texOffset;
531
prev->texture[hw_unit].texPitch45 |= texPitch;
534
prev->texture[hw_unit].texOffset6 = texOffset;
535
prev->texture[hw_unit].texPitch67 = texPitch << 16;
538
prev->texture[hw_unit].texOffset7 = texOffset;
539
prev->texture[hw_unit].texPitch67 |= texPitch;
542
prev->texture[hw_unit].texOffset8 = texOffset;
543
prev->texture[hw_unit].texPitch89 = texPitch << 16;
546
prev->texture[hw_unit].texOffset9 = texOffset;
547
prev->texture[hw_unit].texPitch89 |= texPitch;
550
prev->texture[hw_unit].texOffset10 = texOffset;
551
prev->texture[hw_unit].texPitch10 = texPitch << 16;
554
prev->texture[hw_unit].texOffset11 = texOffset;
555
prev->texture[hw_unit].texPitch10 |= texPitch;
560
if (current->texture[hw_unit].hwTextureSet !=
561
prev->texture[hw_unit].hwTextureSet)
563
prev->texture[hw_unit].hwTextureSet =
564
current->texture[hw_unit].hwTextureSet;
566
smesa->GlobalFlag |= CFLAG_TEXTURERESET_1;
568
smesa->GlobalFlag |= CFLAG_TEXTURERESET;
570
if (current->texture[hw_unit].hwTextureMip !=
571
prev->texture[hw_unit].hwTextureMip)
573
prev->texture[hw_unit].hwTextureMip =
574
current->texture[hw_unit].hwTextureMip;
576
smesa->GlobalFlag |= GFLAG_TEXTUREMIPMAP_1;
578
smesa->GlobalFlag |= GFLAG_TEXTUREMIPMAP;
584
/* Disable a texture unit, called from validate_texture */
586
sis_reset_texture_env (struct gl_context *ctx, int hw_unit)
588
sisContextPtr smesa = SIS_CONTEXT(ctx);
590
__GLSiSHardware *prev = &smesa->prev;
591
__GLSiSHardware *current = &smesa->current;
595
current->hwTexBlendColor1 = STAGE1_C_CF;
596
current->hwTexBlendAlpha1 = STAGE1_A_AF;
598
if ((current->hwTexBlendColor1 != prev->hwTexBlendColor1) ||
599
(current->hwTexBlendAlpha1 != prev->hwTexBlendAlpha1) ||
600
(current->hwTexEnvColor != prev->hwTexEnvColor))
602
prev->hwTexBlendColor1 = current->hwTexBlendColor1;
603
prev->hwTexBlendAlpha1 = current->hwTexBlendAlpha1;
604
prev->hwTexEnvColor = current->hwTexEnvColor;
605
smesa->GlobalFlag |= GFLAG_TEXTUREENV_1;
608
current->hwTexBlendColor0 = STAGE0_C_CF;
609
current->hwTexBlendAlpha0 = STAGE0_A_AF;
611
if ((current->hwTexBlendColor0 != prev->hwTexBlendColor0) ||
612
(current->hwTexBlendAlpha0 != prev->hwTexBlendAlpha0) ||
613
(current->hwTexEnvColor != prev->hwTexEnvColor))
615
prev->hwTexBlendColor0 = current->hwTexBlendColor0;
616
prev->hwTexBlendAlpha0 = current->hwTexBlendAlpha0;
617
prev->hwTexEnvColor = current->hwTexEnvColor;
618
smesa->GlobalFlag |= GFLAG_TEXTUREENV;
623
static void updateTextureUnit( struct gl_context *ctx, int unit )
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;
631
fallbackbit = SIS_FALLBACK_TEXTURE0;
633
fallbackbit = SIS_FALLBACK_TEXTURE1;
635
if (texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) {
636
if (smesa->TexStates[unit] & NEW_TEXTURING) {
639
ok = sis_set_texobj_parm (ctx, texObj, unit);
640
FALLBACK( smesa, fallbackbit, !ok );
642
if (smesa->TexStates[unit] & NEW_TEXTURE_ENV) {
644
sis_set_texture_env0( ctx, texObj, unit );
646
sis_set_texture_env1( ctx, texObj, unit );
648
smesa->TexStates[unit] = 0;
649
} else if ( texUnit->_ReallyEnabled ) {
651
FALLBACK( smesa, fallbackbit, 1 );
653
sis_reset_texture_env( ctx, unit );
654
FALLBACK( smesa, fallbackbit, 0 );
659
void sisUpdateTextureState( struct gl_context *ctx )
661
sisContextPtr smesa = SIS_CONTEXT( ctx );
663
__GLSiSHardware *current = &smesa->current;
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);
671
updateTextureUnit( ctx, 0 );
672
updateTextureUnit( ctx, 1 );
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) )
680
current->hwCapEnable |= MASK_TextureEnable;
681
current->hwCapEnable &= ~MASK_TextureNumUsed;
682
if (ctx->Texture.Unit[1]._ReallyEnabled)
683
current->hwCapEnable |= 0x00002000;
685
current->hwCapEnable |= 0x00001000;
687
current->hwCapEnable &= ~MASK_TextureEnable;
692
BitScanForward( GLshort w )
696
for (i = 0; i < 16; i++) {
704
TransferTexturePitch( GLint dwPitch )
708
i = BitScanForward( (GLshort)dwPitch );
709
dwRet = dwPitch >> i;