Small texture management fixes. Should get rid of assertions some people were getting...
[mesa.git] / src / mesa / drivers / dri / savage / savagetex.c
1 /*
2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25
26 #include <stdlib.h>
27 #include <stdio.h>
28
29 #include <GL/gl.h>
30
31 #include "mm.h"
32 #include "savagecontext.h"
33 #include "savagetex.h"
34 #include "savagetris.h"
35 #include "savageioctl.h"
36 #include "simple_list.h"
37 #include "enums.h"
38 #include "savage_bci.h"
39
40 #include "macros.h"
41 #include "texformat.h"
42 #include "texstore.h"
43 #include "texobj.h"
44
45 #include "swrast/swrast.h"
46
47 /* declarations of static and inline functions */
48 __inline GLuint GetTiledCoordinates8(GLuint iBufferWidth, GLint x, GLint y);
49 static GLuint GetTiledCoordinates16_4( GLint iBufferWidth,GLint x,GLint y );
50 static GLuint GetTiledCoordinates16_8( GLint iBufferWidth,GLint x,GLint y );
51 static GLuint GetTiledCoordinates32_4( GLint iBufferWidth, GLint x, GLint y );
52 static GLuint GetTiledCoordinates32_8( GLint iBufferWidth, GLint x, GLint y );
53 __inline GLuint GetTiledCoordinates( GLint iDepth,GLint iBufferWidth,GLint x,GLint y );
54 __inline void savageUploadImage(savageTextureObjectPtr t, GLuint level, GLuint startx, GLuint starty, GLuint reloc);
55 __inline void savageTileTex(savageTextureObjectPtr tex, GLuint level);
56
57 /* tile sizes depending on texel color depth */
58 GLuint gTileWidth[5] =
59 {
60 64, /* 4-bit */
61 64, /* 8-bit */
62 64, /* 16-bit */
63 0, /* 24-bit */
64 32 /* 32-bit */
65 };
66
67 GLuint gTileHeight[5] =
68 {
69 64, /* 4-bit */
70 32, /* 8-bit */
71 16, /* 16-bit */
72 0, /* 24-bit */
73 16 /* 32-bit */
74 };
75
76 __inline GLuint GetTiledCoordinates8(GLuint iBufferWidth, GLint x, GLint y)
77 {
78 GLint x10, x106, x52;
79 GLint y20, y105, y43;
80 GLuint uWidthInTiles;
81
82 uWidthInTiles = (iBufferWidth + 63) >> 6;
83 x10 = x & 0x3;
84 x52 = (x & 0x3c) >> 2;
85 x106 = (x & 0x7c0) >> 6;
86
87 y20 = y & 0x7;
88 y43 = (y & 0x18) >> 3;
89 y105 = (y & 0x7e0) >> 5;
90
91 return ( x10 |
92 (y20 << 2) |
93 (x52 << 5) |
94 (y43 << 9) |
95 ((y105 * uWidthInTiles) + x106) << 11 );
96 }
97
98 /* 4-pixel wide subtiles */
99 static GLuint GetTiledCoordinates16_4( GLint iBufferWidth,
100 GLint x,
101 GLint y )
102 {
103 GLint x106;
104 GLint x10;
105 GLint x52;
106 GLint y104;
107 GLint y20;
108 GLint y3;
109 GLuint uiWidthInTiles;
110
111 /*
112 // calculating tiled address
113 */
114
115 uiWidthInTiles = (iBufferWidth + 63) >> 6;
116
117 x10 = x & 0x3;
118 x52 = (x & 0x3c ) >> 2;
119 x106 = (x & 0x7c0) >> 6;
120
121 y20 = y & 0x7;
122 y3 = (y & 8 ) >> 3;
123 y104 = (y & 0x7f0) >> 4;
124
125 return( (x10 << 1) |
126 (y20 << 3) |
127 (x52 << 6) |
128 (y3 << 10) |
129 ((y104 * uiWidthInTiles) + x106) << 11 );
130 }
131 /* 8-pixel wide subtiles */
132 static GLuint GetTiledCoordinates16_8( GLint iBufferWidth,
133 GLint x,
134 GLint y )
135 {
136 GLint x106;
137 GLint x20;
138 GLint x53;
139 GLint y104;
140 GLint y20;
141 GLint y3;
142 GLuint uiWidthInTiles;
143
144 /*
145 // calculating tiled address
146 */
147
148 uiWidthInTiles = (iBufferWidth + 63) >> 6;
149
150 x20 = x & 0x7;
151 x53 = (x & 0x38 ) >> 3;
152 x106 = (x & 0x7c0) >> 6;
153
154 y20 = y & 0x7;
155 y3 = (y & 8 ) >> 3;
156 y104 = (y & 0x7f0) >> 4;
157
158 return( (x20 << 1) |
159 (y20 << 4) |
160 (x53 << 7) |
161 (y3 << 10) |
162 ((y104 * uiWidthInTiles) + x106) << 11 );
163 }
164 /* function pointer set to the correct version in savageDDInitTextureFuncs */
165 GLuint (*GetTiledCoordinates16) (GLint, GLint, GLint);
166
167 /* 4-pixel wide subtiles */
168 static GLuint GetTiledCoordinates32_4( GLint iBufferWidth,
169 GLint x,
170 GLint y )
171 {
172 GLint x10;
173 GLint y20;
174 GLuint uiWidthInTiles;
175 GLint x42;
176 GLint x105;
177 GLint y3;
178 GLint y104;
179
180 /*
181 // calculating tiled address
182 */
183
184 uiWidthInTiles = (iBufferWidth + 31) >> 5;
185
186 x10 = x & 0x3;
187 x42 = (x & 0x1c ) >> 2;
188 x105 = (x & 0x7e0) >> 5;
189
190 y20 = y & 0x7;
191 y3 = (y & 8 ) >> 3;
192 y104 = (y & 0x7f0) >> 4;
193
194 return( (x10 << 2) |
195 (y20 << 4) |
196 (x42 << 7) |
197 (y3 << 10) |
198 ((y104 * uiWidthInTiles) + x105) << 11 );
199 }
200 /* 8-pixel wide subtiles */
201 static GLuint GetTiledCoordinates32_8( GLint iBufferWidth,
202 GLint x,
203 GLint y )
204 {
205 GLint x20;
206 GLint y20;
207 GLuint uiWidthInTiles;
208 GLint x43;
209 GLint x105;
210 GLint y3;
211 GLint y104;
212
213 /*
214 // calculating tiled address
215 */
216
217 uiWidthInTiles = (iBufferWidth + 31) >> 5;
218
219 x20 = x & 0x7;
220 x43 = (x & 0x18 ) >> 3;
221 x105 = (x & 0x7e0) >> 5;
222
223 y20 = y & 0x7;
224 y3 = (y & 8 ) >> 3;
225 y104 = (y & 0x7f0) >> 4;
226
227 return( (x20 << 2) |
228 (y20 << 5) |
229 (x43 << 8) |
230 (y3 << 10) |
231 ((y104 * uiWidthInTiles) + x105) << 11 );
232 }
233 /* function pointer set to the correct version in savageDDInitTextureFuncs */
234 GLuint (*GetTiledCoordinates32) (GLint, GLint, GLint);
235
236 __inline GLuint GetTiledCoordinates( GLint iDepth,
237 GLint iBufferWidth,
238 GLint x,
239 GLint y )
240 {
241 /*
242 // don't check for 4 since we only have 3 types of fb
243 */
244
245 if (iDepth == 16)
246 {
247 return( GetTiledCoordinates16( iBufferWidth, x, y ) );
248 }
249 else if (iDepth == 32)
250 {
251 return( GetTiledCoordinates32( iBufferWidth, x, y ) );
252 }
253 else
254 {
255 return( GetTiledCoordinates8( iBufferWidth, x, y ) );
256 }
257 }
258
259 __inline void savageUploadImage(savageTextureObjectPtr t, GLuint level, GLuint startx, GLuint starty, GLuint reloc)
260 {
261 GLuint uMaxTileWidth = gTileWidth[t->texelBytes];
262 GLuint x, y, w, row, col;
263 const struct gl_texture_image *image = t->image[level].image;
264 GLubyte * dst, * src, * pBuffer;
265 GLint xAdd, yAdd;
266 GLuint uRowSeparator, uChunk = MIN_TILE_CHUNK, uWrap;
267
268
269 pBuffer = (GLubyte *)(t->BufAddr + t->image[level].offset);
270 src = (GLubyte *)image->Data;
271 x = startx;
272 y = starty;
273 w = image->Width;
274
275 if(image->Format == GL_COLOR_INDEX)
276 {
277 if(w < MIN_TILE_CHUNK)
278 {
279 w = MIN_TILE_CHUNK;
280 }
281 else
282 {
283 if((w > 64 ) && (image->Height <= 16))
284 {
285 reloc = GL_TRUE;
286 if(image->Height == 16)
287 {
288 uChunk = MIN_TILE_CHUNK << 1;
289 }
290 }
291 }
292
293 if(!reloc & (w > (64 / 2)))
294 {
295 for(row = 0; row < image->Height; row++)
296 {
297 for(col = 0; col < image->Width; col++)
298 {
299 dst = pBuffer + GetTiledCoordinates(t->texelBytes << 3, w, x + col, y + row);
300 memcpy (dst, src, t->texelBytes);
301 src += t->texelBytes;
302 }
303 }
304 }
305 else
306 {
307 if(reloc & (w > 64))
308 {
309 uWrap = ((w + 63) >> 6) - 1;
310 for(row = 0; row < image->Height; row++)
311 {
312 for(col = 0; col < image->Width; col++)
313 {
314 xAdd = (col / (4 * 64)) * 64 + col % 64;
315 yAdd = row + ((col / 64) & 3) * uChunk;
316 dst = pBuffer + GetTiledCoordinates(t->texelBytes << 3, 64, x + xAdd, y + yAdd);
317 memcpy (dst, src, t->texelBytes);
318 src += t->texelBytes;
319 }
320 }
321 }
322 else
323 {
324 uRowSeparator = 64 * MIN_TILE_CHUNK / w;
325 for(row = 0; row < image->Height; row++)
326 {
327 xAdd = (w * (row / MIN_TILE_CHUNK)) % 64;
328 yAdd = row % MIN_TILE_CHUNK + MIN_TILE_CHUNK * (row / uRowSeparator);
329 for(col = 0; col < image->Width; col++)
330 {
331 dst = pBuffer + GetTiledCoordinates(t->texelBytes << 3, w, x + xAdd, y + yAdd);
332 memcpy (dst, src, t->texelBytes);
333 src += t->texelBytes;
334 }
335 }
336 }
337 }
338 }
339 else
340 {
341 if(w < MIN_TILE_CHUNK)
342 {
343 w = MIN_TILE_CHUNK;
344 }
345 else
346 {
347 if((w > uMaxTileWidth ) && (image->Height <= 8))
348 {
349 reloc = GL_TRUE;
350 }
351 }
352 if(!reloc & (w > uMaxTileWidth / 2))
353 {
354 for(row = 0; row < image->Height; row++)
355 {
356 for(col = 0; col < image->Width; col++)
357 {
358 dst = pBuffer + GetTiledCoordinates(t->texelBytes << 3, w, x + col, y + row);
359 memcpy (dst, src, t->texelBytes);
360 src += t->texelBytes;
361 }
362 }
363 }
364 else
365 {
366 if(reloc & (w > uMaxTileWidth))
367 {
368 for(row = 0; row < image->Height; row++)
369 {
370 for(col = 0; col < image->Width; col++)
371 {
372 xAdd = (col / (2 * uMaxTileWidth)) * uMaxTileWidth + col % uMaxTileWidth;
373 yAdd = row + ((col / uMaxTileWidth) & 1) * MIN_TILE_CHUNK;
374 dst = pBuffer + GetTiledCoordinates(t->texelBytes << 3, w, x + xAdd, y + yAdd);
375 memcpy (dst, src, t->texelBytes);
376 src += t->texelBytes;
377 }
378 }
379 }
380 else
381 {
382 uRowSeparator = uMaxTileWidth * MIN_TILE_CHUNK / w;
383 for(row = 0; row < image->Height; row++)
384 {
385 yAdd = row % MIN_TILE_CHUNK + MIN_TILE_CHUNK * (row / uRowSeparator);
386 xAdd = (w * (row / MIN_TILE_CHUNK)) % uMaxTileWidth;
387 for(col = 0; col < image->Width; col++)
388 {
389 dst = pBuffer + GetTiledCoordinates(t->texelBytes << 3, w, x + col + xAdd, y + yAdd);
390 memcpy (dst, src, t->texelBytes);
391 src += t->texelBytes;
392 }
393 }
394 }
395 }
396 }
397 }
398
399
400
401 __inline void savageTileTex(savageTextureObjectPtr tex, GLuint level)
402 {
403 GLuint uWidth, uHeight;
404 GLint xOffset, yOffset;
405 GLint xStart=0, yStart=0;
406 GLint minSize;
407 GLuint xRepeat, yRepeat;
408 GLuint startCol, startRow;
409 GLuint reloc;
410
411 const struct gl_texture_image *image = tex->image[level].image;
412
413 reloc = GL_FALSE;
414 uWidth = image->Width2;
415 uHeight = image->Height2;
416
417 if((uWidth > 4) || (uHeight > 4))
418 minSize = MIN_TILE_CHUNK;
419 else
420 minSize = MIPMAP_CHUNK;
421
422 if(image->Width >= minSize)
423 xRepeat = 1;
424 else
425 xRepeat = minSize / image->Width;
426
427 if(image->Height >= minSize)
428 yRepeat = 1;
429 else
430 {
431 yRepeat = minSize / image->Height;
432 if(minSize == MIN_TILE_CHUNK)
433 reloc = GL_TRUE;
434 }
435
436 if(((uWidth < 4) && (uHeight < 4)) && (tex->texelBytes >= 2))
437 {
438 if((uWidth == 2) || (uHeight == 2))
439 {
440 xStart = 4;
441 yStart = 0;
442 }
443
444 else
445 {
446 xStart = 4;
447 yStart = 4;
448 }
449 }
450 for(xOffset = 0; xOffset < xRepeat; xOffset++)
451 {
452 for(yOffset = 0; yOffset < yRepeat; yOffset++)
453 {
454 startCol = image->Width * xOffset + xStart;
455 startRow = image->Height * yOffset + yStart;
456 savageUploadImage(tex,level, startCol, startRow, reloc);
457 }
458 }
459 }
460
461 static void savageSetTexWrapping(savageTextureObjectPtr tex, GLenum s, GLenum t)
462 {
463 tex->texParams.sWrapMode = s;
464 tex->texParams.tWrapMode = t;
465 }
466
467 static void savageSetTexFilter(savageTextureObjectPtr t,
468 GLenum minf, GLenum magf)
469 {
470 t->texParams.minFilter = minf;
471 t->texParams.magFilter = magf;
472 }
473
474
475 /* Need a fallback ?
476 */
477 static void savageSetTexBorderColor(savageTextureObjectPtr t, GLubyte color[4])
478 {
479 /* t->Setup[SAVAGE_TEXREG_TEXBORDERCOL] = */
480 t->texParams.boarderColor = SAVAGEPACKCOLOR8888(color[0],color[1],color[2],color[3]);
481 }
482
483
484
485 static savageTextureObjectPtr
486 savageAllocTexObj( struct gl_texture_object *texObj )
487 {
488 savageTextureObjectPtr t;
489
490 t = (savageTextureObjectPtr) calloc(1,sizeof(*t));
491 texObj->DriverData = t;
492 if ( t != NULL ) {
493
494 /* Initialize non-image-dependent parts of the state:
495 */
496 t->globj = texObj;
497
498 /* FIXME Something here to set initial values for other parts of
499 * FIXME t->setup?
500 */
501
502 make_empty_list( t );
503
504 savageSetTexWrapping(t,texObj->WrapS,texObj->WrapT);
505 savageSetTexFilter(t,texObj->MinFilter,texObj->MagFilter);
506 savageSetTexBorderColor(t,texObj->_BorderChan);
507 }
508
509 return t;
510 }
511
512 /* Called by the _mesa_store_teximage[123]d() functions. */
513 static const struct gl_texture_format *
514 savageChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
515 GLenum format, GLenum type )
516 {
517 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
518 const GLboolean do32bpt = GL_FALSE;
519 const GLboolean force16bpt = GL_FALSE;
520 const GLboolean isSavage4 = (imesa->savageScreen->chipset >= S3_SAVAGE4);
521 (void) format;
522 (void) type;
523
524 switch ( internalFormat ) {
525 case 4:
526 case GL_RGBA:
527 case GL_COMPRESSED_RGBA:
528 switch ( type ) {
529 case GL_UNSIGNED_INT_10_10_10_2:
530 case GL_UNSIGNED_INT_2_10_10_10_REV:
531 return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb1555;
532 case GL_UNSIGNED_SHORT_4_4_4_4:
533 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
534 return &_mesa_texformat_argb4444;
535 case GL_UNSIGNED_SHORT_5_5_5_1:
536 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
537 return &_mesa_texformat_argb1555;
538 default:
539 return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
540 }
541
542 case 3:
543 case GL_RGB:
544 case GL_COMPRESSED_RGB:
545 switch ( type ) {
546 case GL_UNSIGNED_SHORT_4_4_4_4:
547 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
548 return &_mesa_texformat_argb4444;
549 case GL_UNSIGNED_SHORT_5_5_5_1:
550 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
551 return &_mesa_texformat_argb1555;
552 case GL_UNSIGNED_SHORT_5_6_5:
553 case GL_UNSIGNED_SHORT_5_6_5_REV:
554 return &_mesa_texformat_rgb565;
555 default:
556 return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
557 }
558
559 case GL_RGBA8:
560 case GL_RGBA12:
561 case GL_RGBA16:
562 return !force16bpt ?
563 &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
564
565 case GL_RGB10_A2:
566 return !force16bpt ?
567 &_mesa_texformat_argb8888 : &_mesa_texformat_argb1555;
568
569 case GL_RGBA4:
570 case GL_RGBA2:
571 return &_mesa_texformat_argb4444;
572
573 case GL_RGB5_A1:
574 return &_mesa_texformat_argb1555;
575
576 case GL_RGB8:
577 case GL_RGB10:
578 case GL_RGB12:
579 case GL_RGB16:
580 return !force16bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
581
582 case GL_RGB5:
583 case GL_RGB4:
584 case GL_R3_G3_B2:
585 return &_mesa_texformat_rgb565;
586
587 case GL_ALPHA:
588 case GL_COMPRESSED_ALPHA:
589 return isSavage4 ? &_mesa_texformat_a8 : (
590 do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444);
591 case GL_ALPHA4:
592 return isSavage4 ? &_mesa_texformat_a8 : &_mesa_texformat_argb4444;
593 case GL_ALPHA8:
594 case GL_ALPHA12:
595 case GL_ALPHA16:
596 return isSavage4 ? &_mesa_texformat_a8 : (
597 !force16bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444);
598
599 case 1:
600 case GL_LUMINANCE:
601 case GL_COMPRESSED_LUMINANCE:
602 /* no alpha, but use argb1555 in 16bit case to get pure grey values */
603 return isSavage4 ? &_mesa_texformat_l8 : (
604 do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb1555);
605 case GL_LUMINANCE4:
606 return isSavage4 ? &_mesa_texformat_l8 : &_mesa_texformat_argb1555;
607 case GL_LUMINANCE8:
608 case GL_LUMINANCE12:
609 case GL_LUMINANCE16:
610 return isSavage4 ? &_mesa_texformat_l8 : (
611 !force16bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb1555);
612
613 case 2:
614 case GL_LUMINANCE_ALPHA:
615 case GL_COMPRESSED_LUMINANCE_ALPHA:
616 /* Savage4 has a al44 texture format. But it's not supported by Mesa. */
617 return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
618 case GL_LUMINANCE4_ALPHA4:
619 case GL_LUMINANCE6_ALPHA2:
620 return &_mesa_texformat_argb4444;
621 case GL_LUMINANCE8_ALPHA8:
622 case GL_LUMINANCE12_ALPHA4:
623 case GL_LUMINANCE12_ALPHA12:
624 case GL_LUMINANCE16_ALPHA16:
625 return !force16bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
626
627 case GL_INTENSITY:
628 case GL_COMPRESSED_INTENSITY:
629 return isSavage4 ? &_mesa_texformat_i8 : (
630 do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444);
631 case GL_INTENSITY4:
632 return isSavage4 ? &_mesa_texformat_i8 : &_mesa_texformat_argb4444;
633 case GL_INTENSITY8:
634 case GL_INTENSITY12:
635 case GL_INTENSITY16:
636 return isSavage4 ? &_mesa_texformat_i8 : (
637 !force16bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444);
638 /*
639 case GL_COLOR_INDEX:
640 case GL_COLOR_INDEX1_EXT:
641 case GL_COLOR_INDEX2_EXT:
642 case GL_COLOR_INDEX4_EXT:
643 case GL_COLOR_INDEX8_EXT:
644 case GL_COLOR_INDEX12_EXT:
645 case GL_COLOR_INDEX16_EXT:
646 return &_mesa_texformat_ci8;
647 */
648 default:
649 _mesa_problem(ctx, "unexpected texture format in %s", __FUNCTION__);
650 return NULL;
651 }
652 }
653
654 static void savageSetTexImages( savageContextPtr imesa,
655 const struct gl_texture_object *tObj )
656 {
657 savageTextureObjectPtr t = (savageTextureObjectPtr) tObj->DriverData;
658 struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel];
659 GLuint offset, width, pitch, i, textureFormat, log_pitch;
660
661 assert(t);
662 assert(image);
663
664 switch (image->TexFormat->MesaFormat) {
665 case MESA_FORMAT_ARGB8888:
666 textureFormat = TFT_ARGB8888;
667 t->texelBytes = 4;
668 break;
669 case MESA_FORMAT_ARGB1555:
670 textureFormat = TFT_ARGB1555;
671 t->texelBytes = 2;
672 break;
673 case MESA_FORMAT_ARGB4444:
674 textureFormat = TFT_ARGB4444;
675 t->texelBytes = 2;
676 break;
677 case MESA_FORMAT_RGB565:
678 textureFormat = TFT_RGB565;
679 t->texelBytes = 2;
680 break;
681 case MESA_FORMAT_L8:
682 textureFormat = TFT_L8;
683 t->texelBytes = 1;
684 break;
685 case MESA_FORMAT_I8:
686 textureFormat = TFT_I8;
687 t->texelBytes = 1;
688 break;
689 case MESA_FORMAT_A8:
690 textureFormat = TFT_A8;
691 t->texelBytes = 1;
692 break;
693 default:
694 _mesa_problem(imesa->glCtx, "Bad texture format in %s", __FUNCTION__);
695 }
696
697 /* Figure out the size now (and count the levels). Upload won't be done
698 * until later.
699 */
700 width = image->Width * t->texelBytes;
701 for (pitch = 2, log_pitch=1 ; pitch < width ; pitch *= 2 )
702 log_pitch++;
703
704 t->dirty_images = 0;
705
706 offset = 0;
707 for ( i = 0 ; i < SAVAGE_TEX_MAXLEVELS && tObj->Image[0][i] ; i++ ) {
708 t->image[i].image = tObj->Image[0][i];
709 t->image[i].offset = offset;
710 t->image[i].internalFormat = textureFormat;
711 t->dirty_images |= (1<<i);
712 offset += t->image[i].image->Height * pitch;
713 pitch = pitch >> 1;
714 }
715
716 t->totalSize = offset;
717 t->max_level = i-1;
718 t->min_level = 0;
719 }
720
721 void savageDestroyTexObj(savageContextPtr imesa, savageTextureObjectPtr t)
722 {
723 if (!t) return;
724
725 /* This is sad - need to sync *in case* we upload a texture
726 * to this newly free memory...
727 */
728 if (t->MemBlock) {
729 mmFreeMem(t->MemBlock);
730 t->MemBlock = 0;
731
732 if (t->age > imesa->dirtyAge)
733 imesa->dirtyAge = t->age;
734 }
735
736 if (t->globj)
737 t->globj->DriverData = 0;
738
739 remove_from_list(t);
740 free(t);
741 }
742
743
744 static void savageSwapOutTexObj(savageContextPtr imesa, savageTextureObjectPtr t)
745 {
746 if (t->MemBlock) {
747 mmFreeMem(t->MemBlock);
748 t->MemBlock = 0;
749
750 if (t->age > imesa->dirtyAge)
751 imesa->dirtyAge = t->age;
752 }
753
754 t->dirty_images = ~0;
755 move_to_tail(&(imesa->SwappedOut), t);
756 }
757
758
759
760 /* Upload an image from mesa's internal copy.
761 */
762 static void savageUploadTexLevel( savageTextureObjectPtr t, int level )
763 {
764 const struct gl_texture_image *image = t->image[level].image;
765
766
767 /* Need triangle (rather than pixel) fallbacks to simulate this using
768 * normal textured triangles.
769 *
770 * DO THIS IN DRIVER STATE MANAGMENT, not hardware state.
771 *
772 */
773
774 if(image->Border != 0)
775 fprintf (stderr, "Not supported texture border %d.\n",
776 (int) image->Border);
777
778 savageTileTex(t, level);
779 }
780
781
782
783 void savagePrintLocalLRU( savageContextPtr imesa , GLuint heap)
784 {
785 savageTextureObjectPtr t;
786 int sz = 1 << (imesa->savageScreen->logTextureGranularity[heap]);
787
788 foreach( t, &imesa->TexObjList[heap] ) {
789 if (!t->globj)
790 fprintf(stderr, "Placeholder %d at %x sz %x\n",
791 t->MemBlock->ofs / sz,
792 t->MemBlock->ofs,
793 t->MemBlock->size);
794 else
795 fprintf(stderr, "Texture (bound %d) at %x sz %x\n",
796 t->bound,
797 t->MemBlock->ofs,
798 t->MemBlock->size);
799
800 }
801 }
802
803 void savagePrintGlobalLRU( savageContextPtr imesa , GLuint heap)
804 {
805 int i, j;
806
807 drm_savage_tex_region_t *list = imesa->sarea->texList[heap];
808
809
810 for (i = 0, j = SAVAGE_NR_TEX_REGIONS ; i < SAVAGE_NR_TEX_REGIONS ; i++) {
811 fprintf(stderr, "list[%d] age %d next %d prev %d\n",
812 j, list[j].age, list[j].next, list[j].prev);
813 j = list[j].next;
814 if (j == SAVAGE_NR_TEX_REGIONS) break;
815 }
816
817 if (j != SAVAGE_NR_TEX_REGIONS)
818 fprintf(stderr, "Loop detected in global LRU\n");
819 for (i = 0 ; i < SAVAGE_NR_TEX_REGIONS ; i++)
820 {
821 fprintf(stderr,"list[%d] age %d next %d prev %d\n",
822 i, list[i].age, list[i].next, list[i].prev);
823 }
824 }
825
826
827 void savageResetGlobalLRU( savageContextPtr imesa, GLuint heap )
828 {
829 drm_savage_tex_region_t *list = imesa->sarea->texList[heap];
830 int sz = 1 << imesa->savageScreen->logTextureGranularity[heap];
831 int i;
832
833 /* (Re)initialize the global circular LRU list. The last element
834 * in the array (SAVAGE_NR_TEX_REGIONS) is the sentinal. Keeping it
835 * at the end of the array allows it to be addressed rationally
836 * when looking up objects at a particular location in texture
837 * memory.
838 */
839 for (i = 0 ; (i+1) * sz <= imesa->savageScreen->textureSize[heap]; i++) {
840 list[i].prev = i-1;
841 list[i].next = i+1;
842 list[i].age = 0;
843 }
844
845 i--;
846 list[0].prev = SAVAGE_NR_TEX_REGIONS;
847 list[i].prev = i-1;
848 list[i].next = SAVAGE_NR_TEX_REGIONS;
849 list[SAVAGE_NR_TEX_REGIONS].prev = i;
850 list[SAVAGE_NR_TEX_REGIONS].next = 0;
851 imesa->sarea->texAge[heap] = 0;
852 }
853
854
855 static void savageUpdateTexLRU( savageContextPtr imesa, savageTextureObjectPtr t )
856 {
857 int i;
858 int heap = t->heap;
859 int logsz = imesa->savageScreen->logTextureGranularity[heap];
860 int start = t->MemBlock->ofs >> logsz;
861 int end = (t->MemBlock->ofs + t->MemBlock->size - 1) >> logsz;
862 drm_savage_tex_region_t *list = imesa->sarea->texList[heap];
863
864 imesa->texAge[heap] = ++imesa->sarea->texAge[heap];
865
866 /* Update our local LRU
867 */
868 move_to_head( &(imesa->TexObjList[heap]), t );
869
870 /* Update the global LRU
871 */
872 for (i = start ; i <= end ; i++) {
873
874 list[i].in_use = 1;
875 list[i].age = imesa->texAge[heap];
876
877 /* remove_from_list(i)
878 */
879 list[(unsigned)list[i].next].prev = list[i].prev;
880 list[(unsigned)list[i].prev].next = list[i].next;
881
882 /* insert_at_head(list, i)
883 */
884 list[i].prev = SAVAGE_NR_TEX_REGIONS;
885 list[i].next = list[SAVAGE_NR_TEX_REGIONS].next;
886 list[(unsigned)list[SAVAGE_NR_TEX_REGIONS].next].prev = i;
887 list[SAVAGE_NR_TEX_REGIONS].next = i;
888 }
889 }
890
891
892 /* Called for every shared texture region which has increased in age
893 * since we last held the lock.
894 *
895 * Figures out which of our textures have been ejected by other clients,
896 * and pushes a placeholder texture onto the LRU list to represent
897 * the other client's textures.
898 */
899 void savageTexturesGone( savageContextPtr imesa,
900 GLuint heap,
901 GLuint offset,
902 GLuint size,
903 GLuint in_use )
904 {
905 savageTextureObjectPtr t, tmp;
906
907 foreach_s ( t, tmp, &imesa->TexObjList[heap] ) {
908
909 if (t->MemBlock->ofs >= offset + size ||
910 t->MemBlock->ofs + t->MemBlock->size <= offset)
911 continue;
912
913 /* It overlaps - kick it off. Need to hold onto the currently bound
914 * objects, however.
915 */
916 if (t->bound)
917 savageSwapOutTexObj( imesa, t );
918 else
919 savageDestroyTexObj( imesa, t );
920 }
921
922
923 if (in_use) {
924 t = (savageTextureObjectPtr) calloc(1,sizeof(*t));
925 if (!t) return;
926
927 t->heap = heap;
928 t->MemBlock = mmAllocMem( imesa->texHeap[heap], size, 0, offset);
929 if(!t->MemBlock)
930 {
931 free(t);
932 return;
933 }
934 insert_at_head( &imesa->TexObjList[heap], t );
935 }
936 }
937
938
939
940
941
942 /* This is called with the lock held. May have to eject our own and/or
943 * other client's texture objects to make room for the upload.
944 */
945 int savageUploadTexImages( savageContextPtr imesa, savageTextureObjectPtr t )
946 {
947 int heap;
948 int i;
949 int ofs;
950
951 heap = t->heap = SAVAGE_CARD_HEAP;
952
953 /* Do we need to eject LRU texture objects?
954 */
955 if (!t->MemBlock) {
956 while (1)
957 {
958 t->MemBlock = mmAllocMem( imesa->texHeap[heap], t->totalSize, 12, 0 );
959 if (t->MemBlock)
960 break;
961 else
962 {
963 heap = t->heap = SAVAGE_AGP_HEAP;
964 t->MemBlock = mmAllocMem( imesa->texHeap[heap], t->totalSize, 12, 0 );
965
966 if (t->MemBlock)
967 break;
968 }
969
970 if (imesa->TexObjList[heap].prev->bound) {
971 fprintf(stderr, "Hit bound texture in upload\n");
972 savagePrintLocalLRU( imesa,heap );
973 return -1;
974 }
975
976 if (imesa->TexObjList[heap].prev == &(imesa->TexObjList[heap])) {
977 fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize);
978 mmDumpMemInfo( imesa->texHeap[heap] );
979 return -1;
980 }
981
982 savageDestroyTexObj( imesa, imesa->TexObjList[heap].prev );
983 }
984
985 ofs = t->MemBlock->ofs;
986 t->texParams.hwPhysAddress = imesa->savageScreen->textureOffset[heap] + ofs;
987 t->BufAddr = (char *)((GLuint) imesa->savageScreen->texVirtual[heap] + ofs);
988 imesa->dirty |= SAVAGE_UPLOAD_CTX;
989 }
990
991 /* Let the world know we've used this memory recently.
992 */
993 savageUpdateTexLRU( imesa, t );
994
995 if (t->dirty_images) {
996 if (SAVAGE_DEBUG & DEBUG_VERBOSE_LRU)
997 fprintf(stderr, "*");
998
999 for (i = t->min_level ; i <= t->max_level ; i++)
1000 if (t->dirty_images & (1<<i))
1001 savageUploadTexLevel( t, i );
1002 }
1003
1004
1005 t->dirty_images = 0;
1006 return 0;
1007 }
1008
1009 static void savageTexSetUnit( savageTextureObjectPtr t, GLuint unit )
1010 {
1011 if (t->current_unit == unit) return;
1012
1013 t->current_unit = unit;
1014 }
1015
1016
1017
1018
1019 static void savageUpdateTex0State_s4( GLcontext *ctx )
1020 {
1021 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1022 struct gl_texture_object *tObj;
1023 savageTextureObjectPtr t;
1024 GLuint format;
1025
1026 /* disable */
1027 if (ctx->Texture.Unit[0]._ReallyEnabled == 0) {
1028 imesa->regs.s4.texDescr.ni.tex0En = GL_FALSE;
1029 imesa->regs.s4.texBlendCtrl[0].ui = TBC_NoTexMap;
1030 imesa->regs.s4.texCtrl[0].ui = 0x20f040;
1031 imesa->regs.s4.texAddr[0].ui = 0;
1032 return;
1033 }
1034
1035 tObj = ctx->Texture.Unit[0]._Current;
1036 if (ctx->Texture.Unit[0]._ReallyEnabled != TEXTURE_2D_BIT ||
1037 tObj->Image[0][tObj->BaseLevel]->Border > 0) {
1038 /* 1D or 3D texturing enabled, or texture border - fallback */
1039 FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE);
1040 return;
1041 }
1042
1043 /* Do 2D texture setup */
1044
1045 t = tObj->DriverData;
1046 if (!t) {
1047 t = savageAllocTexObj( tObj );
1048 if (!t)
1049 return;
1050 }
1051
1052 if (t->current_unit != 0)
1053 savageTexSetUnit( t, 0 );
1054
1055 imesa->CurrentTexObj[0] = t;
1056 t->bound |= 1;
1057
1058 if (t->dirty_images) {
1059 savageSetTexImages(imesa, tObj);
1060 savageUploadTexImages(imesa, imesa->CurrentTexObj[0]);
1061 }
1062
1063 if (t->MemBlock)
1064 savageUpdateTexLRU( imesa, t );
1065
1066 format = tObj->Image[0][tObj->BaseLevel]->Format;
1067
1068 switch (ctx->Texture.Unit[0].EnvMode) {
1069 case GL_REPLACE:
1070 imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_FALSE;
1071 switch(format)
1072 {
1073 case GL_LUMINANCE:
1074 case GL_RGB:
1075 imesa->regs.s4.texBlendCtrl[0].ui = TBC_Decal;
1076 break;
1077
1078 case GL_LUMINANCE_ALPHA:
1079 case GL_RGBA:
1080 case GL_INTENSITY:
1081 imesa->regs.s4.texBlendCtrl[0].ui = TBC_Copy;
1082 break;
1083
1084 case GL_ALPHA:
1085 imesa->regs.s4.texBlendCtrl[0].ui = TBC_CopyAlpha;
1086 break;
1087 }
1088 __HWEnvCombineSingleUnitScale(imesa, 0, 0,
1089 &imesa->regs.s4.texBlendCtrl[0]);
1090 break;
1091
1092 case GL_DECAL:
1093 imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_FALSE;
1094 switch (format)
1095 {
1096 case GL_RGB:
1097 case GL_LUMINANCE:
1098 imesa->regs.s4.texBlendCtrl[0].ui = TBC_Decal;
1099 break;
1100
1101 case GL_RGBA:
1102 case GL_INTENSITY:
1103 case GL_LUMINANCE_ALPHA:
1104 imesa->regs.s4.texBlendCtrl[0].ui = TBC_DecalAlpha;
1105 break;
1106
1107 /*
1108 GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_INTENSITY
1109 are undefined with GL_DECAL
1110 */
1111
1112 case GL_ALPHA:
1113 imesa->regs.s4.texBlendCtrl[0].ui = TBC_CopyAlpha;
1114 break;
1115 }
1116 __HWEnvCombineSingleUnitScale(imesa, 0, 0,
1117 &imesa->regs.s4.texBlendCtrl[0]);
1118 break;
1119
1120 case GL_MODULATE:
1121 imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_FALSE;
1122 imesa->regs.s4.texBlendCtrl[0].ui = TBC_ModulAlpha;
1123 __HWEnvCombineSingleUnitScale(imesa, 0, 0,
1124 &imesa->regs.s4.texBlendCtrl[0]);
1125 break;
1126
1127 case GL_BLEND:
1128
1129 switch (format)
1130 {
1131 case GL_ALPHA:
1132 imesa->regs.s4.texBlendCtrl[0].ui = TBC_ModulAlpha;
1133 imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_FALSE;
1134 break;
1135
1136 case GL_LUMINANCE:
1137 case GL_RGB:
1138 imesa->regs.s4.texBlendCtrl[0].ui = TBC_Blend0;
1139 imesa->regs.s4.texDescr.ni.tex1En = GL_TRUE;
1140 imesa->regs.s4.texDescr.ni.texBLoopEn = GL_TRUE;
1141 imesa->regs.s4.texDescr.ni.tex1Width =
1142 imesa->regs.s4.texDescr.ni.tex0Width;
1143 imesa->regs.s4.texDescr.ni.tex1Height =
1144 imesa->regs.s4.texDescr.ni.tex0Height;
1145 imesa->regs.s4.texDescr.ni.tex1Fmt =
1146 imesa->regs.s4.texDescr.ni.tex0Fmt;
1147
1148 imesa->regs.s4.texAddr[1].ui = imesa->regs.s4.texAddr[0].ui;
1149 imesa->regs.s4.texBlendCtrl[1].ui = TBC_Blend1;
1150
1151 imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_TRUE;
1152 imesa->bTexEn1 = GL_TRUE;
1153 break;
1154
1155 case GL_LUMINANCE_ALPHA:
1156 case GL_RGBA:
1157 imesa->regs.s4.texBlendCtrl[0].ui = TBC_BlendAlpha0;
1158 imesa->regs.s4.texDescr.ni.tex1En = GL_TRUE;
1159 imesa->regs.s4.texDescr.ni.texBLoopEn = GL_TRUE;
1160 imesa->regs.s4.texDescr.ni.tex1Width =
1161 imesa->regs.s4.texDescr.ni.tex0Width;
1162 imesa->regs.s4.texDescr.ni.tex1Height =
1163 imesa->regs.s4.texDescr.ni.tex0Height;
1164 imesa->regs.s4.texDescr.ni.tex1Fmt =
1165 imesa->regs.s4.texDescr.ni.tex0Fmt;
1166
1167 imesa->regs.s4.texAddr[1].ui = imesa->regs.s4.texAddr[0].ui;
1168 imesa->regs.s4.texBlendCtrl[1].ui = TBC_BlendAlpha1;
1169
1170 imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_TRUE;
1171 imesa->bTexEn1 = GL_TRUE;
1172 break;
1173
1174 case GL_INTENSITY:
1175 imesa->regs.s4.texBlendCtrl[0].ui = TBC_BlendInt0;
1176 imesa->regs.s4.texDescr.ni.tex1En = GL_TRUE;
1177 imesa->regs.s4.texDescr.ni.texBLoopEn = GL_TRUE;
1178 imesa->regs.s4.texDescr.ni.tex1Width =
1179 imesa->regs.s4.texDescr.ni.tex0Width;
1180 imesa->regs.s4.texDescr.ni.tex1Height =
1181 imesa->regs.s4.texDescr.ni.tex0Height;
1182 imesa->regs.s4.texDescr.ni.tex1Fmt =
1183 imesa->regs.s4.texDescr.ni.tex0Fmt;
1184
1185 imesa->regs.s4.texAddr[1].ui = imesa->regs.s4.texAddr[0].ui;
1186 imesa->regs.s4.texBlendCtrl[1].ui = TBC_BlendInt1;
1187
1188 imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_TRUE;
1189 imesa->regs.s4.texCtrl[0].ni.alphaArg1Invert = GL_TRUE;
1190 imesa->bTexEn1 = GL_TRUE;
1191 break;
1192 }
1193 __HWEnvCombineSingleUnitScale(imesa, 0, 0,
1194 &imesa->regs.s4.texBlendCtrl[0]);
1195 break;
1196
1197 /*
1198 GL_ADD
1199 */
1200 case GL_ADD:
1201 printf("Add\n");
1202 imesa->regs.s4.texCtrl[0].ni.clrArg1Invert = GL_FALSE;
1203 imesa->regs.s4.texBlendCtrl[0].ui = TBC_AddAlpha;
1204 __HWEnvCombineSingleUnitScale(imesa, 0, 0,
1205 &imesa->regs.s4.texBlendCtrl[0]);
1206 break;
1207
1208 #if GL_ARB_texture_env_combine
1209 case GL_COMBINE_ARB:
1210 __HWParseTexEnvCombine(imesa, 0, &imesa->regs.s4.texCtrl[0],
1211 &imesa->regs.s4.texBlendCtrl[0]);
1212 break;
1213 #endif
1214
1215 default:
1216 fprintf(stderr, "unknown tex env mode");
1217 exit(1);
1218 break;
1219 }
1220
1221 imesa->regs.s4.texCtrl[0].ni.uMode = !(t->texParams.sWrapMode & 0x01);
1222 imesa->regs.s4.texCtrl[0].ni.vMode = !(t->texParams.tWrapMode & 0x01);
1223
1224 switch (t->texParams.minFilter)
1225 {
1226 case GL_NEAREST:
1227 imesa->regs.s4.texCtrl[0].ni.filterMode = TFM_Point;
1228 imesa->regs.s4.texCtrl[0].ni.mipmapEnable = GL_FALSE;
1229 break;
1230
1231 case GL_LINEAR:
1232 imesa->regs.s4.texCtrl[0].ni.filterMode = TFM_Bilin;
1233 imesa->regs.s4.texCtrl[0].ni.mipmapEnable = GL_FALSE;
1234 break;
1235
1236 case GL_NEAREST_MIPMAP_NEAREST:
1237 imesa->regs.s4.texCtrl[0].ni.filterMode = TFM_Point;
1238 imesa->regs.s4.texCtrl[0].ni.mipmapEnable = GL_TRUE;
1239 break;
1240
1241 case GL_LINEAR_MIPMAP_NEAREST:
1242 imesa->regs.s4.texCtrl[0].ni.filterMode = TFM_Bilin;
1243 imesa->regs.s4.texCtrl[0].ni.mipmapEnable = GL_TRUE;
1244 break;
1245
1246 case GL_NEAREST_MIPMAP_LINEAR:
1247 case GL_LINEAR_MIPMAP_LINEAR:
1248 imesa->regs.s4.texCtrl[0].ni.filterMode = TFM_Trilin;
1249 imesa->regs.s4.texCtrl[0].ni.mipmapEnable = GL_TRUE;
1250 break;
1251 }
1252
1253 if((ctx->Texture.Unit[0].LodBias !=0.0F) &&
1254 (imesa->regs.s4.texCtrl[0].ni.dBias != 0))
1255 {
1256 union {
1257 GLfloat f;
1258 GLint i;
1259 } bias;
1260 GLuint ul;
1261
1262 bias.f = ctx->Texture.Unit[0].LodBias;
1263
1264 /* if the value is >= 15.9375 determine whether >= 16
1265 or <0
1266 */
1267 if(((bias.i) & 0x7FFFFFFF) >= 0x417F0000)
1268 {
1269 if((bias.i) & 0x80000000)
1270 {
1271 ul=0x101;
1272 }
1273 else
1274 {
1275 ul=0xff;
1276 }
1277 }
1278 else
1279 {
1280 ul=(GLuint)(bias.f*16.0);
1281 }
1282
1283 ul &= 0x1FF;
1284 imesa->regs.s4.texCtrl[0].ni.dBias = ul;
1285 }
1286
1287 imesa->regs.s4.texDescr.ni.tex0En = GL_TRUE;
1288 imesa->regs.s4.texDescr.ni.tex0Width = t->image[0].image->WidthLog2;
1289 imesa->regs.s4.texDescr.ni.tex0Height = t->image[0].image->HeightLog2;
1290 imesa->regs.s4.texDescr.ni.tex0Fmt = t->image[0].internalFormat;
1291 imesa->regs.s4.texCtrl[0].ni.dMax = t->max_level;
1292
1293 if (imesa->regs.s4.texDescr.ni.tex1En)
1294 imesa->regs.s4.texDescr.ni.texBLoopEn = GL_TRUE;
1295
1296 imesa->regs.s4.texAddr[0].ui = (GLuint) t->texParams.hwPhysAddress | 0x2;
1297 if(t->heap == SAVAGE_AGP_HEAP)
1298 imesa->regs.s4.texAddr[0].ui |= 0x1;
1299
1300 return;
1301 }
1302 static void savageUpdateTex1State_s4( GLcontext *ctx )
1303 {
1304 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1305 struct gl_texture_object *tObj;
1306 savageTextureObjectPtr t;
1307 GLuint format;
1308
1309 /* disable */
1310 if(imesa->bTexEn1)
1311 {
1312 imesa->bTexEn1 = GL_FALSE;
1313 return;
1314 }
1315
1316 if (ctx->Texture.Unit[1]._ReallyEnabled == 0) {
1317 imesa->regs.s4.texDescr.ni.tex1En = GL_FALSE;
1318 imesa->regs.s4.texBlendCtrl[1].ui = TBC_NoTexMap1;
1319 imesa->regs.s4.texCtrl[1].ui = 0x20f040;
1320 imesa->regs.s4.texAddr[1].ui = 0;
1321 imesa->regs.s4.texDescr.ni.texBLoopEn = GL_FALSE;
1322 return;
1323 }
1324
1325 tObj = ctx->Texture.Unit[1]._Current;
1326
1327 if (ctx->Texture.Unit[1]._ReallyEnabled != TEXTURE_2D_BIT ||
1328 tObj->Image[0][tObj->BaseLevel]->Border > 0) {
1329 /* 1D or 3D texturing enabled, or texture border - fallback */
1330 FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE);
1331 return;
1332 }
1333
1334 /* Do 2D texture setup */
1335
1336 t = tObj->DriverData;
1337 if (!t) {
1338 t = savageAllocTexObj( tObj );
1339 if (!t)
1340 return;
1341 }
1342
1343 if (t->current_unit != 1)
1344 savageTexSetUnit( t, 1 );
1345
1346 imesa->CurrentTexObj[1] = t;
1347
1348 t->bound |= 2;
1349
1350 if (t->dirty_images) {
1351 savageSetTexImages(imesa, tObj);
1352 savageUploadTexImages(imesa, imesa->CurrentTexObj[1]);
1353 }
1354
1355 if (t->MemBlock)
1356 savageUpdateTexLRU( imesa, t );
1357
1358 format = tObj->Image[0][tObj->BaseLevel]->Format;
1359
1360 switch (ctx->Texture.Unit[1].EnvMode) {
1361 case GL_REPLACE:
1362 imesa->regs.s4.texCtrl[1].ni.clrArg1Invert = GL_FALSE;
1363 switch (format)
1364 {
1365 case GL_LUMINANCE:
1366 case GL_RGB:
1367 imesa->regs.s4.texBlendCtrl[1].ui = TBC_Decal;
1368 break;
1369
1370 case GL_LUMINANCE_ALPHA:
1371 case GL_INTENSITY:
1372 case GL_RGBA:
1373 imesa->regs.s4.texBlendCtrl[1].ui = TBC_Copy;
1374 break;
1375
1376 case GL_ALPHA:
1377 imesa->regs.s4.texBlendCtrl[1].ui = TBC_CopyAlpha1;
1378 break;
1379 }
1380 __HWEnvCombineSingleUnitScale(imesa, 0, 1, &imesa->regs.s4.texBlendCtrl);
1381 break;
1382 case GL_MODULATE:
1383 imesa->regs.s4.texCtrl[1].ni.clrArg1Invert = GL_FALSE;
1384 imesa->regs.s4.texBlendCtrl[1].ui = TBC_ModulAlpha1;
1385 __HWEnvCombineSingleUnitScale(imesa, 0, 1, &imesa->regs.s4.texBlendCtrl);
1386 break;
1387
1388 /*#if GL_EXT_texture_env_add*/
1389 case GL_ADD:
1390 imesa->regs.s4.texCtrl[1].ni.clrArg1Invert = GL_FALSE;
1391 imesa->regs.s4.texBlendCtrl[1].ui = TBC_AddAlpha1;
1392 __HWEnvCombineSingleUnitScale(imesa, 0, 1, &imesa->regs.s4.texBlendCtrl);
1393 break;
1394 /*#endif*/
1395
1396 #if GL_ARB_texture_env_combine
1397 case GL_COMBINE_ARB:
1398 __HWParseTexEnvCombine(imesa, 1, &texCtrl, &imesa->regs.s4.texBlendCtrl);
1399 break;
1400 #endif
1401
1402 case GL_DECAL:
1403 imesa->regs.s4.texCtrl[1].ni.clrArg1Invert = GL_FALSE;
1404
1405 switch (format)
1406 {
1407 case GL_LUMINANCE:
1408 case GL_RGB:
1409 imesa->regs.s4.texBlendCtrl[1].ui = TBC_Decal1;
1410 break;
1411 case GL_LUMINANCE_ALPHA:
1412 case GL_INTENSITY:
1413 case GL_RGBA:
1414 imesa->regs.s4.texBlendCtrl[1].ui = TBC_DecalAlpha1;
1415 break;
1416
1417 /*
1418 // GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_INTENSITY
1419 // are undefined with GL_DECAL
1420 */
1421 case GL_ALPHA:
1422 imesa->regs.s4.texBlendCtrl[1].ui = TBC_CopyAlpha1;
1423 break;
1424 }
1425 __HWEnvCombineSingleUnitScale(imesa, 0, 1, &imesa->regs.s4.texBlendCtrl);
1426 break;
1427
1428 case GL_BLEND:
1429 if (format == GL_LUMINANCE)
1430 {
1431 /*
1432 // This is a hack for GLQuake, invert.
1433 */
1434 imesa->regs.s4.texCtrl[1].ni.clrArg1Invert = GL_TRUE;
1435 imesa->regs.s4.texBlendCtrl[1].ui = 0;
1436 }
1437 __HWEnvCombineSingleUnitScale(imesa, 0, 1, &imesa->regs.s4.texBlendCtrl);
1438 break;
1439
1440 default:
1441 fprintf(stderr, "unkown tex 1 env mode\n");
1442 exit(1);
1443 break;
1444 }
1445
1446 imesa->regs.s4.texCtrl[1].ni.uMode = !(t->texParams.sWrapMode & 0x01);
1447 imesa->regs.s4.texCtrl[1].ni.vMode = !(t->texParams.tWrapMode & 0x01);
1448
1449 switch (t->texParams.minFilter)
1450 {
1451 case GL_NEAREST:
1452 imesa->regs.s4.texCtrl[1].ni.filterMode = TFM_Point;
1453 imesa->regs.s4.texCtrl[1].ni.mipmapEnable = GL_FALSE;
1454 break;
1455
1456 case GL_LINEAR:
1457 imesa->regs.s4.texCtrl[1].ni.filterMode = TFM_Bilin;
1458 imesa->regs.s4.texCtrl[1].ni.mipmapEnable = GL_FALSE;
1459 break;
1460
1461 case GL_NEAREST_MIPMAP_NEAREST:
1462 imesa->regs.s4.texCtrl[1].ni.filterMode = TFM_Point;
1463 imesa->regs.s4.texCtrl[1].ni.mipmapEnable = GL_TRUE;
1464 break;
1465
1466 case GL_LINEAR_MIPMAP_NEAREST:
1467 imesa->regs.s4.texCtrl[1].ni.filterMode = TFM_Bilin;
1468 imesa->regs.s4.texCtrl[1].ni.mipmapEnable = GL_TRUE;
1469 break;
1470
1471 case GL_NEAREST_MIPMAP_LINEAR:
1472 case GL_LINEAR_MIPMAP_LINEAR:
1473 imesa->regs.s4.texCtrl[1].ni.filterMode = TFM_Trilin;
1474 imesa->regs.s4.texCtrl[1].ni.mipmapEnable = GL_TRUE;
1475 break;
1476 }
1477
1478 if((ctx->Texture.Unit[1].LodBias !=0.0F)&&
1479 (imesa->regs.s4.texCtrl[1].ni.dBias != 0))
1480 {
1481 union {
1482 GLfloat f;
1483 GLint i;
1484 } bias;
1485 GLuint ul;
1486
1487 bias.f = ctx->Texture.Unit[1].LodBias;
1488
1489 /* if the value is >= 15.9375 determine whether >= 16
1490 or <0
1491 */
1492 if(((bias.i) & 0x7FFFFFFF) >= 0x417F0000)
1493 {
1494 if((bias.i) & 0x80000000)
1495 {
1496 ul=0x101;
1497 }
1498 else
1499 {
1500 ul=0xff;
1501 }
1502 }
1503 else
1504 {
1505 ul=(GLuint)(bias.f*16.0);
1506 }
1507
1508 ul &= 0x1FF;
1509 imesa->regs.s4.texCtrl[1].ni.dBias = ul;
1510 }
1511
1512 imesa->regs.s4.texDescr.ni.tex1En = GL_TRUE;
1513 imesa->regs.s4.texDescr.ni.tex1Width = t->image[0].image->WidthLog2;
1514 imesa->regs.s4.texDescr.ni.tex1Height = t->image[0].image->HeightLog2;
1515 imesa->regs.s4.texDescr.ni.tex1Fmt = t->image[0].internalFormat;
1516 imesa->regs.s4.texCtrl[1].ni.dMax = t->max_level;
1517 imesa->regs.s4.texDescr.ni.texBLoopEn = GL_TRUE;
1518
1519 imesa->regs.s4.texAddr[1].ui = (GLuint) t->texParams.hwPhysAddress| 2;
1520 if(t->heap == SAVAGE_AGP_HEAP)
1521 imesa->regs.s4.texAddr[1].ui |= 0x1;
1522 }
1523 static void savageUpdateTexState_s3d( GLcontext *ctx )
1524 {
1525 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1526 struct gl_texture_object *tObj;
1527 savageTextureObjectPtr t;
1528 GLuint format;
1529
1530 /* disable */
1531 if (ctx->Texture.Unit[0]._ReallyEnabled == 0) {
1532 imesa->regs.s3d.texCtrl.ui = 0;
1533 imesa->regs.s3d.texCtrl.ni.texEn = GL_FALSE;
1534 imesa->regs.s3d.texCtrl.ni.dBias = 0x08;
1535 imesa->regs.s3d.texCtrl.ni.texXprEn = GL_TRUE;
1536 imesa->regs.s3d.texAddr.ui = 0;
1537 return;
1538 }
1539
1540 tObj = ctx->Texture.Unit[0]._Current;
1541 if (ctx->Texture.Unit[0]._ReallyEnabled != TEXTURE_2D_BIT ||
1542 tObj->Image[0][tObj->BaseLevel]->Border > 0) {
1543 /* 1D or 3D texturing enabled, or texture border - fallback */
1544 FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE);
1545 return;
1546 }
1547
1548 /* Do 2D texture setup */
1549 t = tObj->DriverData;
1550 if (!t) {
1551 t = savageAllocTexObj( tObj );
1552 if (!t)
1553 return;
1554 }
1555
1556 if (t->current_unit != 0)
1557 savageTexSetUnit( t, 0 );
1558
1559 imesa->CurrentTexObj[0] = t;
1560 t->bound |= 1;
1561
1562 if (t->dirty_images) {
1563 savageSetTexImages(imesa, tObj);
1564 savageUploadTexImages(imesa, imesa->CurrentTexObj[0]);
1565 }
1566
1567 if (t->MemBlock)
1568 savageUpdateTexLRU( imesa, t );
1569
1570 format = tObj->Image[0][tObj->BaseLevel]->Format;
1571
1572 /* FIXME: copied from utah-glx, probably needs some tuning */
1573 switch (ctx->Texture.Unit[0].EnvMode) {
1574 case GL_DECAL:
1575 imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = SAVAGETBC_DECAL_S3D;
1576 break;
1577 case GL_REPLACE:
1578 imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = SAVAGETBC_COPY_S3D;
1579 break;
1580 case GL_BLEND: /* FIXIT */
1581 case GL_MODULATE:
1582 imesa->regs.s3d.drawCtrl.ni.texBlendCtrl = SAVAGETBC_MODULATEALPHA_S3D;
1583 break;
1584 default:
1585 fprintf(stderr, "unkown tex env mode\n");
1586 /*exit(1);*/
1587 break;
1588 }
1589
1590 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
1591 imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE;
1592
1593 /* FIXME: this is how the utah-driver works. I doubt it's the ultimate
1594 truth. */
1595 imesa->regs.s3d.texCtrl.ni.uWrapEn = 0;
1596 imesa->regs.s3d.texCtrl.ni.vWrapEn = 0;
1597 if (t->texParams.sWrapMode == GL_CLAMP)
1598 imesa->regs.s3d.texCtrl.ni.wrapMode = TAM_Clamp;
1599 else
1600 imesa->regs.s3d.texCtrl.ni.wrapMode = TAM_Wrap;
1601
1602 switch (t->texParams.minFilter) {
1603 case GL_NEAREST:
1604 imesa->regs.s3d.texCtrl.ni.filterMode = TFM_Point;
1605 imesa->regs.s3d.texCtrl.ni.mipmapDisable = GL_TRUE;
1606 break;
1607
1608 case GL_LINEAR:
1609 imesa->regs.s3d.texCtrl.ni.filterMode = TFM_Bilin;
1610 imesa->regs.s3d.texCtrl.ni.mipmapDisable = GL_TRUE;
1611 break;
1612
1613 case GL_NEAREST_MIPMAP_NEAREST:
1614 imesa->regs.s3d.texCtrl.ni.filterMode = TFM_Point;
1615 imesa->regs.s3d.texCtrl.ni.mipmapDisable = GL_FALSE;
1616 break;
1617
1618 case GL_LINEAR_MIPMAP_NEAREST:
1619 imesa->regs.s3d.texCtrl.ni.filterMode = TFM_Bilin;
1620 imesa->regs.s3d.texCtrl.ni.mipmapDisable = GL_FALSE;
1621 break;
1622
1623 case GL_NEAREST_MIPMAP_LINEAR:
1624 case GL_LINEAR_MIPMAP_LINEAR:
1625 imesa->regs.s3d.texCtrl.ni.filterMode = TFM_Trilin;
1626 imesa->regs.s3d.texCtrl.ni.mipmapDisable = GL_FALSE;
1627 break;
1628 }
1629
1630 /* There is no way to specify a maximum mipmap level. We may have to
1631 disable mipmapping completely. */
1632 /*
1633 if (t->max_level < t->image[0].image->WidthLog2 ||
1634 t->max_level < t->image[0].image->HeightLog2) {
1635 texCtrl.ni.mipmapEnable = GL_TRUE;
1636 if (texCtrl.ni.filterMode == TFM_Trilin)
1637 texCtrl.ni.filterMode = TFM_Bilin;
1638 texCtrl.ni.filterMode = TFM_Point;
1639 }
1640 */
1641
1642 /* LOD bias makes corruption of small mipmap levels worse on Savage IX
1643 * but doesn't show the desired effect with the lodbias mesa demo. */
1644 imesa->regs.s3d.texCtrl.ni.dBias = 0;
1645
1646 imesa->regs.s3d.texCtrl.ni.texEn = GL_TRUE;
1647 imesa->regs.s3d.texDescr.ni.texWidth = t->image[0].image->WidthLog2;
1648 imesa->regs.s3d.texDescr.ni.texHeight = t->image[0].image->HeightLog2;
1649 assert (t->image[0].internalFormat <= 7);
1650 imesa->regs.s3d.texDescr.ni.texFmt = t->image[0].internalFormat;
1651
1652 imesa->regs.s3d.texAddr.ni.addr = (GLuint) t->texParams.hwPhysAddress >> 3;
1653 if(t->heap == SAVAGE_AGP_HEAP) {
1654 imesa->regs.s3d.texAddr.ni.inSysTex = 1;
1655 imesa->regs.s3d.texAddr.ni.inAGPTex = 1;
1656 } else {
1657 imesa->regs.s3d.texAddr.ni.inSysTex = 0;
1658 imesa->regs.s3d.texAddr.ni.inAGPTex = 1;
1659 }
1660 }
1661
1662
1663
1664 static void savageUpdateTextureState_s4( GLcontext *ctx )
1665 {
1666 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1667 if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->bound &= ~1;
1668 if (imesa->CurrentTexObj[1]) imesa->CurrentTexObj[1]->bound &= ~2;
1669 imesa->CurrentTexObj[0] = 0;
1670 imesa->CurrentTexObj[1] = 0;
1671 FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_FALSE);
1672 savageUpdateTex0State_s4( ctx );
1673 savageUpdateTex1State_s4( ctx );
1674 imesa->dirty |= (SAVAGE_UPLOAD_CTX |
1675 SAVAGE_UPLOAD_TEX0 |
1676 SAVAGE_UPLOAD_TEX1);
1677 }
1678 static void savageUpdateTextureState_s3d( GLcontext *ctx )
1679 {
1680 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1681 if (imesa->CurrentTexObj[0]) imesa->CurrentTexObj[0]->bound &= ~1;
1682 imesa->CurrentTexObj[0] = 0;
1683 if (ctx->Texture.Unit[1]._ReallyEnabled) {
1684 FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_TRUE);
1685 } else {
1686 FALLBACK (ctx, SAVAGE_FALLBACK_TEXTURE, GL_FALSE);
1687 savageUpdateTexState_s3d( ctx );
1688 imesa->dirty |= (SAVAGE_UPLOAD_CTX |
1689 SAVAGE_UPLOAD_TEX0);
1690 }
1691 }
1692 static void savageUpdateTextureState_first( GLcontext *ctx)
1693 {
1694 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
1695 if (imesa->savageScreen->chipset <= S3_SAVAGE4) {
1696 GetTiledCoordinates16 = GetTiledCoordinates16_4;
1697 GetTiledCoordinates32 = GetTiledCoordinates32_4;
1698 } else {
1699 GetTiledCoordinates16 = GetTiledCoordinates16_8;
1700 GetTiledCoordinates32 = GetTiledCoordinates32_8;
1701 }
1702 if (imesa->savageScreen->chipset >= S3_SAVAGE4)
1703 savageUpdateTextureState = savageUpdateTextureState_s4;
1704 else
1705 savageUpdateTextureState = savageUpdateTextureState_s3d;
1706 savageUpdateTextureState (ctx);
1707 }
1708 void (*savageUpdateTextureState)( GLcontext *ctx ) =
1709 savageUpdateTextureState_first;
1710
1711
1712
1713 /*****************************************
1714 * DRIVER functions
1715 *****************************************/
1716
1717 static void savageTexEnv( GLcontext *ctx, GLenum target,
1718 GLenum pname, const GLfloat *param )
1719 {
1720 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
1721
1722 if (pname == GL_TEXTURE_ENV_MODE) {
1723
1724 imesa->new_state |= SAVAGE_NEW_TEXTURE;
1725
1726 } else if (pname == GL_TEXTURE_ENV_COLOR) {
1727
1728 struct gl_texture_unit *texUnit =
1729 &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1730 const GLfloat *fc = texUnit->EnvColor;
1731 GLuint r, g, b, a, col;
1732 CLAMPED_FLOAT_TO_UBYTE(r, fc[0]);
1733 CLAMPED_FLOAT_TO_UBYTE(g, fc[1]);
1734 CLAMPED_FLOAT_TO_UBYTE(b, fc[2]);
1735 CLAMPED_FLOAT_TO_UBYTE(a, fc[3]);
1736
1737 col = ((a << 24) |
1738 (r << 16) |
1739 (g << 8) |
1740 (b << 0));
1741
1742
1743 }
1744 }
1745
1746 static void savageTexImage2D( GLcontext *ctx, GLenum target, GLint level,
1747 GLint internalFormat,
1748 GLint width, GLint height, GLint border,
1749 GLenum format, GLenum type, const GLvoid *pixels,
1750 const struct gl_pixelstore_attrib *packing,
1751 struct gl_texture_object *texObj,
1752 struct gl_texture_image *texImage )
1753 {
1754 savageTextureObjectPtr t = (savageTextureObjectPtr) texObj->DriverData;
1755 if (t) {
1756 savageSwapOutTexObj( SAVAGE_CONTEXT(ctx), t );
1757 } else {
1758 t = savageAllocTexObj(texObj);
1759 if (!t) {
1760 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
1761 return;
1762 }
1763 }
1764 _mesa_store_teximage2d( ctx, target, level, internalFormat,
1765 width, height, border, format, type,
1766 pixels, packing, texObj, texImage );
1767 t->dirty_images |= (1 << level);
1768 SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE;
1769 }
1770
1771 static void savageTexSubImage2D( GLcontext *ctx,
1772 GLenum target,
1773 GLint level,
1774 GLint xoffset, GLint yoffset,
1775 GLsizei width, GLsizei height,
1776 GLenum format, GLenum type,
1777 const GLvoid *pixels,
1778 const struct gl_pixelstore_attrib *packing,
1779 struct gl_texture_object *texObj,
1780 struct gl_texture_image *texImage )
1781 {
1782 savageTextureObjectPtr t = (savageTextureObjectPtr) texObj->DriverData;
1783 assert( t ); /* this _should_ be true */
1784 if (t) {
1785 savageSwapOutTexObj( SAVAGE_CONTEXT(ctx), t );
1786 } else {
1787 t = savageAllocTexObj(texObj);
1788 if (!t) {
1789 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
1790 return;
1791 }
1792 }
1793 _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
1794 height, format, type, pixels, packing, texObj,
1795 texImage);
1796 t->dirty_images |= (1 << level);
1797 SAVAGE_CONTEXT(ctx)->new_state |= SAVAGE_NEW_TEXTURE;
1798 }
1799
1800 static void savageTexParameter( GLcontext *ctx, GLenum target,
1801 struct gl_texture_object *tObj,
1802 GLenum pname, const GLfloat *params )
1803 {
1804 savageTextureObjectPtr t = (savageTextureObjectPtr) tObj->DriverData;
1805 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
1806
1807 if (!t || target != GL_TEXTURE_2D)
1808 return;
1809
1810 switch (pname) {
1811 case GL_TEXTURE_MIN_FILTER:
1812 case GL_TEXTURE_MAG_FILTER:
1813 savageSetTexFilter(t,tObj->MinFilter,tObj->MagFilter);
1814 break;
1815
1816 case GL_TEXTURE_WRAP_S:
1817 case GL_TEXTURE_WRAP_T:
1818 savageSetTexWrapping(t,tObj->WrapS,tObj->WrapT);
1819 break;
1820
1821 case GL_TEXTURE_BORDER_COLOR:
1822 savageSetTexBorderColor(t,tObj->_BorderChan);
1823 break;
1824
1825 default:
1826 return;
1827 }
1828
1829 imesa->new_state |= SAVAGE_NEW_TEXTURE;
1830 }
1831
1832 static void savageBindTexture( GLcontext *ctx, GLenum target,
1833 struct gl_texture_object *tObj )
1834 {
1835 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
1836
1837 assert( (target != GL_TEXTURE_2D) || (tObj->DriverData != NULL) );
1838
1839 imesa->new_state |= SAVAGE_NEW_TEXTURE;
1840 }
1841
1842 static void savageDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
1843 {
1844 savageTextureObjectPtr t = (savageTextureObjectPtr)tObj->DriverData;
1845 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
1846
1847 if (t) {
1848
1849 if (t->bound) {
1850 imesa->CurrentTexObj[t->bound-1] = 0;
1851 imesa->new_state |= SAVAGE_NEW_TEXTURE;
1852 }
1853
1854 savageDestroyTexObj(imesa,t);
1855 tObj->DriverData=0;
1856 }
1857 /* Free mipmap images and the texture object itself */
1858 _mesa_delete_texture_object(ctx, tObj);
1859 }
1860
1861
1862 static GLboolean savageIsTextureResident( GLcontext *ctx,
1863 struct gl_texture_object *t )
1864 {
1865 savageTextureObjectPtr mt;
1866
1867 /* LOCK_HARDWARE; */
1868 mt = (savageTextureObjectPtr)t->DriverData;
1869 /* UNLOCK_HARDWARE; */
1870
1871 return mt && mt->MemBlock;
1872 }
1873
1874
1875 static struct gl_texture_object *
1876 savageNewTextureObject( GLcontext *ctx, GLuint name, GLenum target )
1877 {
1878 struct gl_texture_object *obj;
1879 obj = _mesa_new_texture_object(ctx, name, target);
1880 savageAllocTexObj( obj );
1881
1882 return obj;
1883 }
1884
1885 void savageDDInitTextureFuncs( struct dd_function_table *functions )
1886 {
1887 functions->TexEnv = savageTexEnv;
1888 functions->ChooseTextureFormat = savageChooseTextureFormat;
1889 functions->TexImage2D = savageTexImage2D;
1890 functions->TexSubImage2D = savageTexSubImage2D;
1891 functions->BindTexture = savageBindTexture;
1892 functions->NewTextureObject = savageNewTextureObject;
1893 functions->DeleteTexture = savageDeleteTexture;
1894 functions->IsTextureResident = savageIsTextureResident;
1895 functions->TexParameter = savageTexParameter;
1896 }