radeon: renaming and headers cleanup
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_texture.c
1 /*
2 * Copyright (C) 2008 Nicolai Haehnle.
3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4 *
5 * The Weather Channel (TM) funded Tungsten Graphics to develop the
6 * initial release of the Radeon 8500 driver under the XFree86 license.
7 * This notice must be preserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining
10 * a copy of this software and associated documentation files (the
11 * "Software"), to deal in the Software without restriction, including
12 * without limitation the rights to use, copy, modify, merge, publish,
13 * distribute, sublicense, and/or sell copies of the Software, and to
14 * permit persons to whom the Software is furnished to do so, subject to
15 * the following conditions:
16 *
17 * The above copyright notice and this permission notice (including the
18 * next paragraph) shall be included in all copies or substantial
19 * portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 *
29 */
30
31 #include "main/glheader.h"
32 #include "main/imports.h"
33 #include "main/context.h"
34 #include "main/mipmap.h"
35 #include "main/texformat.h"
36 #include "main/texstore.h"
37 #include "main/teximage.h"
38 #include "main/texobj.h"
39
40 #include "xmlpool.h" /* for symbolic values of enum-type options */
41
42 #include "radeon_common.h"
43
44 #include "radeon_mipmap_tree.h"
45
46 /* textures */
47 /**
48 * Allocate an empty texture image object.
49 */
50 struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx)
51 {
52 return CALLOC(sizeof(radeon_texture_image));
53 }
54
55 /**
56 * Free memory associated with this texture image.
57 */
58 void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage)
59 {
60 radeon_texture_image* image = get_radeon_texture_image(timage);
61
62 if (image->mt) {
63 radeon_miptree_unreference(image->mt);
64 image->mt = 0;
65 assert(!image->base.Data);
66 } else {
67 _mesa_free_texture_image_data(ctx, timage);
68 }
69 if (image->bo) {
70 radeon_bo_unref(image->bo);
71 image->bo = NULL;
72 }
73 if (timage->Data) {
74 _mesa_free_texmemory(timage->Data);
75 timage->Data = NULL;
76 }
77 }
78
79 /* Set Data pointer and additional data for mapped texture image */
80 static void teximage_set_map_data(radeon_texture_image *image)
81 {
82 radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
83
84 image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset;
85 image->base.RowStride = lvl->rowstride / image->mt->bpp;
86 }
87
88
89 /**
90 * Map a single texture image for glTexImage and friends.
91 */
92 void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable)
93 {
94 if (image->mt) {
95 assert(!image->base.Data);
96
97 radeon_bo_map(image->mt->bo, write_enable);
98 teximage_set_map_data(image);
99 }
100 }
101
102
103 void radeon_teximage_unmap(radeon_texture_image *image)
104 {
105 if (image->mt) {
106 assert(image->base.Data);
107
108 image->base.Data = 0;
109 radeon_bo_unmap(image->mt->bo);
110 }
111 }
112
113 /**
114 * Map a validated texture for reading during software rendering.
115 */
116 void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
117 {
118 radeonTexObj* t = radeon_tex_obj(texObj);
119 int face, level;
120
121 /* for r100 3D sw fallbacks don't have mt */
122 if (!t->mt)
123 return;
124
125 radeon_bo_map(t->mt->bo, GL_FALSE);
126 for(face = 0; face < t->mt->faces; ++face) {
127 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level)
128 teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level]));
129 }
130 }
131
132 void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
133 {
134 radeonTexObj* t = radeon_tex_obj(texObj);
135 int face, level;
136
137 /* for r100 3D sw fallbacks don't have mt */
138 if (!t->mt)
139 return;
140
141 for(face = 0; face < t->mt->faces; ++face) {
142 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level)
143 texObj->Image[face][level]->Data = 0;
144 }
145 radeon_bo_unmap(t->mt->bo);
146 }
147
148 GLuint radeon_face_for_target(GLenum target)
149 {
150 switch (target) {
151 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
152 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
153 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
154 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
155 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
156 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
157 return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
158 default:
159 return 0;
160 }
161 }
162
163 /**
164 * Wraps Mesa's implementation to ensure that the base level image is mapped.
165 *
166 * This relies on internal details of _mesa_generate_mipmap, in particular
167 * the fact that the memory for recreated texture images is always freed.
168 */
169 static void radeon_generate_mipmap(GLcontext *ctx, GLenum target,
170 struct gl_texture_object *texObj)
171 {
172 radeonTexObj* t = radeon_tex_obj(texObj);
173 GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
174 int i, face;
175
176
177 _mesa_generate_mipmap(ctx, target, texObj);
178
179 for (face = 0; face < nr_faces; face++) {
180 for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) {
181 radeon_texture_image *image;
182
183 image = get_radeon_texture_image(texObj->Image[face][i]);
184
185 if (image == NULL)
186 break;
187
188 image->mtlevel = i;
189 image->mtface = face;
190
191 radeon_miptree_unreference(image->mt);
192 image->mt = NULL;
193 }
194 }
195
196 }
197
198 void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj)
199 {
200 GLuint face = radeon_face_for_target(target);
201 radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]);
202
203 radeon_teximage_map(baseimage, GL_FALSE);
204 radeon_generate_mipmap(ctx, target, texObj);
205 radeon_teximage_unmap(baseimage);
206 }
207
208
209 /* try to find a format which will only need a memcopy */
210 static const struct gl_texture_format *radeonChoose8888TexFormat(radeonContextPtr rmesa,
211 GLenum srcFormat,
212 GLenum srcType)
213 {
214 const GLuint ui = 1;
215 const GLubyte littleEndian = *((const GLubyte *)&ui);
216
217 /* r100 can only do this */
218 if (IS_R100_CLASS(rmesa->radeonScreen))
219 return _dri_texformat_argb8888;
220
221 if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
222 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
223 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
224 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
225 return &_mesa_texformat_rgba8888;
226 } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
227 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
228 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
229 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
230 return &_mesa_texformat_rgba8888_rev;
231 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
232 srcType == GL_UNSIGNED_INT_8_8_8_8)) {
233 return &_mesa_texformat_argb8888_rev;
234 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
235 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
236 return &_mesa_texformat_argb8888;
237 } else
238 return _dri_texformat_argb8888;
239 }
240
241 const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
242 GLint internalFormat,
243 GLenum format,
244 GLenum type)
245 {
246 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
247 const GLboolean do32bpt =
248 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32);
249 const GLboolean force16bpt =
250 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16);
251 (void)format;
252
253 #if 0
254 fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n",
255 _mesa_lookup_enum_by_nr(internalFormat), internalFormat,
256 _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format));
257 fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt);
258 #endif
259
260 switch (internalFormat) {
261 case 4:
262 case GL_RGBA:
263 case GL_COMPRESSED_RGBA:
264 switch (type) {
265 case GL_UNSIGNED_INT_10_10_10_2:
266 case GL_UNSIGNED_INT_2_10_10_10_REV:
267 return do32bpt ? _dri_texformat_argb8888 :
268 _dri_texformat_argb1555;
269 case GL_UNSIGNED_SHORT_4_4_4_4:
270 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
271 return _dri_texformat_argb4444;
272 case GL_UNSIGNED_SHORT_5_5_5_1:
273 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
274 return _dri_texformat_argb1555;
275 default:
276 return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type) :
277 _dri_texformat_argb4444;
278 }
279
280 case 3:
281 case GL_RGB:
282 case GL_COMPRESSED_RGB:
283 switch (type) {
284 case GL_UNSIGNED_SHORT_4_4_4_4:
285 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
286 return _dri_texformat_argb4444;
287 case GL_UNSIGNED_SHORT_5_5_5_1:
288 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
289 return _dri_texformat_argb1555;
290 case GL_UNSIGNED_SHORT_5_6_5:
291 case GL_UNSIGNED_SHORT_5_6_5_REV:
292 return _dri_texformat_rgb565;
293 default:
294 return do32bpt ? _dri_texformat_argb8888 :
295 _dri_texformat_rgb565;
296 }
297
298 case GL_RGBA8:
299 case GL_RGB10_A2:
300 case GL_RGBA12:
301 case GL_RGBA16:
302 return !force16bpt ?
303 radeonChoose8888TexFormat(rmesa, format,type) :
304 _dri_texformat_argb4444;
305
306 case GL_RGBA4:
307 case GL_RGBA2:
308 return _dri_texformat_argb4444;
309
310 case GL_RGB5_A1:
311 return _dri_texformat_argb1555;
312
313 case GL_RGB8:
314 case GL_RGB10:
315 case GL_RGB12:
316 case GL_RGB16:
317 return !force16bpt ? _dri_texformat_argb8888 :
318 _dri_texformat_rgb565;
319
320 case GL_RGB5:
321 case GL_RGB4:
322 case GL_R3_G3_B2:
323 return _dri_texformat_rgb565;
324
325 case GL_ALPHA:
326 case GL_ALPHA4:
327 case GL_ALPHA8:
328 case GL_ALPHA12:
329 case GL_ALPHA16:
330 case GL_COMPRESSED_ALPHA:
331 return _dri_texformat_a8;
332
333 case 1:
334 case GL_LUMINANCE:
335 case GL_LUMINANCE4:
336 case GL_LUMINANCE8:
337 case GL_LUMINANCE12:
338 case GL_LUMINANCE16:
339 case GL_COMPRESSED_LUMINANCE:
340 return _dri_texformat_l8;
341
342 case 2:
343 case GL_LUMINANCE_ALPHA:
344 case GL_LUMINANCE4_ALPHA4:
345 case GL_LUMINANCE6_ALPHA2:
346 case GL_LUMINANCE8_ALPHA8:
347 case GL_LUMINANCE12_ALPHA4:
348 case GL_LUMINANCE12_ALPHA12:
349 case GL_LUMINANCE16_ALPHA16:
350 case GL_COMPRESSED_LUMINANCE_ALPHA:
351 return _dri_texformat_al88;
352
353 case GL_INTENSITY:
354 case GL_INTENSITY4:
355 case GL_INTENSITY8:
356 case GL_INTENSITY12:
357 case GL_INTENSITY16:
358 case GL_COMPRESSED_INTENSITY:
359 return _dri_texformat_i8;
360
361 case GL_YCBCR_MESA:
362 if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
363 type == GL_UNSIGNED_BYTE)
364 return &_mesa_texformat_ycbcr;
365 else
366 return &_mesa_texformat_ycbcr_rev;
367
368 case GL_RGB_S3TC:
369 case GL_RGB4_S3TC:
370 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
371 return &_mesa_texformat_rgb_dxt1;
372
373 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
374 return &_mesa_texformat_rgba_dxt1;
375
376 case GL_RGBA_S3TC:
377 case GL_RGBA4_S3TC:
378 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
379 return &_mesa_texformat_rgba_dxt3;
380
381 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
382 return &_mesa_texformat_rgba_dxt5;
383
384 case GL_ALPHA16F_ARB:
385 return &_mesa_texformat_alpha_float16;
386 case GL_ALPHA32F_ARB:
387 return &_mesa_texformat_alpha_float32;
388 case GL_LUMINANCE16F_ARB:
389 return &_mesa_texformat_luminance_float16;
390 case GL_LUMINANCE32F_ARB:
391 return &_mesa_texformat_luminance_float32;
392 case GL_LUMINANCE_ALPHA16F_ARB:
393 return &_mesa_texformat_luminance_alpha_float16;
394 case GL_LUMINANCE_ALPHA32F_ARB:
395 return &_mesa_texformat_luminance_alpha_float32;
396 case GL_INTENSITY16F_ARB:
397 return &_mesa_texformat_intensity_float16;
398 case GL_INTENSITY32F_ARB:
399 return &_mesa_texformat_intensity_float32;
400 case GL_RGB16F_ARB:
401 return &_mesa_texformat_rgba_float16;
402 case GL_RGB32F_ARB:
403 return &_mesa_texformat_rgba_float32;
404 case GL_RGBA16F_ARB:
405 return &_mesa_texformat_rgba_float16;
406 case GL_RGBA32F_ARB:
407 return &_mesa_texformat_rgba_float32;
408
409 case GL_DEPTH_COMPONENT:
410 case GL_DEPTH_COMPONENT16:
411 case GL_DEPTH_COMPONENT24:
412 case GL_DEPTH_COMPONENT32:
413 #if 0
414 switch (type) {
415 case GL_UNSIGNED_BYTE:
416 case GL_UNSIGNED_SHORT:
417 return &_mesa_texformat_z16;
418 case GL_UNSIGNED_INT:
419 return &_mesa_texformat_z32;
420 case GL_UNSIGNED_INT_24_8_EXT:
421 default:
422 return &_mesa_texformat_z24_s8;
423 }
424 #else
425 return &_mesa_texformat_z16;
426 #endif
427
428 default:
429 _mesa_problem(ctx,
430 "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
431 (int)internalFormat);
432 return NULL;
433 }
434
435 return NULL; /* never get here */
436 }
437
438 /**
439 * All glTexImage calls go through this function.
440 */
441 static void radeon_teximage(
442 GLcontext *ctx, int dims,
443 GLint face, GLint level,
444 GLint internalFormat,
445 GLint width, GLint height, GLint depth,
446 GLsizei imageSize,
447 GLenum format, GLenum type, const GLvoid * pixels,
448 const struct gl_pixelstore_attrib *packing,
449 struct gl_texture_object *texObj,
450 struct gl_texture_image *texImage,
451 int compressed)
452 {
453 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
454 radeonTexObj* t = radeon_tex_obj(texObj);
455 radeon_texture_image* image = get_radeon_texture_image(texImage);
456
457 radeon_firevertices(rmesa);
458
459 t->validated = GL_FALSE;
460
461 /* Choose and fill in the texture format for this image */
462 texImage->TexFormat = radeonChooseTextureFormat(ctx, internalFormat, format, type);
463 _mesa_set_fetch_functions(texImage, dims);
464
465 if (texImage->TexFormat->TexelBytes == 0) {
466 texImage->IsCompressed = GL_TRUE;
467 texImage->CompressedSize =
468 ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
469 texImage->Height, texImage->Depth,
470 texImage->TexFormat->MesaFormat);
471 } else {
472 texImage->IsCompressed = GL_FALSE;
473 texImage->CompressedSize = 0;
474 }
475
476 /* Allocate memory for image */
477 radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */
478
479 if (!t->mt)
480 radeon_try_alloc_miptree(rmesa, t, texImage, face, level);
481 if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) {
482 image->mt = t->mt;
483 image->mtlevel = level - t->mt->firstLevel;
484 image->mtface = face;
485 radeon_miptree_reference(t->mt);
486 } else {
487 int size;
488 if (texImage->IsCompressed) {
489 size = texImage->CompressedSize;
490 } else {
491 size = texImage->Width * texImage->Height * texImage->Depth * texImage->TexFormat->TexelBytes;
492 }
493 texImage->Data = _mesa_alloc_texmemory(size);
494 }
495
496 /* Upload texture image; note that the spec allows pixels to be NULL */
497 if (compressed) {
498 pixels = _mesa_validate_pbo_compressed_teximage(
499 ctx, imageSize, pixels, packing, "glCompressedTexImage");
500 } else {
501 pixels = _mesa_validate_pbo_teximage(
502 ctx, dims, width, height, depth,
503 format, type, pixels, packing, "glTexImage");
504 }
505
506 if (pixels) {
507 radeon_teximage_map(image, GL_TRUE);
508
509 if (compressed) {
510 memcpy(texImage->Data, pixels, imageSize);
511 } else {
512 GLuint dstRowStride;
513 if (image->mt) {
514 radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
515 dstRowStride = lvl->rowstride;
516 } else {
517 dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
518 }
519 if (!texImage->TexFormat->StoreImage(ctx, dims,
520 texImage->_BaseFormat,
521 texImage->TexFormat,
522 texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
523 dstRowStride,
524 texImage->ImageOffsets,
525 width, height, depth,
526 format, type, pixels, packing))
527 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
528 }
529
530 }
531
532 /* SGIS_generate_mipmap */
533 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
534 radeon_generate_mipmap(ctx, texObj->Target, texObj);
535 }
536
537 if (pixels)
538 radeon_teximage_unmap(image);
539
540 _mesa_unmap_teximage_pbo(ctx, packing);
541
542
543 }
544
545 void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level,
546 GLint internalFormat,
547 GLint width, GLint border,
548 GLenum format, GLenum type, const GLvoid * pixels,
549 const struct gl_pixelstore_attrib *packing,
550 struct gl_texture_object *texObj,
551 struct gl_texture_image *texImage)
552 {
553 radeon_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1,
554 0, format, type, pixels, packing, texObj, texImage, 0);
555 }
556
557 void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level,
558 GLint internalFormat,
559 GLint width, GLint height, GLint border,
560 GLenum format, GLenum type, const GLvoid * pixels,
561 const struct gl_pixelstore_attrib *packing,
562 struct gl_texture_object *texObj,
563 struct gl_texture_image *texImage)
564
565 {
566 GLuint face = radeon_face_for_target(target);
567
568 radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
569 0, format, type, pixels, packing, texObj, texImage, 0);
570 }
571
572 void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target,
573 GLint level, GLint internalFormat,
574 GLint width, GLint height, GLint border,
575 GLsizei imageSize, const GLvoid * data,
576 struct gl_texture_object *texObj,
577 struct gl_texture_image *texImage)
578 {
579 GLuint face = radeon_face_for_target(target);
580
581 radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
582 imageSize, 0, 0, data, 0, texObj, texImage, 1);
583 }
584
585 void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
586 GLint internalFormat,
587 GLint width, GLint height, GLint depth,
588 GLint border,
589 GLenum format, GLenum type, const GLvoid * pixels,
590 const struct gl_pixelstore_attrib *packing,
591 struct gl_texture_object *texObj,
592 struct gl_texture_image *texImage)
593 {
594 radeon_teximage(ctx, 3, 0, level, internalFormat, width, height, depth,
595 0, format, type, pixels, packing, texObj, texImage, 0);
596 }
597
598 /**
599 * Update a subregion of the given texture image.
600 */
601 static void radeon_texsubimage(GLcontext* ctx, int dims, int level,
602 GLint xoffset, GLint yoffset, GLint zoffset,
603 GLsizei width, GLsizei height, GLsizei depth,
604 GLenum format, GLenum type,
605 const GLvoid * pixels,
606 const struct gl_pixelstore_attrib *packing,
607 struct gl_texture_object *texObj,
608 struct gl_texture_image *texImage,
609 int compressed)
610 {
611 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
612 radeonTexObj* t = radeon_tex_obj(texObj);
613 radeon_texture_image* image = get_radeon_texture_image(texImage);
614
615 radeon_firevertices(rmesa);
616
617 t->validated = GL_FALSE;
618 pixels = _mesa_validate_pbo_teximage(ctx, dims,
619 width, height, depth, format, type, pixels, packing, "glTexSubImage1D");
620
621 if (pixels) {
622 GLint dstRowStride;
623 radeon_teximage_map(image, GL_TRUE);
624
625 if (image->mt) {
626 radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
627 dstRowStride = lvl->rowstride;
628 } else {
629 dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
630 }
631
632 if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
633 texImage->TexFormat, texImage->Data,
634 xoffset, yoffset, zoffset,
635 dstRowStride,
636 texImage->ImageOffsets,
637 width, height, depth,
638 format, type, pixels, packing))
639 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
640
641
642 }
643
644 /* GL_SGIS_generate_mipmap */
645 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
646 radeon_generate_mipmap(ctx, texObj->Target, texObj);
647 }
648 radeon_teximage_unmap(image);
649
650 _mesa_unmap_teximage_pbo(ctx, packing);
651
652
653 }
654
655 void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
656 GLint xoffset,
657 GLsizei width,
658 GLenum format, GLenum type,
659 const GLvoid * pixels,
660 const struct gl_pixelstore_attrib *packing,
661 struct gl_texture_object *texObj,
662 struct gl_texture_image *texImage)
663 {
664 radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1,
665 format, type, pixels, packing, texObj, texImage, 0);
666 }
667
668 void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
669 GLint xoffset, GLint yoffset,
670 GLsizei width, GLsizei height,
671 GLenum format, GLenum type,
672 const GLvoid * pixels,
673 const struct gl_pixelstore_attrib *packing,
674 struct gl_texture_object *texObj,
675 struct gl_texture_image *texImage)
676 {
677 radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height,
678 1, format, type, pixels, packing, texObj, texImage,
679 0);
680 }
681
682 void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target,
683 GLint level, GLint xoffset,
684 GLint yoffset, GLsizei width,
685 GLsizei height, GLenum format,
686 GLsizei imageSize, const GLvoid * data,
687 struct gl_texture_object *texObj,
688 struct gl_texture_image *texImage)
689 {
690 radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
691 format, 0, data, 0, texObj, texImage, 1);
692 }
693
694
695 void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
696 GLint xoffset, GLint yoffset, GLint zoffset,
697 GLsizei width, GLsizei height, GLsizei depth,
698 GLenum format, GLenum type,
699 const GLvoid * pixels,
700 const struct gl_pixelstore_attrib *packing,
701 struct gl_texture_object *texObj,
702 struct gl_texture_image *texImage)
703 {
704 radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth,
705 format, type, pixels, packing, texObj, texImage, 0);
706 }
707
708 static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
709 GLuint numrows, GLuint rowsize)
710 {
711 assert(rowsize <= dststride);
712 assert(rowsize <= srcstride);
713
714 if (rowsize == srcstride && rowsize == dststride) {
715 memcpy(dst, src, numrows*rowsize);
716 } else {
717 GLuint i;
718 for(i = 0; i < numrows; ++i) {
719 memcpy(dst, src, rowsize);
720 dst += dststride;
721 src += srcstride;
722 }
723 }
724 }
725
726
727 /**
728 * Ensure that the given image is stored in the given miptree from now on.
729 */
730 static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, int face, int level)
731 {
732 radeon_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel];
733 unsigned char *dest;
734
735 assert(image->mt != mt);
736 assert(dstlvl->width == image->base.Width);
737 assert(dstlvl->height == image->base.Height);
738 assert(dstlvl->depth == image->base.Depth);
739
740
741 radeon_bo_map(mt->bo, GL_TRUE);
742 dest = mt->bo->ptr + dstlvl->faces[face].offset;
743
744 if (image->mt) {
745 /* Format etc. should match, so we really just need a memcpy().
746 * In fact, that memcpy() could be done by the hardware in many
747 * cases, provided that we have a proper memory manager.
748 */
749 radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel];
750
751 assert(srclvl->size == dstlvl->size);
752 assert(srclvl->rowstride == dstlvl->rowstride);
753
754 radeon_bo_map(image->mt->bo, GL_FALSE);
755
756 memcpy(dest,
757 image->mt->bo->ptr + srclvl->faces[face].offset,
758 dstlvl->size);
759 radeon_bo_unmap(image->mt->bo);
760
761 radeon_miptree_unreference(image->mt);
762 } else {
763 uint srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
764
765 // if (mt->tilebits)
766 // WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
767
768 copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride,
769 image->base.Height * image->base.Depth, srcrowstride);
770
771 _mesa_free_texmemory(image->base.Data);
772 image->base.Data = 0;
773 }
774
775 radeon_bo_unmap(mt->bo);
776
777 image->mt = mt;
778 image->mtface = face;
779 image->mtlevel = level;
780 radeon_miptree_reference(image->mt);
781 }
782
783 int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj)
784 {
785 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
786 radeonTexObj *t = radeon_tex_obj(texObj);
787 radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[0][texObj->BaseLevel]);
788 int face, level;
789
790 if (t->validated || t->image_override)
791 return GL_TRUE;
792
793 if (RADEON_DEBUG & DEBUG_TEXTURE)
794 fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj);
795
796 if (baseimage->base.Border > 0)
797 return GL_FALSE;
798
799 /* Ensure a matching miptree exists.
800 *
801 * Differing mipmap trees can result when the app uses TexImage to
802 * change texture dimensions.
803 *
804 * Prefer to use base image's miptree if it
805 * exists, since that most likely contains more valid data (remember
806 * that the base level is usually significantly larger than the rest
807 * of the miptree, so cubemaps are the only possible exception).
808 */
809 if (baseimage->mt &&
810 baseimage->mt != t->mt &&
811 radeon_miptree_matches_texture(baseimage->mt, &t->base)) {
812 radeon_miptree_unreference(t->mt);
813 t->mt = baseimage->mt;
814 radeon_miptree_reference(t->mt);
815 } else if (t->mt && !radeon_miptree_matches_texture(t->mt, &t->base)) {
816 radeon_miptree_unreference(t->mt);
817 t->mt = 0;
818 }
819
820 if (!t->mt) {
821 if (RADEON_DEBUG & DEBUG_TEXTURE)
822 fprintf(stderr, " Allocate new miptree\n");
823 radeon_try_alloc_miptree(rmesa, t, &baseimage->base, 0, texObj->BaseLevel);
824 if (!t->mt) {
825 _mesa_problem(ctx, "r300_validate_texture failed to alloc miptree");
826 return GL_FALSE;
827 }
828 }
829
830 /* Ensure all images are stored in the single main miptree */
831 for(face = 0; face < t->mt->faces; ++face) {
832 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) {
833 radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]);
834 if (RADEON_DEBUG & DEBUG_TEXTURE)
835 fprintf(stderr, " face %i, level %i... %p vs %p ", face, level, t->mt, image->mt);
836 if (t->mt == image->mt) {
837 if (RADEON_DEBUG & DEBUG_TEXTURE)
838 fprintf(stderr, "OK\n");
839 continue;
840 }
841
842 if (RADEON_DEBUG & DEBUG_TEXTURE)
843 fprintf(stderr, "migrating\n");
844 migrate_image_to_miptree(t->mt, image, face, level);
845 }
846 }
847
848 return GL_TRUE;
849 }