2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
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:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
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.
32 #include "simple_list.h"
35 #include "texformat.h"
38 #include "via_context.h"
40 #include "via_state.h"
41 #include "via_ioctl.h"
43 GLint texSize8bpp
[12][12] = {
44 {32,32,32,32,32,32,64,128,256,512,1024,2048},
45 {64,64,64,64,64,64,128,256,512,1024,2048,4096},
46 {128,128,128,128,128,128,256,512,1024,2048,4096,8192},
47 {256,256,256,256,256,256,512,1024,2048,4096,8192,16384},
48 {512,512,512,512,512,512,1024,2048,4096,8192,16384,32768},
49 {1024,1024,1024,1024,1024,1024,2048,4096,8192,16384,32768,65536},
50 {2048,2048,2048,2048,2048,2048,4096,8192,16384,32768,65536,131072},
51 {4096,4096,4096,4096,4096,4096,8192,16384,32768,65536,131072,262144},
52 {8192,8192,8192,8192,8192,8192,16384,32768,65536,131072,262144,524288},
53 {16384,16384,16384,16384,16384,16384,32768,65536,131072,262144,524288,1048576},
54 {32768,32768,32768,32768,32768,32768,65536,131072,262144,524288,1048576,2097152},
55 {65536,65536,65536,65536,65536,65536,131072,262144,524288,1048576,2097152,4194304
59 GLint texSize16bpp
[12][12] = {
60 {32,32,32,32,32,64,128,256,512,1024,2048,4096},
61 {64,64,64,64,64,128,256,512,1024,2048,4096,8192},
62 {128,128,128,128,128,256,512,1024,2048,4096,8192,16384},
63 {256,256,256,256,256,512,1024,2048,4096,8192,16384,32768},
64 {512,512,512,512,512,1024,2048,4096,8192,16384,32768,65536},
65 {1024,1024,1024,1024,1024,2048,4096,8192,16384,32768,65536,131072},
66 {2048,2048,2048,2048,2048,4096,8192,16384,32768,65536,131072,262144},
67 {4096,4096,4096,4096,4096,8192,16384,32768,65536,131072,262144,524288},
68 {8192,8192,8192,8192,8192,16384,32768,65536,131072,262144,524288,1048576},
69 {16384,16384,16384,16384,16384,32768,65536,131072,262144,524288,1048576,2097152},
70 {32768,32768,32768,32768,32768,65536,131072,262144,524288,1048576,2097152,4194304},
71 {65536,65536,65536,65536,65536,131072,262144,524288,1048576,2097152,4194304,8388608}
74 GLint texSize32bpp
[12][12] = {
75 {32,32,32,32,64,128,256,512,1024,2048,4096,8192},
76 {64,64,64,64,128,256,512,1024,2048,4096,8192,16384},
77 {128,128,128,128,256,512,1024,2048,4096,8192,16384,32768},
78 {256,256,256,256,512,1024,2048,4096,8192,16384,32768,65536},
79 {512,512,512,512,1024,2048,4096,8192,16384,32768,65536,131072},
80 {1024,1024,1024,1024,2048,4096,8192,16384,32768,65536,131072,262144},
81 {2048,2048,2048,2048,4096,8192,16384,32768,65536,131072,262144,524288},
82 {4096,4096,4096,4096,8192,16384,32768,65536,131072,262144,524288,1048576},
83 {8192,8192,8192,8192,16384,32768,65536,131072,262144,524288,1048576,2097152},
84 {16384,16384,16384,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304},
85 {32768,32768,32768,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608},
86 {65536,65536,65536,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216}
89 GLint mipmapTexSize8bpp
[12][12] = {
90 {32,64,96,128,160,192,256,384,640,1152,2176,4224},
91 {96,96,128,160,192,224,320,512,896,1664,3200,6272},
92 {224,224,224,256,288,320,480,832,1536,2944,5760,11392},
93 {480,480,480,480,512,544,832,1504,2880,5632,11136,22144},
94 {992,992,992,992,992,1024,1568,2880,5600,11072,22016,43904},
95 {2016,2016,2016,2016,2016,2016,3072,5664,11072,21984,43840,87552},
96 {4064,4064,4064,4064,4064,4064,6112,11264,22048,43840,87520,174912},
97 {8160,8160,8160,8160,8160,8160,12256,22496,44032,87584,174912,349664},
98 {16352,16352,16352,16352,16352,16352,24544,45024,88032,175104,349728,699200},
99 {32736,32736,32736,32736,32736,32736,49120,90080,176096,350176,699392,1398304},
100 {65504,65504,65504,65504,65504,65504,98272,180192,352224,700384,1398752,2796544},
101 {131040,131040,131040,131040,131040,131040,196576,360416,704480,1400800,2797536,5593056
105 GLint mipmapTexSize16bpp
[12][12] = {
106 {32,64,96,128,160,224,352,608,1120,2144,4192,8288},
107 {96,96,128,160,192,288,480,864,1632,3168,6240,12384},
108 {224,224,224,256,288,448,800,1504,2912,5728,11360,22624},
109 {480,480,480,480,512,800,1472,2848,5600,11104,22112,44128},
110 {992,992,992,992,992,1536,2848,5568,11040,21984,43872,87648},
111 {2016,2016,2016,2016,2016,3040,5632,11040,21952,43808,87520,174944},
112 {4064,4064,4064,4064,4064,6112,11232,22016,43808,87488,174880,349664},
113 {8160,8160,8160,8160,8160,12256,22496,44000,87552,174880,349632,699168},
114 {16352,16352,16352,16352,16352,24544,45024,88032,175072,349696,699168,1398208},
115 {32736,32736,32736,32736,32736,49120,90080,176096,350176,699360,1398272,2796320},
116 {65504,65504,65504,65504,65504,98272,180192,352224,700384,1398752,2796512,5592576},
117 {131040,131040,131040,131040,131040,196576,360416,704480,1400800,2797536,5593056,11185120}
120 GLint mipmapTexSize32bpp
[12][12] = {
121 {32,64,96,128,192,320,576,1088,2112,4160,8256,16448},
122 {96,96,128,160,256,448,832,1600,3136,6208,12352,24640},
123 {224,224,224,256,416,768,1472,2880,5696,11328,22592,45120},
124 {480,480,480,480,768,1440,2816,5568,11072,22080,44096,88128},
125 {992,992,992,992,1504,2816,5536,11008,21952,43840,87616,175168},
126 {2016,2016,2016,2016,3040,5600,11008,21920,43776,87488,174912,349760},
127 {4064,4064,4064,4064,6112,11232,21984,43776,87456,174848,349632,699200},
128 {8160,8160,8160,8160,12256,22496,44000,87520,174848,349600,699136,1398208},
129 {16352,16352,16352,16352,24544,45024,88032,175072,349664,699136,1398176,2796288},
130 {32736,32736,32736,32736,49120,90080,176096,350176,699360,1398240,2796288,5592480},
131 {65504,65504,65504,65504,98272,180192,352224,700384,1398752,2796512,5592544,11184896},
132 {131040,131040,131040,131040,196576,360416,704480,1400800,2797536,5593056,11185120,22369760}
135 static int logbase2(int n
)
157 static void viaSetTexImages(viaContextPtr vmesa
,
158 struct gl_texture_object
*tObj
)
161 viaTextureObjectPtr t
= (viaTextureObjectPtr
)tObj
->DriverData
;
162 const struct gl_texture_image
*baseImage
= tObj
->Image
[0][tObj
->BaseLevel
];
163 GLint firstLevel
, lastLevel
, numLevels
;
164 GLint log2Width
, log2Height
, log2Pitch
;
165 GLint (*texSize
)[12][12];
172 GLuint heightExp
= 0;
174 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
176 switch (baseImage
->TexFormat
->MesaFormat
) {
177 case MESA_FORMAT_ARGB8888
:
178 if (t
->image
[tObj
->BaseLevel
].internalFormat
== GL_RGB
)
179 texFormat
= HC_HTXnFM_ARGB0888
;
181 texFormat
= HC_HTXnFM_ARGB8888
;
183 case MESA_FORMAT_ARGB4444
:
184 texFormat
= HC_HTXnFM_ARGB4444
;
186 case MESA_FORMAT_RGB565
:
187 texFormat
= HC_HTXnFM_RGB565
;
189 case MESA_FORMAT_ARGB1555
:
190 texFormat
= HC_HTXnFM_ARGB1555
;
193 texFormat
= HC_HTXnFM_L8
;
196 texFormat
= HC_HTXnFM_T8
;
198 case MESA_FORMAT_CI8
:
199 texFormat
= HC_HTXnFM_Index8
;
201 case MESA_FORMAT_AL88
:
202 texFormat
= HC_HTXnFM_AL88
;
204 /*=* John Sheng [2003.7.18] texenv *=*/
206 texFormat
= HC_HTXnFM_A8
;
209 _mesa_problem(vmesa
->glCtx
, "Bad texture format in viaSetTexImages");
210 fprintf(stderr
, "-- TexFormat = %d\n",baseImage
->TexFormat
->MesaFormat
);
213 /* Compute which mipmap levels we really want to send to the hardware.
214 * This depends on the base image size, GL_TEXTURE_MIN_LOD,
215 * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
216 * Yes, this looks overly complicated, but it's all needed.
218 if (tObj
->MinFilter
== GL_LINEAR
|| tObj
->MinFilter
== GL_NEAREST
) {
219 firstLevel
= lastLevel
= tObj
->BaseLevel
;
222 firstLevel
= tObj
->BaseLevel
+ (GLint
)(tObj
->MinLod
+ 0.5);
223 firstLevel
= MAX2(firstLevel
, tObj
->BaseLevel
);
224 lastLevel
= tObj
->BaseLevel
+ (GLint
)(tObj
->MaxLod
+ 0.5);
225 lastLevel
= MAX2(lastLevel
, tObj
->BaseLevel
);
226 lastLevel
= MIN2(lastLevel
, tObj
->BaseLevel
+ baseImage
->MaxLog2
);
227 lastLevel
= MIN2(lastLevel
, tObj
->MaxLevel
);
228 lastLevel
= MAX2(firstLevel
, lastLevel
); /* need at least one level */
231 /* save these values */
232 t
->firstLevel
= firstLevel
;
233 t
->lastLevel
= lastLevel
;
235 numLevels
= lastLevel
- firstLevel
+ 1;
237 /*=* [DBG] fgfs : fix mipmap level 11 over hw limitations and result in segmentation fault *=*/
240 t
->lastLevel
= firstLevel
+ 9;
243 log2Width
= tObj
->Image
[0][firstLevel
]->WidthLog2
;
244 log2Height
= tObj
->Image
[0][firstLevel
]->HeightLog2
;
245 log2Pitch
= logbase2(tObj
->Image
[0][firstLevel
]->Width
* baseImage
->TexFormat
->TexelBytes
);
248 for (i
= 0; i
< numLevels
; i
++) {
249 t
->image
[i
].image
= tObj
->Image
[0][i
];
250 t
->image
[i
].internalFormat
= baseImage
->Format
;
253 if (baseImage
->TexFormat
->TexelBytes
== 1) {
255 texSize
= &mipmapTexSize8bpp
;
257 texSize
= &texSize8bpp
;
259 else if (baseImage
->TexFormat
->TexelBytes
== 2) {
261 texSize
= &mipmapTexSize16bpp
;
263 texSize
= &texSize16bpp
;
267 texSize
= &mipmapTexSize32bpp
;
269 texSize
= &texSize32bpp
;
271 t
->totalSize
= (*texSize
)[log2Height
][log2Width
];
272 t
->texMem
.size
= t
->totalSize
;
274 t
->dirty
= VIA_UPLOAD_TEX0
| VIA_UPLOAD_TEX1
;
277 fprintf(stderr
, "log2Width = %d\n", log2Width
);
278 fprintf(stderr
, "log2Height = %d\n", log2Height
);
279 fprintf(stderr
, "log2Pitch = %d\n", log2Pitch
);
280 fprintf(stderr
, "bytePerTexel = %d\n", baseImage
->TexFormat
->TexelBytes
);
281 fprintf(stderr
, "total size = %d\n", t
->totalSize
);
282 fprintf(stderr
, "actual level = %d\n", t
->actualLevel
);
283 fprintf(stderr
, "numlevel = %d\n", numLevels
);
290 for (i
= 0; i
< numLevels
; i
++) {
291 t
->image
[i
].offset
= t
->totalSize
- (*texSize
)[h
][w
];
297 viaUploadTexImages(vmesa
, t
);
301 t
->regTexFM
= (HC_SubA_HTXnFM
<< 24) | HC_HTXnLoc_AGP
| texFormat
;
303 t
->regTexFM
= (HC_SubA_HTXnFM
<< 24) | HC_HTXnLoc_Local
| texFormat
;
310 for (i
= 0; i
< numLevels
; i
++) {
311 if (i
== (numLevels
- 1))
314 mipmapSize
= (*texSize
)[h
][w
];
316 /*=* John Sheng [2003.5.31] agp tex *=*/
318 texBase
= (GLuint
)vmesa
->agpBase
+ t
->texMem
.offset
+ t
->image
[i
].offset
;
320 texBase
= t
->texMem
.offset
+ t
->image
[i
].offset
;
323 fprintf(stderr
, "texmem offset = %x\n", t
->texMem
.offset
);
324 fprintf(stderr
, "mipmap%d addr = %x\n", i
, t
->image
[i
].offset
);
325 fprintf(stderr
, "mipmap%d size = %d, h = %d, w = %d\n", i
, (*texSize
)[h
][w
], h
, w
);
326 fprintf(stderr
, "texBase%d = %x\n", i
, texBase
);
329 t
->regTexBaseAndPitch
[i
].baseL
= ((HC_SubA_HTXnL0BasL
+ i
) << 24) | (texBase
& 0xFFFFFF);
332 t
->regTexBaseAndPitch
[i
].pitchLog2
= ((HC_SubA_HTXnL0Pit
+ i
) << 24) |
336 t
->regTexBaseAndPitch
[i
].pitchLog2
= ((HC_SubA_HTXnL0Pit
+ i
) << 24) |
341 basH
|= ((texBase
& 0xFF000000) >> (k
<< 3));
343 t
->regTexBaseH
[j
] = ((j
+ HC_SubA_HTXnL012BasH
) << 24) | basH
;
349 widthExp
|= (((GLuint
)w
& 0xF) << (m
<< 2));
350 heightExp
|= (((GLuint
)h
& 0xF) << (m
<< 2));
352 t
->regTexWidthLog2
[l
] = ((l
+ HC_SubA_HTXnL0_5WE
) << 24 | widthExp
);
353 t
->regTexHeightLog2
[l
] = ((l
+ HC_SubA_HTXnL0_5HE
) << 24 | heightExp
);
363 t
->regTexBaseH
[j
] = ((j
+ HC_SubA_HTXnL012BasH
) << 24) | basH
;
366 t
->regTexWidthLog2
[l
] = ((l
+ HC_SubA_HTXnL0_5WE
) << 24 | widthExp
);
367 t
->regTexHeightLog2
[l
] = ((l
+ HC_SubA_HTXnL0_5HE
) << 24 | heightExp
);
371 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
375 /* ================================================================
376 * Texture combine functions
378 #define VIA_DISABLE 0
379 #define VIA_PASSTHRU 1
380 #define VIA_REPLACE 2
381 #define VIA_MODULATE 3
384 #define VIA_ALPHA_BLEND 6
386 #define VIA_MAX_COMBFUNC 8
388 static GLuint via_color_combine
[][VIA_MAX_COMBFUNC
] =
393 /* Disable combiner stage
417 /* GL_BLEND according to alpha
429 /* Disable combiner stage (Note: disables all subsequent stages)
453 /* GL_BLEND according to alpha
463 static GLuint via_alpha_combine
[][VIA_MAX_COMBFUNC
] =
468 /* Disable combiner stage
492 /* GL_BLEND according to alpha (same as above)
504 /* Disable combiner stage
528 /* GL_BLEND according to alpha (same as above)
538 static void viaUpdateTexEnv(GLcontext
*ctx
, GLuint unit
)
540 const struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
541 const struct gl_texture_object
*tObj
= texUnit
->_Current
;
542 const GLuint format
= tObj
->Image
[0][tObj
->BaseLevel
]->Format
;
543 GLuint color_combine
, alpha_combine
;
545 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
547 switch (texUnit
->EnvMode
) {
549 if (format
== GL_ALPHA
) {
550 color_combine
= via_color_combine
[unit
][VIA_PASSTHRU
];
551 alpha_combine
= via_alpha_combine
[unit
][VIA_REPLACE
];
553 else if (format
== GL_LUMINANCE
|| format
== GL_RGB
) {
554 color_combine
= via_color_combine
[unit
][VIA_REPLACE
];
555 alpha_combine
= via_alpha_combine
[unit
][VIA_PASSTHRU
];
558 color_combine
= via_color_combine
[unit
][VIA_REPLACE
];
559 alpha_combine
= via_alpha_combine
[unit
][VIA_REPLACE
];
564 if (format
== GL_ALPHA
) {
565 color_combine
= via_color_combine
[unit
][VIA_PASSTHRU
];
566 alpha_combine
= via_alpha_combine
[unit
][VIA_MODULATE
];
569 color_combine
= via_color_combine
[unit
][VIA_MODULATE
];
570 alpha_combine
= via_alpha_combine
[unit
][VIA_MODULATE
];
577 color_combine
= via_color_combine
[unit
][VIA_ALPHA_BLEND
];
578 alpha_combine
= via_alpha_combine
[unit
][VIA_PASSTHRU
];
581 color_combine
= via_color_combine
[unit
][VIA_REPLACE
];
582 alpha_combine
= via_alpha_combine
[unit
][VIA_PASSTHRU
];
586 case GL_LUMINANCE_ALPHA
:
588 color_combine
= via_color_combine
[unit
][VIA_PASSTHRU
];
589 alpha_combine
= via_alpha_combine
[unit
][VIA_PASSTHRU
];
601 color_combine
= via_color_combine
[unit
][VIA_BLEND
];
602 alpha_combine
= via_alpha_combine
[unit
][VIA_PASSTHRU
];
605 case GL_LUMINANCE_ALPHA
:
606 color_combine
= via_color_combine
[unit
][VIA_BLEND
];
607 alpha_combine
= via_alpha_combine
[unit
][VIA_MODULATE
];
610 color_combine
= via_color_combine
[unit
][VIA_PASSTHRU
];
611 alpha_combine
= via_alpha_combine
[unit
][VIA_MODULATE
];
614 color_combine
= via_color_combine
[unit
][VIA_BLEND
];
615 alpha_combine
= via_alpha_combine
[unit
][VIA_BLEND
];
627 color_combine
= via_color_combine
[unit
][VIA_ADD
];
628 alpha_combine
= via_alpha_combine
[unit
][VIA_PASSTHRU
];
631 case GL_LUMINANCE_ALPHA
:
632 color_combine
= via_color_combine
[unit
][VIA_ADD
];
633 alpha_combine
= via_alpha_combine
[unit
][VIA_MODULATE
];
636 color_combine
= via_color_combine
[unit
][VIA_PASSTHRU
];
637 alpha_combine
= via_alpha_combine
[unit
][VIA_MODULATE
];
640 color_combine
= via_color_combine
[unit
][VIA_ADD
];
641 alpha_combine
= via_alpha_combine
[unit
][VIA_ADD
];
653 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
657 static void viaUpdateTexUnit(GLcontext
*ctx
, GLuint unit
)
659 viaContextPtr vmesa
= VIA_CONTEXT(ctx
);
660 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
662 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
664 if (texUnit
->_ReallyEnabled
) {
665 struct gl_texture_object
*tObj
= texUnit
->_Current
;
666 viaTextureObjectPtr t
= (viaTextureObjectPtr
)tObj
->DriverData
;
668 /* Upload teximages (not pipelined)
670 if (t
->dirtyImages
) {
671 VIA_FIREVERTICES(vmesa
);
672 viaSetTexImages(vmesa
, tObj
);
674 FALLBACK(vmesa
, VIA_FALLBACK_TEXTURE
, GL_TRUE
);
679 if (tObj
->Image
[0][tObj
->BaseLevel
]->Border
> 0) {
680 FALLBACK(vmesa
, VIA_FALLBACK_TEXTURE
, GL_TRUE
);
684 /* Update state if this is a different texture object to last
687 if (vmesa
->CurrentTexObj
[unit
] != t
) {
688 VIA_STATECHANGE(vmesa
, (VIA_UPLOAD_TEX0
<< unit
));
689 vmesa
->CurrentTexObj
[unit
] = t
;
690 viaUpdateTexLRU(vmesa
, t
); /* done too often */
693 /* Update texture environment if texture object image format or
694 * texture environment state has changed.
696 if (tObj
->Image
[0][tObj
->BaseLevel
]->Format
!= vmesa
->TexEnvImageFmt
[unit
]) {
697 vmesa
->TexEnvImageFmt
[unit
] = tObj
->Image
[0][tObj
->BaseLevel
]->Format
;
698 viaUpdateTexEnv(ctx
, unit
);
702 vmesa
->CurrentTexObj
[unit
] = 0;
703 vmesa
->TexEnvImageFmt
[unit
] = 0;
704 vmesa
->dirty
&= ~(VIA_UPLOAD_TEX0
<< unit
);
705 VIA_STATECHANGE(vmesa
, VIA_UPLOAD_CTX
);
708 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
712 void viaUpdateTextureState(GLcontext
*ctx
)
714 viaContextPtr vmesa
= VIA_CONTEXT(ctx
);
716 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
718 FALLBACK(vmesa
, VIA_FALLBACK_TEXTURE
, GL_FALSE
);
719 viaUpdateTexUnit(ctx
, 0);
720 viaUpdateTexUnit(ctx
, 1);
722 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);