r300: bo and cs abstraction.
[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/mipmap.h"
42 #include "main/simple_list.h"
43 #include "main/texformat.h"
44 #include "main/texstore.h"
45 #include "main/teximage.h"
46 #include "main/texobj.h"
47
48 #include "texmem.h"
49
50 #include "r300_context.h"
51 #include "r300_state.h"
52 #include "r300_ioctl.h"
53 #include "r300_mipmap_tree.h"
54 #include "r300_tex.h"
55
56 #include "xmlpool.h"
57
58
59 static unsigned int translate_wrap_mode(GLenum wrapmode)
60 {
61 switch(wrapmode) {
62 case GL_REPEAT: return R300_TX_REPEAT;
63 case GL_CLAMP: return R300_TX_CLAMP;
64 case GL_CLAMP_TO_EDGE: return R300_TX_CLAMP_TO_EDGE;
65 case GL_CLAMP_TO_BORDER: return R300_TX_CLAMP_TO_BORDER;
66 case GL_MIRRORED_REPEAT: return R300_TX_REPEAT | R300_TX_MIRRORED;
67 case GL_MIRROR_CLAMP_EXT: return R300_TX_CLAMP | R300_TX_MIRRORED;
68 case GL_MIRROR_CLAMP_TO_EDGE_EXT: return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
69 case GL_MIRROR_CLAMP_TO_BORDER_EXT: return R300_TX_CLAMP_TO_BORDER | R300_TX_MIRRORED;
70 default:
71 _mesa_problem(NULL, "bad wrap mode in %s", __FUNCTION__);
72 return 0;
73 }
74 }
75
76
77 /**
78 * Update the cached hardware registers based on the current texture wrap modes.
79 *
80 * \param t Texture object whose wrap modes are to be set
81 */
82 static void r300UpdateTexWrap(r300TexObjPtr t)
83 {
84 struct gl_texture_object *tObj = &t->base;
85
86 t->filter &=
87 ~(R300_TX_WRAP_S_MASK | R300_TX_WRAP_T_MASK | R300_TX_WRAP_R_MASK);
88
89 t->filter |= translate_wrap_mode(tObj->WrapS) << R300_TX_WRAP_S_SHIFT;
90
91 if (tObj->Target != GL_TEXTURE_1D) {
92 t->filter |= translate_wrap_mode(tObj->WrapT) << R300_TX_WRAP_T_SHIFT;
93
94 if (tObj->Target == GL_TEXTURE_3D)
95 t->filter |= translate_wrap_mode(tObj->WrapR) << R300_TX_WRAP_R_SHIFT;
96 }
97 }
98
99 static GLuint aniso_filter(GLfloat anisotropy)
100 {
101 if (anisotropy >= 16.0) {
102 return R300_TX_MAX_ANISO_16_TO_1;
103 } else if (anisotropy >= 8.0) {
104 return R300_TX_MAX_ANISO_8_TO_1;
105 } else if (anisotropy >= 4.0) {
106 return R300_TX_MAX_ANISO_4_TO_1;
107 } else if (anisotropy >= 2.0) {
108 return R300_TX_MAX_ANISO_2_TO_1;
109 } else {
110 return R300_TX_MAX_ANISO_1_TO_1;
111 }
112 }
113
114 /**
115 * Set the texture magnification and minification modes.
116 *
117 * \param t Texture whose filter modes are to be set
118 * \param minf Texture minification mode
119 * \param magf Texture magnification mode
120 * \param anisotropy Maximum anisotropy level
121 */
122 static void r300SetTexFilter(r300TexObjPtr t, GLenum minf, GLenum magf, GLfloat anisotropy)
123 {
124 /* Force revalidation to account for switches from/to mipmapping. */
125 t->validated = GL_FALSE;
126
127 t->filter &= ~(R300_TX_MIN_FILTER_MASK | R300_TX_MIN_FILTER_MIP_MASK | R300_TX_MAG_FILTER_MASK | R300_TX_MAX_ANISO_MASK);
128 t->filter_1 &= ~R300_EDGE_ANISO_EDGE_ONLY;
129
130 /* Note that EXT_texture_filter_anisotropic is extremely vague about
131 * how anisotropic filtering interacts with the "normal" filter modes.
132 * When anisotropic filtering is enabled, we override min and mag
133 * filter settings completely. This includes driconf's settings.
134 */
135 if (anisotropy >= 2.0 && (minf != GL_NEAREST) && (magf != GL_NEAREST)) {
136 t->filter |= R300_TX_MAG_FILTER_ANISO
137 | R300_TX_MIN_FILTER_ANISO
138 | R300_TX_MIN_FILTER_MIP_LINEAR
139 | aniso_filter(anisotropy);
140 if (RADEON_DEBUG & DEBUG_TEXTURE)
141 fprintf(stderr, "Using maximum anisotropy of %f\n", anisotropy);
142 return;
143 }
144
145 switch (minf) {
146 case GL_NEAREST:
147 t->filter |= R300_TX_MIN_FILTER_NEAREST;
148 break;
149 case GL_LINEAR:
150 t->filter |= R300_TX_MIN_FILTER_LINEAR;
151 break;
152 case GL_NEAREST_MIPMAP_NEAREST:
153 t->filter |= R300_TX_MIN_FILTER_NEAREST|R300_TX_MIN_FILTER_MIP_NEAREST;
154 break;
155 case GL_NEAREST_MIPMAP_LINEAR:
156 t->filter |= R300_TX_MIN_FILTER_NEAREST|R300_TX_MIN_FILTER_MIP_LINEAR;
157 break;
158 case GL_LINEAR_MIPMAP_NEAREST:
159 t->filter |= R300_TX_MIN_FILTER_LINEAR|R300_TX_MIN_FILTER_MIP_NEAREST;
160 break;
161 case GL_LINEAR_MIPMAP_LINEAR:
162 t->filter |= R300_TX_MIN_FILTER_LINEAR|R300_TX_MIN_FILTER_MIP_LINEAR;
163 break;
164 }
165
166 /* Note we don't have 3D mipmaps so only use the mag filter setting
167 * to set the 3D texture filter mode.
168 */
169 switch (magf) {
170 case GL_NEAREST:
171 t->filter |= R300_TX_MAG_FILTER_NEAREST;
172 break;
173 case GL_LINEAR:
174 t->filter |= R300_TX_MAG_FILTER_LINEAR;
175 break;
176 }
177 }
178
179 static void r300SetTexBorderColor(r300TexObjPtr t, GLubyte c[4])
180 {
181 t->pp_border_color = PACK_COLOR_8888(c[3], c[0], c[1], c[2]);
182 }
183
184 /* try to find a format which will only need a memcopy */
185 static const struct gl_texture_format *r300Choose8888TexFormat(GLenum srcFormat,
186 GLenum srcType)
187 {
188 const GLuint ui = 1;
189 const GLubyte littleEndian = *((const GLubyte *)&ui);
190
191 if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
192 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
193 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
194 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
195 return &_mesa_texformat_rgba8888;
196 } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
197 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
198 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
199 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
200 return &_mesa_texformat_rgba8888_rev;
201 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
202 srcType == GL_UNSIGNED_INT_8_8_8_8)) {
203 return &_mesa_texformat_argb8888_rev;
204 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
205 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
206 return &_mesa_texformat_argb8888;
207 } else
208 return _dri_texformat_argb8888;
209 }
210
211 static const struct gl_texture_format *r300ChooseTextureFormat(GLcontext * ctx,
212 GLint
213 internalFormat,
214 GLenum format,
215 GLenum type)
216 {
217 r300ContextPtr rmesa = R300_CONTEXT(ctx);
218 const GLboolean do32bpt =
219 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32);
220 const GLboolean force16bpt =
221 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16);
222 (void)format;
223
224 #if 0
225 fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n",
226 _mesa_lookup_enum_by_nr(internalFormat), internalFormat,
227 _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format));
228 fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt);
229 #endif
230
231 switch (internalFormat) {
232 case 4:
233 case GL_RGBA:
234 case GL_COMPRESSED_RGBA:
235 switch (type) {
236 case GL_UNSIGNED_INT_10_10_10_2:
237 case GL_UNSIGNED_INT_2_10_10_10_REV:
238 return do32bpt ? _dri_texformat_argb8888 :
239 _dri_texformat_argb1555;
240 case GL_UNSIGNED_SHORT_4_4_4_4:
241 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
242 return _dri_texformat_argb4444;
243 case GL_UNSIGNED_SHORT_5_5_5_1:
244 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
245 return _dri_texformat_argb1555;
246 default:
247 return do32bpt ? r300Choose8888TexFormat(format, type) :
248 _dri_texformat_argb4444;
249 }
250
251 case 3:
252 case GL_RGB:
253 case GL_COMPRESSED_RGB:
254 switch (type) {
255 case GL_UNSIGNED_SHORT_4_4_4_4:
256 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
257 return _dri_texformat_argb4444;
258 case GL_UNSIGNED_SHORT_5_5_5_1:
259 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
260 return _dri_texformat_argb1555;
261 case GL_UNSIGNED_SHORT_5_6_5:
262 case GL_UNSIGNED_SHORT_5_6_5_REV:
263 return _dri_texformat_rgb565;
264 default:
265 return do32bpt ? _dri_texformat_argb8888 :
266 _dri_texformat_rgb565;
267 }
268
269 case GL_RGBA8:
270 case GL_RGB10_A2:
271 case GL_RGBA12:
272 case GL_RGBA16:
273 return !force16bpt ?
274 r300Choose8888TexFormat(format,
275 type) : _dri_texformat_argb4444;
276
277 case GL_RGBA4:
278 case GL_RGBA2:
279 return _dri_texformat_argb4444;
280
281 case GL_RGB5_A1:
282 return _dri_texformat_argb1555;
283
284 case GL_RGB8:
285 case GL_RGB10:
286 case GL_RGB12:
287 case GL_RGB16:
288 return !force16bpt ? _dri_texformat_argb8888 :
289 _dri_texformat_rgb565;
290
291 case GL_RGB5:
292 case GL_RGB4:
293 case GL_R3_G3_B2:
294 return _dri_texformat_rgb565;
295
296 case GL_ALPHA:
297 case GL_ALPHA4:
298 case GL_ALPHA8:
299 case GL_ALPHA12:
300 case GL_ALPHA16:
301 case GL_COMPRESSED_ALPHA:
302 return _dri_texformat_a8;
303
304 case 1:
305 case GL_LUMINANCE:
306 case GL_LUMINANCE4:
307 case GL_LUMINANCE8:
308 case GL_LUMINANCE12:
309 case GL_LUMINANCE16:
310 case GL_COMPRESSED_LUMINANCE:
311 return _dri_texformat_l8;
312
313 case 2:
314 case GL_LUMINANCE_ALPHA:
315 case GL_LUMINANCE4_ALPHA4:
316 case GL_LUMINANCE6_ALPHA2:
317 case GL_LUMINANCE8_ALPHA8:
318 case GL_LUMINANCE12_ALPHA4:
319 case GL_LUMINANCE12_ALPHA12:
320 case GL_LUMINANCE16_ALPHA16:
321 case GL_COMPRESSED_LUMINANCE_ALPHA:
322 return _dri_texformat_al88;
323
324 case GL_INTENSITY:
325 case GL_INTENSITY4:
326 case GL_INTENSITY8:
327 case GL_INTENSITY12:
328 case GL_INTENSITY16:
329 case GL_COMPRESSED_INTENSITY:
330 return _dri_texformat_i8;
331
332 case GL_YCBCR_MESA:
333 if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
334 type == GL_UNSIGNED_BYTE)
335 return &_mesa_texformat_ycbcr;
336 else
337 return &_mesa_texformat_ycbcr_rev;
338
339 case GL_RGB_S3TC:
340 case GL_RGB4_S3TC:
341 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
342 return &_mesa_texformat_rgb_dxt1;
343
344 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
345 return &_mesa_texformat_rgba_dxt1;
346
347 case GL_RGBA_S3TC:
348 case GL_RGBA4_S3TC:
349 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
350 return &_mesa_texformat_rgba_dxt3;
351
352 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
353 return &_mesa_texformat_rgba_dxt5;
354
355 case GL_ALPHA16F_ARB:
356 return &_mesa_texformat_alpha_float16;
357 case GL_ALPHA32F_ARB:
358 return &_mesa_texformat_alpha_float32;
359 case GL_LUMINANCE16F_ARB:
360 return &_mesa_texformat_luminance_float16;
361 case GL_LUMINANCE32F_ARB:
362 return &_mesa_texformat_luminance_float32;
363 case GL_LUMINANCE_ALPHA16F_ARB:
364 return &_mesa_texformat_luminance_alpha_float16;
365 case GL_LUMINANCE_ALPHA32F_ARB:
366 return &_mesa_texformat_luminance_alpha_float32;
367 case GL_INTENSITY16F_ARB:
368 return &_mesa_texformat_intensity_float16;
369 case GL_INTENSITY32F_ARB:
370 return &_mesa_texformat_intensity_float32;
371 case GL_RGB16F_ARB:
372 return &_mesa_texformat_rgba_float16;
373 case GL_RGB32F_ARB:
374 return &_mesa_texformat_rgba_float32;
375 case GL_RGBA16F_ARB:
376 return &_mesa_texformat_rgba_float16;
377 case GL_RGBA32F_ARB:
378 return &_mesa_texformat_rgba_float32;
379
380 case GL_DEPTH_COMPONENT:
381 case GL_DEPTH_COMPONENT16:
382 case GL_DEPTH_COMPONENT24:
383 case GL_DEPTH_COMPONENT32:
384 #if 0
385 switch (type) {
386 case GL_UNSIGNED_BYTE:
387 case GL_UNSIGNED_SHORT:
388 return &_mesa_texformat_z16;
389 case GL_UNSIGNED_INT:
390 return &_mesa_texformat_z32;
391 case GL_UNSIGNED_INT_24_8_EXT:
392 default:
393 return &_mesa_texformat_z24_s8;
394 }
395 #else
396 return &_mesa_texformat_z16;
397 #endif
398
399 default:
400 _mesa_problem(ctx,
401 "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
402 (int)internalFormat);
403 return NULL;
404 }
405
406 return NULL; /* never get here */
407 }
408
409
410 /**
411 * Allocate an empty texture image object.
412 */
413 static struct gl_texture_image *r300NewTextureImage(GLcontext *ctx)
414 {
415 return CALLOC(sizeof(r300_texture_image));
416 }
417
418 /**
419 * Free memory associated with this texture image.
420 */
421 static void r300FreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage)
422 {
423 r300_texture_image* image = get_r300_texture_image(timage);
424
425 if (image->mt) {
426 r300_miptree_unreference(image->mt);
427 image->mt = 0;
428 assert(!image->base.Data);
429 } else {
430 _mesa_free_texture_image_data(ctx, timage);
431 }
432 }
433
434
435 /* Set Data pointer and additional data for mapped texture image */
436 static void teximage_set_map_data(r300_texture_image *image)
437 {
438 r300_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
439 image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset;
440 image->base.RowStride = lvl->rowstride / image->mt->bpp;
441 }
442
443
444 /**
445 * Map a single texture image for glTexImage and friends.
446 */
447 static void r300_teximage_map(r300_texture_image *image, GLboolean write_enable)
448 {
449 if (image->mt) {
450 assert(!image->base.Data);
451
452 radeon_bo_map(image->mt->bo, write_enable);
453 teximage_set_map_data(image);
454 }
455 }
456
457
458 static void r300_teximage_unmap(r300_texture_image *image)
459 {
460 if (image->mt) {
461 assert(image->base.Data);
462
463 image->base.Data = 0;
464 radeon_bo_unmap(image->mt->bo);
465 }
466 }
467
468 /**
469 * Map a validated texture for reading during software rendering.
470 */
471 static void r300MapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
472 {
473 r300TexObj* t = r300_tex_obj(texObj);
474 int face, level;
475
476 assert(texObj->_Complete);
477 assert(t->mt);
478
479 radeon_bo_map(t->mt->bo, GL_FALSE);
480 for(face = 0; face < t->mt->faces; ++face) {
481 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level)
482 teximage_set_map_data(get_r300_texture_image(texObj->Image[face][level]));
483 }
484 }
485
486 static void r300UnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
487 {
488 r300TexObj* t = r300_tex_obj(texObj);
489 int face, level;
490
491 assert(texObj->_Complete);
492 assert(t->mt);
493
494 for(face = 0; face < t->mt->faces; ++face) {
495 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level)
496 texObj->Image[face][level]->Data = 0;
497 }
498 radeon_bo_unmap(t->mt->bo);
499 }
500
501 /**
502 * All glTexImage calls go through this function.
503 */
504 static void r300_teximage(
505 GLcontext *ctx, int dims,
506 GLint face, GLint level,
507 GLint internalFormat,
508 GLint width, GLint height, GLint depth,
509 GLsizei imageSize,
510 GLenum format, GLenum type, const GLvoid * pixels,
511 const struct gl_pixelstore_attrib *packing,
512 struct gl_texture_object *texObj,
513 struct gl_texture_image *texImage,
514 int compressed)
515 {
516 r300ContextPtr rmesa = R300_CONTEXT(ctx);
517 r300TexObj* t = r300_tex_obj(texObj);
518 r300_texture_image* image = get_r300_texture_image(texImage);
519
520 R300_FIREVERTICES(rmesa);
521
522 t->validated = GL_FALSE;
523
524 /* Choose and fill in the texture format for this image */
525 texImage->TexFormat = r300ChooseTextureFormat(ctx, internalFormat, format, type);
526 _mesa_set_fetch_functions(texImage, dims);
527
528 if (texImage->TexFormat->TexelBytes == 0) {
529 texImage->IsCompressed = GL_TRUE;
530 texImage->CompressedSize =
531 ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
532 texImage->Height, texImage->Depth,
533 texImage->TexFormat->MesaFormat);
534 } else {
535 texImage->IsCompressed = GL_FALSE;
536 texImage->CompressedSize = 0;
537 }
538
539 /* Allocate memory for image */
540 r300FreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */
541
542 if (!t->mt)
543 r300_try_alloc_miptree(rmesa, t, texImage, face, level);
544 if (t->mt && r300_miptree_matches_image(t->mt, texImage, face, level)) {
545 image->mt = t->mt;
546 image->mtlevel = level - t->mt->firstLevel;
547 image->mtface = face;
548 r300_miptree_reference(t->mt);
549 } else {
550 int size;
551 if (texImage->IsCompressed) {
552 size = texImage->CompressedSize;
553 } else {
554 size = texImage->Width * texImage->Height * texImage->Depth * texImage->TexFormat->TexelBytes;
555 }
556 texImage->Data = _mesa_alloc_texmemory(size);
557 }
558
559 /* Upload texture image; note that the spec allows pixels to be NULL */
560 if (compressed) {
561 pixels = _mesa_validate_pbo_compressed_teximage(
562 ctx, imageSize, pixels, packing, "glCompressedTexImage");
563 } else {
564 pixels = _mesa_validate_pbo_teximage(
565 ctx, dims, width, height, depth,
566 format, type, pixels, packing, "glTexImage");
567 }
568
569 if (pixels) {
570 r300_teximage_map(image, GL_TRUE);
571
572 if (compressed) {
573 memcpy(texImage->Data, pixels, imageSize);
574 } else {
575 GLuint dstRowStride;
576 if (image->mt) {
577 r300_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
578 dstRowStride = lvl->rowstride;
579 } else {
580 dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
581 }
582 if (!texImage->TexFormat->StoreImage(ctx, dims,
583 texImage->_BaseFormat,
584 texImage->TexFormat,
585 texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
586 dstRowStride,
587 texImage->ImageOffsets,
588 width, height, depth,
589 format, type, pixels, packing))
590 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
591 }
592
593 r300_teximage_unmap(image);
594 }
595
596 _mesa_unmap_teximage_pbo(ctx, packing);
597
598 /* SGIS_generate_mipmap */
599 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
600 ctx->Driver.GenerateMipmap(ctx, texObj->Target, texObj);
601 }
602 }
603
604
605 static GLuint face_for_target(GLenum target)
606 {
607 switch (target) {
608 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
609 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
610 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
611 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
612 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
613 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
614 return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
615 default:
616 return 0;
617 }
618 }
619
620
621 static void r300TexImage1D(GLcontext * ctx, GLenum target, GLint level,
622 GLint internalFormat,
623 GLint width, GLint border,
624 GLenum format, GLenum type, const GLvoid * pixels,
625 const struct gl_pixelstore_attrib *packing,
626 struct gl_texture_object *texObj,
627 struct gl_texture_image *texImage)
628 {
629 r300_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1,
630 0, format, type, pixels, packing, texObj, texImage, 0);
631 }
632
633 static void r300TexImage2D(GLcontext * ctx, GLenum target, GLint level,
634 GLint internalFormat,
635 GLint width, GLint height, GLint border,
636 GLenum format, GLenum type, const GLvoid * pixels,
637 const struct gl_pixelstore_attrib *packing,
638 struct gl_texture_object *texObj,
639 struct gl_texture_image *texImage)
640 {
641 GLuint face = face_for_target(target);
642
643 r300_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
644 0, format, type, pixels, packing, texObj, texImage, 0);
645 }
646
647 static void r300CompressedTexImage2D(GLcontext * ctx, GLenum target,
648 GLint level, GLint internalFormat,
649 GLint width, GLint height, GLint border,
650 GLsizei imageSize, const GLvoid * data,
651 struct gl_texture_object *texObj,
652 struct gl_texture_image *texImage)
653 {
654 GLuint face = face_for_target(target);
655
656 r300_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
657 imageSize, 0, 0, data, 0, texObj, texImage, 1);
658 }
659
660 static void r300TexImage3D(GLcontext * ctx, GLenum target, GLint level,
661 GLint internalFormat,
662 GLint width, GLint height, GLint depth,
663 GLint border,
664 GLenum format, GLenum type, const GLvoid * pixels,
665 const struct gl_pixelstore_attrib *packing,
666 struct gl_texture_object *texObj,
667 struct gl_texture_image *texImage)
668 {
669 r300_teximage(ctx, 3, 0, level, internalFormat, width, height, depth,
670 0, format, type, pixels, packing, texObj, texImage, 0);
671 }
672
673 /**
674 * Update a subregion of the given texture image.
675 */
676 static void r300_texsubimage(GLcontext* ctx, int dims, int level,
677 GLint xoffset, GLint yoffset, GLint zoffset,
678 GLsizei width, GLsizei height, GLsizei depth,
679 GLenum format, GLenum type,
680 const GLvoid * pixels,
681 const struct gl_pixelstore_attrib *packing,
682 struct gl_texture_object *texObj,
683 struct gl_texture_image *texImage,
684 int compressed)
685 {
686 r300ContextPtr rmesa = R300_CONTEXT(ctx);
687 r300_texture_image* image = get_r300_texture_image(texImage);
688
689 R300_FIREVERTICES(rmesa);
690
691 pixels = _mesa_validate_pbo_teximage(ctx, dims,
692 width, height, depth, format, type, pixels, packing, "glTexSubImage1D");
693
694 if (pixels) {
695 GLint dstRowStride;
696 r300_teximage_map(image, GL_TRUE);
697
698 if (image->mt) {
699 r300_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
700 dstRowStride = lvl->rowstride;
701 } else {
702 dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
703 }
704
705 if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
706 texImage->TexFormat, texImage->Data,
707 xoffset, yoffset, zoffset,
708 dstRowStride,
709 texImage->ImageOffsets,
710 width, height, depth,
711 format, type, pixels, packing))
712 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
713
714 r300_teximage_unmap(image);
715 }
716
717 _mesa_unmap_teximage_pbo(ctx, packing);
718
719 /* GL_SGIS_generate_mipmap */
720 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
721 ctx->Driver.GenerateMipmap(ctx, texObj->Target, texObj);
722 }
723 }
724
725 static void r300TexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
726 GLint xoffset,
727 GLsizei width,
728 GLenum format, GLenum type,
729 const GLvoid * pixels,
730 const struct gl_pixelstore_attrib *packing,
731 struct gl_texture_object *texObj,
732 struct gl_texture_image *texImage)
733 {
734 r300_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1,
735 format, type, pixels, packing, texObj, texImage, 0);
736 }
737
738 static void r300TexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
739 GLint xoffset, GLint yoffset,
740 GLsizei width, GLsizei height,
741 GLenum format, GLenum type,
742 const GLvoid * pixels,
743 const struct gl_pixelstore_attrib *packing,
744 struct gl_texture_object *texObj,
745 struct gl_texture_image *texImage)
746 {
747 r300_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
748 format, type, pixels, packing, texObj, texImage, 0);
749 }
750
751 static void r300CompressedTexSubImage2D(GLcontext * ctx, GLenum target,
752 GLint level, GLint xoffset,
753 GLint yoffset, GLsizei width,
754 GLsizei height, GLenum format,
755 GLsizei imageSize, const GLvoid * data,
756 struct gl_texture_object *texObj,
757 struct gl_texture_image *texImage)
758 {
759 r300_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
760 format, 0, data, 0, texObj, texImage, 1);
761 }
762
763 static void
764 r300TexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
765 GLint xoffset, GLint yoffset, GLint zoffset,
766 GLsizei width, GLsizei height, GLsizei depth,
767 GLenum format, GLenum type,
768 const GLvoid * pixels,
769 const struct gl_pixelstore_attrib *packing,
770 struct gl_texture_object *texObj,
771 struct gl_texture_image *texImage)
772 {
773 r300_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth,
774 format, type, pixels, packing, texObj, texImage, 0);
775 }
776
777
778 /**
779 * Wraps Mesa's implementation to ensure that the base level image is mapped.
780 *
781 * This relies on internal details of _mesa_generate_mipmap, in particular
782 * the fact that the memory for recreated texture images is always freed.
783 */
784 static void r300_generate_mipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj)
785 {
786 GLuint face = face_for_target(target);
787 r300_texture_image *baseimage = get_r300_texture_image(texObj->Image[face][texObj->BaseLevel]);
788
789 r300_teximage_map(baseimage, GL_FALSE);
790 _mesa_generate_mipmap(ctx, target, texObj);
791 r300_teximage_unmap(baseimage);
792 }
793
794
795
796 /**
797 * Changes variables and flags for a state update, which will happen at the
798 * next UpdateTextureState
799 */
800
801 static void r300TexParameter(GLcontext * ctx, GLenum target,
802 struct gl_texture_object *texObj,
803 GLenum pname, const GLfloat * params)
804 {
805 r300TexObj* t = r300_tex_obj(texObj);
806
807 if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
808 fprintf(stderr, "%s( %s )\n", __FUNCTION__,
809 _mesa_lookup_enum_by_nr(pname));
810 }
811
812 switch (pname) {
813 case GL_TEXTURE_MIN_FILTER:
814 case GL_TEXTURE_MAG_FILTER:
815 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
816 r300SetTexFilter(t, texObj->MinFilter, texObj->MagFilter, texObj->MaxAnisotropy);
817 break;
818
819 case GL_TEXTURE_WRAP_S:
820 case GL_TEXTURE_WRAP_T:
821 case GL_TEXTURE_WRAP_R:
822 r300UpdateTexWrap(t);
823 break;
824
825 case GL_TEXTURE_BORDER_COLOR:
826 r300SetTexBorderColor(t, texObj->_BorderChan);
827 break;
828
829 case GL_TEXTURE_BASE_LEVEL:
830 case GL_TEXTURE_MAX_LEVEL:
831 case GL_TEXTURE_MIN_LOD:
832 case GL_TEXTURE_MAX_LOD:
833 /* This isn't the most efficient solution but there doesn't appear to
834 * be a nice alternative. Since there's no LOD clamping,
835 * we just have to rely on loading the right subset of mipmap levels
836 * to simulate a clamped LOD.
837 */
838 if (t->mt) {
839 r300_miptree_unreference(t->mt);
840 t->mt = 0;
841 t->validated = GL_FALSE;
842 }
843 break;
844
845 case GL_DEPTH_TEXTURE_MODE:
846 if (!texObj->Image[0][texObj->BaseLevel])
847 return;
848 if (texObj->Image[0][texObj->BaseLevel]->TexFormat->BaseFormat
849 == GL_DEPTH_COMPONENT) {
850 r300SetDepthTexMode(texObj);
851 break;
852 } else {
853 /* If the texture isn't a depth texture, changing this
854 * state won't cause any changes to the hardware.
855 * Don't force a flush of texture state.
856 */
857 return;
858 }
859
860 default:
861 return;
862 }
863 }
864
865 static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj)
866 {
867 r300ContextPtr rmesa = R300_CONTEXT(ctx);
868 r300TexObj* t = r300_tex_obj(texObj);
869
870 if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
871 fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__,
872 (void *)texObj,
873 _mesa_lookup_enum_by_nr(texObj->Target));
874 }
875
876 if (rmesa) {
877 int i;
878 R300_FIREVERTICES(rmesa);
879
880 for(i = 0; i < R300_MAX_TEXTURE_UNITS; ++i)
881 if (rmesa->hw.textures[i] == t)
882 rmesa->hw.textures[i] = 0;
883 }
884
885 if (t->mt) {
886 r300_miptree_unreference(t->mt);
887 t->mt = 0;
888 }
889 _mesa_delete_texture_object(ctx, texObj);
890 }
891
892 /**
893 * Allocate a new texture object.
894 * Called via ctx->Driver.NewTextureObject.
895 * Note: this function will be called during context creation to
896 * allocate the default texture objects.
897 * Fixup MaxAnisotropy according to user preference.
898 */
899 static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx,
900 GLuint name,
901 GLenum target)
902 {
903 r300ContextPtr rmesa = R300_CONTEXT(ctx);
904 r300TexObj* t = CALLOC_STRUCT(r300_tex_obj);
905
906
907 if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
908 fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__,
909 t, _mesa_lookup_enum_by_nr(target));
910 }
911
912 _mesa_initialize_texture_object(&t->base, name, target);
913 t->base.MaxAnisotropy = rmesa->initialMaxAnisotropy;
914
915 /* Initialize hardware state */
916 r300UpdateTexWrap(t);
917 r300SetTexFilter(t, t->base.MinFilter, t->base.MagFilter, t->base.MaxAnisotropy);
918 r300SetTexBorderColor(t, t->base._BorderChan);
919
920 return &t->base;
921 }
922
923 void r300InitTextureFuncs(struct dd_function_table *functions)
924 {
925 /* Note: we only plug in the functions we implement in the driver
926 * since _mesa_init_driver_functions() was already called.
927 */
928 functions->NewTextureImage = r300NewTextureImage;
929 functions->FreeTexImageData = r300FreeTexImageData;
930 functions->MapTexture = r300MapTexture;
931 functions->UnmapTexture = r300UnmapTexture;
932
933 functions->ChooseTextureFormat = r300ChooseTextureFormat;
934 functions->TexImage1D = r300TexImage1D;
935 functions->TexImage2D = r300TexImage2D;
936 functions->TexImage3D = r300TexImage3D;
937 functions->TexSubImage1D = r300TexSubImage1D;
938 functions->TexSubImage2D = r300TexSubImage2D;
939 functions->TexSubImage3D = r300TexSubImage3D;
940 functions->NewTextureObject = r300NewTextureObject;
941 functions->DeleteTexture = r300DeleteTexture;
942 functions->IsTextureResident = driIsTextureResident;
943
944 functions->TexParameter = r300TexParameter;
945
946 functions->CompressedTexImage2D = r300CompressedTexImage2D;
947 functions->CompressedTexSubImage2D = r300CompressedTexSubImage2D;
948
949 functions->GenerateMipmap = r300_generate_mipmap;
950
951 driInitTextureFormats();
952 }