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 GLuint radeon_face_for_target(GLenum target)
201 {
202 switch (target) {
203 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
204 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
205 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
206 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
207 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
208 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
209 return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
210 default:
211 return 0;
212 }
213 }
214
215 /**
216 * Wraps Mesa's implementation to ensure that the base level image is mapped.
217 *
218 * This relies on internal details of _mesa_generate_mipmap, in particular
219 * the fact that the memory for recreated texture images is always freed.
220 */
221 static void radeon_generate_mipmap(GLcontext *ctx, GLenum target,
222 struct gl_texture_object *texObj)
223 {
224 radeonTexObj* t = radeon_tex_obj(texObj);
225 GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
226 int i, face;
227
228
229 _mesa_generate_mipmap(ctx, target, texObj);
230
231 for (face = 0; face < nr_faces; face++) {
232 for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) {
233 radeon_texture_image *image;
234
235 image = get_radeon_texture_image(texObj->Image[face][i]);
236
237 if (image == NULL)
238 break;
239
240 image->mtlevel = i;
241 image->mtface = face;
242
243 radeon_miptree_unreference(&image->mt);
244 }
245 }
246
247 }
248
249 void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj)
250 {
251 GLuint face = radeon_face_for_target(target);
252 radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]);
253
254 radeon_teximage_map(baseimage, GL_FALSE);
255 radeon_generate_mipmap(ctx, target, texObj);
256 radeon_teximage_unmap(baseimage);
257 }
258
259
260 /* try to find a format which will only need a memcopy */
261 static gl_format radeonChoose8888TexFormat(radeonContextPtr rmesa,
262 GLenum srcFormat,
263 GLenum srcType, GLboolean fbo)
264 {
265 const GLuint ui = 1;
266 const GLubyte littleEndian = *((const GLubyte *)&ui);
267
268 /* r100 can only do this */
269 if (IS_R100_CLASS(rmesa->radeonScreen) || fbo)
270 return _dri_texformat_argb8888;
271
272 if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
273 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
274 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
275 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
276 return MESA_FORMAT_RGBA8888;
277 } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
278 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
279 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
280 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
281 return MESA_FORMAT_RGBA8888_REV;
282 } else if (IS_R200_CLASS(rmesa->radeonScreen)) {
283 return _dri_texformat_argb8888;
284 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
285 srcType == GL_UNSIGNED_INT_8_8_8_8)) {
286 return MESA_FORMAT_ARGB8888_REV;
287 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
288 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
289 return MESA_FORMAT_ARGB8888;
290 } else
291 return _dri_texformat_argb8888;
292 }
293
294 gl_format radeonChooseTextureFormat_mesa(GLcontext * ctx,
295 GLint internalFormat,
296 GLenum format,
297 GLenum type)
298 {
299 return radeonChooseTextureFormat(ctx, internalFormat, format,
300 type, 0);
301 }
302
303 gl_format radeonChooseTextureFormat(GLcontext * ctx,
304 GLint internalFormat,
305 GLenum format,
306 GLenum type, GLboolean fbo)
307 {
308 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
309 const GLboolean do32bpt =
310 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32);
311 const GLboolean force16bpt =
312 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16);
313 (void)format;
314
315 #if 0
316 fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n",
317 _mesa_lookup_enum_by_nr(internalFormat), internalFormat,
318 _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format));
319 fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt);
320 #endif
321
322 switch (internalFormat) {
323 case 4:
324 case GL_RGBA:
325 case GL_COMPRESSED_RGBA:
326 switch (type) {
327 case GL_UNSIGNED_INT_10_10_10_2:
328 case GL_UNSIGNED_INT_2_10_10_10_REV:
329 return do32bpt ? _dri_texformat_argb8888 :
330 _dri_texformat_argb1555;
331 case GL_UNSIGNED_SHORT_4_4_4_4:
332 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
333 return _dri_texformat_argb4444;
334 case GL_UNSIGNED_SHORT_5_5_5_1:
335 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
336 return _dri_texformat_argb1555;
337 default:
338 return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type, fbo) :
339 _dri_texformat_argb4444;
340 }
341
342 case 3:
343 case GL_RGB:
344 case GL_COMPRESSED_RGB:
345 switch (type) {
346 case GL_UNSIGNED_SHORT_4_4_4_4:
347 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
348 return _dri_texformat_argb4444;
349 case GL_UNSIGNED_SHORT_5_5_5_1:
350 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
351 return _dri_texformat_argb1555;
352 case GL_UNSIGNED_SHORT_5_6_5:
353 case GL_UNSIGNED_SHORT_5_6_5_REV:
354 return _dri_texformat_rgb565;
355 default:
356 return do32bpt ? _dri_texformat_argb8888 :
357 _dri_texformat_rgb565;
358 }
359
360 case GL_RGBA8:
361 case GL_RGB10_A2:
362 case GL_RGBA12:
363 case GL_RGBA16:
364 return !force16bpt ?
365 radeonChoose8888TexFormat(rmesa, format, type, fbo) :
366 _dri_texformat_argb4444;
367
368 case GL_RGBA4:
369 case GL_RGBA2:
370 return _dri_texformat_argb4444;
371
372 case GL_RGB5_A1:
373 return _dri_texformat_argb1555;
374
375 case GL_RGB8:
376 case GL_RGB10:
377 case GL_RGB12:
378 case GL_RGB16:
379 return !force16bpt ? _dri_texformat_argb8888 :
380 _dri_texformat_rgb565;
381
382 case GL_RGB5:
383 case GL_RGB4:
384 case GL_R3_G3_B2:
385 return _dri_texformat_rgb565;
386
387 case GL_ALPHA:
388 case GL_ALPHA4:
389 case GL_ALPHA8:
390 case GL_ALPHA12:
391 case GL_ALPHA16:
392 case GL_COMPRESSED_ALPHA:
393 /* r200: can't use a8 format since interpreting hw I8 as a8 would result
394 in wrong rgb values (same as alpha value instead of 0). */
395 if (IS_R200_CLASS(rmesa->radeonScreen))
396 return _dri_texformat_al88;
397 else
398 return _dri_texformat_a8;
399 case 1:
400 case GL_LUMINANCE:
401 case GL_LUMINANCE4:
402 case GL_LUMINANCE8:
403 case GL_LUMINANCE12:
404 case GL_LUMINANCE16:
405 case GL_COMPRESSED_LUMINANCE:
406 return _dri_texformat_l8;
407
408 case 2:
409 case GL_LUMINANCE_ALPHA:
410 case GL_LUMINANCE4_ALPHA4:
411 case GL_LUMINANCE6_ALPHA2:
412 case GL_LUMINANCE8_ALPHA8:
413 case GL_LUMINANCE12_ALPHA4:
414 case GL_LUMINANCE12_ALPHA12:
415 case GL_LUMINANCE16_ALPHA16:
416 case GL_COMPRESSED_LUMINANCE_ALPHA:
417 return _dri_texformat_al88;
418
419 case GL_INTENSITY:
420 case GL_INTENSITY4:
421 case GL_INTENSITY8:
422 case GL_INTENSITY12:
423 case GL_INTENSITY16:
424 case GL_COMPRESSED_INTENSITY:
425 return _dri_texformat_i8;
426
427 case GL_YCBCR_MESA:
428 if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
429 type == GL_UNSIGNED_BYTE)
430 return MESA_FORMAT_YCBCR;
431 else
432 return MESA_FORMAT_YCBCR_REV;
433
434 case GL_RGB_S3TC:
435 case GL_RGB4_S3TC:
436 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
437 return MESA_FORMAT_RGB_DXT1;
438
439 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
440 return MESA_FORMAT_RGBA_DXT1;
441
442 case GL_RGBA_S3TC:
443 case GL_RGBA4_S3TC:
444 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
445 return MESA_FORMAT_RGBA_DXT3;
446
447 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
448 return MESA_FORMAT_RGBA_DXT5;
449
450 case GL_ALPHA16F_ARB:
451 return MESA_FORMAT_ALPHA_FLOAT16;
452 case GL_ALPHA32F_ARB:
453 return MESA_FORMAT_ALPHA_FLOAT32;
454 case GL_LUMINANCE16F_ARB:
455 return MESA_FORMAT_LUMINANCE_FLOAT16;
456 case GL_LUMINANCE32F_ARB:
457 return MESA_FORMAT_LUMINANCE_FLOAT32;
458 case GL_LUMINANCE_ALPHA16F_ARB:
459 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16;
460 case GL_LUMINANCE_ALPHA32F_ARB:
461 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32;
462 case GL_INTENSITY16F_ARB:
463 return MESA_FORMAT_INTENSITY_FLOAT16;
464 case GL_INTENSITY32F_ARB:
465 return MESA_FORMAT_INTENSITY_FLOAT32;
466 case GL_RGB16F_ARB:
467 return MESA_FORMAT_RGBA_FLOAT16;
468 case GL_RGB32F_ARB:
469 return MESA_FORMAT_RGBA_FLOAT32;
470 case GL_RGBA16F_ARB:
471 return MESA_FORMAT_RGBA_FLOAT16;
472 case GL_RGBA32F_ARB:
473 return MESA_FORMAT_RGBA_FLOAT32;
474
475 #ifdef RADEON_R300
476 case GL_DEPTH_COMPONENT:
477 case GL_DEPTH_COMPONENT16:
478 return MESA_FORMAT_Z16;
479 case GL_DEPTH_COMPONENT24:
480 case GL_DEPTH_COMPONENT32:
481 case GL_DEPTH_STENCIL_EXT:
482 case GL_DEPTH24_STENCIL8_EXT:
483 if (rmesa->radeonScreen->chip_family >= CHIP_FAMILY_RV515)
484 return MESA_FORMAT_S8_Z24;
485 else
486 return MESA_FORMAT_Z16;
487 #else
488 case GL_DEPTH_COMPONENT:
489 case GL_DEPTH_COMPONENT16:
490 case GL_DEPTH_COMPONENT24:
491 case GL_DEPTH_COMPONENT32:
492 case GL_DEPTH_STENCIL_EXT:
493 case GL_DEPTH24_STENCIL8_EXT:
494 return MESA_FORMAT_S8_Z24;
495 #endif
496
497 /* EXT_texture_sRGB */
498 case GL_SRGB:
499 case GL_SRGB8:
500 case GL_SRGB_ALPHA:
501 case GL_SRGB8_ALPHA8:
502 case GL_COMPRESSED_SRGB:
503 case GL_COMPRESSED_SRGB_ALPHA:
504 return MESA_FORMAT_SRGBA8;
505
506 case GL_SLUMINANCE:
507 case GL_SLUMINANCE8:
508 case GL_COMPRESSED_SLUMINANCE:
509 return MESA_FORMAT_SL8;
510
511 case GL_SLUMINANCE_ALPHA:
512 case GL_SLUMINANCE8_ALPHA8:
513 case GL_COMPRESSED_SLUMINANCE_ALPHA:
514 return MESA_FORMAT_SLA8;
515
516 default:
517 _mesa_problem(ctx,
518 "unexpected internalFormat 0x%x in %s",
519 (int)internalFormat, __func__);
520 return MESA_FORMAT_NONE;
521 }
522
523 return MESA_FORMAT_NONE; /* never get here */
524 }
525
526 /** Check if given image is valid within current texture object.
527 */
528 static int image_matches_texture_obj(struct gl_texture_object *texObj,
529 struct gl_texture_image *texImage,
530 unsigned level)
531 {
532 const struct gl_texture_image *baseImage = texObj->Image[0][texObj->BaseLevel];
533
534 if (!baseImage)
535 return 0;
536
537 if (level < texObj->BaseLevel || level > texObj->MaxLevel)
538 return 0;
539
540 const unsigned levelDiff = level - texObj->BaseLevel;
541 const unsigned refWidth = MAX2(baseImage->Width >> levelDiff, 1);
542 const unsigned refHeight = MAX2(baseImage->Height >> levelDiff, 1);
543 const unsigned refDepth = MAX2(baseImage->Depth >> levelDiff, 1);
544
545 return (texImage->Width == refWidth &&
546 texImage->Height == refHeight &&
547 texImage->Depth == refDepth);
548 }
549
550 static void teximage_assign_miptree(radeonContextPtr rmesa,
551 struct gl_texture_object *texObj,
552 struct gl_texture_image *texImage,
553 unsigned face,
554 unsigned level)
555 {
556 radeonTexObj *t = radeon_tex_obj(texObj);
557 radeon_texture_image* image = get_radeon_texture_image(texImage);
558
559 /* Since miptree holds only images for levels <BaseLevel..MaxLevel>
560 * don't allocate the miptree if the teximage won't fit.
561 */
562 if (!image_matches_texture_obj(texObj, texImage, level))
563 return;
564
565 /* Try using current miptree, or create new if there isn't any */
566 if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) {
567 radeon_miptree_unreference(&t->mt);
568 radeon_try_alloc_miptree(rmesa, t);
569 if (RADEON_DEBUG & RADEON_TEXTURE) {
570 fprintf(stderr, "%s: texObj %p, texImage %p, face %d, level %d, "
571 "texObj miptree doesn't match, allocated new miptree %p\n",
572 __FUNCTION__, texObj, texImage, face, level, t->mt);
573 }
574 }
575
576 /* Miptree alocation may have failed,
577 * when there was no image for baselevel specified */
578 if (t->mt) {
579 image->mtface = face;
580 image->mtlevel = level;
581 radeon_miptree_reference(t->mt, &image->mt);
582 }
583 }
584
585 static GLuint * allocate_image_offsets(GLcontext *ctx,
586 unsigned alignedWidth,
587 unsigned height,
588 unsigned depth)
589 {
590 int i;
591 GLuint *offsets;
592
593 offsets = _mesa_malloc(depth * sizeof(GLuint)) ;
594 if (!offsets) {
595 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex[Sub]Image");
596 return NULL;
597 }
598
599 for (i = 0; i < depth; ++i) {
600 offsets[i] = alignedWidth * height * i;
601 }
602
603 return offsets;
604 }
605
606 /**
607 * Update a subregion of the given texture image.
608 */
609 static void radeon_store_teximage(GLcontext* ctx, int dims,
610 GLint xoffset, GLint yoffset, GLint zoffset,
611 GLsizei width, GLsizei height, GLsizei depth,
612 GLsizei imageSize,
613 GLenum format, GLenum type,
614 const GLvoid * pixels,
615 const struct gl_pixelstore_attrib *packing,
616 struct gl_texture_object *texObj,
617 struct gl_texture_image *texImage,
618 int compressed)
619 {
620 radeonTexObj *t = radeon_tex_obj(texObj);
621 radeon_texture_image* image = get_radeon_texture_image(texImage);
622
623 GLuint dstRowStride;
624 GLuint *dstImageOffsets;
625
626 if (image->mt) {
627 dstRowStride = image->mt->levels[image->mtlevel].rowstride;
628 } else if (t->bo) {
629 /* TFP case */
630 /* TODO */
631 assert(0);
632 } else {
633 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
634 }
635
636 assert(dstRowStride);
637
638 if (dims == 3) {
639 unsigned alignedWidth = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat);
640 dstImageOffsets = allocate_image_offsets(ctx, alignedWidth, texImage->Height, texImage->Depth);
641 if (!dstImageOffsets) {
642 return;
643 }
644 } else {
645 dstImageOffsets = texImage->ImageOffsets;
646 }
647
648 radeon_teximage_map(image, GL_TRUE);
649
650 if (compressed) {
651 uint32_t srcRowStride, bytesPerRow, rows, block_width, block_height;
652 GLubyte *img_start;
653
654 _mesa_get_format_block_size(texImage->TexFormat, &block_width, &block_height);
655
656 if (!image->mt) {
657 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
658 img_start = _mesa_compressed_image_address(xoffset, yoffset, 0,
659 texImage->TexFormat,
660 texImage->Width, texImage->Data);
661 }
662 else {
663 uint32_t offset;
664 offset = dstRowStride / _mesa_get_format_bytes(texImage->TexFormat) * yoffset / block_height + xoffset / block_width;
665 offset *= _mesa_get_format_bytes(texImage->TexFormat);
666 img_start = texImage->Data + offset;
667 }
668 srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
669 bytesPerRow = srcRowStride;
670 rows = (height + block_height - 1) / block_height;
671
672 copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow);
673 }
674 else {
675 if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
676 texImage->TexFormat, texImage->Data,
677 xoffset, yoffset, zoffset,
678 dstRowStride,
679 dstImageOffsets,
680 width, height, depth,
681 format, type, pixels, packing)) {
682 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
683 }
684 }
685
686 if (dims == 3) {
687 _mesa_free(dstImageOffsets);
688 }
689
690 radeon_teximage_unmap(image);
691 }
692
693 /**
694 * All glTexImage calls go through this function.
695 */
696 static void radeon_teximage(
697 GLcontext *ctx, int dims,
698 GLenum target, GLint level,
699 GLint internalFormat,
700 GLint width, GLint height, GLint depth,
701 GLsizei imageSize,
702 GLenum format, GLenum type, const GLvoid * pixels,
703 const struct gl_pixelstore_attrib *packing,
704 struct gl_texture_object *texObj,
705 struct gl_texture_image *texImage,
706 int compressed)
707 {
708 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
709 radeonTexObj* t = radeon_tex_obj(texObj);
710 radeon_texture_image* image = get_radeon_texture_image(texImage);
711 GLint postConvWidth = width;
712 GLint postConvHeight = height;
713 GLuint face = radeon_face_for_target(target);
714
715 {
716 struct radeon_bo *bo;
717 bo = !image->mt ? image->bo : image->mt->bo;
718 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
719 radeon_firevertices(rmesa);
720 }
721 }
722
723 if (RADEON_DEBUG & RADEON_TEXTURE) {
724 fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, face %d, level %d\n",
725 dims, texObj, texImage, face, level);
726 }
727
728 t->validated = GL_FALSE;
729
730 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
731 _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
732 &postConvHeight);
733 }
734
735 if (!_mesa_is_format_compressed(texImage->TexFormat)) {
736 GLuint texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
737 /* Minimum pitch of 32 bytes */
738 if (postConvWidth * texelBytes < 32) {
739 postConvWidth = 32 / texelBytes;
740 texImage->RowStride = postConvWidth;
741 }
742 if (!image->mt) {
743 assert(texImage->RowStride == postConvWidth);
744 }
745 }
746
747 /* Mesa core only clears texImage->Data but not image->mt */
748 radeonFreeTexImageData(ctx, texImage);
749
750 if (!t->bo) {
751 teximage_assign_miptree(rmesa, texObj, texImage, face, level);
752 if (!image->mt) {
753 int size = _mesa_format_image_size(texImage->TexFormat,
754 texImage->Width,
755 texImage->Height,
756 texImage->Depth);
757 texImage->Data = _mesa_alloc_texmemory(size);
758 if (RADEON_DEBUG & RADEON_TEXTURE) {
759 fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, "
760 " no miptree assigned, using local memory %p\n",
761 dims, texObj, texImage, texImage->Data);
762 }
763 }
764 }
765
766 /* Upload texture image; note that the spec allows pixels to be NULL */
767 if (compressed) {
768 pixels = _mesa_validate_pbo_compressed_teximage(
769 ctx, imageSize, pixels, packing, "glCompressedTexImage");
770 } else {
771 pixels = _mesa_validate_pbo_teximage(
772 ctx, dims, width, height, depth,
773 format, type, pixels, packing, "glTexImage");
774 }
775
776 if (pixels) {
777 radeon_store_teximage(ctx, dims,
778 0, 0, 0,
779 width, height, depth,
780 imageSize, format, type,
781 pixels, packing,
782 texObj, texImage,
783 compressed);
784 }
785
786 _mesa_unmap_teximage_pbo(ctx, packing);
787 }
788
789 void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level,
790 GLint internalFormat,
791 GLint width, GLint border,
792 GLenum format, GLenum type, const GLvoid * pixels,
793 const struct gl_pixelstore_attrib *packing,
794 struct gl_texture_object *texObj,
795 struct gl_texture_image *texImage)
796 {
797 radeon_teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
798 0, format, type, pixels, packing, texObj, texImage, 0);
799 }
800
801 void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level,
802 GLint internalFormat,
803 GLint width, GLint height, GLint border,
804 GLenum format, GLenum type, const GLvoid * pixels,
805 const struct gl_pixelstore_attrib *packing,
806 struct gl_texture_object *texObj,
807 struct gl_texture_image *texImage)
808
809 {
810 radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
811 0, format, type, pixels, packing, texObj, texImage, 0);
812 }
813
814 void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target,
815 GLint level, GLint internalFormat,
816 GLint width, GLint height, GLint border,
817 GLsizei imageSize, const GLvoid * data,
818 struct gl_texture_object *texObj,
819 struct gl_texture_image *texImage)
820 {
821 radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
822 imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1);
823 }
824
825 void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
826 GLint internalFormat,
827 GLint width, GLint height, GLint depth,
828 GLint border,
829 GLenum format, GLenum type, const GLvoid * pixels,
830 const struct gl_pixelstore_attrib *packing,
831 struct gl_texture_object *texObj,
832 struct gl_texture_image *texImage)
833 {
834 radeon_teximage(ctx, 3, target, level, internalFormat, width, height, depth,
835 0, format, type, pixels, packing, texObj, texImage, 0);
836 }
837
838 /**
839 * All glTexSubImage calls go through this function.
840 */
841 static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int level,
842 GLint xoffset, GLint yoffset, GLint zoffset,
843 GLsizei width, GLsizei height, GLsizei depth,
844 GLsizei imageSize,
845 GLenum format, GLenum type,
846 const GLvoid * pixels,
847 const struct gl_pixelstore_attrib *packing,
848 struct gl_texture_object *texObj,
849 struct gl_texture_image *texImage,
850 int compressed)
851 {
852 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
853 radeonTexObj* t = radeon_tex_obj(texObj);
854 radeon_texture_image* image = get_radeon_texture_image(texImage);
855
856 {
857 struct radeon_bo *bo;
858 bo = !image->mt ? image->bo : image->mt->bo;
859 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
860 radeon_firevertices(rmesa);
861 }
862 }
863
864 if (RADEON_DEBUG & RADEON_TEXTURE) {
865 fprintf(stderr, "radeon_texsubimage%dd: texObj %p, texImage %p, face %d, level %d\n",
866 dims, texObj, texImage, radeon_face_for_target(target), level);
867 }
868
869 t->validated = GL_FALSE;
870 if (compressed) {
871 pixels = _mesa_validate_pbo_compressed_teximage(
872 ctx, imageSize, pixels, packing, "glCompressedTexSubImage");
873 } else {
874 pixels = _mesa_validate_pbo_teximage(ctx, dims,
875 width, height, depth, format, type, pixels, packing, "glTexSubImage");
876 }
877
878 if (pixels) {
879 radeon_store_teximage(ctx, dims,
880 xoffset, yoffset, zoffset,
881 width, height, depth,
882 imageSize, format, type,
883 pixels, packing,
884 texObj, texImage,
885 compressed);
886 }
887
888 _mesa_unmap_teximage_pbo(ctx, packing);
889 }
890
891 void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
892 GLint xoffset,
893 GLsizei width,
894 GLenum format, GLenum type,
895 const GLvoid * pixels,
896 const struct gl_pixelstore_attrib *packing,
897 struct gl_texture_object *texObj,
898 struct gl_texture_image *texImage)
899 {
900 radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0,
901 format, type, pixels, packing, texObj, texImage, 0);
902 }
903
904 void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
905 GLint xoffset, GLint yoffset,
906 GLsizei width, GLsizei height,
907 GLenum format, GLenum type,
908 const GLvoid * pixels,
909 const struct gl_pixelstore_attrib *packing,
910 struct gl_texture_object *texObj,
911 struct gl_texture_image *texImage)
912 {
913 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
914 0, format, type, pixels, packing, texObj, texImage,
915 0);
916 }
917
918 void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target,
919 GLint level, GLint xoffset,
920 GLint yoffset, GLsizei width,
921 GLsizei height, GLenum format,
922 GLsizei imageSize, const GLvoid * data,
923 struct gl_texture_object *texObj,
924 struct gl_texture_image *texImage)
925 {
926 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
927 imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1);
928 }
929
930
931 void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
932 GLint xoffset, GLint yoffset, GLint zoffset,
933 GLsizei width, GLsizei height, GLsizei depth,
934 GLenum format, GLenum type,
935 const GLvoid * pixels,
936 const struct gl_pixelstore_attrib *packing,
937 struct gl_texture_object *texObj,
938 struct gl_texture_image *texImage)
939 {
940 radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0,
941 format, type, pixels, packing, texObj, texImage, 0);
942 }
943
944 /**
945 * Need to map texture image into memory before copying image data,
946 * then unmap it.
947 */
948 static void
949 radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
950 GLenum format, GLenum type, GLvoid * pixels,
951 struct gl_texture_object *texObj,
952 struct gl_texture_image *texImage, int compressed)
953 {
954 radeon_texture_image *image = get_radeon_texture_image(texImage);
955
956 if (image->mt) {
957 /* Map the texture image read-only */
958 radeon_teximage_map(image, GL_FALSE);
959 } else {
960 /* Image hasn't been uploaded to a miptree yet */
961 assert(image->base.Data);
962 }
963
964 if (compressed) {
965 /* FIXME: this can't work for small textures (mips) which
966 use different hw stride */
967 _mesa_get_compressed_teximage(ctx, target, level, pixels,
968 texObj, texImage);
969 } else {
970 _mesa_get_teximage(ctx, target, level, format, type, pixels,
971 texObj, texImage);
972 }
973
974 if (image->mt) {
975 radeon_teximage_unmap(image);
976 }
977 }
978
979 void
980 radeonGetTexImage(GLcontext * ctx, GLenum target, GLint level,
981 GLenum format, GLenum type, GLvoid * pixels,
982 struct gl_texture_object *texObj,
983 struct gl_texture_image *texImage)
984 {
985 radeon_get_tex_image(ctx, target, level, format, type, pixels,
986 texObj, texImage, 0);
987 }
988
989 void
990 radeonGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
991 GLvoid *pixels,
992 struct gl_texture_object *texObj,
993 struct gl_texture_image *texImage)
994 {
995 radeon_get_tex_image(ctx, target, level, 0, 0, pixels,
996 texObj, texImage, 1);
997 }