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