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