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