Merge remote branch 'nouveau/gallium-0.1' into nouveau-gallium-0.2
[mesa.git] / src / mesa / drivers / dri / r300 / r300_tex.c
1 /*
2 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
3
4 The Weather Channel (TM) funded Tungsten Graphics to develop the
5 initial release of the Radeon 8500 driver under the XFree86 license.
6 This notice must be preserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
15
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 */
28
29 /**
30 * \file
31 *
32 * \author Keith Whitwell <keith@tungstengraphics.com>
33 */
34
35 #include "glheader.h"
36 #include "imports.h"
37 #include "colormac.h"
38 #include "context.h"
39 #include "enums.h"
40 #include "image.h"
41 #include "simple_list.h"
42 #include "texformat.h"
43 #include "texstore.h"
44 #include "texmem.h"
45 #include "teximage.h"
46 #include "texobj.h"
47
48 #include "r300_context.h"
49 #include "r300_state.h"
50 #include "r300_ioctl.h"
51 #include "r300_tex.h"
52
53 #include "xmlpool.h"
54
55
56 static unsigned int translate_wrap_mode(GLenum wrapmode)
57 {
58 switch(wrapmode) {
59 case GL_REPEAT: return R300_TX_REPEAT;
60 case GL_CLAMP: return R300_TX_CLAMP;
61 case GL_CLAMP_TO_EDGE: return R300_TX_CLAMP_TO_EDGE;
62 case GL_CLAMP_TO_BORDER: return R300_TX_CLAMP_TO_BORDER;
63 case GL_MIRRORED_REPEAT: return R300_TX_REPEAT | R300_TX_MIRRORED;
64 case GL_MIRROR_CLAMP_EXT: return R300_TX_CLAMP | R300_TX_MIRRORED;
65 case GL_MIRROR_CLAMP_TO_EDGE_EXT: return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
66 case GL_MIRROR_CLAMP_TO_BORDER_EXT: return R300_TX_CLAMP_TO_BORDER | R300_TX_MIRRORED;
67 default:
68 _mesa_problem(NULL, "bad wrap mode in %s", __FUNCTION__);
69 return 0;
70 }
71 }
72
73
74 /**
75 * Update the cached hardware registers based on the current texture wrap modes.
76 *
77 * \param t Texture object whose wrap modes are to be set
78 */
79 static void r300UpdateTexWrap(r300TexObjPtr t)
80 {
81 struct gl_texture_object *tObj = t->base.tObj;
82
83 t->filter &=
84 ~(R300_TX_WRAP_S_MASK | R300_TX_WRAP_T_MASK | R300_TX_WRAP_R_MASK);
85
86 t->filter |= translate_wrap_mode(tObj->WrapS) << R300_TX_WRAP_S_SHIFT;
87
88 if (tObj->Target != GL_TEXTURE_1D) {
89 t->filter |= translate_wrap_mode(tObj->WrapT) << R300_TX_WRAP_T_SHIFT;
90
91 if (tObj->Target == GL_TEXTURE_3D)
92 t->filter |= translate_wrap_mode(tObj->WrapR) << R300_TX_WRAP_R_SHIFT;
93 }
94 }
95
96 static GLuint aniso_filter(GLfloat anisotropy)
97 {
98 if (anisotropy >= 16.0) {
99 return R300_TX_MAX_ANISO_16_TO_1;
100 } else if (anisotropy >= 8.0) {
101 return R300_TX_MAX_ANISO_8_TO_1;
102 } else if (anisotropy >= 4.0) {
103 return R300_TX_MAX_ANISO_4_TO_1;
104 } else if (anisotropy >= 2.0) {
105 return R300_TX_MAX_ANISO_2_TO_1;
106 } else {
107 return R300_TX_MAX_ANISO_1_TO_1;
108 }
109 }
110
111 /**
112 * Set the texture magnification and minification modes.
113 *
114 * \param t Texture whose filter modes are to be set
115 * \param minf Texture minification mode
116 * \param magf Texture magnification mode
117 * \param anisotropy Maximum anisotropy level
118 */
119 static void r300SetTexFilter(r300TexObjPtr t, GLenum minf, GLenum magf, GLfloat anisotropy)
120 {
121 t->filter &= ~(R300_TX_MIN_FILTER_MASK | R300_TX_MIN_FILTER_MIP_MASK | R300_TX_MAG_FILTER_MASK | R300_TX_MAX_ANISO_MASK);
122 t->filter_1 &= ~R300_EDGE_ANISO_EDGE_ONLY;
123
124 /* Note that EXT_texture_filter_anisotropic is extremely vague about
125 * how anisotropic filtering interacts with the "normal" filter modes.
126 * When anisotropic filtering is enabled, we override min and mag
127 * filter settings completely. This includes driconf's settings.
128 */
129 if (anisotropy >= 2.0 && (minf != GL_NEAREST) && (magf != GL_NEAREST)) {
130 t->filter |= R300_TX_MAG_FILTER_ANISO
131 | R300_TX_MIN_FILTER_ANISO
132 | R300_TX_MIN_FILTER_MIP_LINEAR
133 | aniso_filter(anisotropy);
134 if (RADEON_DEBUG & DEBUG_TEXTURE)
135 fprintf(stderr, "Using maximum anisotropy of %f\n", anisotropy);
136 return;
137 }
138
139 switch (minf) {
140 case GL_NEAREST:
141 t->filter |= R300_TX_MIN_FILTER_NEAREST;
142 break;
143 case GL_LINEAR:
144 t->filter |= R300_TX_MIN_FILTER_LINEAR;
145 break;
146 case GL_NEAREST_MIPMAP_NEAREST:
147 t->filter |= R300_TX_MIN_FILTER_NEAREST|R300_TX_MIN_FILTER_MIP_NEAREST;
148 break;
149 case GL_NEAREST_MIPMAP_LINEAR:
150 t->filter |= R300_TX_MIN_FILTER_NEAREST|R300_TX_MIN_FILTER_MIP_LINEAR;
151 break;
152 case GL_LINEAR_MIPMAP_NEAREST:
153 t->filter |= R300_TX_MIN_FILTER_LINEAR|R300_TX_MIN_FILTER_MIP_NEAREST;
154 break;
155 case GL_LINEAR_MIPMAP_LINEAR:
156 t->filter |= R300_TX_MIN_FILTER_LINEAR|R300_TX_MIN_FILTER_MIP_LINEAR;
157 break;
158 }
159
160 /* Note we don't have 3D mipmaps so only use the mag filter setting
161 * to set the 3D texture filter mode.
162 */
163 switch (magf) {
164 case GL_NEAREST:
165 t->filter |= R300_TX_MAG_FILTER_NEAREST;
166 break;
167 case GL_LINEAR:
168 t->filter |= R300_TX_MAG_FILTER_LINEAR;
169 break;
170 }
171 }
172
173 static void r300SetTexBorderColor(r300TexObjPtr t, GLubyte c[4])
174 {
175 t->pp_border_color = PACK_COLOR_8888(c[3], c[0], c[1], c[2]);
176 }
177
178 /**
179 * Allocate space for and load the mesa images into the texture memory block.
180 * This will happen before drawing with a new texture, or drawing with a
181 * texture after it was swapped out or teximaged again.
182 */
183
184 static r300TexObjPtr r300AllocTexObj(struct gl_texture_object *texObj)
185 {
186 r300TexObjPtr t;
187
188 t = CALLOC_STRUCT(r300_tex_obj);
189 texObj->DriverData = t;
190 if (t != NULL) {
191 if (RADEON_DEBUG & DEBUG_TEXTURE) {
192 fprintf(stderr, "%s( %p, %p )\n", __FUNCTION__,
193 (void *)texObj, (void *)t);
194 }
195
196 /* Initialize non-image-dependent parts of the state:
197 */
198 t->base.tObj = texObj;
199 t->border_fallback = GL_FALSE;
200
201 make_empty_list(&t->base);
202
203 r300UpdateTexWrap(t);
204 r300SetTexFilter(t, texObj->MinFilter, texObj->MagFilter, texObj->MaxAnisotropy);
205 r300SetTexBorderColor(t, texObj->_BorderChan);
206 }
207
208 return t;
209 }
210
211 /* try to find a format which will only need a memcopy */
212 static const struct gl_texture_format *r300Choose8888TexFormat(GLenum srcFormat,
213 GLenum srcType)
214 {
215 const GLuint ui = 1;
216 const GLubyte littleEndian = *((const GLubyte *)&ui);
217
218 if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
219 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
220 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
221 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
222 return &_mesa_texformat_rgba8888;
223 } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
224 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
225 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
226 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
227 return &_mesa_texformat_rgba8888_rev;
228 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
229 srcType == GL_UNSIGNED_INT_8_8_8_8)) {
230 return &_mesa_texformat_argb8888_rev;
231 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
232 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
233 return &_mesa_texformat_argb8888;
234 } else
235 return _dri_texformat_argb8888;
236 }
237
238 static const struct gl_texture_format *r300ChooseTextureFormat(GLcontext * ctx,
239 GLint
240 internalFormat,
241 GLenum format,
242 GLenum type)
243 {
244 r300ContextPtr rmesa = R300_CONTEXT(ctx);
245 const GLboolean do32bpt =
246 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32);
247 const GLboolean force16bpt =
248 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16);
249 (void)format;
250
251 #if 0
252 fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n",
253 _mesa_lookup_enum_by_nr(internalFormat), internalFormat,
254 _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format));
255 fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt);
256 #endif
257
258 switch (internalFormat) {
259 case 4:
260 case GL_RGBA:
261 case GL_COMPRESSED_RGBA:
262 switch (type) {
263 case GL_UNSIGNED_INT_10_10_10_2:
264 case GL_UNSIGNED_INT_2_10_10_10_REV:
265 return do32bpt ? _dri_texformat_argb8888 :
266 _dri_texformat_argb1555;
267 case GL_UNSIGNED_SHORT_4_4_4_4:
268 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
269 return _dri_texformat_argb4444;
270 case GL_UNSIGNED_SHORT_5_5_5_1:
271 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
272 return _dri_texformat_argb1555;
273 default:
274 return do32bpt ? r300Choose8888TexFormat(format, type) :
275 _dri_texformat_argb4444;
276 }
277
278 case 3:
279 case GL_RGB:
280 case GL_COMPRESSED_RGB:
281 switch (type) {
282 case GL_UNSIGNED_SHORT_4_4_4_4:
283 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
284 return _dri_texformat_argb4444;
285 case GL_UNSIGNED_SHORT_5_5_5_1:
286 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
287 return _dri_texformat_argb1555;
288 case GL_UNSIGNED_SHORT_5_6_5:
289 case GL_UNSIGNED_SHORT_5_6_5_REV:
290 return _dri_texformat_rgb565;
291 default:
292 return do32bpt ? _dri_texformat_argb8888 :
293 _dri_texformat_rgb565;
294 }
295
296 case GL_RGBA8:
297 case GL_RGB10_A2:
298 case GL_RGBA12:
299 case GL_RGBA16:
300 return !force16bpt ?
301 r300Choose8888TexFormat(format,
302 type) : _dri_texformat_argb4444;
303
304 case GL_RGBA4:
305 case GL_RGBA2:
306 return _dri_texformat_argb4444;
307
308 case GL_RGB5_A1:
309 return _dri_texformat_argb1555;
310
311 case GL_RGB8:
312 case GL_RGB10:
313 case GL_RGB12:
314 case GL_RGB16:
315 return !force16bpt ? _dri_texformat_argb8888 :
316 _dri_texformat_rgb565;
317
318 case GL_RGB5:
319 case GL_RGB4:
320 case GL_R3_G3_B2:
321 return _dri_texformat_rgb565;
322
323 case GL_ALPHA:
324 case GL_ALPHA4:
325 case GL_ALPHA8:
326 case GL_ALPHA12:
327 case GL_ALPHA16:
328 case GL_COMPRESSED_ALPHA:
329 return _dri_texformat_a8;
330
331 case 1:
332 case GL_LUMINANCE:
333 case GL_LUMINANCE4:
334 case GL_LUMINANCE8:
335 case GL_LUMINANCE12:
336 case GL_LUMINANCE16:
337 case GL_COMPRESSED_LUMINANCE:
338 return _dri_texformat_l8;
339
340 case 2:
341 case GL_LUMINANCE_ALPHA:
342 case GL_LUMINANCE4_ALPHA4:
343 case GL_LUMINANCE6_ALPHA2:
344 case GL_LUMINANCE8_ALPHA8:
345 case GL_LUMINANCE12_ALPHA4:
346 case GL_LUMINANCE12_ALPHA12:
347 case GL_LUMINANCE16_ALPHA16:
348 case GL_COMPRESSED_LUMINANCE_ALPHA:
349 return _dri_texformat_al88;
350
351 case GL_INTENSITY:
352 case GL_INTENSITY4:
353 case GL_INTENSITY8:
354 case GL_INTENSITY12:
355 case GL_INTENSITY16:
356 case GL_COMPRESSED_INTENSITY:
357 return _dri_texformat_i8;
358
359 case GL_YCBCR_MESA:
360 if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
361 type == GL_UNSIGNED_BYTE)
362 return &_mesa_texformat_ycbcr;
363 else
364 return &_mesa_texformat_ycbcr_rev;
365
366 case GL_RGB_S3TC:
367 case GL_RGB4_S3TC:
368 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
369 return &_mesa_texformat_rgb_dxt1;
370
371 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
372 return &_mesa_texformat_rgba_dxt1;
373
374 case GL_RGBA_S3TC:
375 case GL_RGBA4_S3TC:
376 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
377 return &_mesa_texformat_rgba_dxt3;
378
379 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
380 return &_mesa_texformat_rgba_dxt5;
381
382 case GL_ALPHA16F_ARB:
383 return &_mesa_texformat_alpha_float16;
384 case GL_ALPHA32F_ARB:
385 return &_mesa_texformat_alpha_float32;
386 case GL_LUMINANCE16F_ARB:
387 return &_mesa_texformat_luminance_float16;
388 case GL_LUMINANCE32F_ARB:
389 return &_mesa_texformat_luminance_float32;
390 case GL_LUMINANCE_ALPHA16F_ARB:
391 return &_mesa_texformat_luminance_alpha_float16;
392 case GL_LUMINANCE_ALPHA32F_ARB:
393 return &_mesa_texformat_luminance_alpha_float32;
394 case GL_INTENSITY16F_ARB:
395 return &_mesa_texformat_intensity_float16;
396 case GL_INTENSITY32F_ARB:
397 return &_mesa_texformat_intensity_float32;
398 case GL_RGB16F_ARB:
399 return &_mesa_texformat_rgba_float16;
400 case GL_RGB32F_ARB:
401 return &_mesa_texformat_rgba_float32;
402 case GL_RGBA16F_ARB:
403 return &_mesa_texformat_rgba_float16;
404 case GL_RGBA32F_ARB:
405 return &_mesa_texformat_rgba_float32;
406
407 case GL_DEPTH_COMPONENT:
408 case GL_DEPTH_COMPONENT16:
409 case GL_DEPTH_COMPONENT24:
410 case GL_DEPTH_COMPONENT32:
411 #if 0
412 switch (type) {
413 case GL_UNSIGNED_BYTE:
414 case GL_UNSIGNED_SHORT:
415 return &_mesa_texformat_z16;
416 case GL_UNSIGNED_INT:
417 return &_mesa_texformat_z32;
418 case GL_UNSIGNED_INT_24_8_EXT:
419 default:
420 return &_mesa_texformat_z24_s8;
421 }
422 #else
423 return &_mesa_texformat_z16;
424 #endif
425
426 default:
427 _mesa_problem(ctx,
428 "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
429 (int)internalFormat);
430 return NULL;
431 }
432
433 return NULL; /* never get here */
434 }
435
436 static GLboolean
437 r300ValidateClientStorage(GLcontext * ctx, GLenum target,
438 GLint internalFormat,
439 GLint srcWidth, GLint srcHeight,
440 GLenum format, GLenum type, const void *pixels,
441 const struct gl_pixelstore_attrib *packing,
442 struct gl_texture_object *texObj,
443 struct gl_texture_image *texImage)
444 {
445 r300ContextPtr rmesa = R300_CONTEXT(ctx);
446
447 if (RADEON_DEBUG & DEBUG_TEXTURE)
448 fprintf(stderr, "intformat %s format %s type %s\n",
449 _mesa_lookup_enum_by_nr(internalFormat),
450 _mesa_lookup_enum_by_nr(format),
451 _mesa_lookup_enum_by_nr(type));
452
453 if (!ctx->Unpack.ClientStorage)
454 return 0;
455
456 if (ctx->_ImageTransferState ||
457 texImage->IsCompressed || texObj->GenerateMipmap)
458 return 0;
459
460 /* This list is incomplete, may be different on ppc???
461 */
462 switch (internalFormat) {
463 case GL_RGBA:
464 if (format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV) {
465 texImage->TexFormat = _dri_texformat_argb8888;
466 } else
467 return 0;
468 break;
469
470 case GL_RGB:
471 if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) {
472 texImage->TexFormat = _dri_texformat_rgb565;
473 } else
474 return 0;
475 break;
476
477 case GL_YCBCR_MESA:
478 if (format == GL_YCBCR_MESA &&
479 type == GL_UNSIGNED_SHORT_8_8_REV_APPLE) {
480 texImage->TexFormat = &_mesa_texformat_ycbcr_rev;
481 } else if (format == GL_YCBCR_MESA &&
482 (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
483 type == GL_UNSIGNED_BYTE)) {
484 texImage->TexFormat = &_mesa_texformat_ycbcr;
485 } else
486 return 0;
487 break;
488
489 default:
490 return 0;
491 }
492
493 /* Could deal with these packing issues, but currently don't:
494 */
495 if (packing->SkipPixels ||
496 packing->SkipRows || packing->SwapBytes || packing->LsbFirst) {
497 return 0;
498 }
499
500 GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth,
501 format, type);
502
503 if (RADEON_DEBUG & DEBUG_TEXTURE)
504 fprintf(stderr, "%s: srcRowStride %d/%x\n",
505 __FUNCTION__, srcRowStride, srcRowStride);
506
507 /* Could check this later in upload, pitch restrictions could be
508 * relaxed, but would need to store the image pitch somewhere,
509 * as packing details might change before image is uploaded:
510 */
511 if (!r300IsGartMemory(rmesa, pixels, srcHeight * srcRowStride)
512 || (srcRowStride & 63))
513 return 0;
514
515 /* Have validated that _mesa_transfer_teximage would be a straight
516 * memcpy at this point. NOTE: future calls to TexSubImage will
517 * overwrite the client data. This is explicitly mentioned in the
518 * extension spec.
519 */
520 texImage->Data = (void *)pixels;
521 texImage->IsClientData = GL_TRUE;
522 texImage->RowStride = srcRowStride / texImage->TexFormat->TexelBytes;
523
524 return 1;
525 }
526
527 static void r300TexImage1D(GLcontext * ctx, GLenum target, GLint level,
528 GLint internalFormat,
529 GLint width, GLint border,
530 GLenum format, GLenum type, const GLvoid * pixels,
531 const struct gl_pixelstore_attrib *packing,
532 struct gl_texture_object *texObj,
533 struct gl_texture_image *texImage)
534 {
535 driTextureObject *t = (driTextureObject *) texObj->DriverData;
536
537 if (t) {
538 driSwapOutTextureObject(t);
539 } else {
540 t = (driTextureObject *) r300AllocTexObj(texObj);
541 if (!t) {
542 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
543 return;
544 }
545 }
546
547 /* Note, this will call ChooseTextureFormat */
548 _mesa_store_teximage1d(ctx, target, level, internalFormat,
549 width, border, format, type, pixels,
550 &ctx->Unpack, texObj, texImage);
551
552 t->dirty_images[0] |= (1 << level);
553 }
554
555 static void r300TexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
556 GLint xoffset,
557 GLsizei width,
558 GLenum format, GLenum type,
559 const GLvoid * pixels,
560 const struct gl_pixelstore_attrib *packing,
561 struct gl_texture_object *texObj,
562 struct gl_texture_image *texImage)
563 {
564 driTextureObject *t = (driTextureObject *) texObj->DriverData;
565
566 assert(t); /* this _should_ be true */
567 if (t) {
568 driSwapOutTextureObject(t);
569 } else {
570 t = (driTextureObject *) r300AllocTexObj(texObj);
571 if (!t) {
572 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
573 return;
574 }
575 }
576
577 _mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
578 format, type, pixels, packing, texObj,
579 texImage);
580
581 t->dirty_images[0] |= (1 << level);
582 }
583
584 static void r300TexImage2D(GLcontext * ctx, GLenum target, GLint level,
585 GLint internalFormat,
586 GLint width, GLint height, GLint border,
587 GLenum format, GLenum type, const GLvoid * pixels,
588 const struct gl_pixelstore_attrib *packing,
589 struct gl_texture_object *texObj,
590 struct gl_texture_image *texImage)
591 {
592 driTextureObject *t = (driTextureObject *) texObj->DriverData;
593 GLuint face;
594
595 /* which cube face or ordinary 2D image */
596 switch (target) {
597 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
598 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
599 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
600 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
601 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
602 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
603 face =
604 (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
605 ASSERT(face < 6);
606 break;
607 default:
608 face = 0;
609 }
610
611 if (t != NULL) {
612 driSwapOutTextureObject(t);
613 } else {
614 t = (driTextureObject *) r300AllocTexObj(texObj);
615 if (!t) {
616 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
617 return;
618 }
619 }
620
621 texImage->IsClientData = GL_FALSE;
622
623 if (r300ValidateClientStorage(ctx, target,
624 internalFormat,
625 width, height,
626 format, type, pixels,
627 packing, texObj, texImage)) {
628 if (RADEON_DEBUG & DEBUG_TEXTURE)
629 fprintf(stderr, "%s: Using client storage\n",
630 __FUNCTION__);
631 } else {
632 if (RADEON_DEBUG & DEBUG_TEXTURE)
633 fprintf(stderr, "%s: Using normal storage\n",
634 __FUNCTION__);
635
636 /* Normal path: copy (to cached memory) and eventually upload
637 * via another copy to GART memory and then a blit... Could
638 * eliminate one copy by going straight to (permanent) GART.
639 *
640 * Note, this will call r300ChooseTextureFormat.
641 */
642 _mesa_store_teximage2d(ctx, target, level, internalFormat,
643 width, height, border, format, type,
644 pixels, &ctx->Unpack, texObj, texImage);
645
646 t->dirty_images[face] |= (1 << level);
647 }
648 }
649
650 static void r300TexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
651 GLint xoffset, GLint yoffset,
652 GLsizei width, GLsizei height,
653 GLenum format, GLenum type,
654 const GLvoid * pixels,
655 const struct gl_pixelstore_attrib *packing,
656 struct gl_texture_object *texObj,
657 struct gl_texture_image *texImage)
658 {
659 driTextureObject *t = (driTextureObject *) texObj->DriverData;
660 GLuint face;
661
662 /* which cube face or ordinary 2D image */
663 switch (target) {
664 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
665 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
666 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
667 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
668 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
669 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
670 face =
671 (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
672 ASSERT(face < 6);
673 break;
674 default:
675 face = 0;
676 }
677
678 assert(t); /* this _should_ be true */
679 if (t) {
680 driSwapOutTextureObject(t);
681 } else {
682 t = (driTextureObject *) r300AllocTexObj(texObj);
683 if (!t) {
684 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
685 return;
686 }
687 }
688
689 _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
690 height, format, type, pixels, packing, texObj,
691 texImage);
692
693 t->dirty_images[face] |= (1 << level);
694 }
695
696 static void r300CompressedTexImage2D(GLcontext * ctx, GLenum target,
697 GLint level, GLint internalFormat,
698 GLint width, GLint height, GLint border,
699 GLsizei imageSize, const GLvoid * data,
700 struct gl_texture_object *texObj,
701 struct gl_texture_image *texImage)
702 {
703 driTextureObject *t = (driTextureObject *) texObj->DriverData;
704 GLuint face;
705
706 /* which cube face or ordinary 2D image */
707 switch (target) {
708 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
709 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
710 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
711 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
712 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
713 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
714 face =
715 (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
716 ASSERT(face < 6);
717 break;
718 default:
719 face = 0;
720 }
721
722 if (t != NULL) {
723 driSwapOutTextureObject(t);
724 } else {
725 t = (driTextureObject *) r300AllocTexObj(texObj);
726 if (!t) {
727 _mesa_error(ctx, GL_OUT_OF_MEMORY,
728 "glCompressedTexImage2D");
729 return;
730 }
731 }
732
733 texImage->IsClientData = GL_FALSE;
734
735 /* can't call this, different parameters. Would never evaluate to true anyway currently */
736 #if 0
737 if (r300ValidateClientStorage(ctx, target,
738 internalFormat,
739 width, height,
740 format, type, pixels,
741 packing, texObj, texImage)) {
742 if (RADEON_DEBUG & DEBUG_TEXTURE)
743 fprintf(stderr, "%s: Using client storage\n",
744 __FUNCTION__);
745 } else
746 #endif
747 {
748 if (RADEON_DEBUG & DEBUG_TEXTURE)
749 fprintf(stderr, "%s: Using normal storage\n",
750 __FUNCTION__);
751
752 /* Normal path: copy (to cached memory) and eventually upload
753 * via another copy to GART memory and then a blit... Could
754 * eliminate one copy by going straight to (permanent) GART.
755 *
756 * Note, this will call r300ChooseTextureFormat.
757 */
758 _mesa_store_compressed_teximage2d(ctx, target, level,
759 internalFormat, width, height,
760 border, imageSize, data,
761 texObj, texImage);
762
763 t->dirty_images[face] |= (1 << level);
764 }
765 }
766
767 static void r300CompressedTexSubImage2D(GLcontext * ctx, GLenum target,
768 GLint level, GLint xoffset,
769 GLint yoffset, GLsizei width,
770 GLsizei height, GLenum format,
771 GLsizei imageSize, const GLvoid * data,
772 struct gl_texture_object *texObj,
773 struct gl_texture_image *texImage)
774 {
775 driTextureObject *t = (driTextureObject *) texObj->DriverData;
776 GLuint face;
777
778 /* which cube face or ordinary 2D image */
779 switch (target) {
780 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
781 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
782 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
783 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
784 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
785 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
786 face =
787 (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
788 ASSERT(face < 6);
789 break;
790 default:
791 face = 0;
792 }
793
794 assert(t); /* this _should_ be true */
795 if (t) {
796 driSwapOutTextureObject(t);
797 } else {
798 t = (driTextureObject *) r300AllocTexObj(texObj);
799 if (!t) {
800 _mesa_error(ctx, GL_OUT_OF_MEMORY,
801 "glCompressedTexSubImage3D");
802 return;
803 }
804 }
805
806 _mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset,
807 yoffset, width, height, format,
808 imageSize, data, texObj, texImage);
809
810 t->dirty_images[face] |= (1 << level);
811 }
812
813 static void r300TexImage3D(GLcontext * ctx, GLenum target, GLint level,
814 GLint internalFormat,
815 GLint width, GLint height, GLint depth,
816 GLint border,
817 GLenum format, GLenum type, const GLvoid * pixels,
818 const struct gl_pixelstore_attrib *packing,
819 struct gl_texture_object *texObj,
820 struct gl_texture_image *texImage)
821 {
822 driTextureObject *t = (driTextureObject *) texObj->DriverData;
823
824 if (t) {
825 driSwapOutTextureObject(t);
826 } else {
827 t = (driTextureObject *) r300AllocTexObj(texObj);
828 if (!t) {
829 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
830 return;
831 }
832 }
833
834 texImage->IsClientData = GL_FALSE;
835
836 #if 0
837 if (r300ValidateClientStorage(ctx, target,
838 internalFormat,
839 width, height,
840 format, type, pixels,
841 packing, texObj, texImage)) {
842 if (RADEON_DEBUG & DEBUG_TEXTURE)
843 fprintf(stderr, "%s: Using client storage\n",
844 __FUNCTION__);
845 } else
846 #endif
847 {
848 if (RADEON_DEBUG & DEBUG_TEXTURE)
849 fprintf(stderr, "%s: Using normal storage\n",
850 __FUNCTION__);
851
852 /* Normal path: copy (to cached memory) and eventually upload
853 * via another copy to GART memory and then a blit... Could
854 * eliminate one copy by going straight to (permanent) GART.
855 *
856 * Note, this will call r300ChooseTextureFormat.
857 */
858 _mesa_store_teximage3d(ctx, target, level, internalFormat,
859 width, height, depth, border,
860 format, type, pixels,
861 &ctx->Unpack, texObj, texImage);
862
863 t->dirty_images[0] |= (1 << level);
864 }
865 }
866
867 static void
868 r300TexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
869 GLint xoffset, GLint yoffset, GLint zoffset,
870 GLsizei width, GLsizei height, GLsizei depth,
871 GLenum format, GLenum type,
872 const GLvoid * pixels,
873 const struct gl_pixelstore_attrib *packing,
874 struct gl_texture_object *texObj,
875 struct gl_texture_image *texImage)
876 {
877 driTextureObject *t = (driTextureObject *) texObj->DriverData;
878
879 /* fprintf(stderr, "%s\n", __FUNCTION__); */
880
881 assert(t); /* this _should_ be true */
882 if (t) {
883 driSwapOutTextureObject(t);
884 } else {
885 t = (driTextureObject *) r300AllocTexObj(texObj);
886 if (!t) {
887 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
888 return;
889 }
890 texObj->DriverData = t;
891 }
892
893 _mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset,
894 width, height, depth,
895 format, type, pixels, packing, texObj,
896 texImage);
897
898 t->dirty_images[0] |= (1 << level);
899 }
900
901 /**
902 * Changes variables and flags for a state update, which will happen at the
903 * next UpdateTextureState
904 */
905
906 static void r300TexParameter(GLcontext * ctx, GLenum target,
907 struct gl_texture_object *texObj,
908 GLenum pname, const GLfloat * params)
909 {
910 r300TexObjPtr t = (r300TexObjPtr) texObj->DriverData;
911
912 if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
913 fprintf(stderr, "%s( %s )\n", __FUNCTION__,
914 _mesa_lookup_enum_by_nr(pname));
915 }
916
917 switch (pname) {
918 case GL_TEXTURE_MIN_FILTER:
919 case GL_TEXTURE_MAG_FILTER:
920 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
921 r300SetTexFilter(t, texObj->MinFilter, texObj->MagFilter, texObj->MaxAnisotropy);
922 break;
923
924 case GL_TEXTURE_WRAP_S:
925 case GL_TEXTURE_WRAP_T:
926 case GL_TEXTURE_WRAP_R:
927 r300UpdateTexWrap(t);
928 break;
929
930 case GL_TEXTURE_BORDER_COLOR:
931 r300SetTexBorderColor(t, texObj->_BorderChan);
932 break;
933
934 case GL_TEXTURE_BASE_LEVEL:
935 case GL_TEXTURE_MAX_LEVEL:
936 case GL_TEXTURE_MIN_LOD:
937 case GL_TEXTURE_MAX_LOD:
938 /* This isn't the most efficient solution but there doesn't appear to
939 * be a nice alternative. Since there's no LOD clamping,
940 * we just have to rely on loading the right subset of mipmap levels
941 * to simulate a clamped LOD.
942 */
943 driSwapOutTextureObject((driTextureObject *) t);
944 break;
945
946 case GL_DEPTH_TEXTURE_MODE:
947 if (!texObj->Image[0][texObj->BaseLevel])
948 return;
949 if (texObj->Image[0][texObj->BaseLevel]->TexFormat->BaseFormat
950 == GL_DEPTH_COMPONENT) {
951 r300SetDepthTexMode(texObj);
952 break;
953 } else {
954 /* If the texture isn't a depth texture, changing this
955 * state won't cause any changes to the hardware.
956 * Don't force a flush of texture state.
957 */
958 return;
959 }
960
961 default:
962 return;
963 }
964 }
965
966 static void r300BindTexture(GLcontext * ctx, GLenum target,
967 struct gl_texture_object *texObj)
968 {
969 if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
970 fprintf(stderr, "%s( %p ) unit=%d\n", __FUNCTION__,
971 (void *)texObj, ctx->Texture.CurrentUnit);
972 }
973
974 if ((target == GL_TEXTURE_1D)
975 || (target == GL_TEXTURE_2D)
976 || (target == GL_TEXTURE_3D)
977 || (target == GL_TEXTURE_CUBE_MAP)
978 || (target == GL_TEXTURE_RECTANGLE_NV)) {
979 assert(texObj->DriverData != NULL);
980 }
981 }
982
983 static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj)
984 {
985 r300ContextPtr rmesa = R300_CONTEXT(ctx);
986 driTextureObject *t = (driTextureObject *) texObj->DriverData;
987
988 if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
989 fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__,
990 (void *)texObj,
991 _mesa_lookup_enum_by_nr(texObj->Target));
992 }
993
994 if (t != NULL) {
995 if (rmesa) {
996 R300_FIREVERTICES(rmesa);
997 }
998
999 driDestroyTextureObject(t);
1000 }
1001 /* Free mipmap images and the texture object itself */
1002 _mesa_delete_texture_object(ctx, texObj);
1003 }
1004
1005 /**
1006 * Allocate a new texture object.
1007 * Called via ctx->Driver.NewTextureObject.
1008 * Note: this function will be called during context creation to
1009 * allocate the default texture objects.
1010 * Note: we could use containment here to 'derive' the driver-specific
1011 * texture object from the core mesa gl_texture_object. Not done at this time.
1012 * Fixup MaxAnisotropy according to user preference.
1013 */
1014 static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx,
1015 GLuint name,
1016 GLenum target)
1017 {
1018 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1019 struct gl_texture_object *obj;
1020 obj = _mesa_new_texture_object(ctx, name, target);
1021 if (!obj)
1022 return NULL;
1023 obj->MaxAnisotropy = rmesa->initialMaxAnisotropy;
1024
1025 r300AllocTexObj(obj);
1026 return obj;
1027 }
1028
1029 void r300InitTextureFuncs(struct dd_function_table *functions)
1030 {
1031 /* Note: we only plug in the functions we implement in the driver
1032 * since _mesa_init_driver_functions() was already called.
1033 */
1034 functions->ChooseTextureFormat = r300ChooseTextureFormat;
1035 functions->TexImage1D = r300TexImage1D;
1036 functions->TexImage2D = r300TexImage2D;
1037 functions->TexImage3D = r300TexImage3D;
1038 functions->TexSubImage1D = r300TexSubImage1D;
1039 functions->TexSubImage2D = r300TexSubImage2D;
1040 functions->TexSubImage3D = r300TexSubImage3D;
1041 functions->NewTextureObject = r300NewTextureObject;
1042 functions->BindTexture = r300BindTexture;
1043 functions->DeleteTexture = r300DeleteTexture;
1044 functions->IsTextureResident = driIsTextureResident;
1045
1046 functions->TexParameter = r300TexParameter;
1047
1048 functions->CompressedTexImage2D = r300CompressedTexImage2D;
1049 functions->CompressedTexSubImage2D = r300CompressedTexSubImage2D;
1050
1051 driInitTextureFormats();
1052 }