Merge branch 'mesa_7_7_branch'
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_texture.c
1 /*
2 * Copyright (C) 2009 Maciej Cencora.
3 * Copyright (C) 2008 Nicolai Haehnle.
4 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
5 *
6 * The Weather Channel (TM) funded Tungsten Graphics to develop the
7 * initial release of the Radeon 8500 driver under the XFree86 license.
8 * This notice must be preserved.
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining
11 * a copy of this software and associated documentation files (the
12 * "Software"), to deal in the Software without restriction, including
13 * without limitation the rights to use, copy, modify, merge, publish,
14 * distribute, sublicense, and/or sell copies of the Software, and to
15 * permit persons to whom the Software is furnished to do so, subject to
16 * the following conditions:
17 *
18 * The above copyright notice and this permission notice (including the
19 * next paragraph) shall be included in all copies or substantial
20 * portions of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
26 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 *
30 */
31
32 #include "main/glheader.h"
33 #include "main/imports.h"
34 #include "main/context.h"
35 #include "main/convolve.h"
36 #include "main/mipmap.h"
37 #include "main/texcompress.h"
38 #include "main/texstore.h"
39 #include "main/teximage.h"
40 #include "main/texobj.h"
41 #include "main/texgetimage.h"
42
43 #include "xmlpool.h" /* for symbolic values of enum-type options */
44
45 #include "radeon_common.h"
46
47 #include "radeon_mipmap_tree.h"
48
49
50 void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
51 GLuint numrows, GLuint rowsize)
52 {
53 assert(rowsize <= dststride);
54 assert(rowsize <= srcstride);
55
56 if (rowsize == srcstride && rowsize == dststride) {
57 memcpy(dst, src, numrows*rowsize);
58 } else {
59 GLuint i;
60 for(i = 0; i < numrows; ++i) {
61 memcpy(dst, src, rowsize);
62 dst += dststride;
63 src += srcstride;
64 }
65 }
66 }
67
68 /* textures */
69 /**
70 * Allocate an empty texture image object.
71 */
72 struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx)
73 {
74 return CALLOC(sizeof(radeon_texture_image));
75 }
76
77 /**
78 * Free memory associated with this texture image.
79 */
80 void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage)
81 {
82 radeon_texture_image* image = get_radeon_texture_image(timage);
83
84 if (image->mt) {
85 radeon_miptree_unreference(&image->mt);
86 assert(!image->base.Data);
87 } else {
88 _mesa_free_texture_image_data(ctx, timage);
89 }
90 if (image->bo) {
91 radeon_bo_unref(image->bo);
92 image->bo = NULL;
93 }
94 if (timage->Data) {
95 _mesa_free_texmemory(timage->Data);
96 timage->Data = NULL;
97 }
98 }
99
100 /* Set Data pointer and additional data for mapped texture image */
101 static void teximage_set_map_data(radeon_texture_image *image)
102 {
103 radeon_mipmap_level *lvl;
104
105 if (!image->mt)
106 return;
107
108 lvl = &image->mt->levels[image->mtlevel];
109
110 image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset;
111 image->base.RowStride = lvl->rowstride / _mesa_get_format_bytes(image->base.TexFormat);
112 }
113
114
115 /**
116 * Map a single texture image for glTexImage and friends.
117 */
118 void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable)
119 {
120 if (image->mt) {
121 assert(!image->base.Data);
122
123 radeon_bo_map(image->mt->bo, write_enable);
124 teximage_set_map_data(image);
125 }
126 }
127
128
129 void radeon_teximage_unmap(radeon_texture_image *image)
130 {
131 if (image->mt) {
132 assert(image->base.Data);
133
134 image->base.Data = 0;
135 radeon_bo_unmap(image->mt->bo);
136 }
137 }
138
139 static void map_override(GLcontext *ctx, radeonTexObj *t)
140 {
141 radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
142
143 radeon_bo_map(t->bo, GL_FALSE);
144
145 img->base.Data = t->bo->ptr;
146 }
147
148 static void unmap_override(GLcontext *ctx, radeonTexObj *t)
149 {
150 radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
151
152 radeon_bo_unmap(t->bo);
153
154 img->base.Data = NULL;
155 }
156
157 /**
158 * Map a validated texture for reading during software rendering.
159 */
160 void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
161 {
162 radeonTexObj* t = radeon_tex_obj(texObj);
163 int face, level;
164
165 if (!radeon_validate_texture_miptree(ctx, texObj))
166 return;
167
168 /* for r100 3D sw fallbacks don't have mt */
169 if (t->image_override && t->bo)
170 map_override(ctx, t);
171
172 if (!t->mt)
173 return;
174
175 radeon_bo_map(t->mt->bo, GL_FALSE);
176 for(face = 0; face < t->mt->faces; ++face) {
177 for(level = t->minLod; level <= t->maxLod; ++level)
178 teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level]));
179 }
180 }
181
182 void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
183 {
184 radeonTexObj* t = radeon_tex_obj(texObj);
185 int face, level;
186
187 if (t->image_override && t->bo)
188 unmap_override(ctx, t);
189 /* for r100 3D sw fallbacks don't have mt */
190 if (!t->mt)
191 return;
192
193 for(face = 0; face < t->mt->faces; ++face) {
194 for(level = t->minLod; level <= t->maxLod; ++level)
195 texObj->Image[face][level]->Data = 0;
196 }
197 radeon_bo_unmap(t->mt->bo);
198 }
199
200 /**
201 * Wraps Mesa's implementation to ensure that the base level image is mapped.
202 *
203 * This relies on internal details of _mesa_generate_mipmap, in particular
204 * the fact that the memory for recreated texture images is always freed.
205 */
206 static void radeon_generate_mipmap(GLcontext *ctx, GLenum target,
207 struct gl_texture_object *texObj)
208 {
209 radeonTexObj* t = radeon_tex_obj(texObj);
210 GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
211 int i, face;
212
213
214 _mesa_generate_mipmap(ctx, target, texObj);
215
216 for (face = 0; face < nr_faces; face++) {
217 for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) {
218 radeon_texture_image *image;
219
220 image = get_radeon_texture_image(texObj->Image[face][i]);
221
222 if (image == NULL)
223 break;
224
225 image->mtlevel = i;
226 image->mtface = face;
227
228 radeon_miptree_unreference(&image->mt);
229 }
230 }
231
232 }
233
234 void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj)
235 {
236 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
237 struct radeon_bo *bo;
238 GLuint face = _mesa_tex_target_to_face(target);
239 radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]);
240 bo = !baseimage->mt ? baseimage->bo : baseimage->mt->bo;
241
242 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
243 radeon_firevertices(rmesa);
244 }
245
246 radeon_teximage_map(baseimage, GL_FALSE);
247 radeon_generate_mipmap(ctx, target, texObj);
248 radeon_teximage_unmap(baseimage);
249 }
250
251
252 /* try to find a format which will only need a memcopy */
253 static gl_format radeonChoose8888TexFormat(radeonContextPtr rmesa,
254 GLenum srcFormat,
255 GLenum srcType, GLboolean fbo)
256 {
257 const GLuint ui = 1;
258 const GLubyte littleEndian = *((const GLubyte *)&ui);
259
260 /* r100 can only do this */
261 if (IS_R100_CLASS(rmesa->radeonScreen) || fbo)
262 return _dri_texformat_argb8888;
263
264 if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
265 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
266 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
267 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
268 return MESA_FORMAT_RGBA8888;
269 } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
270 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
271 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
272 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
273 return MESA_FORMAT_RGBA8888_REV;
274 } else if (IS_R200_CLASS(rmesa->radeonScreen)) {
275 return _dri_texformat_argb8888;
276 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
277 srcType == GL_UNSIGNED_INT_8_8_8_8)) {
278 return MESA_FORMAT_ARGB8888_REV;
279 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
280 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
281 return MESA_FORMAT_ARGB8888;
282 } else
283 return _dri_texformat_argb8888;
284 }
285
286 gl_format radeonChooseTextureFormat_mesa(GLcontext * ctx,
287 GLint internalFormat,
288 GLenum format,
289 GLenum type)
290 {
291 return radeonChooseTextureFormat(ctx, internalFormat, format,
292 type, 0);
293 }
294
295 gl_format radeonChooseTextureFormat(GLcontext * ctx,
296 GLint internalFormat,
297 GLenum format,
298 GLenum type, GLboolean fbo)
299 {
300 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
301 const GLboolean do32bpt =
302 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32);
303 const GLboolean force16bpt =
304 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16);
305 (void)format;
306
307 #if 0
308 fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n",
309 _mesa_lookup_enum_by_nr(internalFormat), internalFormat,
310 _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format));
311 fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt);
312 #endif
313
314 switch (internalFormat) {
315 case 4:
316 case GL_RGBA:
317 case GL_COMPRESSED_RGBA:
318 switch (type) {
319 case GL_UNSIGNED_INT_10_10_10_2:
320 case GL_UNSIGNED_INT_2_10_10_10_REV:
321 return do32bpt ? _dri_texformat_argb8888 :
322 _dri_texformat_argb1555;
323 case GL_UNSIGNED_SHORT_4_4_4_4:
324 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
325 return _dri_texformat_argb4444;
326 case GL_UNSIGNED_SHORT_5_5_5_1:
327 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
328 return _dri_texformat_argb1555;
329 default:
330 return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type, fbo) :
331 _dri_texformat_argb4444;
332 }
333
334 case 3:
335 case GL_RGB:
336 case GL_COMPRESSED_RGB:
337 switch (type) {
338 case GL_UNSIGNED_SHORT_4_4_4_4:
339 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
340 return _dri_texformat_argb4444;
341 case GL_UNSIGNED_SHORT_5_5_5_1:
342 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
343 return _dri_texformat_argb1555;
344 case GL_UNSIGNED_SHORT_5_6_5:
345 case GL_UNSIGNED_SHORT_5_6_5_REV:
346 return _dri_texformat_rgb565;
347 default:
348 return do32bpt ? _dri_texformat_argb8888 :
349 _dri_texformat_rgb565;
350 }
351
352 case GL_RGBA8:
353 case GL_RGB10_A2:
354 case GL_RGBA12:
355 case GL_RGBA16:
356 return !force16bpt ?
357 radeonChoose8888TexFormat(rmesa, format, type, fbo) :
358 _dri_texformat_argb4444;
359
360 case GL_RGBA4:
361 case GL_RGBA2:
362 return _dri_texformat_argb4444;
363
364 case GL_RGB5_A1:
365 return _dri_texformat_argb1555;
366
367 case GL_RGB8:
368 case GL_RGB10:
369 case GL_RGB12:
370 case GL_RGB16:
371 return !force16bpt ? _dri_texformat_argb8888 :
372 _dri_texformat_rgb565;
373
374 case GL_RGB5:
375 case GL_RGB4:
376 case GL_R3_G3_B2:
377 return _dri_texformat_rgb565;
378
379 case GL_ALPHA:
380 case GL_ALPHA4:
381 case GL_ALPHA8:
382 case GL_ALPHA12:
383 case GL_ALPHA16:
384 case GL_COMPRESSED_ALPHA:
385 /* r200: can't use a8 format since interpreting hw I8 as a8 would result
386 in wrong rgb values (same as alpha value instead of 0). */
387 if (IS_R200_CLASS(rmesa->radeonScreen))
388 return _dri_texformat_al88;
389 else
390 return _dri_texformat_a8;
391 case 1:
392 case GL_LUMINANCE:
393 case GL_LUMINANCE4:
394 case GL_LUMINANCE8:
395 case GL_LUMINANCE12:
396 case GL_LUMINANCE16:
397 case GL_COMPRESSED_LUMINANCE:
398 return _dri_texformat_l8;
399
400 case 2:
401 case GL_LUMINANCE_ALPHA:
402 case GL_LUMINANCE4_ALPHA4:
403 case GL_LUMINANCE6_ALPHA2:
404 case GL_LUMINANCE8_ALPHA8:
405 case GL_LUMINANCE12_ALPHA4:
406 case GL_LUMINANCE12_ALPHA12:
407 case GL_LUMINANCE16_ALPHA16:
408 case GL_COMPRESSED_LUMINANCE_ALPHA:
409 return _dri_texformat_al88;
410
411 case GL_INTENSITY:
412 case GL_INTENSITY4:
413 case GL_INTENSITY8:
414 case GL_INTENSITY12:
415 case GL_INTENSITY16:
416 case GL_COMPRESSED_INTENSITY:
417 return _dri_texformat_i8;
418
419 case GL_YCBCR_MESA:
420 if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
421 type == GL_UNSIGNED_BYTE)
422 return MESA_FORMAT_YCBCR;
423 else
424 return MESA_FORMAT_YCBCR_REV;
425
426 case GL_RGB_S3TC:
427 case GL_RGB4_S3TC:
428 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
429 return MESA_FORMAT_RGB_DXT1;
430
431 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
432 return MESA_FORMAT_RGBA_DXT1;
433
434 case GL_RGBA_S3TC:
435 case GL_RGBA4_S3TC:
436 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
437 return MESA_FORMAT_RGBA_DXT3;
438
439 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
440 return MESA_FORMAT_RGBA_DXT5;
441
442 case GL_ALPHA16F_ARB:
443 return MESA_FORMAT_ALPHA_FLOAT16;
444 case GL_ALPHA32F_ARB:
445 return MESA_FORMAT_ALPHA_FLOAT32;
446 case GL_LUMINANCE16F_ARB:
447 return MESA_FORMAT_LUMINANCE_FLOAT16;
448 case GL_LUMINANCE32F_ARB:
449 return MESA_FORMAT_LUMINANCE_FLOAT32;
450 case GL_LUMINANCE_ALPHA16F_ARB:
451 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16;
452 case GL_LUMINANCE_ALPHA32F_ARB:
453 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32;
454 case GL_INTENSITY16F_ARB:
455 return MESA_FORMAT_INTENSITY_FLOAT16;
456 case GL_INTENSITY32F_ARB:
457 return MESA_FORMAT_INTENSITY_FLOAT32;
458 case GL_RGB16F_ARB:
459 return MESA_FORMAT_RGBA_FLOAT16;
460 case GL_RGB32F_ARB:
461 return MESA_FORMAT_RGBA_FLOAT32;
462 case GL_RGBA16F_ARB:
463 return MESA_FORMAT_RGBA_FLOAT16;
464 case GL_RGBA32F_ARB:
465 return MESA_FORMAT_RGBA_FLOAT32;
466
467 #ifdef RADEON_R300
468 case GL_DEPTH_COMPONENT:
469 case GL_DEPTH_COMPONENT16:
470 return MESA_FORMAT_Z16;
471 case GL_DEPTH_COMPONENT24:
472 case GL_DEPTH_COMPONENT32:
473 case GL_DEPTH_STENCIL_EXT:
474 case GL_DEPTH24_STENCIL8_EXT:
475 if (rmesa->radeonScreen->chip_family >= CHIP_FAMILY_RV515)
476 return MESA_FORMAT_S8_Z24;
477 else
478 return MESA_FORMAT_Z16;
479 #else
480 case GL_DEPTH_COMPONENT:
481 case GL_DEPTH_COMPONENT16:
482 case GL_DEPTH_COMPONENT24:
483 case GL_DEPTH_COMPONENT32:
484 case GL_DEPTH_STENCIL_EXT:
485 case GL_DEPTH24_STENCIL8_EXT:
486 return MESA_FORMAT_S8_Z24;
487 #endif
488
489 /* EXT_texture_sRGB */
490 case GL_SRGB:
491 case GL_SRGB8:
492 case GL_SRGB_ALPHA:
493 case GL_SRGB8_ALPHA8:
494 case GL_COMPRESSED_SRGB:
495 case GL_COMPRESSED_SRGB_ALPHA:
496 return MESA_FORMAT_SRGBA8;
497
498 case GL_SLUMINANCE:
499 case GL_SLUMINANCE8:
500 case GL_COMPRESSED_SLUMINANCE:
501 return MESA_FORMAT_SL8;
502
503 case GL_SLUMINANCE_ALPHA:
504 case GL_SLUMINANCE8_ALPHA8:
505 case GL_COMPRESSED_SLUMINANCE_ALPHA:
506 return MESA_FORMAT_SLA8;
507
508 default:
509 _mesa_problem(ctx,
510 "unexpected internalFormat 0x%x in %s",
511 (int)internalFormat, __func__);
512 return MESA_FORMAT_NONE;
513 }
514
515 return MESA_FORMAT_NONE; /* never get here */
516 }
517
518 /** Check if given image is valid within current texture object.
519 */
520 static int image_matches_texture_obj(struct gl_texture_object *texObj,
521 struct gl_texture_image *texImage,
522 unsigned level)
523 {
524 const struct gl_texture_image *baseImage = texObj->Image[0][texObj->BaseLevel];
525
526 if (!baseImage)
527 return 0;
528
529 if (level < texObj->BaseLevel || level > texObj->MaxLevel)
530 return 0;
531
532 const unsigned levelDiff = level - texObj->BaseLevel;
533 const unsigned refWidth = MAX2(baseImage->Width >> levelDiff, 1);
534 const unsigned refHeight = MAX2(baseImage->Height >> levelDiff, 1);
535 const unsigned refDepth = MAX2(baseImage->Depth >> levelDiff, 1);
536
537 return (texImage->Width == refWidth &&
538 texImage->Height == refHeight &&
539 texImage->Depth == refDepth);
540 }
541
542 static void teximage_assign_miptree(radeonContextPtr rmesa,
543 struct gl_texture_object *texObj,
544 struct gl_texture_image *texImage,
545 unsigned face,
546 unsigned level)
547 {
548 radeonTexObj *t = radeon_tex_obj(texObj);
549 radeon_texture_image* image = get_radeon_texture_image(texImage);
550
551 /* Since miptree holds only images for levels <BaseLevel..MaxLevel>
552 * don't allocate the miptree if the teximage won't fit.
553 */
554 if (!image_matches_texture_obj(texObj, texImage, level))
555 return;
556
557 /* Try using current miptree, or create new if there isn't any */
558 if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) {
559 radeon_miptree_unreference(&t->mt);
560 radeon_try_alloc_miptree(rmesa, t);
561 if (RADEON_DEBUG & RADEON_TEXTURE) {
562 fprintf(stderr, "%s: texObj %p, texImage %p, face %d, level %d, "
563 "texObj miptree doesn't match, allocated new miptree %p\n",
564 __FUNCTION__, texObj, texImage, face, level, t->mt);
565 }
566 }
567
568 /* Miptree alocation may have failed,
569 * when there was no image for baselevel specified */
570 if (t->mt) {
571 image->mtface = face;
572 image->mtlevel = level;
573 radeon_miptree_reference(t->mt, &image->mt);
574 }
575 }
576
577 static GLuint * allocate_image_offsets(GLcontext *ctx,
578 unsigned alignedWidth,
579 unsigned height,
580 unsigned depth)
581 {
582 int i;
583 GLuint *offsets;
584
585 offsets = _mesa_malloc(depth * sizeof(GLuint)) ;
586 if (!offsets) {
587 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex[Sub]Image");
588 return NULL;
589 }
590
591 for (i = 0; i < depth; ++i) {
592 offsets[i] = alignedWidth * height * i;
593 }
594
595 return offsets;
596 }
597
598 /**
599 * Update a subregion of the given texture image.
600 */
601 static void radeon_store_teximage(GLcontext* ctx, int dims,
602 GLint xoffset, GLint yoffset, GLint zoffset,
603 GLsizei width, GLsizei height, GLsizei depth,
604 GLsizei imageSize,
605 GLenum format, GLenum type,
606 const GLvoid * pixels,
607 const struct gl_pixelstore_attrib *packing,
608 struct gl_texture_object *texObj,
609 struct gl_texture_image *texImage,
610 int compressed)
611 {
612 radeonTexObj *t = radeon_tex_obj(texObj);
613 radeon_texture_image* image = get_radeon_texture_image(texImage);
614
615 GLuint dstRowStride;
616 GLuint *dstImageOffsets;
617
618 if (image->mt) {
619 dstRowStride = image->mt->levels[image->mtlevel].rowstride;
620 } else if (t->bo) {
621 /* TFP case */
622 /* TODO */
623 assert(0);
624 } else {
625 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
626 }
627
628 assert(dstRowStride);
629
630 if (dims == 3) {
631 unsigned alignedWidth = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat);
632 dstImageOffsets = allocate_image_offsets(ctx, alignedWidth, texImage->Height, texImage->Depth);
633 if (!dstImageOffsets) {
634 return;
635 }
636 } else {
637 dstImageOffsets = texImage->ImageOffsets;
638 }
639
640 radeon_teximage_map(image, GL_TRUE);
641
642 if (compressed) {
643 uint32_t srcRowStride, bytesPerRow, rows, block_width, block_height;
644 GLubyte *img_start;
645
646 _mesa_get_format_block_size(texImage->TexFormat, &block_width, &block_height);
647
648 if (!image->mt) {
649 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
650 img_start = _mesa_compressed_image_address(xoffset, yoffset, 0,
651 texImage->TexFormat,
652 texImage->Width, texImage->Data);
653 }
654 else {
655 uint32_t offset;
656 offset = dstRowStride / _mesa_get_format_bytes(texImage->TexFormat) * yoffset / block_height + xoffset / block_width;
657 offset *= _mesa_get_format_bytes(texImage->TexFormat);
658 img_start = texImage->Data + offset;
659 }
660 srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
661 bytesPerRow = srcRowStride;
662 rows = (height + block_height - 1) / block_height;
663
664 copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow);
665 }
666 else {
667 if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
668 texImage->TexFormat, texImage->Data,
669 xoffset, yoffset, zoffset,
670 dstRowStride,
671 dstImageOffsets,
672 width, height, depth,
673 format, type, pixels, packing)) {
674 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
675 }
676 }
677
678 if (dims == 3) {
679 _mesa_free(dstImageOffsets);
680 }
681
682 radeon_teximage_unmap(image);
683 }
684
685 /**
686 * All glTexImage calls go through this function.
687 */
688 static void radeon_teximage(
689 GLcontext *ctx, int dims,
690 GLenum target, GLint level,
691 GLint internalFormat,
692 GLint width, GLint height, GLint depth,
693 GLsizei imageSize,
694 GLenum format, GLenum type, const GLvoid * pixels,
695 const struct gl_pixelstore_attrib *packing,
696 struct gl_texture_object *texObj,
697 struct gl_texture_image *texImage,
698 int compressed)
699 {
700 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
701 radeonTexObj* t = radeon_tex_obj(texObj);
702 radeon_texture_image* image = get_radeon_texture_image(texImage);
703 GLint postConvWidth = width;
704 GLint postConvHeight = height;
705 GLuint face = _mesa_tex_target_to_face(target);
706
707 {
708 struct radeon_bo *bo;
709 bo = !image->mt ? image->bo : image->mt->bo;
710 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
711 radeon_firevertices(rmesa);
712 }
713 }
714
715 if (RADEON_DEBUG & RADEON_TEXTURE) {
716 fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, face %d, level %d\n",
717 dims, texObj, texImage, face, level);
718 }
719
720 t->validated = GL_FALSE;
721
722 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
723 _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
724 &postConvHeight);
725 }
726
727 if (!_mesa_is_format_compressed(texImage->TexFormat)) {
728 GLuint texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
729 /* Minimum pitch of 32 bytes */
730 if (postConvWidth * texelBytes < 32) {
731 postConvWidth = 32 / texelBytes;
732 texImage->RowStride = postConvWidth;
733 }
734 if (!image->mt) {
735 assert(texImage->RowStride == postConvWidth);
736 }
737 }
738
739 /* Mesa core only clears texImage->Data but not image->mt */
740 radeonFreeTexImageData(ctx, texImage);
741
742 if (!t->bo) {
743 teximage_assign_miptree(rmesa, texObj, texImage, face, level);
744 if (!image->mt) {
745 int size = _mesa_format_image_size(texImage->TexFormat,
746 texImage->Width,
747 texImage->Height,
748 texImage->Depth);
749 texImage->Data = _mesa_alloc_texmemory(size);
750 if (RADEON_DEBUG & RADEON_TEXTURE) {
751 fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, "
752 " no miptree assigned, using local memory %p\n",
753 dims, texObj, texImage, texImage->Data);
754 }
755 }
756 }
757
758 /* Upload texture image; note that the spec allows pixels to be NULL */
759 if (compressed) {
760 pixels = _mesa_validate_pbo_compressed_teximage(
761 ctx, imageSize, pixels, packing, "glCompressedTexImage");
762 } else {
763 pixels = _mesa_validate_pbo_teximage(
764 ctx, dims, width, height, depth,
765 format, type, pixels, packing, "glTexImage");
766 }
767
768 if (pixels) {
769 radeon_store_teximage(ctx, dims,
770 0, 0, 0,
771 width, height, depth,
772 imageSize, format, type,
773 pixels, packing,
774 texObj, texImage,
775 compressed);
776 }
777
778 _mesa_unmap_teximage_pbo(ctx, packing);
779 }
780
781 void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level,
782 GLint internalFormat,
783 GLint width, GLint border,
784 GLenum format, GLenum type, const GLvoid * pixels,
785 const struct gl_pixelstore_attrib *packing,
786 struct gl_texture_object *texObj,
787 struct gl_texture_image *texImage)
788 {
789 radeon_teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
790 0, format, type, pixels, packing, texObj, texImage, 0);
791 }
792
793 void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level,
794 GLint internalFormat,
795 GLint width, GLint height, GLint border,
796 GLenum format, GLenum type, const GLvoid * pixels,
797 const struct gl_pixelstore_attrib *packing,
798 struct gl_texture_object *texObj,
799 struct gl_texture_image *texImage)
800
801 {
802 radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
803 0, format, type, pixels, packing, texObj, texImage, 0);
804 }
805
806 void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target,
807 GLint level, GLint internalFormat,
808 GLint width, GLint height, GLint border,
809 GLsizei imageSize, const GLvoid * data,
810 struct gl_texture_object *texObj,
811 struct gl_texture_image *texImage)
812 {
813 radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
814 imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1);
815 }
816
817 void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
818 GLint internalFormat,
819 GLint width, GLint height, GLint depth,
820 GLint border,
821 GLenum format, GLenum type, const GLvoid * pixels,
822 const struct gl_pixelstore_attrib *packing,
823 struct gl_texture_object *texObj,
824 struct gl_texture_image *texImage)
825 {
826 radeon_teximage(ctx, 3, target, level, internalFormat, width, height, depth,
827 0, format, type, pixels, packing, texObj, texImage, 0);
828 }
829
830 /**
831 * All glTexSubImage calls go through this function.
832 */
833 static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int level,
834 GLint xoffset, GLint yoffset, GLint zoffset,
835 GLsizei width, GLsizei height, GLsizei depth,
836 GLsizei imageSize,
837 GLenum format, GLenum type,
838 const GLvoid * pixels,
839 const struct gl_pixelstore_attrib *packing,
840 struct gl_texture_object *texObj,
841 struct gl_texture_image *texImage,
842 int compressed)
843 {
844 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
845 radeonTexObj* t = radeon_tex_obj(texObj);
846 radeon_texture_image* image = get_radeon_texture_image(texImage);
847
848 {
849 struct radeon_bo *bo;
850 bo = !image->mt ? image->bo : image->mt->bo;
851 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
852 radeon_firevertices(rmesa);
853 }
854 }
855
856 if (RADEON_DEBUG & RADEON_TEXTURE) {
857 fprintf(stderr, "radeon_texsubimage%dd: texObj %p, texImage %p, face %d, level %d\n",
858 dims, texObj, texImage, _mesa_tex_target_to_face(target), level);
859 }
860
861 t->validated = GL_FALSE;
862 if (compressed) {
863 pixels = _mesa_validate_pbo_compressed_teximage(
864 ctx, imageSize, pixels, packing, "glCompressedTexSubImage");
865 } else {
866 pixels = _mesa_validate_pbo_teximage(ctx, dims,
867 width, height, depth, format, type, pixels, packing, "glTexSubImage");
868 }
869
870 if (pixels) {
871 radeon_store_teximage(ctx, dims,
872 xoffset, yoffset, zoffset,
873 width, height, depth,
874 imageSize, format, type,
875 pixels, packing,
876 texObj, texImage,
877 compressed);
878 }
879
880 _mesa_unmap_teximage_pbo(ctx, packing);
881 }
882
883 void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
884 GLint xoffset,
885 GLsizei width,
886 GLenum format, GLenum type,
887 const GLvoid * pixels,
888 const struct gl_pixelstore_attrib *packing,
889 struct gl_texture_object *texObj,
890 struct gl_texture_image *texImage)
891 {
892 radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0,
893 format, type, pixels, packing, texObj, texImage, 0);
894 }
895
896 void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
897 GLint xoffset, GLint yoffset,
898 GLsizei width, GLsizei height,
899 GLenum format, GLenum type,
900 const GLvoid * pixels,
901 const struct gl_pixelstore_attrib *packing,
902 struct gl_texture_object *texObj,
903 struct gl_texture_image *texImage)
904 {
905 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
906 0, format, type, pixels, packing, texObj, texImage,
907 0);
908 }
909
910 void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target,
911 GLint level, GLint xoffset,
912 GLint yoffset, GLsizei width,
913 GLsizei height, GLenum format,
914 GLsizei imageSize, const GLvoid * data,
915 struct gl_texture_object *texObj,
916 struct gl_texture_image *texImage)
917 {
918 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
919 imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1);
920 }
921
922
923 void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
924 GLint xoffset, GLint yoffset, GLint zoffset,
925 GLsizei width, GLsizei height, GLsizei depth,
926 GLenum format, GLenum type,
927 const GLvoid * pixels,
928 const struct gl_pixelstore_attrib *packing,
929 struct gl_texture_object *texObj,
930 struct gl_texture_image *texImage)
931 {
932 radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0,
933 format, type, pixels, packing, texObj, texImage, 0);
934 }
935
936 /**
937 * Need to map texture image into memory before copying image data,
938 * then unmap it.
939 */
940 static void
941 radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
942 GLenum format, GLenum type, GLvoid * pixels,
943 struct gl_texture_object *texObj,
944 struct gl_texture_image *texImage, int compressed)
945 {
946 radeon_texture_image *image = get_radeon_texture_image(texImage);
947
948 if (image->mt) {
949 /* Map the texture image read-only */
950 radeon_teximage_map(image, GL_FALSE);
951 } else {
952 /* Image hasn't been uploaded to a miptree yet */
953 assert(image->base.Data);
954 }
955
956 if (compressed) {
957 /* FIXME: this can't work for small textures (mips) which
958 use different hw stride */
959 _mesa_get_compressed_teximage(ctx, target, level, pixels,
960 texObj, texImage);
961 } else {
962 _mesa_get_teximage(ctx, target, level, format, type, pixels,
963 texObj, texImage);
964 }
965
966 if (image->mt) {
967 radeon_teximage_unmap(image);
968 }
969 }
970
971 void
972 radeonGetTexImage(GLcontext * ctx, GLenum target, GLint level,
973 GLenum format, GLenum type, GLvoid * pixels,
974 struct gl_texture_object *texObj,
975 struct gl_texture_image *texImage)
976 {
977 radeon_get_tex_image(ctx, target, level, format, type, pixels,
978 texObj, texImage, 0);
979 }
980
981 void
982 radeonGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
983 GLvoid *pixels,
984 struct gl_texture_object *texObj,
985 struct gl_texture_image *texImage)
986 {
987 radeon_get_tex_image(ctx, target, level, 0, 0, pixels,
988 texObj, texImage, 1);
989 }