Merge branch 'master' into gallium-texture-transfer
[mesa.git] / src / mesa / drivers / dri / s3v / s3v_texstate.c
1 /*
2 * Author: Max Lingua <sunmax@libero.it>
3 */
4
5 #include <stdlib.h>
6 #include <stdio.h>
7
8 #include "main/glheader.h"
9 #include "main/macros.h"
10 #include "main/mtypes.h"
11 #include "main/simple_list.h"
12 #include "main/enums.h"
13
14 #include "main/mm.h"
15 #include "s3v_context.h"
16 #include "s3v_tex.h"
17
18
19 static void s3vSetTexImages( s3vContextPtr vmesa,
20 struct gl_texture_object *tObj )
21 {
22 GLuint height, width, pitch, i, /*textureFormat,*/ log_pitch;
23 s3vTextureObjectPtr t = (s3vTextureObjectPtr) tObj->DriverData;
24 const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
25 GLint firstLevel, lastLevel, numLevels;
26 GLint log2Width, log2Height;
27 #if TEX_DEBUG_ON
28 static unsigned int times=0;
29 DEBUG_TEX(("*** s3vSetTexImages: #%i ***\n", ++times));
30 #endif
31
32 t->texelBytes = 2; /* FIXME: always 2 ? */
33
34 /* Compute which mipmap levels we really want to send to the hardware.
35 * This depends on the base image size, GL_TEXTURE_MIN_LOD,
36 * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
37 * Yes, this looks overly complicated, but it's all needed.
38 */
39 if (tObj->MinFilter == GL_LINEAR || tObj->MinFilter == GL_NEAREST) {
40 firstLevel = lastLevel = tObj->BaseLevel;
41 }
42 else {
43 firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5);
44 firstLevel = MAX2(firstLevel, tObj->BaseLevel);
45 lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5);
46 lastLevel = MAX2(lastLevel, tObj->BaseLevel);
47 lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
48 lastLevel = MIN2(lastLevel, tObj->MaxLevel);
49 lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
50 }
51
52 /* save these values */
53 t->firstLevel = firstLevel;
54 t->lastLevel = lastLevel;
55
56 numLevels = lastLevel - firstLevel + 1;
57
58 log2Width = tObj->Image[0][firstLevel]->WidthLog2;
59 log2Height = tObj->Image[0][firstLevel]->HeightLog2;
60
61
62 /* Figure out the amount of memory required to hold all the mipmap
63 * levels. Choose the smallest pitch to accomodate the largest
64 * mipmap:
65 */
66 width = tObj->Image[0][firstLevel]->Width * t->texelBytes;
67 for (pitch = 32, log_pitch=2 ; pitch < width ; pitch *= 2 )
68 log_pitch++;
69
70 /* All images must be loaded at this pitch. Count the number of
71 * lines required:
72 */
73 for ( height = i = 0 ; i < numLevels ; i++ ) {
74 t->image[i].image = tObj->Image[0][firstLevel + i];
75 t->image[i].offset = height * pitch;
76 t->image[i].internalFormat = baseImage->_BaseFormat;
77 height += t->image[i].image->Height;
78 t->TextureBaseAddr[i] = (t->BufAddr + t->image[i].offset +
79 _TEXALIGN) & (GLuint)(~_TEXALIGN);
80 }
81
82 t->Pitch = pitch;
83 t->WidthLog2 = log2Width;
84 t->totalSize = height*pitch;
85 t->max_level = i-1;
86 vmesa->dirty |= S3V_UPLOAD_TEX0 /* | S3V_UPLOAD_TEX1*/;
87 vmesa->restore_primitive = -1;
88 DEBUG(("<><>pitch = TexStride = %i\n", pitch));
89 DEBUG(("log2Width = %i\n", log2Width));
90
91 s3vUploadTexImages( vmesa, t );
92 }
93
94 static void s3vUpdateTexEnv( GLcontext *ctx, GLuint unit )
95 {
96 s3vContextPtr vmesa = S3V_CONTEXT(ctx);
97 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
98 const struct gl_texture_object *tObj = texUnit->_Current;
99 const GLuint format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
100 /*
101 s3vTextureObjectPtr t = (s3vTextureObjectPtr)tObj->DriverData;
102 GLuint tc;
103 */
104 GLuint alpha = 0;
105 GLuint cmd = vmesa->CMD;
106 #if TEX_DEBUG_ON
107 static unsigned int times=0;
108 DEBUG_TEX(("*** s3vUpdateTexEnv: %i ***\n", ++times));
109 #endif
110
111 cmd &= ~TEX_COL_MASK;
112 cmd &= ~TEX_BLEND_MAKS;
113 /* cmd &= ~ALPHA_BLEND_MASK; */
114
115 DEBUG(("format = "));
116
117 switch (format) {
118 case GL_RGB:
119 DEBUG_TEX(("GL_RGB\n"));
120 cmd |= TEX_COL_ARGB1555;
121 break;
122 case GL_LUMINANCE:
123 DEBUG_TEX(("GL_LUMINANCE\n"));
124 cmd |= TEX_COL_ARGB4444;
125 alpha = 1; /* FIXME: check */
126 break;
127 case GL_ALPHA:
128 DEBUG_TEX(("GL_ALPHA\n"));
129 cmd |= TEX_COL_ARGB4444;
130 alpha = 1;
131 break;
132 case GL_LUMINANCE_ALPHA:
133 DEBUG_TEX(("GL_LUMINANCE_ALPHA\n"));
134 cmd |= TEX_COL_ARGB4444;
135 alpha = 1;
136 break;
137 case GL_INTENSITY:
138 DEBUG_TEX(("GL_INTENSITY\n"));
139 cmd |= TEX_COL_ARGB4444;
140 alpha = 1;
141 break;
142 case GL_RGBA:
143 DEBUG_TEX(("GL_RGBA\n"));
144 cmd |= TEX_COL_ARGB4444;
145 alpha = 1;
146 break;
147 case GL_COLOR_INDEX:
148 DEBUG_TEX(("GL_COLOR_INDEX\n"));
149 cmd |= TEX_COL_PAL;
150 break;
151 }
152
153 DEBUG_TEX(("EnvMode = "));
154
155 switch (texUnit->EnvMode) {
156 case GL_REPLACE:
157 DEBUG_TEX(("GL_REPLACE\n"));
158 cmd |= TEX_REFLECT; /* FIXME */
159 vmesa->_tri[1] = DO_TEX_UNLIT_TRI; /* FIXME: white tri hack */
160 vmesa->_alpha_tex = ALPHA_TEX /* * alpha */;
161 break;
162 case GL_MODULATE:
163 DEBUG_TEX(("GL_MODULATE\n"));
164 cmd |= TEX_MODULATE;
165 vmesa->_tri[1] = DO_TEX_LIT_TRI;
166 #if 0
167 if (alpha)
168 vmesa->_alpha_tex = ALPHA_TEX /* * alpha */;
169 else
170 vmesa->_alpha_tex = ALPHA_SRC /* * alpha */;
171 #else
172 vmesa->_alpha_tex = ALPHA_TEX ;
173 #endif
174 break;
175 case GL_ADD:
176 DEBUG_TEX(("DEBUG_TEX\n"));
177 /* do nothing ???*/
178 break;
179 case GL_DECAL:
180 DEBUG_TEX(("GL_DECAL\n"));
181 cmd |= TEX_DECAL;
182 vmesa->_tri[1] = DO_TEX_LIT_TRI;
183 vmesa->_alpha_tex = ALPHA_OFF;
184 break;
185 case GL_BLEND:
186 DEBUG_TEX(("GL_BLEND\n"));
187 cmd |= TEX_DECAL;
188 vmesa->_tri[1] = DO_TEX_LIT_TRI;
189 vmesa->_alpha_tex = ALPHA_OFF; /* FIXME: sure? */
190 break;
191 default:
192 fprintf(stderr, "unknown tex env mode");
193 return;
194 }
195
196 DEBUG_TEX(("\n\n vmesa->CMD was 0x%x\n", vmesa->CMD));
197 DEBUG_TEX(( " vmesa->CMD is 0x%x\n\n", cmd ));
198
199 vmesa->_alpha[1] = vmesa->_alpha_tex;
200 vmesa->CMD = cmd; /* | MIPMAP_LEVEL(8); */
201 vmesa->restore_primitive = -1;
202 }
203
204 static void s3vUpdateTexUnit( GLcontext *ctx, GLuint unit )
205 {
206 s3vContextPtr vmesa = S3V_CONTEXT(ctx);
207 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
208 GLuint cmd = vmesa->CMD;
209 #if TEX_DEBUG_ON
210 static unsigned int times=0;
211 DEBUG_TEX(("*** s3vUpdateTexUnit: %i ***\n", ++times));
212 DEBUG_TEX(("and vmesa->CMD was 0x%x\n", vmesa->CMD));
213 #endif
214
215 if (texUnit->_ReallyEnabled == TEXTURE_2D_BIT)
216 {
217 struct gl_texture_object *tObj = texUnit->_Current;
218 s3vTextureObjectPtr t = (s3vTextureObjectPtr)tObj->DriverData;
219
220 /* Upload teximages (not pipelined)
221 */
222 if (t->dirty_images) {
223 #if _TEXFLUSH
224 DMAFLUSH();
225 #endif
226 s3vSetTexImages( vmesa, tObj );
227 if (!t->MemBlock) {
228 #if _TEXFALLBACK
229 FALLBACK( vmesa, S3V_FALLBACK_TEXTURE, GL_TRUE );
230 #endif
231 return;
232 }
233 }
234
235 /* Update state if this is a different texture object to last
236 * time.
237 */
238 #if 1
239 if (vmesa->CurrentTexObj[unit] != t) {
240 vmesa->dirty |= S3V_UPLOAD_TEX0 /* << unit */;
241 vmesa->CurrentTexObj[unit] = t;
242 s3vUpdateTexLRU( vmesa, t ); /* done too often */
243 }
244 #endif
245
246 /* Update texture environment if texture object image format or
247 * texture environment state has changed.
248 */
249 if (tObj->Image[0][tObj->BaseLevel]->_BaseFormat !=
250 vmesa->TexEnvImageFmt[unit]) {
251 vmesa->TexEnvImageFmt[unit] = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
252 s3vUpdateTexEnv( ctx, unit );
253 }
254 #if 1
255 cmd = vmesa->CMD & ~MIP_MASK;
256 vmesa->dirty |= S3V_UPLOAD_TEX0 /* << unit */;
257 vmesa->CurrentTexObj[unit] = t;
258 vmesa->TexOffset = t->TextureBaseAddr[tObj->BaseLevel];
259 vmesa->TexStride = t->Pitch;
260 cmd |= MIPMAP_LEVEL(t->WidthLog2);
261
262 DEBUG_TEX(("\n\n>> vmesa->CMD was 0x%x\n", vmesa->CMD));
263 DEBUG_TEX(( ">> vmesa->CMD is 0x%x\n\n", cmd ));
264 DEBUG_TEX(("t->WidthLog2 = %i\n", t->WidthLog2));
265 DEBUG_TEX(("MIPMAP_LEVEL(t->WidthLog2) = 0x%x\n", MIPMAP_LEVEL(t->WidthLog2)));
266
267 vmesa->CMD = cmd;
268 vmesa->restore_primitive = -1;
269 #endif
270 }
271 else if (texUnit->_ReallyEnabled) { /* _ReallyEnabled but != TEXTURE0_2D */
272 #if _TEXFALLBACK
273 FALLBACK( vmesa, S3V_FALLBACK_TEXTURE, GL_TRUE );
274 #endif
275 }
276 else /*if (vmesa->CurrentTexObj[unit])*/ { /* !_ReallyEnabled */
277 vmesa->CurrentTexObj[unit] = 0;
278 vmesa->TexEnvImageFmt[unit] = 0;
279 vmesa->dirty &= ~(S3V_UPLOAD_TEX0<<unit);
280 }
281 }
282
283
284 void s3vUpdateTextureState( GLcontext *ctx )
285 {
286 s3vContextPtr vmesa = S3V_CONTEXT(ctx);
287 (void) vmesa;
288 #if TEX_DEBUG_ON
289 static unsigned int times=0;
290 DEBUG_TEX(("*** s3vUpdateTextureState: #%i ***\n", ++times));
291 #endif
292
293 #if _TEXFALLBACK
294 FALLBACK( vmesa, S3V_FALLBACK_TEXTURE, GL_FALSE );
295 #endif
296 s3vUpdateTexUnit( ctx, 0 );
297 #if 0
298 s3vUpdateTexUnit( ctx, 1 );
299 #endif
300 }