Merge branch 'mesa_7_6_branch'
[mesa.git] / src / mesa / drivers / dri / s3v / s3v_tex.c
1 /*
2 * Author: Max Lingua <sunmax@libero.it>
3 */
4
5 #include <stdlib.h>
6 #include <stdio.h>
7
8 #include "main/glheader.h"
9 #include "main/mtypes.h"
10 #include "main/simple_list.h"
11 #include "main/enums.h"
12 #include "main/mm.h"
13 #include "main/texstore.h"
14 #include "main/texformat.h"
15 #include "main/teximage.h"
16 #include "swrast/swrast.h"
17
18 #include "s3v_context.h"
19 #include "s3v_tex.h"
20
21
22 extern void s3vSwapOutTexObj(s3vContextPtr vmesa, s3vTextureObjectPtr t);
23 extern void s3vDestroyTexObj(s3vContextPtr vmesa, s3vTextureObjectPtr t);
24
25 /*
26 static GLuint s3vComputeLodBias(GLfloat bias)
27 {
28 #if TEX_DEBUG_ON
29 DEBUG_TEX(("*** s3vComputeLodBias ***\n"));
30 #endif
31 return bias;
32 }
33 */
34
35 static void s3vSetTexWrapping(s3vContextPtr vmesa,
36 s3vTextureObjectPtr t,
37 GLenum wraps, GLenum wrapt)
38 {
39 GLuint t0 = t->TextureCMD;
40 GLuint cmd = vmesa->CMD;
41 #if TEX_DEBUG_ON
42 static unsigned int times=0;
43 DEBUG_TEX(("*** s3vSetTexWrapping: #%i ***\n", ++times));
44 #endif
45
46
47 t0 &= ~TEX_WRAP_MASK;
48 cmd &= ~TEX_WRAP_MASK;
49
50 if ((wraps != GL_CLAMP) || (wrapt != GL_CLAMP)) {
51 DEBUG(("TEX_WRAP_ON\n"));
52 t0 |= TEX_WRAP_ON;
53 cmd |= TEX_WRAP_ON;
54 }
55
56 cmd |= TEX_WRAP_ON; /* FIXME: broken if off */
57 t->TextureCMD = t0;
58 vmesa->CMD = cmd;
59 }
60
61
62 static void s3vSetTexFilter(s3vContextPtr vmesa,
63 s3vTextureObjectPtr t,
64 GLenum minf, GLenum magf)
65 {
66 GLuint t0 = t->TextureCMD;
67 GLuint cmd = vmesa->CMD;
68 #if TEX_DEBUG_ON
69 static unsigned int times=0;
70 DEBUG_TEX(("*** s3vSetTexFilter: #%i ***\n", ++times));
71 #endif
72
73 t0 &= ~TEX_FILTER_MASK;
74 cmd &= ~TEX_FILTER_MASK;
75
76 switch (minf) {
77 case GL_NEAREST:
78 DEBUG(("GL_NEAREST\n"));
79 t0 |= NEAREST;
80 cmd |= NEAREST;
81 break;
82 case GL_LINEAR:
83 DEBUG(("GL_LINEAR\n"));
84 t0 |= LINEAR;
85 cmd |= LINEAR;
86 break;
87 case GL_NEAREST_MIPMAP_NEAREST:
88 DEBUG(("GL_MIPMAP_NEAREST\n"));
89 t0 |= MIP_NEAREST;
90 cmd |= MIP_NEAREST;
91 break;
92 case GL_LINEAR_MIPMAP_NEAREST:
93 DEBUG(("GL_LINEAR_MIPMAP_NEAREST\n"));
94 t0 |= LINEAR_MIP_NEAREST;
95 cmd |= LINEAR_MIP_NEAREST;
96 break;
97 case GL_NEAREST_MIPMAP_LINEAR:
98 DEBUG(("GL_NEAREST_MIPMAP_LINEAR\n"));
99 t0 |= MIP_LINEAR;
100 cmd |= MIP_LINEAR;
101 break;
102 case GL_LINEAR_MIPMAP_LINEAR:
103 DEBUG(("GL_LINEAR_MIPMAP_LINEAR\n"));
104 t0 |= LINEAR_MIP_LINEAR;
105 cmd |= LINEAR_MIP_LINEAR;
106 break;
107 default:
108 break;
109 }
110 /* FIXME: bilinear? */
111
112 #if 0
113 switch (magf) {
114 case GL_NEAREST:
115 break;
116 case GL_LINEAR:
117 break;
118 default:
119 break;
120 }
121 #endif
122
123 t->TextureCMD = t0;
124
125 DEBUG(("CMD was = 0x%x\n", vmesa->CMD));
126 DEBUG(("CMD is = 0x%x\n", cmd));
127
128 vmesa->CMD = cmd;
129 /* CMDCHANGE(); */
130 }
131
132
133 static void s3vSetTexBorderColor(s3vContextPtr vmesa,
134 s3vTextureObjectPtr t,
135 const GLfloat color[4])
136 {
137 GLubyte c[4];
138 CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
139 CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
140 CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
141 CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
142
143 #if TEX_DEBUG_ON
144 static unsigned int times=0;
145 DEBUG_TEX(("*** s3vSetTexBorderColor: #%i ***\n", ++times));
146 #endif
147
148 /*FIXME: it should depend on tex col format */
149 /* switch(t0 ... t->TextureColorMode) */
150
151 /* case TEX_COL_ARGB1555: */
152 t->TextureBorderColor = S3VIRGEPACKCOLOR555(c[0], c[1], c[2], c[3]);
153
154 DEBUG(("TextureBorderColor = 0x%x\n", t->TextureBorderColor));
155
156 vmesa->TextureBorderColor = t->TextureBorderColor;
157 }
158
159 static void s3vTexParameter( GLcontext *ctx, GLenum target,
160 struct gl_texture_object *tObj,
161 GLenum pname, const GLfloat *params )
162 {
163 s3vContextPtr vmesa = S3V_CONTEXT(ctx);
164 s3vTextureObjectPtr t = (s3vTextureObjectPtr) tObj->DriverData;
165 #if TEX_DEBUG_ON
166 static unsigned int times=0;
167 DEBUG_TEX(("*** s3vTexParameter: #%i ***\n", ++times));
168 #endif
169
170 if (!t) return;
171
172 /* Can't do the update now as we don't know whether to flush
173 * vertices or not. Setting vmesa->new_state means that
174 * s3vUpdateTextureState() will be called before any triangles are
175 * rendered. If a statechange has occurred, it will be detected at
176 * that point, and buffered vertices flushed.
177 */
178 switch (pname) {
179 case GL_TEXTURE_MIN_FILTER:
180 case GL_TEXTURE_MAG_FILTER:
181 s3vSetTexFilter( vmesa, t, tObj->MinFilter, tObj->MagFilter );
182 break;
183
184 case GL_TEXTURE_WRAP_S:
185 case GL_TEXTURE_WRAP_T:
186 s3vSetTexWrapping( vmesa, t, tObj->WrapS, tObj->WrapT );
187 break;
188
189 case GL_TEXTURE_BORDER_COLOR:
190 s3vSetTexBorderColor( vmesa, t, tObj->BorderColor );
191 break;
192
193 case GL_TEXTURE_BASE_LEVEL:
194 case GL_TEXTURE_MAX_LEVEL:
195 case GL_TEXTURE_MIN_LOD:
196 case GL_TEXTURE_MAX_LOD:
197 /* This isn't the most efficient solution but there doesn't appear to
198 * be a nice alternative for Virge. Since there's no LOD clamping,
199 * we just have to rely on loading the right subset of mipmap levels
200 * to simulate a clamped LOD.
201 */
202 s3vSwapOutTexObj( vmesa, t );
203 break;
204
205 default:
206 return;
207 }
208
209 if (t == vmesa->CurrentTexObj[0])
210 vmesa->dirty |= S3V_UPLOAD_TEX0;
211
212 #if 0
213 if (t == vmesa->CurrentTexObj[1]) {
214 vmesa->dirty |= S3V_UPLOAD_TEX1;
215 }
216 #endif
217 }
218
219
220 static void s3vTexEnv( GLcontext *ctx, GLenum target,
221 GLenum pname, const GLfloat *param )
222 {
223 s3vContextPtr vmesa = S3V_CONTEXT( ctx );
224 GLuint unit = ctx->Texture.CurrentUnit;
225 #if TEX_DEBUG_ON
226 static unsigned int times=0;
227 DEBUG_TEX(("*** s3vTexEnv: #%i ***\n", ++times));
228 #endif
229
230 /* Only one env color. Need a fallback if env colors are different
231 * and texture setup references env color in both units.
232 */
233 switch (pname) {
234 case GL_TEXTURE_ENV_COLOR: {
235 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
236 GLfloat *fc = texUnit->EnvColor;
237 GLuint r, g, b, a, col;
238 CLAMPED_FLOAT_TO_UBYTE(r, fc[0]);
239 CLAMPED_FLOAT_TO_UBYTE(g, fc[1]);
240 CLAMPED_FLOAT_TO_UBYTE(b, fc[2]);
241 CLAMPED_FLOAT_TO_UBYTE(a, fc[3]);
242
243 col = ((a << 24) |
244 (r << 16) |
245 (g << 8) |
246 (b << 0));
247
248 break;
249 }
250 case GL_TEXTURE_ENV_MODE:
251 vmesa->TexEnvImageFmt[unit] = 0; /* force recalc of env state */
252 break;
253 case GL_TEXTURE_LOD_BIAS_EXT: {
254 /*
255 struct gl_texture_object *tObj =
256 ctx->Texture.Unit[unit]._Current;
257
258 s3vTextureObjectPtr t = (s3vTextureObjectPtr) tObj->DriverData;
259 */
260 break;
261 }
262 default:
263 break;
264 }
265 }
266
267 static void s3vTexImage1D( GLcontext *ctx, GLenum target, GLint level,
268 GLint internalFormat,
269 GLint width, GLint border,
270 GLenum format, GLenum type,
271 const GLvoid *pixels,
272 const struct gl_pixelstore_attrib *pack,
273 struct gl_texture_object *texObj,
274 struct gl_texture_image *texImage )
275 {
276 s3vContextPtr vmesa = S3V_CONTEXT( ctx );
277 s3vTextureObjectPtr t = (s3vTextureObjectPtr) texObj->DriverData;
278 #if TEX_DEBUG_ON
279 static unsigned int times=0;
280 DEBUG_TEX(("*** s3vTexImage1D: #%i ***\n", ++times));
281 #endif
282
283 #if 1
284 if (t) {
285 #if _TEXFLUSH
286 DMAFLUSH();
287 #endif
288 s3vSwapOutTexObj( vmesa, t );
289 /*
290 s3vDestroyTexObj( vmesa, t );
291 texObj->DriverData = 0;
292 */
293 }
294 #endif
295 _mesa_store_teximage1d( ctx, target, level, internalFormat,
296 width, border, format, type,
297 pixels, pack, texObj, texImage );
298 }
299
300 static void s3vTexSubImage1D( GLcontext *ctx,
301 GLenum target,
302 GLint level,
303 GLint xoffset,
304 GLsizei width,
305 GLenum format, GLenum type,
306 const GLvoid *pixels,
307 const struct gl_pixelstore_attrib *pack,
308 struct gl_texture_object *texObj,
309 struct gl_texture_image *texImage )
310 {
311 s3vContextPtr vmesa = S3V_CONTEXT( ctx );
312 s3vTextureObjectPtr t = (s3vTextureObjectPtr) texObj->DriverData;
313 #if TEX_DEBUG_ON
314 static unsigned int times=0;
315 DEBUG_TEX(("*** s3vTexSubImage1D: #%i ***\n", ++times));
316 #endif
317
318 #if 1
319 if (t) {
320 #if _TEXFLUSH
321 DMAFLUSH();
322 #endif
323 s3vSwapOutTexObj( vmesa, t );
324 /*
325 s3vDestroyTexObj( vmesa, t );
326 texObj->DriverData = 0;
327 */
328 }
329 #endif
330 _mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
331 format, type, pixels, pack, texObj,
332 texImage);
333 }
334
335 static void s3vTexImage2D( GLcontext *ctx, GLenum target, GLint level,
336 GLint internalFormat,
337 GLint width, GLint height, GLint border,
338 GLenum format, GLenum type, const GLvoid *pixels,
339 const struct gl_pixelstore_attrib *packing,
340 struct gl_texture_object *texObj,
341 struct gl_texture_image *texImage )
342 {
343 s3vContextPtr vmesa = S3V_CONTEXT( ctx );
344 s3vTextureObjectPtr t = (s3vTextureObjectPtr) texObj->DriverData;
345
346 #if TEX_DEBUG_ON
347 static unsigned int times=0;
348 DEBUG_TEX(("*** s3vTexImage2D: #%i ***\n", ++times));
349 #endif
350
351 #if 1
352 if (t) {
353 #if _TEXFLUSH
354 DMAFLUSH();
355 #endif
356 s3vSwapOutTexObj( vmesa, t );
357 /*
358 s3vDestroyTexObj( vmesa, t );
359 texObj->DriverData = 0;
360 */
361 }
362 #endif
363 _mesa_store_teximage2d( ctx, target, level, internalFormat,
364 width, height, border, format, type,
365 pixels, packing, texObj, texImage );
366 }
367
368 static void s3vTexSubImage2D( GLcontext *ctx,
369 GLenum target,
370 GLint level,
371 GLint xoffset, GLint yoffset,
372 GLsizei width, GLsizei height,
373 GLenum format, GLenum type,
374 const GLvoid *pixels,
375 const struct gl_pixelstore_attrib *packing,
376 struct gl_texture_object *texObj,
377 struct gl_texture_image *texImage )
378 {
379 s3vContextPtr vmesa = S3V_CONTEXT( ctx );
380 s3vTextureObjectPtr t = (s3vTextureObjectPtr) texObj->DriverData;
381 #if TEX_DEBUG_ON
382 static unsigned int times=0;
383 DEBUG_TEX(("*** s3vTexSubImage2D: #%i ***\n", ++times));
384 #endif
385
386 #if 1
387 if (t) {
388 #if _TEXFLUSH
389 DMAFLUSH();
390 #endif
391 s3vSwapOutTexObj( vmesa, t );
392 /*
393 s3vDestroyTexObj( vmesa, t );
394 texObj->DriverData = 0;
395 */
396 }
397 #endif
398 _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
399 height, format, type, pixels, packing, texObj,
400 texImage);
401 }
402
403
404 static void s3vBindTexture( GLcontext *ctx, GLenum target,
405 struct gl_texture_object *tObj )
406 {
407 s3vContextPtr vmesa = S3V_CONTEXT( ctx );
408 s3vTextureObjectPtr t = (s3vTextureObjectPtr) tObj->DriverData;
409 GLuint cmd = vmesa->CMD;
410 #if TEX_DEBUG_ON
411 static unsigned int times=0;
412 DEBUG_TEX(("*** s3vBindTexture: #%i ***\n", ++times));
413 #endif
414
415 if (!t) {
416 /*
417 GLfloat bias = ctx->Texture.Unit[ctx->Texture.CurrentUnit].LodBias;
418 */
419 t = CALLOC_STRUCT(s3v_texture_object_t);
420
421 /* Initialize non-image-dependent parts of the state:
422 */
423 t->globj = tObj;
424 #if 0
425 if (target == GL_TEXTURE_2D) {
426 } else
427 if (target == GL_TEXTURE_1D) {
428 }
429
430 #if X_BYTE_ORDER == X_LITTLE_ENDIAN
431 t->TextureFormat = (TF_LittleEndian |
432 #else
433 t->TextureFormat = (TF_BigEndian |
434 #endif
435 #endif
436 t->dirty_images = ~0;
437
438 tObj->DriverData = t;
439 make_empty_list( t );
440 #if 0
441 s3vSetTexWrapping( vmesa, t, tObj->WrapS, tObj->WrapT );
442 s3vSetTexFilter( vmesa, t, tObj->MinFilter, tObj->MagFilter );
443 s3vSetTexBorderColor( vmesa, t, tObj->BorderColor );
444 #endif
445 }
446
447 cmd = vmesa->CMD & ~MIP_MASK;
448 vmesa->dirty |= S3V_UPLOAD_TEX0;
449 vmesa->TexOffset = t->TextureBaseAddr[tObj->BaseLevel];
450 vmesa->TexStride = t->Pitch;
451 cmd |= MIPMAP_LEVEL(t->WidthLog2);
452 vmesa->CMD = cmd;
453 vmesa->restore_primitive = -1;
454 #if 0
455 printf("t->TextureBaseAddr[0] = 0x%x\n", t->TextureBaseAddr[0]);
456 printf("t->TextureBaseAddr[1] = 0x%x\n", t->TextureBaseAddr[1]);
457 printf("t->TextureBaseAddr[2] = 0x%x\n", t->TextureBaseAddr[2]);
458 #endif
459 }
460
461
462 static void s3vDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
463 {
464 s3vTextureObjectPtr t = (s3vTextureObjectPtr)tObj->DriverData;
465 #if TEX_DEBUG_ON
466 static unsigned int times=0;
467 DEBUG_TEX(("*** s3vDeleteTexture: #%i ***\n", ++times));
468 #endif
469
470 if (t) {
471 s3vContextPtr vmesa = S3V_CONTEXT( ctx );
472
473 #if _TEXFLUSH
474 if (vmesa) {
475 DMAFLUSH();
476 }
477 #endif
478
479 s3vDestroyTexObj( vmesa, t );
480 tObj->DriverData = 0;
481
482 }
483 }
484
485 static GLboolean s3vIsTextureResident( GLcontext *ctx,
486 struct gl_texture_object *tObj )
487 {
488 s3vTextureObjectPtr t = (s3vTextureObjectPtr)tObj->DriverData;
489 #if TEX_DEBUG_ON
490 static unsigned int times=0;
491 DEBUG_TEX(("*** s3vIsTextureResident: #%i ***\n", ++times));
492 #endif
493
494 return (t && t->MemBlock);
495 }
496
497 static void s3vInitTextureObjects( GLcontext *ctx )
498 {
499 /* s3vContextPtr vmesa = S3V_CONTEXT(ctx); */
500 struct gl_texture_object *texObj;
501 GLuint tmp = ctx->Texture.CurrentUnit;
502 #if TEX_DEBUG_ON
503 static unsigned int times=0;
504 DEBUG_TEX(("*** s3vInitTextureObjects: #%i ***\n", ++times));
505 #endif
506
507 #if 1
508 ctx->Texture.CurrentUnit = 0;
509
510 texObj = ctx->Texture.Unit[0].CurrentTex[TEXTURE_1D_INDEX];
511 s3vBindTexture( ctx, GL_TEXTURE_1D, texObj );
512
513 texObj = ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX];
514 s3vBindTexture( ctx, GL_TEXTURE_2D, texObj );
515 #endif
516
517 #if 0
518 ctx->Texture.CurrentUnit = 1;
519
520 texObj = ctx->Texture.Unit[1].CurrentTex[TEXTURE_1D_INDEX];
521 s3vBindTexture( ctx, GL_TEXTURE_1D, texObj );
522
523 texObj = ctx->Texture.Unit[1].CurrentTex[TEXTURE_2D_INDEX];
524 s3vBindTexture( ctx, GL_TEXTURE_2D, texObj );
525 #endif
526
527 ctx->Texture.CurrentUnit = tmp;
528 }
529
530
531 void s3vInitTextureFuncs( GLcontext *ctx )
532 {
533 #if TEX_DEBUG_ON
534 static unsigned int times=0;
535 DEBUG_TEX(("*** s3vInitTextureFuncs: #%i ***\n", ++times));
536 #endif
537
538 ctx->Driver.TexEnv = s3vTexEnv;
539 ctx->Driver.TexImage2D = s3vTexImage2D;
540 ctx->Driver.TexSubImage2D = s3vTexSubImage2D;
541 ctx->Driver.BindTexture = s3vBindTexture;
542 ctx->Driver.DeleteTexture = s3vDeleteTexture;
543 ctx->Driver.TexParameter = s3vTexParameter;
544 ctx->Driver.UpdateTexturePalette = 0;
545 ctx->Driver.IsTextureResident = s3vIsTextureResident;
546
547 s3vInitTextureObjects( ctx );
548 }