radeon_texture.c revision 23d3559bd4ece1fcab5513ebdaa38600d6654374
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/mipmap.h"
35#include "main/texformat.h"
36#include "main/texstore.h"
37#include "main/teximage.h"
38#include "main/texobj.h"
39
40#include "xmlpool.h"		/* for symbolic values of enum-type options */
41
42#include "radeon_common.h"
43
44#include "radeon_mipmap_tree.h"
45
46/* textures */
47/**
48 * Allocate an empty texture image object.
49 */
50struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx)
51{
52	return CALLOC(sizeof(radeon_texture_image));
53}
54
55/**
56 * Free memory associated with this texture image.
57 */
58void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage)
59{
60	radeon_texture_image* image = get_radeon_texture_image(timage);
61
62	if (image->mt) {
63		radeon_miptree_unreference(image->mt);
64		image->mt = 0;
65		assert(!image->base.Data);
66	} else {
67		_mesa_free_texture_image_data(ctx, timage);
68	}
69	if (image->bo) {
70		radeon_bo_unref(image->bo);
71		image->bo = NULL;
72	}
73	if (timage->Data) {
74		_mesa_free_texmemory(timage->Data);
75		timage->Data = NULL;
76	}
77}
78
79/* Set Data pointer and additional data for mapped texture image */
80static void teximage_set_map_data(radeon_texture_image *image)
81{
82	radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
83
84	image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset;
85	image->base.RowStride = lvl->rowstride / image->mt->bpp;
86}
87
88
89/**
90 * Map a single texture image for glTexImage and friends.
91 */
92void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable)
93{
94	if (image->mt) {
95		assert(!image->base.Data);
96
97		radeon_bo_map(image->mt->bo, write_enable);
98		teximage_set_map_data(image);
99	}
100}
101
102
103void radeon_teximage_unmap(radeon_texture_image *image)
104{
105	if (image->mt) {
106		assert(image->base.Data);
107
108		image->base.Data = 0;
109		radeon_bo_unmap(image->mt->bo);
110	}
111}
112
113/**
114 * Map a validated texture for reading during software rendering.
115 */
116void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
117{
118	radeonTexObj* t = radeon_tex_obj(texObj);
119	int face, level;
120
121	/* for r100 3D sw fallbacks don't have mt */
122	if (!t->mt)
123	  return;
124
125	radeon_bo_map(t->mt->bo, GL_FALSE);
126	for(face = 0; face < t->mt->faces; ++face) {
127		for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level)
128			teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level]));
129	}
130}
131
132void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
133{
134	radeonTexObj* t = radeon_tex_obj(texObj);
135	int face, level;
136
137	/* for r100 3D sw fallbacks don't have mt */
138	if (!t->mt)
139	  return;
140
141	for(face = 0; face < t->mt->faces; ++face) {
142		for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level)
143			texObj->Image[face][level]->Data = 0;
144	}
145	radeon_bo_unmap(t->mt->bo);
146}
147
148GLuint radeon_face_for_target(GLenum target)
149{
150	switch (target) {
151	case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
152	case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
153	case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
154	case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
155	case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
156	case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
157		return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
158	default:
159		return 0;
160	}
161}
162
163/**
164 * Wraps Mesa's implementation to ensure that the base level image is mapped.
165 *
166 * This relies on internal details of _mesa_generate_mipmap, in particular
167 * the fact that the memory for recreated texture images is always freed.
168 */
169static void radeon_generate_mipmap(GLcontext *ctx, GLenum target,
170				   struct gl_texture_object *texObj)
171{
172	radeonTexObj* t = radeon_tex_obj(texObj);
173	GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
174	int i, face;
175
176
177	_mesa_generate_mipmap(ctx, target, texObj);
178
179	for (face = 0; face < nr_faces; face++) {
180		for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) {
181			radeon_texture_image *image;
182
183			image = get_radeon_texture_image(texObj->Image[face][i]);
184
185			if (image == NULL)
186				break;
187
188			image->mtlevel = i;
189			image->mtface = face;
190
191			radeon_miptree_unreference(image->mt);
192			image->mt = NULL;
193		}
194	}
195
196}
197
198void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj)
199{
200	GLuint face = radeon_face_for_target(target);
201	radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]);
202
203	radeon_teximage_map(baseimage, GL_FALSE);
204	radeon_generate_mipmap(ctx, target, texObj);
205	radeon_teximage_unmap(baseimage);
206}
207
208
209/* try to find a format which will only need a memcopy */
210static const struct gl_texture_format *radeonChoose8888TexFormat(radeonContextPtr rmesa,
211								 GLenum srcFormat,
212								 GLenum srcType)
213{
214	const GLuint ui = 1;
215	const GLubyte littleEndian = *((const GLubyte *)&ui);
216
217	/* r100 can only do this */
218	if (IS_R100_CLASS(rmesa->radeonScreen))
219	  return _dri_texformat_argb8888;
220
221	if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
222	    (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
223	    (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
224	    (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
225		return &_mesa_texformat_rgba8888;
226	} else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
227		   (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
228		   (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
229		   (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
230		return &_mesa_texformat_rgba8888_rev;
231	} else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
232					    srcType == GL_UNSIGNED_INT_8_8_8_8)) {
233		return &_mesa_texformat_argb8888_rev;
234	} else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
235					    srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
236		return &_mesa_texformat_argb8888;
237	} else
238		return _dri_texformat_argb8888;
239}
240
241const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
242							  GLint internalFormat,
243							  GLenum format,
244							  GLenum type)
245{
246	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
247	const GLboolean do32bpt =
248	    (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32);
249	const GLboolean force16bpt =
250	    (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16);
251	(void)format;
252
253#if 0
254	fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n",
255		_mesa_lookup_enum_by_nr(internalFormat), internalFormat,
256		_mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format));
257	fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt);
258#endif
259
260	switch (internalFormat) {
261	case 4:
262	case GL_RGBA:
263	case GL_COMPRESSED_RGBA:
264		switch (type) {
265		case GL_UNSIGNED_INT_10_10_10_2:
266		case GL_UNSIGNED_INT_2_10_10_10_REV:
267			return do32bpt ? _dri_texformat_argb8888 :
268			    _dri_texformat_argb1555;
269		case GL_UNSIGNED_SHORT_4_4_4_4:
270		case GL_UNSIGNED_SHORT_4_4_4_4_REV:
271			return _dri_texformat_argb4444;
272		case GL_UNSIGNED_SHORT_5_5_5_1:
273		case GL_UNSIGNED_SHORT_1_5_5_5_REV:
274			return _dri_texformat_argb1555;
275		default:
276			return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type) :
277			    _dri_texformat_argb4444;
278		}
279
280	case 3:
281	case GL_RGB:
282	case GL_COMPRESSED_RGB:
283		switch (type) {
284		case GL_UNSIGNED_SHORT_4_4_4_4:
285		case GL_UNSIGNED_SHORT_4_4_4_4_REV:
286			return _dri_texformat_argb4444;
287		case GL_UNSIGNED_SHORT_5_5_5_1:
288		case GL_UNSIGNED_SHORT_1_5_5_5_REV:
289			return _dri_texformat_argb1555;
290		case GL_UNSIGNED_SHORT_5_6_5:
291		case GL_UNSIGNED_SHORT_5_6_5_REV:
292			return _dri_texformat_rgb565;
293		default:
294			return do32bpt ? _dri_texformat_argb8888 :
295			    _dri_texformat_rgb565;
296		}
297
298	case GL_RGBA8:
299	case GL_RGB10_A2:
300	case GL_RGBA12:
301	case GL_RGBA16:
302		return !force16bpt ?
303			radeonChoose8888TexFormat(rmesa, format,type) :
304			_dri_texformat_argb4444;
305
306	case GL_RGBA4:
307	case GL_RGBA2:
308		return _dri_texformat_argb4444;
309
310	case GL_RGB5_A1:
311		return _dri_texformat_argb1555;
312
313	case GL_RGB8:
314	case GL_RGB10:
315	case GL_RGB12:
316	case GL_RGB16:
317		return !force16bpt ? _dri_texformat_argb8888 :
318		    _dri_texformat_rgb565;
319
320	case GL_RGB5:
321	case GL_RGB4:
322	case GL_R3_G3_B2:
323		return _dri_texformat_rgb565;
324
325	case GL_ALPHA:
326	case GL_ALPHA4:
327	case GL_ALPHA8:
328	case GL_ALPHA12:
329	case GL_ALPHA16:
330	case GL_COMPRESSED_ALPHA:
331		return _dri_texformat_a8;
332
333	case 1:
334	case GL_LUMINANCE:
335	case GL_LUMINANCE4:
336	case GL_LUMINANCE8:
337	case GL_LUMINANCE12:
338	case GL_LUMINANCE16:
339	case GL_COMPRESSED_LUMINANCE:
340		return _dri_texformat_l8;
341
342	case 2:
343	case GL_LUMINANCE_ALPHA:
344	case GL_LUMINANCE4_ALPHA4:
345	case GL_LUMINANCE6_ALPHA2:
346	case GL_LUMINANCE8_ALPHA8:
347	case GL_LUMINANCE12_ALPHA4:
348	case GL_LUMINANCE12_ALPHA12:
349	case GL_LUMINANCE16_ALPHA16:
350	case GL_COMPRESSED_LUMINANCE_ALPHA:
351		return _dri_texformat_al88;
352
353	case GL_INTENSITY:
354	case GL_INTENSITY4:
355	case GL_INTENSITY8:
356	case GL_INTENSITY12:
357	case GL_INTENSITY16:
358	case GL_COMPRESSED_INTENSITY:
359		return _dri_texformat_i8;
360
361	case GL_YCBCR_MESA:
362		if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
363		    type == GL_UNSIGNED_BYTE)
364			return &_mesa_texformat_ycbcr;
365		else
366			return &_mesa_texformat_ycbcr_rev;
367
368	case GL_RGB_S3TC:
369	case GL_RGB4_S3TC:
370	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
371		return &_mesa_texformat_rgb_dxt1;
372
373	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
374		return &_mesa_texformat_rgba_dxt1;
375
376	case GL_RGBA_S3TC:
377	case GL_RGBA4_S3TC:
378	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
379		return &_mesa_texformat_rgba_dxt3;
380
381	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
382		return &_mesa_texformat_rgba_dxt5;
383
384	case GL_ALPHA16F_ARB:
385		return &_mesa_texformat_alpha_float16;
386	case GL_ALPHA32F_ARB:
387		return &_mesa_texformat_alpha_float32;
388	case GL_LUMINANCE16F_ARB:
389		return &_mesa_texformat_luminance_float16;
390	case GL_LUMINANCE32F_ARB:
391		return &_mesa_texformat_luminance_float32;
392	case GL_LUMINANCE_ALPHA16F_ARB:
393		return &_mesa_texformat_luminance_alpha_float16;
394	case GL_LUMINANCE_ALPHA32F_ARB:
395		return &_mesa_texformat_luminance_alpha_float32;
396	case GL_INTENSITY16F_ARB:
397		return &_mesa_texformat_intensity_float16;
398	case GL_INTENSITY32F_ARB:
399		return &_mesa_texformat_intensity_float32;
400	case GL_RGB16F_ARB:
401		return &_mesa_texformat_rgba_float16;
402	case GL_RGB32F_ARB:
403		return &_mesa_texformat_rgba_float32;
404	case GL_RGBA16F_ARB:
405		return &_mesa_texformat_rgba_float16;
406	case GL_RGBA32F_ARB:
407		return &_mesa_texformat_rgba_float32;
408
409	case GL_DEPTH_COMPONENT:
410	case GL_DEPTH_COMPONENT16:
411	case GL_DEPTH_COMPONENT24:
412	case GL_DEPTH_COMPONENT32:
413#if 0
414		switch (type) {
415		case GL_UNSIGNED_BYTE:
416		case GL_UNSIGNED_SHORT:
417			return &_mesa_texformat_z16;
418		case GL_UNSIGNED_INT:
419			return &_mesa_texformat_z32;
420		case GL_UNSIGNED_INT_24_8_EXT:
421		default:
422			return &_mesa_texformat_z24_s8;
423		}
424#else
425		return &_mesa_texformat_z16;
426#endif
427
428	default:
429		_mesa_problem(ctx,
430			      "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
431			      (int)internalFormat);
432		return NULL;
433	}
434
435	return NULL;		/* never get here */
436}
437
438/**
439 * All glTexImage calls go through this function.
440 */
441static void radeon_teximage(
442	GLcontext *ctx, int dims,
443	GLint face, GLint level,
444	GLint internalFormat,
445	GLint width, GLint height, GLint depth,
446	GLsizei imageSize,
447	GLenum format, GLenum type, const GLvoid * pixels,
448	const struct gl_pixelstore_attrib *packing,
449	struct gl_texture_object *texObj,
450	struct gl_texture_image *texImage,
451	int compressed)
452{
453	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
454	radeonTexObj* t = radeon_tex_obj(texObj);
455	radeon_texture_image* image = get_radeon_texture_image(texImage);
456
457	radeon_firevertices(rmesa);
458
459	t->validated = GL_FALSE;
460
461	/* Choose and fill in the texture format for this image */
462	texImage->TexFormat = radeonChooseTextureFormat(ctx, internalFormat, format, type);
463	_mesa_set_fetch_functions(texImage, dims);
464
465	if (texImage->TexFormat->TexelBytes == 0) {
466		texImage->IsCompressed = GL_TRUE;
467		texImage->CompressedSize =
468			ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
469					   texImage->Height, texImage->Depth,
470					   texImage->TexFormat->MesaFormat);
471	} else {
472		texImage->IsCompressed = GL_FALSE;
473		texImage->CompressedSize = 0;
474	}
475
476	/* Allocate memory for image */
477	radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */
478
479	if (!t->mt)
480		radeon_try_alloc_miptree(rmesa, t, texImage, face, level);
481	if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) {
482		image->mt = t->mt;
483		image->mtlevel = level - t->mt->firstLevel;
484		image->mtface = face;
485		radeon_miptree_reference(t->mt);
486	} else {
487		int size;
488		if (texImage->IsCompressed) {
489			size = texImage->CompressedSize;
490		} else {
491			size = texImage->Width * texImage->Height * texImage->Depth * texImage->TexFormat->TexelBytes;
492		}
493		texImage->Data = _mesa_alloc_texmemory(size);
494	}
495
496	/* Upload texture image; note that the spec allows pixels to be NULL */
497	if (compressed) {
498		pixels = _mesa_validate_pbo_compressed_teximage(
499			ctx, imageSize, pixels, packing, "glCompressedTexImage");
500	} else {
501		pixels = _mesa_validate_pbo_teximage(
502			ctx, dims, width, height, depth,
503			format, type, pixels, packing, "glTexImage");
504	}
505
506	if (pixels) {
507		radeon_teximage_map(image, GL_TRUE);
508
509		if (compressed) {
510			memcpy(texImage->Data, pixels, imageSize);
511		} else {
512			GLuint dstRowStride;
513			if (image->mt) {
514				radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
515				dstRowStride = lvl->rowstride;
516			} else {
517				dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
518			}
519			if (!texImage->TexFormat->StoreImage(ctx, dims,
520						texImage->_BaseFormat,
521						texImage->TexFormat,
522						texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
523						dstRowStride,
524						texImage->ImageOffsets,
525						width, height, depth,
526						format, type, pixels, packing))
527				_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
528		}
529
530	}
531
532	/* SGIS_generate_mipmap */
533	if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
534		radeon_generate_mipmap(ctx, texObj->Target, texObj);
535	}
536
537	if (pixels)
538	  radeon_teximage_unmap(image);
539
540	_mesa_unmap_teximage_pbo(ctx, packing);
541
542
543}
544
545void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level,
546		      GLint internalFormat,
547		      GLint width, GLint border,
548		      GLenum format, GLenum type, const GLvoid * pixels,
549		      const struct gl_pixelstore_attrib *packing,
550		      struct gl_texture_object *texObj,
551		      struct gl_texture_image *texImage)
552{
553	radeon_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1,
554		0, format, type, pixels, packing, texObj, texImage, 0);
555}
556
557void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level,
558			   GLint internalFormat,
559			   GLint width, GLint height, GLint border,
560			   GLenum format, GLenum type, const GLvoid * pixels,
561			   const struct gl_pixelstore_attrib *packing,
562			   struct gl_texture_object *texObj,
563			   struct gl_texture_image *texImage)
564
565{
566	GLuint face = radeon_face_for_target(target);
567
568	radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
569		0, format, type, pixels, packing, texObj, texImage, 0);
570}
571
572void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target,
573				     GLint level, GLint internalFormat,
574				     GLint width, GLint height, GLint border,
575				     GLsizei imageSize, const GLvoid * data,
576				     struct gl_texture_object *texObj,
577				     struct gl_texture_image *texImage)
578{
579	GLuint face = radeon_face_for_target(target);
580
581	radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
582		imageSize, 0, 0, data, 0, texObj, texImage, 1);
583}
584
585void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
586		      GLint internalFormat,
587		      GLint width, GLint height, GLint depth,
588		      GLint border,
589		      GLenum format, GLenum type, const GLvoid * pixels,
590		      const struct gl_pixelstore_attrib *packing,
591		      struct gl_texture_object *texObj,
592		      struct gl_texture_image *texImage)
593{
594	radeon_teximage(ctx, 3, 0, level, internalFormat, width, height, depth,
595		0, format, type, pixels, packing, texObj, texImage, 0);
596}
597
598/**
599 * Update a subregion of the given texture image.
600 */
601static void radeon_texsubimage(GLcontext* ctx, int dims, int level,
602		GLint xoffset, GLint yoffset, GLint zoffset,
603		GLsizei width, GLsizei height, GLsizei depth,
604		GLenum format, GLenum type,
605		const GLvoid * pixels,
606		const struct gl_pixelstore_attrib *packing,
607		struct gl_texture_object *texObj,
608		struct gl_texture_image *texImage,
609			       int compressed)
610{
611	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
612	radeonTexObj* t = radeon_tex_obj(texObj);
613	radeon_texture_image* image = get_radeon_texture_image(texImage);
614
615	radeon_firevertices(rmesa);
616
617	t->validated = GL_FALSE;
618	pixels = _mesa_validate_pbo_teximage(ctx, dims,
619		width, height, depth, format, type, pixels, packing, "glTexSubImage1D");
620
621	if (pixels) {
622		GLint dstRowStride;
623		radeon_teximage_map(image, GL_TRUE);
624
625		if (image->mt) {
626			radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
627			dstRowStride = lvl->rowstride;
628		} else {
629			dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
630		}
631
632		if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
633				texImage->TexFormat, texImage->Data,
634				xoffset, yoffset, zoffset,
635				dstRowStride,
636				texImage->ImageOffsets,
637				width, height, depth,
638				format, type, pixels, packing))
639			_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
640
641
642	}
643
644	/* GL_SGIS_generate_mipmap */
645	if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
646		radeon_generate_mipmap(ctx, texObj->Target, texObj);
647	}
648	radeon_teximage_unmap(image);
649
650	_mesa_unmap_teximage_pbo(ctx, packing);
651
652
653}
654
655void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
656			 GLint xoffset,
657			 GLsizei width,
658			 GLenum format, GLenum type,
659			 const GLvoid * pixels,
660			 const struct gl_pixelstore_attrib *packing,
661			 struct gl_texture_object *texObj,
662			 struct gl_texture_image *texImage)
663{
664	radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1,
665		format, type, pixels, packing, texObj, texImage, 0);
666}
667
668void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
669			 GLint xoffset, GLint yoffset,
670			 GLsizei width, GLsizei height,
671			 GLenum format, GLenum type,
672			 const GLvoid * pixels,
673			 const struct gl_pixelstore_attrib *packing,
674			 struct gl_texture_object *texObj,
675			 struct gl_texture_image *texImage)
676{
677	radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height,
678			   1, format, type, pixels, packing, texObj, texImage,
679			   0);
680}
681
682void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target,
683				   GLint level, GLint xoffset,
684				   GLint yoffset, GLsizei width,
685				   GLsizei height, GLenum format,
686				   GLsizei imageSize, const GLvoid * data,
687				   struct gl_texture_object *texObj,
688				   struct gl_texture_image *texImage)
689{
690	radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
691		format, 0, data, 0, texObj, texImage, 1);
692}
693
694
695void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
696			 GLint xoffset, GLint yoffset, GLint zoffset,
697			 GLsizei width, GLsizei height, GLsizei depth,
698			 GLenum format, GLenum type,
699			 const GLvoid * pixels,
700			 const struct gl_pixelstore_attrib *packing,
701			 struct gl_texture_object *texObj,
702			 struct gl_texture_image *texImage)
703{
704	radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth,
705		format, type, pixels, packing, texObj, texImage, 0);
706}
707
708static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
709	GLuint numrows, GLuint rowsize)
710{
711	assert(rowsize <= dststride);
712	assert(rowsize <= srcstride);
713
714	if (rowsize == srcstride && rowsize == dststride) {
715		memcpy(dst, src, numrows*rowsize);
716	} else {
717		GLuint i;
718		for(i = 0; i < numrows; ++i) {
719			memcpy(dst, src, rowsize);
720			dst += dststride;
721			src += srcstride;
722		}
723	}
724}
725
726
727/**
728 * Ensure that the given image is stored in the given miptree from now on.
729 */
730static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, int face, int level)
731{
732	radeon_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel];
733	unsigned char *dest;
734
735	assert(image->mt != mt);
736	assert(dstlvl->width == image->base.Width);
737	assert(dstlvl->height == image->base.Height);
738	assert(dstlvl->depth == image->base.Depth);
739
740
741	radeon_bo_map(mt->bo, GL_TRUE);
742	dest = mt->bo->ptr + dstlvl->faces[face].offset;
743
744	if (image->mt) {
745		/* Format etc. should match, so we really just need a memcpy().
746		 * In fact, that memcpy() could be done by the hardware in many
747		 * cases, provided that we have a proper memory manager.
748		 */
749		radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel];
750
751		assert(srclvl->size == dstlvl->size);
752		assert(srclvl->rowstride == dstlvl->rowstride);
753
754		radeon_bo_map(image->mt->bo, GL_FALSE);
755
756		memcpy(dest,
757			image->mt->bo->ptr + srclvl->faces[face].offset,
758			dstlvl->size);
759		radeon_bo_unmap(image->mt->bo);
760
761		radeon_miptree_unreference(image->mt);
762	} else {
763		uint srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
764
765//		if (mt->tilebits)
766//			WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
767
768		copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride,
769			image->base.Height * image->base.Depth, srcrowstride);
770
771		_mesa_free_texmemory(image->base.Data);
772		image->base.Data = 0;
773	}
774
775	radeon_bo_unmap(mt->bo);
776
777	image->mt = mt;
778	image->mtface = face;
779	image->mtlevel = level;
780	radeon_miptree_reference(image->mt);
781}
782
783int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj)
784{
785	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
786	radeonTexObj *t = radeon_tex_obj(texObj);
787	radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[0][texObj->BaseLevel]);
788	int face, level;
789
790	if (t->validated || t->image_override)
791		return GL_TRUE;
792
793	if (RADEON_DEBUG & DEBUG_TEXTURE)
794		fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj);
795
796	if (baseimage->base.Border > 0)
797		return GL_FALSE;
798
799	/* Ensure a matching miptree exists.
800	 *
801	 * Differing mipmap trees can result when the app uses TexImage to
802	 * change texture dimensions.
803	 *
804	 * Prefer to use base image's miptree if it
805	 * exists, since that most likely contains more valid data (remember
806	 * that the base level is usually significantly larger than the rest
807	 * of the miptree, so cubemaps are the only possible exception).
808	 */
809	if (baseimage->mt &&
810	    baseimage->mt != t->mt &&
811	    radeon_miptree_matches_texture(baseimage->mt, &t->base)) {
812		radeon_miptree_unreference(t->mt);
813		t->mt = baseimage->mt;
814		radeon_miptree_reference(t->mt);
815	} else if (t->mt && !radeon_miptree_matches_texture(t->mt, &t->base)) {
816		radeon_miptree_unreference(t->mt);
817		t->mt = 0;
818	}
819
820	if (!t->mt) {
821		if (RADEON_DEBUG & DEBUG_TEXTURE)
822			fprintf(stderr, " Allocate new miptree\n");
823		radeon_try_alloc_miptree(rmesa, t, &baseimage->base, 0, texObj->BaseLevel);
824		if (!t->mt) {
825			_mesa_problem(ctx, "r300_validate_texture failed to alloc miptree");
826			return GL_FALSE;
827		}
828	}
829
830	/* Ensure all images are stored in the single main miptree */
831	for(face = 0; face < t->mt->faces; ++face) {
832		for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) {
833			radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]);
834			if (RADEON_DEBUG & DEBUG_TEXTURE)
835				fprintf(stderr, " face %i, level %i... %p vs %p ", face, level, t->mt, image->mt);
836			if (t->mt == image->mt) {
837				if (RADEON_DEBUG & DEBUG_TEXTURE)
838					fprintf(stderr, "OK\n");
839				continue;
840			}
841
842			if (RADEON_DEBUG & DEBUG_TEXTURE)
843				fprintf(stderr, "migrating\n");
844			migrate_image_to_miptree(t->mt, image, face, level);
845		}
846	}
847
848	return GL_TRUE;
849}
850