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