(Stephane Marchesin, me) add hyperz support to radeon and r200 drivers. Only fast...
[mesa.git] / src / mesa / drivers / dri / i830 / i830_tex.c
1 /**************************************************************************
2
3 Copyright 2001 2d3d Inc., Delray Beach, FL
4
5 All Rights Reserved.
6
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the "Software"),
9 to deal in the Software without restriction, including without limitation
10 on the rights to use, copy, modify, merge, publish, distribute, sub
11 license, and/or sell copies of the Software, and to permit persons to whom
12 the Software is furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice (including the next
15 paragraph) shall be included in all copies or substantial portions of the
16 Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **************************************************************************/
27
28 /* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_tex.c,v 1.5 2003/05/07 21:56:31 dawes Exp $ */
29
30 /*
31 * Author:
32 * Jeff Hartmann <jhartmann@2d3d.com>
33 *
34 * Heavily based on the I810 driver, which was written by:
35 * Keith Whitwell <keithw@tungstengraphics.com>
36 */
37
38 #include "glheader.h"
39 #include "mtypes.h"
40 #include "imports.h"
41 #include "simple_list.h"
42 #include "enums.h"
43 #include "texstore.h"
44 #include "teximage.h"
45 #include "texformat.h"
46 #include "texmem.h"
47 #include "texobj.h"
48 #include "swrast/swrast.h"
49 #include "texobj.h"
50 #include "mm.h"
51
52 #include "i830_screen.h"
53 #include "i830_dri.h"
54 #include "i830_context.h"
55 #include "i830_tex.h"
56 #include "i830_state.h"
57 #include "i830_ioctl.h"
58
59 /*
60 * Compute the 'S2.4' lod bias factor from the floating point OpenGL bias.
61 */
62 static void i830ComputeLodBias( i830ContextPtr imesa, unsigned unit,
63 GLfloat bias )
64 {
65 int b;
66
67 b = (int) (bias * 16.0);
68 if(b > 63) b = 63;
69 else if (b < -64) b = -64;
70 imesa->LodBias[ unit ] = ((b << TM0S3_LOD_BIAS_SHIFT) &
71 TM0S3_LOD_BIAS_MASK);
72 }
73
74
75 /**
76 * Set the texture wrap modes.
77 *
78 * The i830M (and related graphics cores) do not support GL_CLAMP. The Intel
79 * drivers for "other operating systems" implement GL_CLAMP as
80 * GL_CLAMP_TO_EDGE, so the same is done here.
81 *
82 * \param t Texture object whose wrap modes are to be set
83 * \param swrap Wrap mode for the \a s texture coordinate
84 * \param twrap Wrap mode for the \a t texture coordinate
85 */
86
87 static void i830SetTexWrapping(i830TextureObjectPtr tex,
88 GLenum swrap, GLenum twrap)
89 {
90 tex->Setup[I830_TEXREG_MCS] &= ~(TEXCOORD_ADDR_U_MASK|TEXCOORD_ADDR_V_MASK);
91
92 switch( swrap ) {
93 case GL_REPEAT:
94 tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP);
95 break;
96 case GL_CLAMP:
97 case GL_CLAMP_TO_EDGE:
98 tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP);
99 break;
100 case GL_CLAMP_TO_BORDER:
101 tex->Setup[I830_TEXREG_MCS] |=
102 TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP_BORDER);
103 break;
104 case GL_MIRRORED_REPEAT:
105 tex->Setup[I830_TEXREG_MCS] |=
106 TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_MIRROR);
107 break;
108 default:
109 _mesa_problem(NULL, "bad S wrap mode in %s", __FUNCTION__);
110 }
111
112 switch( twrap ) {
113 case GL_REPEAT:
114 tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP);
115 break;
116 case GL_CLAMP:
117 case GL_CLAMP_TO_EDGE:
118 tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP);
119 break;
120 case GL_CLAMP_TO_BORDER:
121 tex->Setup[I830_TEXREG_MCS] |=
122 TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP_BORDER);
123 break;
124 case GL_MIRRORED_REPEAT:
125 tex->Setup[I830_TEXREG_MCS] |=
126 TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_MIRROR);
127 break;
128 default:
129 _mesa_problem(NULL, "bad T wrap mode in %s", __FUNCTION__);
130 }
131 }
132
133 static void i830SetTexMaxAnisotropy( i830TextureObjectPtr t, GLfloat max )
134 {
135 t->max_anisotropy = max;
136 }
137
138
139 /**
140 * Set the texture magnification and minification modes.
141 *
142 * \param t Texture whose filter modes are to be set
143 * \param minf Texture minification mode
144 * \param magf Texture magnification mode
145 * \param bias LOD bias for this texture unit.
146 */
147
148 static void i830SetTexFilter( i830TextureObjectPtr t,
149 GLenum minf, GLenum magf )
150 {
151 int minFilt = 0, mipFilt = 0, magFilt = 0;
152
153 if(I830_DEBUG&DEBUG_DRI)
154 fprintf(stderr, "%s\n", __FUNCTION__);
155
156 if ( t->max_anisotropy > 1.0 ) {
157 minFilt = FILTER_ANISOTROPIC;
158 magFilt = FILTER_ANISOTROPIC;
159 }
160 else {
161 switch (minf) {
162 case GL_NEAREST:
163 minFilt = FILTER_NEAREST;
164 mipFilt = MIPFILTER_NONE;
165 break;
166 case GL_LINEAR:
167 minFilt = FILTER_LINEAR;
168 mipFilt = MIPFILTER_NONE;
169 break;
170 case GL_NEAREST_MIPMAP_NEAREST:
171 minFilt = FILTER_NEAREST;
172 mipFilt = MIPFILTER_NEAREST;
173 break;
174 case GL_LINEAR_MIPMAP_NEAREST:
175 minFilt = FILTER_LINEAR;
176 mipFilt = MIPFILTER_NEAREST;
177 break;
178 case GL_NEAREST_MIPMAP_LINEAR:
179 minFilt = FILTER_NEAREST;
180 mipFilt = MIPFILTER_LINEAR;
181 break;
182 case GL_LINEAR_MIPMAP_LINEAR:
183 minFilt = FILTER_LINEAR;
184 mipFilt = MIPFILTER_LINEAR;
185 break;
186 default:
187 _mesa_problem(NULL, "%s: Unsupported min. filter %d", __FUNCTION__,
188 (int) minf );
189 break;
190 }
191
192 switch (magf) {
193 case GL_NEAREST:
194 magFilt = FILTER_NEAREST;
195 break;
196 case GL_LINEAR:
197 magFilt = FILTER_LINEAR;
198 break;
199 default:
200 _mesa_problem(NULL, "%s: Unsupported mag. filter %d", __FUNCTION__,
201 (int) magf );
202 break;
203 }
204 }
205
206 t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_FILTER_MASK;
207 t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIP_FILTER_MASK;
208 t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAG_FILTER_MASK;
209 t->Setup[I830_TEXREG_TM0S3] |= ((minFilt << TM0S3_MIN_FILTER_SHIFT) |
210 (mipFilt << TM0S3_MIP_FILTER_SHIFT) |
211 (magFilt << TM0S3_MAG_FILTER_SHIFT));
212 }
213
214 static void i830SetTexBorderColor(i830TextureObjectPtr t, GLubyte color[4])
215 {
216 if(I830_DEBUG&DEBUG_DRI)
217 fprintf(stderr, "%s\n", __FUNCTION__);
218
219 t->Setup[I830_TEXREG_TM0S4] =
220 I830PACKCOLOR8888(color[0],color[1],color[2],color[3]);
221 }
222
223
224 /**
225 * Allocate space for and load the mesa images into the texture memory block.
226 * This will happen before drawing with a new texture, or drawing with a
227 * texture after it was swapped out or teximaged again.
228 */
229
230 static i830TextureObjectPtr i830AllocTexObj( struct gl_texture_object *texObj )
231 {
232 i830TextureObjectPtr t;
233
234 t = CALLOC_STRUCT( i830_texture_object_t );
235 texObj->DriverData = t;
236 if ( t != NULL ) {
237 /* Initialize non-image-dependent parts of the state:
238 */
239 t->base.tObj = texObj;
240
241 t->Setup[I830_TEXREG_TM0LI] = STATE3D_LOAD_STATE_IMMEDIATE_2;
242 t->Setup[I830_TEXREG_TM0S0] = TM0S0_USE_FENCE;
243 t->Setup[I830_TEXREG_TM0S1] = 0;
244 t->Setup[I830_TEXREG_TM0S2] = 0;
245 t->Setup[I830_TEXREG_TM0S3] = 0;
246
247 t->Setup[I830_TEXREG_NOP0] = 0;
248 t->Setup[I830_TEXREG_NOP1] = 0;
249 t->Setup[I830_TEXREG_NOP2] = 0;
250
251 t->Setup[I830_TEXREG_MCS] = (STATE3D_MAP_COORD_SET_CMD |
252 MAP_UNIT(0) |
253 ENABLE_TEXCOORD_PARAMS |
254 TEXCOORDS_ARE_NORMAL |
255 TEXCOORDTYPE_CARTESIAN |
256 ENABLE_ADDR_V_CNTL |
257 TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) |
258 ENABLE_ADDR_U_CNTL |
259 TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP));
260
261 make_empty_list( & t->base );
262
263 i830SetTexWrapping( t, texObj->WrapS, texObj->WrapT );
264 i830SetTexMaxAnisotropy( t, texObj->MaxAnisotropy );
265 i830SetTexFilter( t, texObj->MinFilter, texObj->MagFilter );
266 i830SetTexBorderColor( t, texObj->_BorderChan );
267 }
268
269 return t;
270 }
271
272
273 static void i830TexParameter( GLcontext *ctx, GLenum target,
274 struct gl_texture_object *tObj,
275 GLenum pname, const GLfloat *params )
276 {
277 i830ContextPtr imesa = I830_CONTEXT(ctx);
278 i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData;
279 GLuint unit = ctx->Texture.CurrentUnit;
280
281 if (!t)
282 return;
283
284 if ( target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE_NV )
285 return;
286
287 /* Can't do the update now as we don't know whether to flush
288 * vertices or not. Setting imesa->NewGLState means that
289 * i830UpdateTextureState() will be called before any triangles are
290 * rendered. If a statechange has occurred, it will be detected at
291 * that point, and buffered vertices flushed.
292 */
293 switch (pname) {
294 case GL_TEXTURE_MIN_FILTER:
295 case GL_TEXTURE_MAG_FILTER:
296 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
297 i830SetTexMaxAnisotropy( t, tObj->MaxAnisotropy );
298 i830SetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
299 break;
300
301 case GL_TEXTURE_WRAP_S:
302 case GL_TEXTURE_WRAP_T:
303 i830SetTexWrapping( t, tObj->WrapS, tObj->WrapT );
304 break;
305
306 case GL_TEXTURE_BORDER_COLOR:
307 i830SetTexBorderColor( t, tObj->_BorderChan );
308 break;
309
310 case GL_TEXTURE_BASE_LEVEL:
311 case GL_TEXTURE_MAX_LEVEL:
312 case GL_TEXTURE_MIN_LOD:
313 case GL_TEXTURE_MAX_LOD:
314 /* The i830 and its successors can do a lot of this without
315 * reloading the textures. A project for someone?
316 */
317 I830_FIREVERTICES( I830_CONTEXT(ctx) );
318 driSwapOutTextureObject( (driTextureObject *) t );
319 break;
320
321 default:
322 return;
323 }
324
325 if (t == imesa->CurrentTexObj[unit]) {
326 I830_STATECHANGE( imesa, I830_UPLOAD_TEX0 );
327 }
328 }
329
330
331 static void i830TexEnv( GLcontext *ctx, GLenum target,
332 GLenum pname, const GLfloat *param )
333 {
334 i830ContextPtr imesa = I830_CONTEXT( ctx );
335 GLuint unit = ctx->Texture.CurrentUnit;
336
337 /* Only one env color. Need a fallback if env colors are different
338 * and texture setup references env color in both units.
339 */
340 switch (pname) {
341 case GL_TEXTURE_ENV_COLOR:
342 case GL_TEXTURE_ENV_MODE:
343 case GL_COMBINE_RGB_EXT:
344 case GL_COMBINE_ALPHA_EXT:
345 case GL_SOURCE0_RGB_EXT:
346 case GL_SOURCE1_RGB_EXT:
347 case GL_SOURCE2_RGB_EXT:
348 case GL_SOURCE0_ALPHA_EXT:
349 case GL_SOURCE1_ALPHA_EXT:
350 case GL_SOURCE2_ALPHA_EXT:
351 case GL_OPERAND0_RGB_EXT:
352 case GL_OPERAND1_RGB_EXT:
353 case GL_OPERAND2_RGB_EXT:
354 case GL_OPERAND0_ALPHA_EXT:
355 case GL_OPERAND1_ALPHA_EXT:
356 case GL_OPERAND2_ALPHA_EXT:
357 case GL_RGB_SCALE_EXT:
358 case GL_ALPHA_SCALE:
359 imesa->TexEnvImageFmt[unit] = 0; /* force recalc of env state */
360 break;
361
362 case GL_TEXTURE_LOD_BIAS_EXT:
363 i830ComputeLodBias( imesa, unit, *param );
364 I830_STATECHANGE( imesa, I830_UPLOAD_TEX_N(unit) );
365 break;
366
367 default:
368 break;
369 }
370 }
371
372 static void i830TexImage2D( GLcontext *ctx, GLenum target, GLint level,
373 GLint internalFormat,
374 GLint width, GLint height, GLint border,
375 GLenum format, GLenum type, const GLvoid *pixels,
376 const struct gl_pixelstore_attrib *packing,
377 struct gl_texture_object *texObj,
378 struct gl_texture_image *texImage )
379 {
380 driTextureObject * t = (driTextureObject *) texObj->DriverData;
381 if (t) {
382 I830_FIREVERTICES( I830_CONTEXT(ctx) );
383 driSwapOutTextureObject( t );
384 }
385 else {
386 t = (driTextureObject *) i830AllocTexObj( texObj );
387 if (!t) {
388 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
389 return;
390 }
391 }
392
393 _mesa_store_teximage2d( ctx, target, level, internalFormat,
394 width, height, border, format, type,
395 pixels, packing, texObj, texImage );
396 }
397
398 static void i830TexSubImage2D( GLcontext *ctx,
399 GLenum target,
400 GLint level,
401 GLint xoffset, GLint yoffset,
402 GLsizei width, GLsizei height,
403 GLenum format, GLenum type,
404 const GLvoid *pixels,
405 const struct gl_pixelstore_attrib *packing,
406 struct gl_texture_object *texObj,
407 struct gl_texture_image *texImage )
408 {
409 driTextureObject * t = (driTextureObject *) texObj->DriverData;
410 if (t) {
411 I830_FIREVERTICES( I830_CONTEXT(ctx) );
412 driSwapOutTextureObject( t );
413 }
414 _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
415 height, format, type, pixels, packing, texObj,
416 texImage);
417
418 }
419
420
421
422 static void i830CompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
423 GLint internalFormat,
424 GLint width, GLint height, GLint border,
425 GLsizei imageSize, const GLvoid *data,
426 struct gl_texture_object *texObj,
427 struct gl_texture_image *texImage )
428 {
429 driTextureObject * t = (driTextureObject *) texObj->DriverData;
430 GLuint face;
431
432 /* which cube face or ordinary 2D image */
433 switch (target) {
434 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
435 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
436 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
437 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
438 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
439 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
440 face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
441 ASSERT(face < 6);
442 break;
443 default:
444 face = 0;
445 }
446
447 if ( t != NULL ) {
448 driSwapOutTextureObject( t );
449 }
450 else {
451 t = (driTextureObject *) i830AllocTexObj( texObj );
452 if (!t) {
453 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
454 return;
455 }
456 }
457
458 texImage->IsClientData = GL_FALSE;
459
460 if (I830_DEBUG & DEBUG_TEXTURE)
461 fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__);
462
463 _mesa_store_compressed_teximage2d(ctx, target, level, internalFormat, width,
464 height, border, imageSize, data, texObj, texImage);
465
466 t->dirty_images[face] |= (1 << level);
467 }
468
469
470 static void i830CompressedTexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
471 GLint xoffset, GLint yoffset,
472 GLsizei width, GLsizei height,
473 GLenum format,
474 GLsizei imageSize, const GLvoid *data,
475 struct gl_texture_object *texObj,
476 struct gl_texture_image *texImage )
477 {
478 driTextureObject * t = (driTextureObject *) texObj->DriverData;
479 GLuint face;
480
481
482 /* which cube face or ordinary 2D image */
483 switch (target) {
484 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
485 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
486 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
487 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
488 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
489 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
490 face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
491 ASSERT(face < 6);
492 break;
493 default:
494 face = 0;
495 }
496
497 assert( t ); /* this _should_ be true */
498 if ( t ) {
499 driSwapOutTextureObject( t );
500 }
501 else {
502 t = (driTextureObject *) i830AllocTexObj( texObj );
503 if (!t) {
504 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2D");
505 return;
506 }
507 }
508
509 _mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
510 height, format, imageSize, data, texObj, texImage);
511
512 t->dirty_images[face] |= (1 << level);
513 }
514
515
516 static void i830BindTexture( GLcontext *ctx, GLenum target,
517 struct gl_texture_object *tObj )
518 {
519 assert( (target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE_NV) ||
520 (tObj->DriverData != NULL) );
521 }
522
523
524 static void i830DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
525 {
526 driTextureObject * t = (driTextureObject *) tObj->DriverData;
527 if ( t != NULL ) {
528 i830ContextPtr imesa = I830_CONTEXT( ctx );
529
530 if ( imesa ) {
531 I830_FIREVERTICES( imesa );
532 }
533
534 driDestroyTextureObject( t );
535 }
536 /* Free mipmap images and the texture object itself */
537 _mesa_delete_texture_object(ctx, tObj);
538 }
539
540
541 static const struct gl_texture_format *
542 i830ChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
543 GLenum format, GLenum type )
544 {
545 i830ContextPtr imesa = I830_CONTEXT( ctx );
546 const GLboolean do32bpt = ( imesa->i830Screen->cpp == 4 &&
547 imesa->i830Screen->textureSize > 4*1024*1024);
548
549 switch ( internalFormat ) {
550 case 4:
551 case GL_RGBA:
552 case GL_COMPRESSED_RGBA:
553 if ( format == GL_BGRA ) {
554 if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
555 return &_mesa_texformat_argb8888;
556 }
557 else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
558 return &_mesa_texformat_argb4444;
559 }
560 else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
561 return &_mesa_texformat_argb1555;
562 }
563 }
564 return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
565
566 case 3:
567 case GL_RGB:
568 case GL_COMPRESSED_RGB:
569 if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
570 return &_mesa_texformat_rgb565;
571 }
572 return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
573
574 case GL_RGBA8:
575 case GL_RGB10_A2:
576 case GL_RGBA12:
577 case GL_RGBA16:
578 return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
579
580 case GL_RGBA4:
581 case GL_RGBA2:
582 return &_mesa_texformat_argb4444;
583
584 case GL_RGB5_A1:
585 return &_mesa_texformat_argb1555;
586
587 case GL_RGB8:
588 case GL_RGB10:
589 case GL_RGB12:
590 case GL_RGB16:
591 return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
592
593 case GL_RGB5:
594 case GL_RGB4:
595 case GL_R3_G3_B2:
596 return &_mesa_texformat_rgb565;
597
598 case GL_ALPHA:
599 case GL_ALPHA4:
600 case GL_ALPHA8:
601 case GL_ALPHA12:
602 case GL_ALPHA16:
603 case GL_COMPRESSED_ALPHA:
604 return &_mesa_texformat_al88;
605
606 case 1:
607 case GL_LUMINANCE:
608 case GL_LUMINANCE4:
609 case GL_LUMINANCE8:
610 case GL_LUMINANCE12:
611 case GL_LUMINANCE16:
612 case GL_COMPRESSED_LUMINANCE:
613 return &_mesa_texformat_l8;
614
615 case 2:
616 case GL_LUMINANCE_ALPHA:
617 case GL_LUMINANCE4_ALPHA4:
618 case GL_LUMINANCE6_ALPHA2:
619 case GL_LUMINANCE8_ALPHA8:
620 case GL_LUMINANCE12_ALPHA4:
621 case GL_LUMINANCE12_ALPHA12:
622 case GL_LUMINANCE16_ALPHA16:
623 case GL_COMPRESSED_LUMINANCE_ALPHA:
624 return &_mesa_texformat_al88;
625
626 case GL_INTENSITY:
627 case GL_INTENSITY4:
628 case GL_INTENSITY8:
629 case GL_INTENSITY12:
630 case GL_INTENSITY16:
631 case GL_COMPRESSED_INTENSITY:
632 return &_mesa_texformat_i8;
633
634 case GL_YCBCR_MESA:
635 if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
636 type == GL_UNSIGNED_BYTE)
637 return &_mesa_texformat_ycbcr;
638 else
639 return &_mesa_texformat_ycbcr_rev;
640
641 case GL_COMPRESSED_RGB_FXT1_3DFX:
642 return &_mesa_texformat_rgb_fxt1;
643 case GL_COMPRESSED_RGBA_FXT1_3DFX:
644 return &_mesa_texformat_rgba_fxt1;
645
646 case GL_RGB_S3TC:
647 case GL_RGB4_S3TC:
648 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
649 return &_mesa_texformat_rgb_dxt1;
650
651 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
652 return &_mesa_texformat_rgba_dxt1;
653
654 case GL_RGBA_S3TC:
655 case GL_RGBA4_S3TC:
656 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
657 return &_mesa_texformat_rgba_dxt3;
658
659 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
660 return &_mesa_texformat_rgba_dxt5;
661
662 default:
663 fprintf(stderr, "unexpected texture format in %s\n", __FUNCTION__);
664 return NULL;
665 }
666
667 return NULL; /* never get here */
668 }
669
670 /**
671 * Allocate a new texture object.
672 * Called via ctx->Driver.NewTextureObject.
673 * Note: this function will be called during context creation to
674 * allocate the default texture objects.
675 * Note: we could use containment here to 'derive' the driver-specific
676 * texture object from the core mesa gl_texture_object. Not done at this time.
677 */
678 static struct gl_texture_object *
679 i830NewTextureObject( GLcontext *ctx, GLuint name, GLenum target )
680 {
681 struct gl_texture_object *obj;
682 obj = _mesa_new_texture_object(ctx, name, target);
683 i830AllocTexObj( obj );
684 return obj;
685 }
686
687 void i830InitTextureFuncs( struct dd_function_table *functions )
688 {
689 functions->NewTextureObject = i830NewTextureObject;
690 functions->DeleteTexture = i830DeleteTexture;
691 functions->ChooseTextureFormat = i830ChooseTextureFormat;
692 functions->TexImage2D = i830TexImage2D;
693 functions->TexSubImage2D = i830TexSubImage2D;
694 functions->BindTexture = i830BindTexture;
695 functions->TexParameter = i830TexParameter;
696 functions->TexEnv = i830TexEnv;
697 functions->IsTextureResident = driIsTextureResident;
698 functions->CompressedTexImage2D = i830CompressedTexImage2D;
699 functions->CompressedTexSubImage2D = i830CompressedTexSubImage2D;
700 }