2 * Author: Max Lingua <sunmax@libero.it>
8 #include "main/glheader.h"
9 #include "main/macros.h"
10 #include "main/mtypes.h"
11 #include "main/simple_list.h"
12 #include "main/enums.h"
15 #include "s3v_context.h"
19 static void s3vSetTexImages( s3vContextPtr vmesa
,
20 struct gl_texture_object
*tObj
)
22 GLuint height
, width
, pitch
, i
, /*textureFormat,*/ log_pitch
;
23 s3vTextureObjectPtr t
= (s3vTextureObjectPtr
) tObj
->DriverData
;
24 const struct gl_texture_image
*baseImage
= tObj
->Image
[0][tObj
->BaseLevel
];
25 GLint firstLevel
, lastLevel
, numLevels
;
26 GLint log2Width
, log2Height
;
28 static unsigned int times
=0;
29 DEBUG_TEX(("*** s3vSetTexImages: #%i ***\n", ++times
));
32 t
->texelBytes
= 2; /* FIXME: always 2 ? */
34 /* Compute which mipmap levels we really want to send to the hardware.
35 * This depends on the base image size, GL_TEXTURE_MIN_LOD,
36 * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
37 * Yes, this looks overly complicated, but it's all needed.
39 if (tObj
->MinFilter
== GL_LINEAR
|| tObj
->MinFilter
== GL_NEAREST
) {
40 firstLevel
= lastLevel
= tObj
->BaseLevel
;
43 firstLevel
= tObj
->BaseLevel
+ (GLint
) (tObj
->MinLod
+ 0.5);
44 firstLevel
= MAX2(firstLevel
, tObj
->BaseLevel
);
45 lastLevel
= tObj
->BaseLevel
+ (GLint
) (tObj
->MaxLod
+ 0.5);
46 lastLevel
= MAX2(lastLevel
, tObj
->BaseLevel
);
47 lastLevel
= MIN2(lastLevel
, tObj
->BaseLevel
+ baseImage
->MaxLog2
);
48 lastLevel
= MIN2(lastLevel
, tObj
->MaxLevel
);
49 lastLevel
= MAX2(firstLevel
, lastLevel
); /* need at least one level */
52 /* save these values */
53 t
->firstLevel
= firstLevel
;
54 t
->lastLevel
= lastLevel
;
56 numLevels
= lastLevel
- firstLevel
+ 1;
58 log2Width
= tObj
->Image
[0][firstLevel
]->WidthLog2
;
59 log2Height
= tObj
->Image
[0][firstLevel
]->HeightLog2
;
62 /* Figure out the amount of memory required to hold all the mipmap
63 * levels. Choose the smallest pitch to accomodate the largest
66 width
= tObj
->Image
[0][firstLevel
]->Width
* t
->texelBytes
;
67 for (pitch
= 32, log_pitch
=2 ; pitch
< width
; pitch
*= 2 )
70 /* All images must be loaded at this pitch. Count the number of
73 for ( height
= i
= 0 ; i
< numLevels
; i
++ ) {
74 t
->image
[i
].image
= tObj
->Image
[0][firstLevel
+ i
];
75 t
->image
[i
].offset
= height
* pitch
;
76 t
->image
[i
].internalFormat
= baseImage
->_BaseFormat
;
77 height
+= t
->image
[i
].image
->Height
;
78 t
->TextureBaseAddr
[i
] = (t
->BufAddr
+ t
->image
[i
].offset
+
79 _TEXALIGN
) & (GLuint
)(~_TEXALIGN
);
83 t
->WidthLog2
= log2Width
;
84 t
->totalSize
= height
*pitch
;
86 vmesa
->dirty
|= S3V_UPLOAD_TEX0
/* | S3V_UPLOAD_TEX1*/;
87 vmesa
->restore_primitive
= -1;
88 DEBUG(("<><>pitch = TexStride = %i\n", pitch
));
89 DEBUG(("log2Width = %i\n", log2Width
));
91 s3vUploadTexImages( vmesa
, t
);
94 static void s3vUpdateTexEnv( GLcontext
*ctx
, GLuint unit
)
96 s3vContextPtr vmesa
= S3V_CONTEXT(ctx
);
97 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
98 const struct gl_texture_object
*tObj
= texUnit
->_Current
;
99 const GLuint format
= tObj
->Image
[0][tObj
->BaseLevel
]->_BaseFormat
;
101 s3vTextureObjectPtr t = (s3vTextureObjectPtr)tObj->DriverData;
105 GLuint cmd
= vmesa
->CMD
;
107 static unsigned int times
=0;
108 DEBUG_TEX(("*** s3vUpdateTexEnv: %i ***\n", ++times
));
111 cmd
&= ~TEX_COL_MASK
;
112 cmd
&= ~TEX_BLEND_MAKS
;
113 /* cmd &= ~ALPHA_BLEND_MASK; */
115 DEBUG(("format = "));
119 DEBUG_TEX(("GL_RGB\n"));
120 cmd
|= TEX_COL_ARGB1555
;
123 DEBUG_TEX(("GL_LUMINANCE\n"));
124 cmd
|= TEX_COL_ARGB4444
;
125 alpha
= 1; /* FIXME: check */
128 DEBUG_TEX(("GL_ALPHA\n"));
129 cmd
|= TEX_COL_ARGB4444
;
132 case GL_LUMINANCE_ALPHA
:
133 DEBUG_TEX(("GL_LUMINANCE_ALPHA\n"));
134 cmd
|= TEX_COL_ARGB4444
;
138 DEBUG_TEX(("GL_INTENSITY\n"));
139 cmd
|= TEX_COL_ARGB4444
;
143 DEBUG_TEX(("GL_RGBA\n"));
144 cmd
|= TEX_COL_ARGB4444
;
148 DEBUG_TEX(("GL_COLOR_INDEX\n"));
153 DEBUG_TEX(("EnvMode = "));
155 switch (texUnit
->EnvMode
) {
157 DEBUG_TEX(("GL_REPLACE\n"));
158 cmd
|= TEX_REFLECT
; /* FIXME */
159 vmesa
->_tri
[1] = DO_TEX_UNLIT_TRI
; /* FIXME: white tri hack */
160 vmesa
->_alpha_tex
= ALPHA_TEX
/* * alpha */;
163 DEBUG_TEX(("GL_MODULATE\n"));
165 vmesa
->_tri
[1] = DO_TEX_LIT_TRI
;
168 vmesa
->_alpha_tex
= ALPHA_TEX
/* * alpha */;
170 vmesa
->_alpha_tex
= ALPHA_SRC
/* * alpha */;
172 vmesa
->_alpha_tex
= ALPHA_TEX
;
176 DEBUG_TEX(("DEBUG_TEX\n"));
180 DEBUG_TEX(("GL_DECAL\n"));
182 vmesa
->_tri
[1] = DO_TEX_LIT_TRI
;
183 vmesa
->_alpha_tex
= ALPHA_OFF
;
186 DEBUG_TEX(("GL_BLEND\n"));
188 vmesa
->_tri
[1] = DO_TEX_LIT_TRI
;
189 vmesa
->_alpha_tex
= ALPHA_OFF
; /* FIXME: sure? */
192 fprintf(stderr
, "unknown tex env mode");
196 DEBUG_TEX(("\n\n vmesa->CMD was 0x%x\n", vmesa
->CMD
));
197 DEBUG_TEX(( " vmesa->CMD is 0x%x\n\n", cmd
));
199 vmesa
->_alpha
[1] = vmesa
->_alpha_tex
;
200 vmesa
->CMD
= cmd
; /* | MIPMAP_LEVEL(8); */
201 vmesa
->restore_primitive
= -1;
204 static void s3vUpdateTexUnit( GLcontext
*ctx
, GLuint unit
)
206 s3vContextPtr vmesa
= S3V_CONTEXT(ctx
);
207 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
208 GLuint cmd
= vmesa
->CMD
;
210 static unsigned int times
=0;
211 DEBUG_TEX(("*** s3vUpdateTexUnit: %i ***\n", ++times
));
212 DEBUG_TEX(("and vmesa->CMD was 0x%x\n", vmesa
->CMD
));
215 if (texUnit
->_ReallyEnabled
== TEXTURE_2D_BIT
)
217 struct gl_texture_object
*tObj
= texUnit
->_Current
;
218 s3vTextureObjectPtr t
= (s3vTextureObjectPtr
)tObj
->DriverData
;
220 /* Upload teximages (not pipelined)
222 if (t
->dirty_images
) {
226 s3vSetTexImages( vmesa
, tObj
);
229 FALLBACK( vmesa
, S3V_FALLBACK_TEXTURE
, GL_TRUE
);
235 /* Update state if this is a different texture object to last
239 if (vmesa
->CurrentTexObj
[unit
] != t
) {
240 vmesa
->dirty
|= S3V_UPLOAD_TEX0
/* << unit */;
241 vmesa
->CurrentTexObj
[unit
] = t
;
242 s3vUpdateTexLRU( vmesa
, t
); /* done too often */
246 /* Update texture environment if texture object image format or
247 * texture environment state has changed.
249 if (tObj
->Image
[0][tObj
->BaseLevel
]->_BaseFormat
!=
250 vmesa
->TexEnvImageFmt
[unit
]) {
251 vmesa
->TexEnvImageFmt
[unit
] = tObj
->Image
[0][tObj
->BaseLevel
]->_BaseFormat
;
252 s3vUpdateTexEnv( ctx
, unit
);
255 cmd
= vmesa
->CMD
& ~MIP_MASK
;
256 vmesa
->dirty
|= S3V_UPLOAD_TEX0
/* << unit */;
257 vmesa
->CurrentTexObj
[unit
] = t
;
258 vmesa
->TexOffset
= t
->TextureBaseAddr
[tObj
->BaseLevel
];
259 vmesa
->TexStride
= t
->Pitch
;
260 cmd
|= MIPMAP_LEVEL(t
->WidthLog2
);
262 DEBUG_TEX(("\n\n>> vmesa->CMD was 0x%x\n", vmesa
->CMD
));
263 DEBUG_TEX(( ">> vmesa->CMD is 0x%x\n\n", cmd
));
264 DEBUG_TEX(("t->WidthLog2 = %i\n", t
->WidthLog2
));
265 DEBUG_TEX(("MIPMAP_LEVEL(t->WidthLog2) = 0x%x\n", MIPMAP_LEVEL(t
->WidthLog2
)));
268 vmesa
->restore_primitive
= -1;
271 else if (texUnit
->_ReallyEnabled
) { /* _ReallyEnabled but != TEXTURE0_2D */
273 FALLBACK( vmesa
, S3V_FALLBACK_TEXTURE
, GL_TRUE
);
276 else /*if (vmesa->CurrentTexObj[unit])*/ { /* !_ReallyEnabled */
277 vmesa
->CurrentTexObj
[unit
] = 0;
278 vmesa
->TexEnvImageFmt
[unit
] = 0;
279 vmesa
->dirty
&= ~(S3V_UPLOAD_TEX0
<<unit
);
284 void s3vUpdateTextureState( GLcontext
*ctx
)
286 s3vContextPtr vmesa
= S3V_CONTEXT(ctx
);
289 static unsigned int times
=0;
290 DEBUG_TEX(("*** s3vUpdateTextureState: #%i ***\n", ++times
));
294 FALLBACK( vmesa
, S3V_FALLBACK_TEXTURE
, GL_FALSE
);
296 s3vUpdateTexUnit( ctx
, 0 );
298 s3vUpdateTexUnit( ctx
, 1 );