GL_INTENSITY case was incorrect in extract_float_rgba()
[mesa.git] / src / mesa / drivers / glide / fxddtex.c
1
2 /*
3 * Mesa 3-D graphics library
4 * Version: 3.5
5 *
6 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 *
26 * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
27 * terms stated above.
28 *
29 * Thank you for your contribution, David!
30 *
31 * Please make note of the above copyright/license statement. If you
32 * contributed code or bug fixes to this code under the previous (GNU
33 * Library) license and object to the new license, your code will be
34 * removed at your request. Please see the Mesa docs/COPYRIGHT file
35 * for more information.
36 *
37 * Additional Mesa/3Dfx driver developers:
38 * Daryll Strauss <daryll@precisioninsight.com>
39 * Keith Whitwell <keith@precisioninsight.com>
40 *
41 * See fxapi.h for more revision/author details.
42 */
43
44
45 #ifdef HAVE_CONFIG_H
46 #include "conf.h"
47 #endif
48
49 #if defined(FX)
50
51 #include "fxdrv.h"
52 #include "image.h"
53 #include "teximage.h"
54 #include "texformat.h"
55 #include "texstore.h"
56 #include "texutil.h"
57
58
59 void
60 fxPrintTextureData(tfxTexInfo * ti)
61 {
62 fprintf(stderr, "Texture Data:\n");
63 if (ti->tObj) {
64 fprintf(stderr, "\tName: %d\n", ti->tObj->Name);
65 fprintf(stderr, "\tBaseLevel: %d\n", ti->tObj->BaseLevel);
66 fprintf(stderr, "\tSize: %d x %d\n",
67 ti->tObj->Image[ti->tObj->BaseLevel]->Width,
68 ti->tObj->Image[ti->tObj->BaseLevel]->Height);
69 }
70 else
71 fprintf(stderr, "\tName: UNNAMED\n");
72 fprintf(stderr, "\tLast used: %d\n", ti->lastTimeUsed);
73 fprintf(stderr, "\tTMU: %ld\n", ti->whichTMU);
74 fprintf(stderr, "\t%s\n", (ti->isInTM) ? "In TMU" : "Not in TMU");
75 if (ti->tm[0])
76 fprintf(stderr, "\tMem0: %x-%x\n", (unsigned) ti->tm[0]->startAddr,
77 (unsigned) ti->tm[0]->endAddr);
78 if (ti->tm[1])
79 fprintf(stderr, "\tMem1: %x-%x\n", (unsigned) ti->tm[1]->startAddr,
80 (unsigned) ti->tm[1]->endAddr);
81 fprintf(stderr, "\tMipmaps: %d-%d\n", ti->minLevel, ti->maxLevel);
82 fprintf(stderr, "\tFilters: min %d min %d\n",
83 (int) ti->minFilt, (int) ti->maxFilt);
84 fprintf(stderr, "\tClamps: s %d t %d\n", (int) ti->sClamp,
85 (int) ti->tClamp);
86 fprintf(stderr, "\tScales: s %f t %f\n", ti->sScale, ti->tScale);
87 fprintf(stderr, "\tInt Scales: s %d t %d\n",
88 ti->int_sScale / 0x800000, ti->int_tScale / 0x800000);
89 fprintf(stderr, "\t%s\n",
90 (ti->fixedPalette) ? "Fixed palette" : "Non fixed palette");
91 fprintf(stderr, "\t%s\n", (ti->validated) ? "Validated" : "Not validated");
92 }
93
94
95 /************************************************************************/
96 /*************************** Texture Mapping ****************************/
97 /************************************************************************/
98
99 static void
100 fxTexInvalidate(GLcontext * ctx, struct gl_texture_object *tObj)
101 {
102 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
103 tfxTexInfo *ti;
104
105 ti = fxTMGetTexInfo(tObj);
106 if (ti->isInTM)
107 fxTMMoveOutTM(fxMesa, tObj); /* TO DO: SLOW but easy to write */
108
109 ti->validated = GL_FALSE;
110 fxMesa->new_state |= FX_NEW_TEXTURING;
111 }
112
113 static tfxTexInfo *
114 fxAllocTexObjData(fxMesaContext fxMesa)
115 {
116 tfxTexInfo *ti;
117
118 if (!(ti = CALLOC(sizeof(tfxTexInfo)))) {
119 fprintf(stderr, "fx Driver: out of memory !\n");
120 fxCloseHardware();
121 exit(-1);
122 }
123
124 ti->validated = GL_FALSE;
125 ti->isInTM = GL_FALSE;
126
127 ti->whichTMU = FX_TMU_NONE;
128
129 ti->tm[FX_TMU0] = NULL;
130 ti->tm[FX_TMU1] = NULL;
131
132 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
133 ti->maxFilt = GR_TEXTUREFILTER_BILINEAR;
134
135 ti->sClamp = GR_TEXTURECLAMP_WRAP;
136 ti->tClamp = GR_TEXTURECLAMP_WRAP;
137
138 ti->mmMode = GR_MIPMAP_NEAREST;
139 ti->LODblend = FXFALSE;
140
141 return ti;
142 }
143
144 void
145 fxDDTexBind(GLcontext * ctx, GLenum target, struct gl_texture_object *tObj)
146 {
147 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
148 tfxTexInfo *ti;
149
150 if (MESA_VERBOSE & VERBOSE_DRIVER) {
151 fprintf(stderr, "fxmesa: fxDDTexBind(%d,%x)\n", tObj->Name,
152 (GLuint) tObj->DriverData);
153 }
154
155 if (target != GL_TEXTURE_2D)
156 return;
157
158 if (!tObj->DriverData) {
159 tObj->DriverData = fxAllocTexObjData(fxMesa);
160 }
161
162 ti = fxTMGetTexInfo(tObj);
163
164 fxMesa->texBindNumber++;
165 ti->lastTimeUsed = fxMesa->texBindNumber;
166
167 fxMesa->new_state |= FX_NEW_TEXTURING;
168 }
169
170 void
171 fxDDTexEnv(GLcontext * ctx, GLenum target, GLenum pname,
172 const GLfloat * param)
173 {
174 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
175
176 if (MESA_VERBOSE & VERBOSE_DRIVER) {
177 if (param)
178 fprintf(stderr, "fxmesa: texenv(%x,%x)\n", pname, (GLint) (*param));
179 else
180 fprintf(stderr, "fxmesa: texenv(%x)\n", pname);
181 }
182
183 /* apply any lod biasing right now */
184 if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
185 FX_grTexLodBiasValue(GR_TMU0, *param);
186
187 if (fxMesa->haveTwoTMUs) {
188 FX_grTexLodBiasValue(GR_TMU1, *param);
189 }
190
191 }
192
193 fxMesa->new_state |= FX_NEW_TEXTURING;
194 }
195
196 void
197 fxDDTexParam(GLcontext * ctx, GLenum target, struct gl_texture_object *tObj,
198 GLenum pname, const GLfloat * params)
199 {
200 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
201 GLenum param = (GLenum) (GLint) params[0];
202 tfxTexInfo *ti;
203
204 if (MESA_VERBOSE & VERBOSE_DRIVER) {
205 fprintf(stderr, "fxmesa: fxDDTexParam(%d,%x,%x,%x)\n", tObj->Name,
206 (GLuint) tObj->DriverData, pname, param);
207 }
208
209 if (target != GL_TEXTURE_2D)
210 return;
211
212 if (!tObj->DriverData)
213 tObj->DriverData = fxAllocTexObjData(fxMesa);
214
215 ti = fxTMGetTexInfo(tObj);
216
217 switch (pname) {
218
219 case GL_TEXTURE_MIN_FILTER:
220 switch (param) {
221 case GL_NEAREST:
222 ti->mmMode = GR_MIPMAP_DISABLE;
223 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
224 ti->LODblend = FXFALSE;
225 break;
226 case GL_LINEAR:
227 ti->mmMode = GR_MIPMAP_DISABLE;
228 ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
229 ti->LODblend = FXFALSE;
230 break;
231 case GL_NEAREST_MIPMAP_NEAREST:
232 ti->mmMode = GR_MIPMAP_NEAREST;
233 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
234 ti->LODblend = FXFALSE;
235 break;
236 case GL_LINEAR_MIPMAP_NEAREST:
237 ti->mmMode = GR_MIPMAP_NEAREST;
238 ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
239 ti->LODblend = FXFALSE;
240 break;
241 case GL_NEAREST_MIPMAP_LINEAR:
242 if (fxMesa->haveTwoTMUs) {
243 ti->mmMode = GR_MIPMAP_NEAREST;
244 ti->LODblend = FXTRUE;
245 }
246 else {
247 ti->mmMode = GR_MIPMAP_NEAREST_DITHER;
248 ti->LODblend = FXFALSE;
249 }
250 ti->minFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
251 break;
252 case GL_LINEAR_MIPMAP_LINEAR:
253 if (fxMesa->haveTwoTMUs) {
254 ti->mmMode = GR_MIPMAP_NEAREST;
255 ti->LODblend = FXTRUE;
256 }
257 else {
258 ti->mmMode = GR_MIPMAP_NEAREST_DITHER;
259 ti->LODblend = FXFALSE;
260 }
261 ti->minFilt = GR_TEXTUREFILTER_BILINEAR;
262 break;
263 default:
264 break;
265 }
266 fxTexInvalidate(ctx, tObj);
267 break;
268
269 case GL_TEXTURE_MAG_FILTER:
270 switch (param) {
271 case GL_NEAREST:
272 ti->maxFilt = GR_TEXTUREFILTER_POINT_SAMPLED;
273 break;
274 case GL_LINEAR:
275 ti->maxFilt = GR_TEXTUREFILTER_BILINEAR;
276 break;
277 default:
278 break;
279 }
280 fxTexInvalidate(ctx, tObj);
281 break;
282
283 case GL_TEXTURE_WRAP_S:
284 switch (param) {
285 case GL_CLAMP:
286 ti->sClamp = GR_TEXTURECLAMP_CLAMP;
287 break;
288 case GL_REPEAT:
289 ti->sClamp = GR_TEXTURECLAMP_WRAP;
290 break;
291 default:
292 break;
293 }
294 fxMesa->new_state |= FX_NEW_TEXTURING;
295 break;
296
297 case GL_TEXTURE_WRAP_T:
298 switch (param) {
299 case GL_CLAMP:
300 ti->tClamp = GR_TEXTURECLAMP_CLAMP;
301 break;
302 case GL_REPEAT:
303 ti->tClamp = GR_TEXTURECLAMP_WRAP;
304 break;
305 default:
306 break;
307 }
308 fxMesa->new_state |= FX_NEW_TEXTURING;
309 break;
310
311 case GL_TEXTURE_BORDER_COLOR:
312 /* TO DO */
313 break;
314
315 case GL_TEXTURE_MIN_LOD:
316 /* TO DO */
317 break;
318 case GL_TEXTURE_MAX_LOD:
319 /* TO DO */
320 break;
321 case GL_TEXTURE_BASE_LEVEL:
322 fxTexInvalidate(ctx, tObj);
323 break;
324 case GL_TEXTURE_MAX_LEVEL:
325 fxTexInvalidate(ctx, tObj);
326 break;
327
328 default:
329 break;
330 }
331 }
332
333 void
334 fxDDTexDel(GLcontext * ctx, struct gl_texture_object *tObj)
335 {
336 fxMesaContext fxMesa = FX_CONTEXT(ctx);
337 tfxTexInfo *ti = fxTMGetTexInfo(tObj);
338
339 if (MESA_VERBOSE & VERBOSE_DRIVER) {
340 fprintf(stderr, "fxmesa: fxDDTexDel(%d,%p)\n", tObj->Name, ti);
341 }
342
343 if (!ti)
344 return;
345
346 fxTMFreeTexture(fxMesa, tObj);
347
348 FREE(ti);
349 tObj->DriverData = NULL;
350 }
351
352
353
354 /*
355 * Convert a gl_color_table texture palette to Glide's format.
356 */
357 static void
358 convertPalette(FxU32 data[256], const struct gl_color_table *table)
359 {
360 const GLubyte *tableUB = (const GLubyte *) table->Table;
361 GLint width = table->Size;
362 FxU32 r, g, b, a;
363 GLint i;
364
365 ASSERT(!table->FloatTable);
366
367 switch (table->Format) {
368 case GL_INTENSITY:
369 for (i = 0; i < width; i++) {
370 r = tableUB[i];
371 g = tableUB[i];
372 b = tableUB[i];
373 a = tableUB[i];
374 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
375 }
376 break;
377 case GL_LUMINANCE:
378 for (i = 0; i < width; i++) {
379 r = tableUB[i];
380 g = tableUB[i];
381 b = tableUB[i];
382 a = 255;
383 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
384 }
385 break;
386 case GL_ALPHA:
387 for (i = 0; i < width; i++) {
388 r = g = b = 255;
389 a = tableUB[i];
390 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
391 }
392 break;
393 case GL_LUMINANCE_ALPHA:
394 for (i = 0; i < width; i++) {
395 r = g = b = tableUB[i * 2 + 0];
396 a = tableUB[i * 2 + 1];
397 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
398 }
399 break;
400 case GL_RGB:
401 for (i = 0; i < width; i++) {
402 r = tableUB[i * 3 + 0];
403 g = tableUB[i * 3 + 1];
404 b = tableUB[i * 3 + 2];
405 a = 255;
406 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
407 }
408 break;
409 case GL_RGBA:
410 for (i = 0; i < width; i++) {
411 r = tableUB[i * 4 + 0];
412 g = tableUB[i * 4 + 1];
413 b = tableUB[i * 4 + 2];
414 a = tableUB[i * 4 + 3];
415 data[i] = (a << 24) | (r << 16) | (g << 8) | b;
416 }
417 break;
418 }
419 }
420
421
422 void
423 fxDDTexPalette(GLcontext * ctx, struct gl_texture_object *tObj)
424 {
425 fxMesaContext fxMesa = FX_CONTEXT(ctx);
426
427 if (tObj) {
428 /* per-texture palette */
429 tfxTexInfo *ti;
430 if (MESA_VERBOSE & VERBOSE_DRIVER) {
431 fprintf(stderr, "fxmesa: fxDDTexPalette(%d,%x)\n",
432 tObj->Name, (GLuint) tObj->DriverData);
433 }
434 if (!tObj->DriverData)
435 tObj->DriverData = fxAllocTexObjData(fxMesa);
436 ti = fxTMGetTexInfo(tObj);
437 convertPalette(ti->palette.data, &tObj->Palette);
438 fxTexInvalidate(ctx, tObj);
439 }
440 else {
441 /* global texture palette */
442 if (MESA_VERBOSE & VERBOSE_DRIVER) {
443 fprintf(stderr, "fxmesa: fxDDTexPalette(global)\n");
444 }
445 convertPalette(fxMesa->glbPalette.data, &ctx->Texture.Palette);
446 fxMesa->new_state |= FX_NEW_TEXTURING;
447 }
448 }
449
450
451 void
452 fxDDTexUseGlbPalette(GLcontext * ctx, GLboolean state)
453 {
454 fxMesaContext fxMesa = FX_CONTEXT(ctx);
455
456 if (MESA_VERBOSE & VERBOSE_DRIVER) {
457 fprintf(stderr, "fxmesa: fxDDTexUseGlbPalette(%d)\n", state);
458 }
459
460 if (state) {
461 fxMesa->haveGlobalPaletteTexture = 1;
462
463 FX_grTexDownloadTable(GR_TMU0, GR_TEXTABLE_PALETTE,
464 &(fxMesa->glbPalette));
465 if (fxMesa->haveTwoTMUs)
466 FX_grTexDownloadTable(GR_TMU1, GR_TEXTABLE_PALETTE,
467 &(fxMesa->glbPalette));
468 }
469 else {
470 fxMesa->haveGlobalPaletteTexture = 0;
471
472 if ((ctx->Texture.Unit[0]._Current == ctx->Texture.Unit[0].Current2D) &&
473 (ctx->Texture.Unit[0]._Current != NULL)) {
474 struct gl_texture_object *tObj = ctx->Texture.Unit[0]._Current;
475
476 if (!tObj->DriverData)
477 tObj->DriverData = fxAllocTexObjData(fxMesa);
478
479 fxTexInvalidate(ctx, tObj);
480 }
481 }
482 }
483
484
485 static int
486 logbase2(int n)
487 {
488 GLint i = 1;
489 GLint log2 = 0;
490
491 if (n < 0) {
492 return -1;
493 }
494
495 while (n > i) {
496 i *= 2;
497 log2++;
498 }
499 if (i != n) {
500 return -1;
501 }
502 else {
503 return log2;
504 }
505 }
506
507 /* Need different versions for different cpus.
508 */
509 #define INT_TRICK(l2) (0x800000 * l2)
510
511
512 int
513 fxTexGetInfo(int w, int h, GrLOD_t * lodlevel, GrAspectRatio_t * ar,
514 float *sscale, float *tscale,
515 int *i_sscale, int *i_tscale, int *wscale, int *hscale)
516 {
517
518 static GrLOD_t lod[9] = { GR_LOD_256, GR_LOD_128, GR_LOD_64, GR_LOD_32,
519 GR_LOD_16, GR_LOD_8, GR_LOD_4, GR_LOD_2, GR_LOD_1
520 };
521
522 int logw, logh, ws, hs;
523 GrLOD_t l;
524 GrAspectRatio_t aspectratio;
525 float s, t;
526 int is, it;
527
528 logw = logbase2(w);
529 logh = logbase2(h);
530
531 switch (logw - logh) {
532 case 0:
533 aspectratio = GR_ASPECT_1x1;
534 l = lod[8 - logw];
535 s = t = 256.0f;
536 is = it = INT_TRICK(8);
537 ws = hs = 1;
538 break;
539 case 1:
540 aspectratio = GR_ASPECT_2x1;
541 l = lod[8 - logw];
542 s = 256.0f;
543 t = 128.0f;
544 is = INT_TRICK(8);
545 it = INT_TRICK(7);
546 ws = 1;
547 hs = 1;
548 break;
549 case 2:
550 aspectratio = GR_ASPECT_4x1;
551 l = lod[8 - logw];
552 s = 256.0f;
553 t = 64.0f;
554 is = INT_TRICK(8);
555 it = INT_TRICK(6);
556 ws = 1;
557 hs = 1;
558 break;
559 case 3:
560 aspectratio = GR_ASPECT_8x1;
561 l = lod[8 - logw];
562 s = 256.0f;
563 t = 32.0f;
564 is = INT_TRICK(8);
565 it = INT_TRICK(5);
566 ws = 1;
567 hs = 1;
568 break;
569 case 4:
570 aspectratio = GR_ASPECT_8x1;
571 l = lod[8 - logw];
572 s = 256.0f;
573 t = 32.0f;
574 is = INT_TRICK(8);
575 it = INT_TRICK(5);
576 ws = 1;
577 hs = 2;
578 break;
579 case 5:
580 aspectratio = GR_ASPECT_8x1;
581 l = lod[8 - logw];
582 s = 256.0f;
583 t = 32.0f;
584 is = INT_TRICK(8);
585 it = INT_TRICK(5);
586 ws = 1;
587 hs = 4;
588 break;
589 case 6:
590 aspectratio = GR_ASPECT_8x1;
591 l = lod[8 - logw];
592 s = 256.0f;
593 t = 32.0f;
594 is = INT_TRICK(8);
595 it = INT_TRICK(5);
596 ws = 1;
597 hs = 8;
598 break;
599 case 7:
600 aspectratio = GR_ASPECT_8x1;
601 l = lod[8 - logw];
602 s = 256.0f;
603 t = 32.0f;
604 is = INT_TRICK(8);
605 it = INT_TRICK(5);
606 ws = 1;
607 hs = 16;
608 break;
609 case 8:
610 aspectratio = GR_ASPECT_8x1;
611 l = lod[8 - logw];
612 s = 256.0f;
613 t = 32.0f;
614 is = INT_TRICK(8);
615 it = INT_TRICK(5);
616 ws = 1;
617 hs = 32;
618 break;
619 case -1:
620 aspectratio = GR_ASPECT_1x2;
621 l = lod[8 - logh];
622 s = 128.0f;
623 t = 256.0f;
624 is = INT_TRICK(7);
625 it = INT_TRICK(8);
626 ws = 1;
627 hs = 1;
628 break;
629 case -2:
630 aspectratio = GR_ASPECT_1x4;
631 l = lod[8 - logh];
632 s = 64.0f;
633 t = 256.0f;
634 is = INT_TRICK(6);
635 it = INT_TRICK(8);
636 ws = 1;
637 hs = 1;
638 break;
639 case -3:
640 aspectratio = GR_ASPECT_1x8;
641 l = lod[8 - logh];
642 s = 32.0f;
643 t = 256.0f;
644 is = INT_TRICK(5);
645 it = INT_TRICK(8);
646 ws = 1;
647 hs = 1;
648 break;
649 case -4:
650 aspectratio = GR_ASPECT_1x8;
651 l = lod[8 - logh];
652 s = 32.0f;
653 t = 256.0f;
654 is = INT_TRICK(5);
655 it = INT_TRICK(8);
656 ws = 2;
657 hs = 1;
658 break;
659 case -5:
660 aspectratio = GR_ASPECT_1x8;
661 l = lod[8 - logh];
662 s = 32.0f;
663 t = 256.0f;
664 is = INT_TRICK(5);
665 it = INT_TRICK(8);
666 ws = 4;
667 hs = 1;
668 break;
669 case -6:
670 aspectratio = GR_ASPECT_1x8;
671 l = lod[8 - logh];
672 s = 32.0f;
673 t = 256.0f;
674 is = INT_TRICK(5);
675 it = INT_TRICK(8);
676 ws = 8;
677 hs = 1;
678 break;
679 case -7:
680 aspectratio = GR_ASPECT_1x8;
681 l = lod[8 - logh];
682 s = 32.0f;
683 t = 256.0f;
684 is = INT_TRICK(5);
685 it = INT_TRICK(8);
686 ws = 16;
687 hs = 1;
688 break;
689 case -8:
690 aspectratio = GR_ASPECT_1x8;
691 l = lod[8 - logh];
692 s = 32.0f;
693 t = 256.0f;
694 is = INT_TRICK(5);
695 it = INT_TRICK(8);
696 ws = 32;
697 hs = 1;
698 break;
699 default:
700 return 0;
701 break;
702 }
703
704 if (lodlevel)
705 (*lodlevel) = l;
706
707 if (ar)
708 (*ar) = aspectratio;
709
710 if (sscale)
711 (*sscale) = s;
712
713 if (tscale)
714 (*tscale) = t;
715
716 if (wscale)
717 (*wscale) = ws;
718
719 if (hscale)
720 (*hscale) = hs;
721
722 if (i_sscale)
723 *i_sscale = is;
724
725 if (i_tscale)
726 *i_tscale = it;
727
728
729 return 1;
730 }
731
732 /*
733 * Given an OpenGL internal texture format, return the corresponding
734 * Glide internal texture format and base texture format.
735 */
736 void
737 fxTexGetFormat(GLenum glformat, GrTextureFormat_t * tfmt, GLint * ifmt)
738 {
739 switch (glformat) {
740 case 1:
741 case GL_LUMINANCE:
742 case GL_LUMINANCE4:
743 case GL_LUMINANCE8:
744 case GL_LUMINANCE12:
745 case GL_LUMINANCE16:
746 if (tfmt)
747 (*tfmt) = GR_TEXFMT_INTENSITY_8;
748 if (ifmt)
749 (*ifmt) = GL_LUMINANCE;
750 break;
751 case 2:
752 case GL_LUMINANCE_ALPHA:
753 case GL_LUMINANCE4_ALPHA4:
754 case GL_LUMINANCE6_ALPHA2:
755 case GL_LUMINANCE8_ALPHA8:
756 case GL_LUMINANCE12_ALPHA4:
757 case GL_LUMINANCE12_ALPHA12:
758 case GL_LUMINANCE16_ALPHA16:
759 if (tfmt)
760 (*tfmt) = GR_TEXFMT_ALPHA_INTENSITY_88;
761 if (ifmt)
762 (*ifmt) = GL_LUMINANCE_ALPHA;
763 break;
764 case GL_INTENSITY:
765 case GL_INTENSITY4:
766 case GL_INTENSITY8:
767 case GL_INTENSITY12:
768 case GL_INTENSITY16:
769 if (tfmt)
770 (*tfmt) = GR_TEXFMT_ALPHA_8;
771 if (ifmt)
772 (*ifmt) = GL_INTENSITY;
773 break;
774 case GL_ALPHA:
775 case GL_ALPHA4:
776 case GL_ALPHA8:
777 case GL_ALPHA12:
778 case GL_ALPHA16:
779 if (tfmt)
780 (*tfmt) = GR_TEXFMT_ALPHA_8;
781 if (ifmt)
782 (*ifmt) = GL_ALPHA;
783 break;
784 case 3:
785 case GL_RGB:
786 case GL_R3_G3_B2:
787 case GL_RGB4:
788 case GL_RGB5:
789 case GL_RGB8:
790 case GL_RGB10:
791 case GL_RGB12:
792 case GL_RGB16:
793 if (tfmt)
794 (*tfmt) = GR_TEXFMT_RGB_565;
795 if (ifmt)
796 (*ifmt) = GL_RGB;
797 break;
798 case 4:
799 case GL_RGBA:
800 case GL_RGBA2:
801 case GL_RGBA4:
802 case GL_RGBA8:
803 case GL_RGB10_A2:
804 case GL_RGBA12:
805 case GL_RGBA16:
806 if (tfmt)
807 (*tfmt) = GR_TEXFMT_ARGB_4444;
808 if (ifmt)
809 (*ifmt) = GL_RGBA;
810 break;
811 case GL_RGB5_A1:
812 if (tfmt)
813 (*tfmt) = GR_TEXFMT_ARGB_1555;
814 if (ifmt)
815 (*ifmt) = GL_RGBA;
816 break;
817 case GL_COLOR_INDEX:
818 case GL_COLOR_INDEX1_EXT:
819 case GL_COLOR_INDEX2_EXT:
820 case GL_COLOR_INDEX4_EXT:
821 case GL_COLOR_INDEX8_EXT:
822 case GL_COLOR_INDEX12_EXT:
823 case GL_COLOR_INDEX16_EXT:
824 if (tfmt)
825 (*tfmt) = GR_TEXFMT_P_8;
826 if (ifmt)
827 (*ifmt) = GL_RGBA; /* XXX why is this RGBA? */
828 break;
829 default:
830 fprintf(stderr,
831 "fx Driver: unsupported internalFormat (0x%x) in fxTexGetFormat()\n",
832 glformat);
833 fxCloseHardware();
834 exit(-1);
835 break;
836 }
837 }
838
839 static GLboolean
840 fxIsTexSupported(GLenum target, GLint internalFormat,
841 const struct gl_texture_image *image)
842 {
843 if (target != GL_TEXTURE_2D)
844 return GL_FALSE;
845
846 if (!fxTexGetInfo
847 (image->Width, image->Height, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
848 NULL)) return GL_FALSE;
849
850 if (image->Border > 0)
851 return GL_FALSE;
852
853 return GL_TRUE;
854 }
855
856
857 /**********************************************************************/
858 /**** NEW TEXTURE IMAGE FUNCTIONS ****/
859 /**********************************************************************/
860
861 /* Texel-fetch functions for software texturing and glGetTexImage().
862 * We should have been able to use some "standard" fetch functions (which
863 * may get defined in texutil.c) but we have to account for scaled texture
864 * images on tdfx hardware (the 8:1 aspect ratio limit).
865 * Hence, we need special functions here.
866 */
867
868 static void
869 fetch_intensity8(const struct gl_texture_image *texImage,
870 GLint i, GLint j, GLint k, GLvoid * texelOut)
871 {
872 GLchan *rgba = (GLchan *) texelOut;
873 const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
874 const GLubyte *texel;
875
876 i = i * mml->wScale;
877 j = j * mml->hScale;
878
879 texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
880 rgba[RCOMP] = *texel;
881 rgba[GCOMP] = *texel;
882 rgba[BCOMP] = *texel;
883 rgba[ACOMP] = *texel;
884 }
885
886
887 static void
888 fetch_luminance8(const struct gl_texture_image *texImage,
889 GLint i, GLint j, GLint k, GLvoid * texelOut)
890 {
891 GLchan *rgba = (GLchan *) texelOut;
892 const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
893 const GLubyte *texel;
894
895 i = i * mml->wScale;
896 j = j * mml->hScale;
897
898 texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
899 rgba[RCOMP] = *texel;
900 rgba[GCOMP] = *texel;
901 rgba[BCOMP] = *texel;
902 rgba[ACOMP] = 255;
903 }
904
905
906 static void
907 fetch_alpha8(const struct gl_texture_image *texImage,
908 GLint i, GLint j, GLint k, GLvoid * texelOut)
909 {
910 GLchan *rgba = (GLchan *) texelOut;
911 const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
912 const GLubyte *texel;
913
914 i = i * mml->wScale;
915 j = j * mml->hScale;
916 i = i * mml->width / texImage->Width;
917 j = j * mml->height / texImage->Height;
918
919 texel = ((GLubyte *) texImage->Data) + j * mml->width + i;
920 rgba[RCOMP] = 255;
921 rgba[GCOMP] = 255;
922 rgba[BCOMP] = 255;
923 rgba[ACOMP] = *texel;
924 }
925
926
927 static void
928 fetch_index8(const struct gl_texture_image *texImage,
929 GLint i, GLint j, GLint k, GLvoid * texelOut)
930 {
931 /* XXX todo */
932 }
933
934
935 static void
936 fetch_luminance8_alpha8(const struct gl_texture_image *texImage,
937 GLint i, GLint j, GLint k, GLvoid * texelOut)
938 {
939 GLchan *rgba = (GLchan *) texelOut;
940 const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
941 const GLubyte *texel;
942
943 i = i * mml->wScale;
944 j = j * mml->hScale;
945
946 texel = ((GLubyte *) texImage->Data) + (j * mml->width + i) * 2;
947 rgba[RCOMP] = texel[0];
948 rgba[GCOMP] = texel[0];
949 rgba[BCOMP] = texel[0];
950 rgba[ACOMP] = texel[1];
951 }
952
953
954 static void
955 fetch_r5g6b5(const struct gl_texture_image *texImage,
956 GLint i, GLint j, GLint k, GLvoid * texelOut)
957 {
958 GLchan *rgba = (GLchan *) texelOut;
959 const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
960 const GLushort *texel;
961
962 i = i * mml->wScale;
963 j = j * mml->hScale;
964
965 texel = ((GLushort *) texImage->Data) + j * mml->width + i;
966 rgba[RCOMP] = (((*texel) >> 11) & 0x1f) * 255 / 31;
967 rgba[GCOMP] = (((*texel) >> 5) & 0x3f) * 255 / 63;
968 rgba[BCOMP] = (((*texel) >> 0) & 0x1f) * 255 / 31;
969 rgba[ACOMP] = 255;
970 }
971
972
973 static void
974 fetch_r4g4b4a4(const struct gl_texture_image *texImage,
975 GLint i, GLint j, GLint k, GLvoid * texelOut)
976 {
977 GLchan *rgba = (GLchan *) texelOut;
978 const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
979 const GLushort *texel;
980
981 i = i * mml->wScale;
982 j = j * mml->hScale;
983
984 texel = ((GLushort *) texImage->Data) + j * mml->width + i;
985 rgba[RCOMP] = (((*texel) >> 12) & 0xf) * 255 / 15;
986 rgba[GCOMP] = (((*texel) >> 8) & 0xf) * 255 / 15;
987 rgba[BCOMP] = (((*texel) >> 4) & 0xf) * 255 / 15;
988 rgba[ACOMP] = (((*texel) >> 0) & 0xf) * 255 / 15;
989 }
990
991
992 static void
993 fetch_r5g5b5a1(const struct gl_texture_image *texImage,
994 GLint i, GLint j, GLint k, GLvoid * texelOut)
995 {
996 GLchan *rgba = (GLchan *) texelOut;
997 const tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
998 const GLushort *texel;
999
1000 i = i * mml->wScale;
1001 j = j * mml->hScale;
1002
1003 texel = ((GLushort *) texImage->Data) + j * mml->width + i;
1004 rgba[RCOMP] = (((*texel) >> 11) & 0x1f) * 255 / 31;
1005 rgba[GCOMP] = (((*texel) >> 6) & 0x1f) * 255 / 31;
1006 rgba[BCOMP] = (((*texel) >> 1) & 0x1f) * 255 / 31;
1007 rgba[ACOMP] = (((*texel) >> 0) & 0x01) * 255;
1008 }
1009
1010
1011 static void
1012 PrintTexture(int w, int h, int c, const GLubyte * data)
1013 {
1014 int i, j;
1015 for (i = 0; i < h; i++) {
1016 for (j = 0; j < w; j++) {
1017 if (c == 2)
1018 printf("%02x %02x ", data[0], data[1]);
1019 else if (c == 3)
1020 printf("%02x %02x %02x ", data[0], data[1], data[2]);
1021 data += c;
1022 }
1023 printf("\n");
1024 }
1025 }
1026
1027
1028 static const struct gl_texture_format *
1029 choose_format(GLenum format, GLenum type)
1030 {
1031 if (type == CHAN_TYPE) {
1032 switch (format) {
1033 case GL_ALPHA:
1034 return &_mesa_texformat_alpha;
1035 case GL_LUMINANCE:
1036 return &_mesa_texformat_luminance;
1037 case GL_LUMINANCE_ALPHA:
1038 return &_mesa_texformat_luminance_alpha;
1039 case GL_INTENSITY:
1040 return &_mesa_texformat_intensity;
1041 case GL_RGB:
1042 return &_mesa_texformat_rgb;
1043 case GL_RGBA:
1044 return &_mesa_texformat_rgba;
1045 case GL_COLOR_INDEX:
1046 return &_mesa_texformat_color_index;
1047 default:
1048 _mesa_problem(NULL, "Unexpected CHAN format in choose_format\n");
1049 return NULL;
1050 }
1051 }
1052 else if (format == GL_DEPTH_COMPONENT && type == GL_FLOAT) {
1053 return &_mesa_texformat_depth_component;
1054 }
1055 else {
1056 _mesa_problem(NULL, "Unexpected format/type in choose_format\n");
1057 return NULL;
1058 }
1059 }
1060
1061
1062 void
1063 fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level,
1064 GLint internalFormat, GLint width, GLint height, GLint border,
1065 GLenum format, GLenum type, const GLvoid * pixels,
1066 const struct gl_pixelstore_attrib *packing,
1067 struct gl_texture_object *texObj,
1068 struct gl_texture_image *texImage)
1069 {
1070 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
1071 GrTextureFormat_t gldformat;
1072 tfxTexInfo *ti;
1073 tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
1074 const struct gl_texture_format *mesaTexFormat;
1075 GLint texelSize;
1076 GLboolean success;
1077
1078 if (!fxIsTexSupported(target, internalFormat, texImage)) {
1079 _mesa_problem(NULL, "fx Driver: unsupported texture in fxDDTexImg()\n");
1080 return;
1081 }
1082
1083 if (!texObj->DriverData)
1084 texObj->DriverData = fxAllocTexObjData(fxMesa);
1085 ti = fxTMGetTexInfo(texObj);
1086
1087 if (!mml) {
1088 texImage->DriverData = MALLOC(sizeof(tfxMipMapLevel));
1089 mml = FX_MIPMAP_DATA(texImage);
1090 }
1091
1092 fxTexGetFormat(internalFormat, &gldformat, NULL);
1093
1094 fxTexGetInfo(width, height, NULL, NULL, NULL, NULL,
1095 NULL, NULL, &mml->wScale, &mml->hScale);
1096
1097 mml->width = width * mml->wScale;
1098 mml->height = height * mml->hScale;
1099
1100 switch (internalFormat) {
1101 case GL_INTENSITY:
1102 case GL_INTENSITY4:
1103 case GL_INTENSITY8:
1104 case GL_INTENSITY12:
1105 case GL_INTENSITY16:
1106 texImage->Format = GL_INTENSITY;
1107 texImage->FetchTexel = fetch_intensity8;
1108 texelSize = 1;
1109 mesaTexFormat = &_mesa_texformat_i8;
1110 break;
1111 case 1:
1112 case GL_LUMINANCE:
1113 case GL_LUMINANCE4:
1114 case GL_LUMINANCE8:
1115 case GL_LUMINANCE12:
1116 case GL_LUMINANCE16:
1117 texImage->Format = GL_LUMINANCE;
1118 texImage->FetchTexel = fetch_luminance8;
1119 texelSize = 1;
1120 mesaTexFormat = &_mesa_texformat_l8;
1121 break;
1122 case GL_ALPHA:
1123 case GL_ALPHA4:
1124 case GL_ALPHA8:
1125 case GL_ALPHA12:
1126 case GL_ALPHA16:
1127 texImage->Format = GL_ALPHA;
1128 texImage->FetchTexel = fetch_alpha8;
1129 texelSize = 1;
1130 mesaTexFormat = &_mesa_texformat_a8;
1131 break;
1132 case GL_COLOR_INDEX:
1133 case GL_COLOR_INDEX1_EXT:
1134 case GL_COLOR_INDEX2_EXT:
1135 case GL_COLOR_INDEX4_EXT:
1136 case GL_COLOR_INDEX8_EXT:
1137 case GL_COLOR_INDEX12_EXT:
1138 case GL_COLOR_INDEX16_EXT:
1139 texImage->Format = GL_COLOR_INDEX;
1140 texImage->FetchTexel = fetch_index8;
1141 texelSize = 1;
1142 mesaTexFormat = &_mesa_texformat_ci8;
1143 break;
1144 case 2:
1145 case GL_LUMINANCE_ALPHA:
1146 case GL_LUMINANCE4_ALPHA4:
1147 case GL_LUMINANCE6_ALPHA2:
1148 case GL_LUMINANCE8_ALPHA8:
1149 case GL_LUMINANCE12_ALPHA4:
1150 case GL_LUMINANCE12_ALPHA12:
1151 case GL_LUMINANCE16_ALPHA16:
1152 texImage->Format = GL_LUMINANCE_ALPHA;
1153 texImage->FetchTexel = fetch_luminance8_alpha8;
1154 texelSize = 2;
1155 mesaTexFormat = &_mesa_texformat_al88;
1156 break;
1157 case 3:
1158 case GL_RGB:
1159 case GL_R3_G3_B2:
1160 case GL_RGB4:
1161 case GL_RGB5:
1162 case GL_RGB8:
1163 case GL_RGB10:
1164 case GL_RGB12:
1165 case GL_RGB16:
1166 texImage->Format = GL_RGB;
1167 texImage->FetchTexel = fetch_r5g6b5;
1168 texelSize = 2;
1169 mesaTexFormat = &_mesa_texformat_rgb565;
1170 break;
1171 case 4:
1172 case GL_RGBA:
1173 case GL_RGBA2:
1174 case GL_RGBA4:
1175 case GL_RGBA8:
1176 case GL_RGB10_A2:
1177 case GL_RGBA12:
1178 case GL_RGBA16:
1179 texImage->Format = GL_RGBA;
1180 texImage->FetchTexel = fetch_r4g4b4a4;
1181 texelSize = 2;
1182 mesaTexFormat = &_mesa_texformat_argb4444;
1183 break;
1184 case GL_RGB5_A1:
1185 texImage->Format = GL_RGBA;
1186 texImage->FetchTexel = fetch_r5g5b5a1;
1187 texelSize = 2;
1188 mesaTexFormat = &_mesa_texformat_argb1555;
1189 break;
1190 default:
1191 _mesa_problem(NULL, "tdfx driver: texbuildimagemap() bad format");
1192 return;
1193 }
1194
1195 texImage->TexFormat = mesaTexFormat;
1196
1197 /* allocate storage for texture image */
1198 texImage->Data = MALLOC(mml->width * mml->height * texelSize);
1199 if (!texImage->Data)
1200 return;
1201
1202 mml->glideFormat = gldformat;
1203 fxTexInvalidate(ctx, texObj);
1204
1205 /* store the texture image */
1206 if (ctx->_ImageTransferState ||
1207 mml->width != width ||
1208 mml->height != height) {
1209 /* Need to image transfer ops or image rescale */
1210 success = GL_FALSE;
1211 }
1212 else {
1213 success = _mesa_convert_texsubimage2d(mesaTexFormat->MesaFormat,
1214 0, 0, /* xoffset, yoffset */
1215 mml->width, mml->height,
1216 mml->width, /* destImageWidth */
1217 format, type, /* user fmt/type */
1218 packing, /* user packing params */
1219 pixels, texImage->Data);
1220 }
1221
1222 if (!success) {
1223 /* First attempt at texture conversion failed. We may need to
1224 * do fancy pixel transfer ops or convert from an obscure texture
1225 * format.
1226 */
1227 GLenum simpleFormat = _mesa_base_tex_format(ctx, internalFormat);
1228 GLint comps = _mesa_components_in_format(simpleFormat);
1229 GLubyte *tempImage;
1230
1231 tempImage = MALLOC(width * height * comps * sizeof(GLubyte));
1232
1233 /* Apply pixel transfer ops and convert image format to something
1234 * simple (format = simpleFormat, type = CHAN_TYPE).
1235 */
1236 _mesa_transfer_teximage(ctx, 2, /* dimensions */
1237 simpleFormat, /* dest format */
1238 tempImage, /* dest addr */
1239 width, height, 1, /* src size */
1240 0, 0, 0, /* dst offsets */
1241 width * comps, /* dstRowStride */
1242 0, /* dstImageStride */
1243 format, type, pixels, packing /* src info */ );
1244
1245 if (mml->width != width || mml->height != height) {
1246 /* Upscale image to accomodate Glide's image aspect limitations. */
1247 const struct gl_texture_format *texFormat
1248 = choose_format(simpleFormat, CHAN_TYPE);
1249 GLvoid *rescaledImage = MALLOC(mml->width * mml->height
1250 * texFormat->TexelBytes);
1251 if (!rescaledImage) {
1252 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
1253 return;
1254 }
1255 _mesa_rescale_teximage2d(texFormat,
1256 width, height, mml->width, mml->height,
1257 tempImage, rescaledImage);
1258 success = _mesa_convert_texsubimage2d(mesaTexFormat->MesaFormat,
1259 0, 0, /* xoffset, yoffset */
1260 mml->width, mml->height,
1261 mml->width, /* destImageWidth */
1262 simpleFormat, /* source format */
1263 CHAN_TYPE, /* source type */
1264 &_mesa_native_packing,
1265 rescaledImage, texImage->Data);
1266 FREE(rescaledImage);
1267 }
1268 else {
1269 success = _mesa_convert_texsubimage2d(mesaTexFormat->MesaFormat,
1270 0, 0, /* xoffset, yoffset */
1271 mml->width, mml->height,
1272 mml->width, /* destImageWidth */
1273 simpleFormat, /* source format */
1274 CHAN_TYPE, /* source type */
1275 &_mesa_native_packing,
1276 tempImage, texImage->Data);
1277 }
1278 /* the conversion had better of worked! */
1279 assert(success);
1280 FREE(tempImage);
1281 }
1282
1283 if (ti->validated && ti->isInTM) {
1284 /*printf("reloadmipmaplevels\n"); */
1285 fxTMReloadMipMapLevel(fxMesa, texObj, level);
1286 }
1287 else {
1288 /*printf("invalidate2\n"); */
1289 fxTexInvalidate(ctx, texObj);
1290 }
1291 }
1292
1293
1294 void
1295 fxDDTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
1296 GLint xoffset, GLint yoffset,
1297 GLsizei width, GLsizei height,
1298 GLenum format, GLenum type, const GLvoid * pixels,
1299 const struct gl_pixelstore_attrib *packing,
1300 struct gl_texture_object *texObj,
1301 struct gl_texture_image *texImage)
1302 {
1303 fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
1304 tfxTexInfo *ti;
1305 tfxMipMapLevel *mml;
1306 GLboolean success;
1307
1308 if (!texObj->DriverData) {
1309 _mesa_problem(ctx, "problem in fxDDTexSubImage2D");
1310 return;
1311 }
1312
1313 ti = fxTMGetTexInfo(texObj);
1314 assert(ti);
1315 mml = FX_MIPMAP_DATA(texImage);
1316 assert(mml);
1317
1318 assert(texImage->Data); /* must have an existing texture image! */
1319 assert(texImage->Format);
1320
1321 /* XXX check for image rescale */
1322 if (ctx->_ImageTransferState ||
1323 texImage->Width != mml->width ||
1324 texImage->Height != mml->height) {
1325 success = GL_FALSE;
1326 }
1327 else {
1328 success = _mesa_convert_texsubimage2d(texImage->TexFormat->MesaFormat,
1329 xoffset, yoffset,
1330 width, height,
1331 mml->width,
1332 format, type, packing,
1333 pixels, texImage->Data);
1334 }
1335
1336 if (!success) {
1337 /* Incoming image might need scale/bias or is in an uncommon format
1338 * that _mesa_convert_texsubimage() can't deal with. Convert it to
1339 * a simpler format now.
1340 */
1341
1342 GLenum simpleFormat = _mesa_base_tex_format(ctx, texImage->TexFormat->IntFormat);
1343 GLint comps = _mesa_components_in_format(simpleFormat);
1344 GLubyte *tempImage;
1345 GLboolean success;
1346
1347 tempImage = MALLOC(width * height * comps * sizeof(GLubyte));
1348
1349 /* Apply pixel transfer ops and convert image format to something
1350 * simple (format = simpleFormat, type = CHAN_TYPE).
1351 */
1352 _mesa_transfer_teximage(ctx, 2, /* dimensions */
1353 simpleFormat, /* dest format */
1354 tempImage, /* dest addr */
1355 width, height, 1, /* src size */
1356 0, 0, 0, /* dst offsets */
1357 width * comps, /* dstRowStride */
1358 0, /* dstImageStride */
1359 format, type, pixels, packing /* src info */ );
1360
1361 if (texImage->Width != mml->width || texImage->Height != mml->height) {
1362 /* Upscale image to accomodate Glide's image aspect limitations. */
1363 const GLint wScale = mml->width / texImage->Width;
1364 const GLint hScale = mml->height / texImage->Height;
1365 const GLint newWidth = width * wScale;
1366 const GLint newHeight = height *hScale;
1367 GLvoid *rescaledImage = MALLOC(newWidth * newHeight
1368 * texImage->TexFormat->TexelBytes);
1369 assert(mml->width >= texImage->Width);
1370 assert(mml->height >= texImage->Height);
1371 if (!rescaledImage) {
1372 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
1373 return;
1374 }
1375 _mesa_rescale_teximage2d(texImage->TexFormat,
1376 width, height, newWidth, newHeight,
1377 tempImage, rescaledImage);
1378 success = _mesa_convert_texsubimage2d(texImage->TexFormat->MesaFormat,
1379 xoffset * wScale, yoffset * hScale,
1380 newWidth, newHeight,
1381 mml->width, /* destImageWidth */
1382 simpleFormat, /* source format */
1383 CHAN_TYPE, /* source type */
1384 &_mesa_native_packing,
1385 rescaledImage, texImage->Data);
1386 FREE(rescaledImage);
1387 }
1388 else {
1389 success = _mesa_convert_texsubimage2d(texImage->TexFormat->MesaFormat,
1390 xoffset, yoffset,
1391 width, height,
1392 mml->width,
1393 simpleFormat, CHAN_TYPE,
1394 &_mesa_native_packing,
1395 tempImage, texImage->Data);
1396 }
1397 /* the conversion had better of worked! */
1398 assert(success);
1399 FREE(tempImage);
1400 }
1401
1402 if (ti->validated && ti->isInTM)
1403 fxTMReloadMipMapLevel(fxMesa, texObj, level);
1404 else
1405 fxTexInvalidate(ctx, texObj);
1406 }
1407
1408
1409 #else
1410
1411
1412 /*
1413 * Need this to provide at least one external definition.
1414 */
1415
1416 extern int gl_fx_dummy_function_ddtex(void);
1417 int
1418 gl_fx_dummy_function_ddtex(void)
1419 {
1420 return 0;
1421 }
1422
1423 #endif /* FX */