call _mesa_delete_texture_object() from in the driver's DeleteTexture function
[mesa.git] / src / mesa / drivers / dri / gamma / gamma_tex.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_tex.c,v 1.4 2002/11/05 17:46:07 tsi Exp $ */
2
3 #include <stdlib.h>
4 #include <stdio.h>
5
6 #include "glheader.h"
7 #include "mtypes.h"
8 #include "imports.h"
9 #include "simple_list.h"
10 #include "enums.h"
11 #include "texstore.h"
12 #include "teximage.h"
13 #include "texformat.h"
14 #include "swrast/swrast.h"
15
16 #include "mm.h"
17 #include "gamma_context.h"
18 #include "colormac.h"
19
20
21 /*
22 * Compute the 'S2.4' lod bias factor from the floating point OpenGL bias.
23 */
24 #if 0
25 static GLuint gammaComputeLodBias(GLfloat bias)
26 {
27 return bias;
28 }
29 #endif
30
31 static void gammaSetTexWrapping(gammaTextureObjectPtr t,
32 GLenum wraps, GLenum wrapt)
33 {
34 CARD32 t1 = t->TextureAddressMode;
35 CARD32 t2 = t->TextureReadMode;
36
37 t1 &= ~(TAM_SWrap_Mask | TAM_TWrap_Mask);
38 t2 &= ~(TRM_UWrap_Mask | TRM_VWrap_Mask);
39
40 if (wraps != GL_CLAMP) {
41 t1 |= TAM_SWrap_Repeat;
42 t2 |= TRM_UWrap_Repeat;
43 }
44
45 if (wrapt != GL_CLAMP) {
46 t1 |= TAM_TWrap_Repeat;
47 t2 |= TRM_VWrap_Repeat;
48 }
49
50 t->TextureAddressMode = t1;
51 t->TextureReadMode = t2;
52 }
53
54
55 static void gammaSetTexFilter(gammaContextPtr gmesa,
56 gammaTextureObjectPtr t,
57 GLenum minf, GLenum magf,
58 GLfloat bias)
59 {
60 CARD32 t1 = t->TextureAddressMode;
61 CARD32 t2 = t->TextureReadMode;
62
63 t2 &= ~(TRM_Mag_Mask | TRM_Min_Mask);
64
65 switch (minf) {
66 case GL_NEAREST:
67 t1 &= ~TAM_LODEnable;
68 t2 &= ~TRM_MipMapEnable;
69 t2 |= TRM_Min_Nearest;
70 break;
71 case GL_LINEAR:
72 t1 &= ~TAM_LODEnable;
73 t2 &= ~TRM_MipMapEnable;
74 t2 |= TRM_Min_Linear;
75 break;
76 case GL_NEAREST_MIPMAP_NEAREST:
77 t2 |= TRM_Min_NearestMMNearest;
78 break;
79 case GL_LINEAR_MIPMAP_NEAREST:
80 t2 |= TRM_Min_LinearMMNearest;
81 break;
82 case GL_NEAREST_MIPMAP_LINEAR:
83 t2 |= TRM_Min_NearestMMLinear;
84 break;
85 case GL_LINEAR_MIPMAP_LINEAR:
86 t2 |= TRM_Min_LinearMMLinear;
87 break;
88 default:
89 break;
90 }
91
92 switch (magf) {
93 case GL_NEAREST:
94 t2 |= TRM_Mag_Nearest;
95 break;
96 case GL_LINEAR:
97 t2 |= TRM_Mag_Linear;
98 break;
99 default:
100 break;
101 }
102
103 t->TextureAddressMode = t1;
104 t->TextureReadMode = t2;
105 }
106
107
108 static void gammaSetTexBorderColor(gammaContextPtr gmesa,
109 gammaTextureObjectPtr t,
110 GLubyte color[4])
111 {
112 t->TextureBorderColor = PACK_COLOR_8888(color[0], color[1], color[2], color[3]);
113 }
114
115
116 static void gammaTexParameter( GLcontext *ctx, GLenum target,
117 struct gl_texture_object *tObj,
118 GLenum pname, const GLfloat *params )
119 {
120 gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
121 gammaTextureObjectPtr t = (gammaTextureObjectPtr) tObj->DriverData;
122 if (!t)
123 return;
124
125 /* Can't do the update now as we don't know whether to flush
126 * vertices or not. Setting gmesa->new_state means that
127 * gammaUpdateTextureState() will be called before any triangles are
128 * rendered. If a statechange has occurred, it will be detected at
129 * that point, and buffered vertices flushed.
130 */
131 switch (pname) {
132 case GL_TEXTURE_MIN_FILTER:
133 case GL_TEXTURE_MAG_FILTER:
134 {
135 GLfloat bias = ctx->Texture.Unit[ctx->Texture.CurrentUnit].LodBias;
136 gammaSetTexFilter( gmesa, t, tObj->MinFilter, tObj->MagFilter, bias );
137 }
138 break;
139
140 case GL_TEXTURE_WRAP_S:
141 case GL_TEXTURE_WRAP_T:
142 gammaSetTexWrapping( t, tObj->WrapS, tObj->WrapT );
143 break;
144
145 case GL_TEXTURE_BORDER_COLOR:
146 gammaSetTexBorderColor( gmesa, t, tObj->_BorderChan );
147 break;
148
149 case GL_TEXTURE_BASE_LEVEL:
150 case GL_TEXTURE_MAX_LEVEL:
151 case GL_TEXTURE_MIN_LOD:
152 case GL_TEXTURE_MAX_LOD:
153 /* This isn't the most efficient solution but there doesn't appear to
154 * be a nice alternative for Radeon. Since there's no LOD clamping,
155 * we just have to rely on loading the right subset of mipmap levels
156 * to simulate a clamped LOD.
157 */
158 gammaSwapOutTexObj( gmesa, t );
159 break;
160
161 default:
162 return;
163 }
164
165 if (t == gmesa->CurrentTexObj[0])
166 gmesa->dirty |= GAMMA_UPLOAD_TEX0;
167
168 #if 0
169 if (t == gmesa->CurrentTexObj[1]) {
170 gmesa->dirty |= GAMMA_UPLOAD_TEX1;
171 }
172 #endif
173 }
174
175
176 static void gammaTexEnv( GLcontext *ctx, GLenum target,
177 GLenum pname, const GLfloat *param )
178 {
179 gammaContextPtr gmesa = GAMMA_CONTEXT( ctx );
180 GLuint unit = ctx->Texture.CurrentUnit;
181
182 /* Only one env color. Need a fallback if env colors are different
183 * and texture setup references env color in both units.
184 */
185 switch (pname) {
186 case GL_TEXTURE_ENV_COLOR: {
187 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
188 GLfloat *fc = texUnit->EnvColor;
189 GLuint r, g, b, a, col;
190 CLAMPED_FLOAT_TO_UBYTE(r, fc[0]);
191 CLAMPED_FLOAT_TO_UBYTE(g, fc[1]);
192 CLAMPED_FLOAT_TO_UBYTE(b, fc[2]);
193 CLAMPED_FLOAT_TO_UBYTE(a, fc[3]);
194
195 col = ((a << 24) |
196 (r << 16) |
197 (g << 8) |
198 (b << 0));
199
200 break;
201 }
202 case GL_TEXTURE_ENV_MODE:
203 gmesa->TexEnvImageFmt[unit] = 0; /* force recalc of env state */
204 break;
205
206 case GL_TEXTURE_LOD_BIAS_EXT:
207 #if 0 /* ?!?!?! */
208 {
209 struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
210 gammaTextureObjectPtr t = (gammaTextureObjectPtr) tObj->DriverData;
211 (void) t;
212 /* XXX Looks like there's something missing here */
213 }
214 #endif
215 break;
216
217 default:
218 break;
219 }
220 }
221
222 #if 0
223 static void gammaTexImage1D( GLcontext *ctx, GLenum target, GLint level,
224 GLint internalFormat,
225 GLint width, GLint border,
226 GLenum format, GLenum type,
227 const GLvoid *pixels,
228 const struct gl_pixelstore_attrib *pack,
229 struct gl_texture_object *texObj,
230 struct gl_texture_image *texImage )
231 {
232 gammaTextureObjectPtr t = (gammaTextureObjectPtr) texObj->DriverData;
233 if (t) {
234 gammaSwapOutTexObj( GAMMA_CONTEXT(ctx), t );
235 }
236 _mesa_store_teximage1d( ctx, target, level, internalFormat,
237 width, border, format, type,
238 pixels, pack, texObj, texImage );
239 }
240 #endif
241
242 #if 0
243 static void gammaTexSubImage1D( GLcontext *ctx,
244 GLenum target,
245 GLint level,
246 GLint xoffset,
247 GLsizei width,
248 GLenum format, GLenum type,
249 const GLvoid *pixels,
250 const struct gl_pixelstore_attrib *pack,
251 struct gl_texture_object *texObj,
252 struct gl_texture_image *texImage )
253 {
254 gammaTextureObjectPtr t = (gammaTextureObjectPtr) texObj->DriverData;
255 if (t) {
256 gammaSwapOutTexObj( GAMMA_CONTEXT(ctx), t );
257 }
258 _mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
259 format, type, pixels, pack, texObj,
260 texImage);
261 }
262 #endif
263
264 static void gammaTexImage2D( GLcontext *ctx, GLenum target, GLint level,
265 GLint internalFormat,
266 GLint width, GLint height, GLint border,
267 GLenum format, GLenum type, const GLvoid *pixels,
268 const struct gl_pixelstore_attrib *packing,
269 struct gl_texture_object *texObj,
270 struct gl_texture_image *texImage )
271 {
272 gammaTextureObjectPtr t = (gammaTextureObjectPtr) texObj->DriverData;
273 if (t) {
274 gammaSwapOutTexObj( GAMMA_CONTEXT(ctx), t );
275 }
276 _mesa_store_teximage2d( ctx, target, level, internalFormat,
277 width, height, border, format, type,
278 pixels, packing, texObj, texImage );
279 }
280
281 static void gammaTexSubImage2D( GLcontext *ctx,
282 GLenum target,
283 GLint level,
284 GLint xoffset, GLint yoffset,
285 GLsizei width, GLsizei height,
286 GLenum format, GLenum type,
287 const GLvoid *pixels,
288 const struct gl_pixelstore_attrib *packing,
289 struct gl_texture_object *texObj,
290 struct gl_texture_image *texImage )
291 {
292 gammaTextureObjectPtr t = (gammaTextureObjectPtr) texObj->DriverData;
293 if (t) {
294 gammaSwapOutTexObj( GAMMA_CONTEXT(ctx), t );
295 }
296 _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
297 height, format, type, pixels, packing, texObj,
298 texImage);
299 }
300
301
302 static void gammaBindTexture( GLcontext *ctx, GLenum target,
303 struct gl_texture_object *tObj )
304 {
305 gammaContextPtr gmesa = GAMMA_CONTEXT( ctx );
306 gammaTextureObjectPtr t = (gammaTextureObjectPtr) tObj->DriverData;
307
308 if (!t) {
309 GLfloat bias = ctx->Texture.Unit[ctx->Texture.CurrentUnit].LodBias;
310 t = CALLOC_STRUCT(gamma_texture_object_t);
311
312 /* Initialize non-image-dependent parts of the state:
313 */
314 t->globj = tObj;
315
316 t->TextureAddressMode = TextureAddressModeEnable | TAM_Operation_3D |
317 TAM_DY_Enable | TAM_LODEnable;
318 t->TextureReadMode = TextureReadModeEnable | TRM_PrimaryCacheEnable |
319 TRM_MipMapEnable | TRM_BorderClamp | TRM_Border;
320 t->TextureColorMode = TextureColorModeEnable;
321 t->TextureFilterMode = TextureFilterModeEnable;
322
323 if (target == GL_TEXTURE_2D) {
324 t->TextureAddressMode |= TAM_TexMapType_2D;
325 t->TextureReadMode |= TRM_TexMapType_2D;
326 } else
327 if (target == GL_TEXTURE_1D) {
328 t->TextureAddressMode |= TAM_TexMapType_1D;
329 t->TextureReadMode |= TRM_TexMapType_1D;
330 }
331
332 t->TextureColorMode = TextureColorModeEnable;
333
334 t->TextureFilterMode = TextureFilterModeEnable;
335
336 #ifdef MESA_LITTLE_ENDIAN
337 t->TextureFormat = (TF_LittleEndian |
338 #else
339 t->TextureFormat = (TF_BigEndian |
340 #endif
341 TF_ColorOrder_RGB |
342 TF_OutputFmt_Texel);
343
344 t->dirty_images = ~0;
345
346 tObj->DriverData = t;
347 make_empty_list( t );
348
349 gammaSetTexWrapping( t, tObj->WrapS, tObj->WrapT );
350 gammaSetTexFilter( gmesa, t, tObj->MinFilter, tObj->MagFilter, bias );
351 gammaSetTexBorderColor( gmesa, t, tObj->_BorderChan );
352 }
353 }
354
355
356 static void gammaDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
357 {
358 gammaTextureObjectPtr t = (gammaTextureObjectPtr)tObj->DriverData;
359
360 if (t) {
361 gammaContextPtr gmesa = GAMMA_CONTEXT( ctx );
362 #if 0
363 if (gmesa)
364 GAMMA_FIREVERTICES( gmesa );
365 #endif
366 gammaDestroyTexObj( gmesa, t );
367 tObj->DriverData = 0;
368 }
369 /* Free mipmap images and the texture object itself */
370 _mesa_delete_texture_object(ctx, tObj);
371 }
372
373 static GLboolean gammaIsTextureResident( GLcontext *ctx,
374 struct gl_texture_object *tObj )
375 {
376 gammaTextureObjectPtr t = (gammaTextureObjectPtr)tObj->DriverData;
377 return t && t->MemBlock;
378 }
379
380 static void gammaInitTextureObjects( GLcontext *ctx )
381 {
382 struct gl_texture_object *texObj;
383 GLuint tmp = ctx->Texture.CurrentUnit;
384
385 ctx->Texture.CurrentUnit = 0;
386
387 texObj = ctx->Texture.Unit[0].Current1D;
388 gammaBindTexture( ctx, GL_TEXTURE_1D, texObj );
389
390 texObj = ctx->Texture.Unit[0].Current2D;
391 gammaBindTexture( ctx, GL_TEXTURE_2D, texObj );
392
393 #if 0
394 ctx->Texture.CurrentUnit = 1;
395
396 texObj = ctx->Texture.Unit[1].Current1D;
397 gammaBindTexture( ctx, GL_TEXTURE_1D, texObj );
398
399 texObj = ctx->Texture.Unit[1].Current2D;
400 gammaBindTexture( ctx, GL_TEXTURE_2D, texObj );
401 #endif
402
403 ctx->Texture.CurrentUnit = tmp;
404 }
405
406
407 void gammaDDInitTextureFuncs( GLcontext *ctx )
408 {
409 ctx->Driver.TexEnv = gammaTexEnv;
410 ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
411 ctx->Driver.TexImage1D = _mesa_store_teximage1d;
412 ctx->Driver.TexImage2D = gammaTexImage2D;
413 ctx->Driver.TexImage3D = _mesa_store_teximage3d;
414 ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
415 ctx->Driver.TexSubImage2D = gammaTexSubImage2D;
416 ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
417 ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
418 ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
419 ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
420 ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
421 ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
422 ctx->Driver.BindTexture = gammaBindTexture;
423 ctx->Driver.DeleteTexture = gammaDeleteTexture;
424 ctx->Driver.TexParameter = gammaTexParameter;
425 ctx->Driver.UpdateTexturePalette = 0;
426 ctx->Driver.IsTextureResident = gammaIsTextureResident;
427 ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
428
429 gammaInitTextureObjects( ctx );
430 }