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