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