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