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