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