Merge branch 'mesa_7_6_branch' into 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 case GL_DEPTH_COMPONENT:
476 case GL_DEPTH_COMPONENT16:
477 case GL_DEPTH_COMPONENT24:
478 case GL_DEPTH_COMPONENT32:
479 case GL_DEPTH_STENCIL_EXT:
480 case GL_DEPTH24_STENCIL8_EXT:
481 return MESA_FORMAT_S8_Z24;
482
483 /* EXT_texture_sRGB */
484 case GL_SRGB:
485 case GL_SRGB8:
486 case GL_SRGB_ALPHA:
487 case GL_SRGB8_ALPHA8:
488 case GL_COMPRESSED_SRGB:
489 case GL_COMPRESSED_SRGB_ALPHA:
490 return MESA_FORMAT_SRGBA8;
491
492 case GL_SLUMINANCE:
493 case GL_SLUMINANCE8:
494 case GL_COMPRESSED_SLUMINANCE:
495 return MESA_FORMAT_SL8;
496
497 case GL_SLUMINANCE_ALPHA:
498 case GL_SLUMINANCE8_ALPHA8:
499 case GL_COMPRESSED_SLUMINANCE_ALPHA:
500 return MESA_FORMAT_SLA8;
501
502 default:
503 _mesa_problem(ctx,
504 "unexpected internalFormat 0x%x in %s",
505 (int)internalFormat, __func__);
506 return MESA_FORMAT_NONE;
507 }
508
509 return MESA_FORMAT_NONE; /* never get here */
510 }
511
512 /** Check if given image is valid within current texture object.
513 */
514 static int image_matches_texture_obj(struct gl_texture_object *texObj,
515 struct gl_texture_image *texImage,
516 unsigned level)
517 {
518 const struct gl_texture_image *baseImage = texObj->Image[0][texObj->BaseLevel];
519
520 if (!baseImage)
521 return 0;
522
523 if (level < texObj->BaseLevel || level > texObj->MaxLevel)
524 return 0;
525
526 const unsigned levelDiff = level - texObj->BaseLevel;
527 const unsigned refWidth = MAX2(baseImage->Width >> levelDiff, 1);
528 const unsigned refHeight = MAX2(baseImage->Height >> levelDiff, 1);
529 const unsigned refDepth = MAX2(baseImage->Depth >> levelDiff, 1);
530
531 return (texImage->Width == refWidth &&
532 texImage->Height == refHeight &&
533 texImage->Depth == refDepth);
534 }
535
536 static void teximage_assign_miptree(radeonContextPtr rmesa,
537 struct gl_texture_object *texObj,
538 struct gl_texture_image *texImage,
539 unsigned face,
540 unsigned level)
541 {
542 radeonTexObj *t = radeon_tex_obj(texObj);
543 radeon_texture_image* image = get_radeon_texture_image(texImage);
544
545 /* Since miptree holds only images for levels <BaseLevel..MaxLevel>
546 * don't allocate the miptree if the teximage won't fit.
547 */
548 if (!image_matches_texture_obj(texObj, texImage, level))
549 return;
550
551 /* Try using current miptree, or create new if there isn't any */
552 if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) {
553 radeon_miptree_unreference(&t->mt);
554 radeon_try_alloc_miptree(rmesa, t);
555 if (RADEON_DEBUG & RADEON_TEXTURE) {
556 fprintf(stderr, "%s: texObj %p, texImage %p, face %d, level %d, "
557 "texObj miptree doesn't match, allocated new miptree %p\n",
558 __FUNCTION__, texObj, texImage, face, level, t->mt);
559 }
560 }
561
562 /* Miptree alocation may have failed,
563 * when there was no image for baselevel specified */
564 if (t->mt) {
565 image->mtface = face;
566 image->mtlevel = level;
567 radeon_miptree_reference(t->mt, &image->mt);
568 }
569 }
570
571 static GLuint * allocate_image_offsets(GLcontext *ctx,
572 unsigned alignedWidth,
573 unsigned height,
574 unsigned depth)
575 {
576 int i;
577 GLuint *offsets;
578
579 offsets = _mesa_malloc(depth * sizeof(GLuint)) ;
580 if (!offsets) {
581 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex[Sub]Image");
582 return NULL;
583 }
584
585 for (i = 0; i < depth; ++i) {
586 offsets[i] = alignedWidth * height * i;
587 }
588
589 return offsets;
590 }
591
592 /**
593 * Update a subregion of the given texture image.
594 */
595 static void radeon_store_teximage(GLcontext* ctx, int dims,
596 GLint xoffset, GLint yoffset, GLint zoffset,
597 GLsizei width, GLsizei height, GLsizei depth,
598 GLsizei imageSize,
599 GLenum format, GLenum type,
600 const GLvoid * pixels,
601 const struct gl_pixelstore_attrib *packing,
602 struct gl_texture_object *texObj,
603 struct gl_texture_image *texImage,
604 int compressed)
605 {
606 radeonTexObj *t = radeon_tex_obj(texObj);
607 radeon_texture_image* image = get_radeon_texture_image(texImage);
608
609 GLuint dstRowStride;
610 GLuint *dstImageOffsets;
611
612 if (image->mt) {
613 dstRowStride = image->mt->levels[image->mtlevel].rowstride;
614 } else if (t->bo) {
615 /* TFP case */
616 /* TODO */
617 assert(0);
618 } else {
619 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
620 }
621
622 assert(dstRowStride);
623
624 if (dims == 3) {
625 unsigned alignedWidth = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat);
626 dstImageOffsets = allocate_image_offsets(ctx, alignedWidth, texImage->Height, texImage->Depth);
627 if (!dstImageOffsets) {
628 return;
629 }
630 } else {
631 dstImageOffsets = texImage->ImageOffsets;
632 }
633
634 radeon_teximage_map(image, GL_TRUE);
635
636 if (compressed) {
637 uint32_t srcRowStride, bytesPerRow, rows, block_width, block_height;
638 GLubyte *img_start;
639
640 _mesa_get_format_block_size(texImage->TexFormat, &block_width, &block_height);
641
642 if (!image->mt) {
643 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
644 img_start = _mesa_compressed_image_address(xoffset, yoffset, 0,
645 texImage->TexFormat,
646 texImage->Width, texImage->Data);
647 }
648 else {
649 uint32_t offset;
650 offset = dstRowStride / _mesa_get_format_bytes(texImage->TexFormat) * yoffset / block_height + xoffset / block_width;
651 offset *= _mesa_get_format_bytes(texImage->TexFormat);
652 img_start = texImage->Data + offset;
653 }
654 srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
655 bytesPerRow = srcRowStride;
656 rows = (height + block_height - 1) / block_height;
657
658 copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow);
659 }
660 else {
661 if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
662 texImage->TexFormat, texImage->Data,
663 xoffset, yoffset, zoffset,
664 dstRowStride,
665 dstImageOffsets,
666 width, height, depth,
667 format, type, pixels, packing)) {
668 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
669 }
670 }
671
672 if (dims == 3) {
673 _mesa_free(dstImageOffsets);
674 }
675
676 radeon_teximage_unmap(image);
677 }
678
679 /**
680 * All glTexImage calls go through this function.
681 */
682 static void radeon_teximage(
683 GLcontext *ctx, int dims,
684 GLenum target, GLint level,
685 GLint internalFormat,
686 GLint width, GLint height, GLint depth,
687 GLsizei imageSize,
688 GLenum format, GLenum type, const GLvoid * pixels,
689 const struct gl_pixelstore_attrib *packing,
690 struct gl_texture_object *texObj,
691 struct gl_texture_image *texImage,
692 int compressed)
693 {
694 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
695 radeonTexObj* t = radeon_tex_obj(texObj);
696 radeon_texture_image* image = get_radeon_texture_image(texImage);
697 GLint postConvWidth = width;
698 GLint postConvHeight = height;
699 GLuint face = radeon_face_for_target(target);
700
701 {
702 struct radeon_bo *bo;
703 bo = !image->mt ? image->bo : image->mt->bo;
704 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
705 radeon_firevertices(rmesa);
706 }
707 }
708
709 if (RADEON_DEBUG & RADEON_TEXTURE) {
710 fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, face %d, level %d\n",
711 dims, texObj, texImage, face, level);
712 }
713
714 t->validated = GL_FALSE;
715
716 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
717 _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
718 &postConvHeight);
719 }
720
721 if (!_mesa_is_format_compressed(texImage->TexFormat)) {
722 GLuint texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
723 /* Minimum pitch of 32 bytes */
724 if (postConvWidth * texelBytes < 32) {
725 postConvWidth = 32 / texelBytes;
726 texImage->RowStride = postConvWidth;
727 }
728 if (!image->mt) {
729 assert(texImage->RowStride == postConvWidth);
730 }
731 }
732
733 /* Mesa core only clears texImage->Data but not image->mt */
734 radeonFreeTexImageData(ctx, texImage);
735
736 if (!t->bo) {
737 teximage_assign_miptree(rmesa, texObj, texImage, face, level);
738 if (!image->mt) {
739 int size = _mesa_format_image_size(texImage->TexFormat,
740 texImage->Width,
741 texImage->Height,
742 texImage->Depth);
743 texImage->Data = _mesa_alloc_texmemory(size);
744 if (RADEON_DEBUG & RADEON_TEXTURE) {
745 fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, "
746 " no miptree assigned, using local memory %p\n",
747 dims, texObj, texImage, texImage->Data);
748 }
749 }
750 }
751
752 /* Upload texture image; note that the spec allows pixels to be NULL */
753 if (compressed) {
754 pixels = _mesa_validate_pbo_compressed_teximage(
755 ctx, imageSize, pixels, packing, "glCompressedTexImage");
756 } else {
757 pixels = _mesa_validate_pbo_teximage(
758 ctx, dims, width, height, depth,
759 format, type, pixels, packing, "glTexImage");
760 }
761
762 if (pixels) {
763 radeon_store_teximage(ctx, dims,
764 0, 0, 0,
765 width, height, depth,
766 imageSize, format, type,
767 pixels, packing,
768 texObj, texImage,
769 compressed);
770 }
771
772 _mesa_unmap_teximage_pbo(ctx, packing);
773 }
774
775 void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level,
776 GLint internalFormat,
777 GLint width, GLint border,
778 GLenum format, GLenum type, const GLvoid * pixels,
779 const struct gl_pixelstore_attrib *packing,
780 struct gl_texture_object *texObj,
781 struct gl_texture_image *texImage)
782 {
783 radeon_teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
784 0, format, type, pixels, packing, texObj, texImage, 0);
785 }
786
787 void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level,
788 GLint internalFormat,
789 GLint width, GLint height, GLint border,
790 GLenum format, GLenum type, const GLvoid * pixels,
791 const struct gl_pixelstore_attrib *packing,
792 struct gl_texture_object *texObj,
793 struct gl_texture_image *texImage)
794
795 {
796 radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
797 0, format, type, pixels, packing, texObj, texImage, 0);
798 }
799
800 void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target,
801 GLint level, GLint internalFormat,
802 GLint width, GLint height, GLint border,
803 GLsizei imageSize, const GLvoid * data,
804 struct gl_texture_object *texObj,
805 struct gl_texture_image *texImage)
806 {
807 radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
808 imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1);
809 }
810
811 void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
812 GLint internalFormat,
813 GLint width, GLint height, GLint depth,
814 GLint border,
815 GLenum format, GLenum type, const GLvoid * pixels,
816 const struct gl_pixelstore_attrib *packing,
817 struct gl_texture_object *texObj,
818 struct gl_texture_image *texImage)
819 {
820 radeon_teximage(ctx, 3, target, level, internalFormat, width, height, depth,
821 0, format, type, pixels, packing, texObj, texImage, 0);
822 }
823
824 /**
825 * All glTexSubImage calls go through this function.
826 */
827 static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int level,
828 GLint xoffset, GLint yoffset, GLint zoffset,
829 GLsizei width, GLsizei height, GLsizei depth,
830 GLsizei imageSize,
831 GLenum format, GLenum type,
832 const GLvoid * pixels,
833 const struct gl_pixelstore_attrib *packing,
834 struct gl_texture_object *texObj,
835 struct gl_texture_image *texImage,
836 int compressed)
837 {
838 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
839 radeonTexObj* t = radeon_tex_obj(texObj);
840 radeon_texture_image* image = get_radeon_texture_image(texImage);
841
842 {
843 struct radeon_bo *bo;
844 bo = !image->mt ? image->bo : image->mt->bo;
845 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
846 radeon_firevertices(rmesa);
847 }
848 }
849
850 if (RADEON_DEBUG & RADEON_TEXTURE) {
851 fprintf(stderr, "radeon_texsubimage%dd: texObj %p, texImage %p, face %d, level %d\n",
852 dims, texObj, texImage, radeon_face_for_target(target), level);
853 }
854
855 t->validated = GL_FALSE;
856 if (compressed) {
857 pixels = _mesa_validate_pbo_compressed_teximage(
858 ctx, imageSize, pixels, packing, "glCompressedTexSubImage");
859 } else {
860 pixels = _mesa_validate_pbo_teximage(ctx, dims,
861 width, height, depth, format, type, pixels, packing, "glTexSubImage");
862 }
863
864 if (pixels) {
865 radeon_store_teximage(ctx, dims,
866 xoffset, yoffset, zoffset,
867 width, height, depth,
868 imageSize, format, type,
869 pixels, packing,
870 texObj, texImage,
871 compressed);
872 }
873
874 _mesa_unmap_teximage_pbo(ctx, packing);
875 }
876
877 void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
878 GLint xoffset,
879 GLsizei width,
880 GLenum format, GLenum type,
881 const GLvoid * pixels,
882 const struct gl_pixelstore_attrib *packing,
883 struct gl_texture_object *texObj,
884 struct gl_texture_image *texImage)
885 {
886 radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0,
887 format, type, pixels, packing, texObj, texImage, 0);
888 }
889
890 void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
891 GLint xoffset, GLint yoffset,
892 GLsizei width, GLsizei height,
893 GLenum format, GLenum type,
894 const GLvoid * pixels,
895 const struct gl_pixelstore_attrib *packing,
896 struct gl_texture_object *texObj,
897 struct gl_texture_image *texImage)
898 {
899 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
900 0, format, type, pixels, packing, texObj, texImage,
901 0);
902 }
903
904 void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target,
905 GLint level, GLint xoffset,
906 GLint yoffset, GLsizei width,
907 GLsizei height, GLenum format,
908 GLsizei imageSize, const GLvoid * data,
909 struct gl_texture_object *texObj,
910 struct gl_texture_image *texImage)
911 {
912 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
913 imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1);
914 }
915
916
917 void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
918 GLint xoffset, GLint yoffset, GLint zoffset,
919 GLsizei width, GLsizei height, GLsizei depth,
920 GLenum format, GLenum type,
921 const GLvoid * pixels,
922 const struct gl_pixelstore_attrib *packing,
923 struct gl_texture_object *texObj,
924 struct gl_texture_image *texImage)
925 {
926 radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0,
927 format, type, pixels, packing, texObj, texImage, 0);
928 }
929
930 /**
931 * Need to map texture image into memory before copying image data,
932 * then unmap it.
933 */
934 static void
935 radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
936 GLenum format, GLenum type, GLvoid * pixels,
937 struct gl_texture_object *texObj,
938 struct gl_texture_image *texImage, int compressed)
939 {
940 radeon_texture_image *image = get_radeon_texture_image(texImage);
941
942 if (image->mt) {
943 /* Map the texture image read-only */
944 radeon_teximage_map(image, GL_FALSE);
945 } else {
946 /* Image hasn't been uploaded to a miptree yet */
947 assert(image->base.Data);
948 }
949
950 if (compressed) {
951 /* FIXME: this can't work for small textures (mips) which
952 use different hw stride */
953 _mesa_get_compressed_teximage(ctx, target, level, pixels,
954 texObj, texImage);
955 } else {
956 _mesa_get_teximage(ctx, target, level, format, type, pixels,
957 texObj, texImage);
958 }
959
960 if (image->mt) {
961 radeon_teximage_unmap(image);
962 }
963 }
964
965 void
966 radeonGetTexImage(GLcontext * ctx, GLenum target, GLint level,
967 GLenum format, GLenum type, GLvoid * pixels,
968 struct gl_texture_object *texObj,
969 struct gl_texture_image *texImage)
970 {
971 radeon_get_tex_image(ctx, target, level, format, type, pixels,
972 texObj, texImage, 0);
973 }
974
975 void
976 radeonGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
977 GLvoid *pixels,
978 struct gl_texture_object *texObj,
979 struct gl_texture_image *texImage)
980 {
981 radeon_get_tex_image(ctx, target, level, 0, 0, pixels,
982 texObj, texImage, 1);
983 }