radeon_texture.c revision 3996ed555e0a024051e4d161c8d31b2530d8cdc5
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/enums.h"
36#include "main/mfeatures.h"
37#include "main/mipmap.h"
38#include "main/pbo.h"
39#include "main/texcompress.h"
40#include "main/texstore.h"
41#include "main/teximage.h"
42#include "main/texobj.h"
43#include "drivers/common/meta.h"
44
45#include "xmlpool.h"		/* for symbolic values of enum-type options */
46
47#include "radeon_common.h"
48
49#include "radeon_mipmap_tree.h"
50
51
52void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
53	GLuint numrows, GLuint rowsize)
54{
55	assert(rowsize <= dststride);
56	assert(rowsize <= srcstride);
57
58	radeon_print(RADEON_TEXTURE, RADEON_TRACE,
59		"%s dst %p, stride %u, src %p, stride %u, "
60		"numrows %u, rowsize %u.\n",
61		__func__, dst, dststride,
62		src, srcstride,
63		numrows, rowsize);
64
65	if (rowsize == srcstride && rowsize == dststride) {
66		memcpy(dst, src, numrows*rowsize);
67	} else {
68		GLuint i;
69		for(i = 0; i < numrows; ++i) {
70			memcpy(dst, src, rowsize);
71			dst += dststride;
72			src += srcstride;
73		}
74	}
75}
76
77/* textures */
78/**
79 * Allocate an empty texture image object.
80 */
81struct gl_texture_image *radeonNewTextureImage(struct gl_context *ctx)
82{
83	return CALLOC(sizeof(radeon_texture_image));
84}
85
86
87/**
88 * Delete a texture image object.
89 */
90static void
91radeonDeleteTextureImage(struct gl_context *ctx, struct gl_texture_image *img)
92{
93	/* nothing special (yet) for radeon_texture_image */
94	_mesa_delete_texture_image(ctx, img);
95}
96
97
98/**
99 * Free memory associated with this texture image.
100 */
101void radeonFreeTextureImageBuffer(struct gl_context *ctx, struct gl_texture_image *timage)
102{
103	radeon_texture_image* image = get_radeon_texture_image(timage);
104
105	if (image->mt) {
106		radeon_miptree_unreference(&image->mt);
107		assert(!image->base.Buffer);
108	} else {
109		_swrast_free_texture_image_buffer(ctx, timage);
110	}
111	if (image->bo) {
112		radeon_bo_unref(image->bo);
113		image->bo = NULL;
114	}
115	if (image->base.Buffer) {
116		_mesa_align_free(image->base.Buffer);
117		image->base.Buffer = NULL;
118	}
119
120	if (image->base.ImageOffsets) {
121		free(image->base.ImageOffsets);
122		image->base.ImageOffsets = NULL;
123	}
124}
125
126/* Set Data pointer and additional data for mapped texture image */
127static void teximage_set_map_data(radeon_texture_image *image)
128{
129	radeon_mipmap_level *lvl;
130
131	if (!image->mt) {
132		radeon_warning("%s(%p) Trying to set map data without miptree.\n",
133				__func__, image);
134
135		return;
136	}
137
138	lvl = &image->mt->levels[image->mtlevel];
139
140	image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset;
141	image->base.RowStride = lvl->rowstride / _mesa_get_format_bytes(image->base.Base.TexFormat);
142}
143
144
145/**
146 * Map a single texture image for glTexImage and friends.
147 */
148void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable)
149{
150	radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
151			"%s(img %p), write_enable %s.\n",
152			__func__, image,
153			write_enable ? "true": "false");
154	if (image->mt) {
155		assert(!image->base.Data);
156
157		radeon_bo_map(image->mt->bo, write_enable);
158		teximage_set_map_data(image);
159	}
160}
161
162
163void radeon_teximage_unmap(radeon_texture_image *image)
164{
165	radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
166			"%s(img %p)\n",
167			__func__, image);
168	if (image->mt) {
169		assert(image->base.Data);
170
171		image->base.Data = 0;
172		radeon_bo_unmap(image->mt->bo);
173	}
174}
175
176static void map_override(struct gl_context *ctx, radeonTexObj *t)
177{
178	radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
179
180	radeon_bo_map(t->bo, GL_FALSE);
181
182	img->base.Data = t->bo->ptr;
183}
184
185static void unmap_override(struct gl_context *ctx, radeonTexObj *t)
186{
187	radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
188
189	radeon_bo_unmap(t->bo);
190
191	img->base.Data = NULL;
192}
193
194/**
195 * Map a validated texture for reading during software rendering.
196 */
197void radeonMapTexture(struct gl_context *ctx, struct gl_texture_object *texObj)
198{
199	radeonTexObj* t = radeon_tex_obj(texObj);
200	int face, level;
201
202	radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
203			"%s(%p, tex %p)\n",
204			__func__, ctx, texObj);
205
206	if (!radeon_validate_texture_miptree(ctx, texObj)) {
207		radeon_error("%s(%p, tex %p) Failed to validate miptree for "
208			"sw fallback.\n",
209			__func__, ctx, texObj);
210		return;
211	}
212
213	if (t->image_override && t->bo) {
214		radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
215			"%s(%p, tex %p) Work around for missing miptree in r100.\n",
216			__func__, ctx, texObj);
217
218		map_override(ctx, t);
219	}
220
221	/* for r100 3D sw fallbacks don't have mt */
222	if (!t->mt) {
223		radeon_warning("%s(%p, tex %p) No miptree in texture.\n",
224			__func__, ctx, texObj);
225		return;
226	}
227
228	radeon_bo_map(t->mt->bo, GL_FALSE);
229	for(face = 0; face < t->mt->faces; ++face) {
230		for(level = t->minLod; level <= t->maxLod; ++level)
231			teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level]));
232	}
233}
234
235void radeonUnmapTexture(struct gl_context *ctx, struct gl_texture_object *texObj)
236{
237	radeonTexObj* t = radeon_tex_obj(texObj);
238	int face, level;
239
240	radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
241			"%s(%p, tex %p)\n",
242			__func__, ctx, texObj);
243
244	if (t->image_override && t->bo)
245		unmap_override(ctx, t);
246	/* for r100 3D sw fallbacks don't have mt */
247	if (!t->mt)
248	  return;
249
250	for(face = 0; face < t->mt->faces; ++face) {
251		for(level = t->minLod; level <= t->maxLod; ++level) {
252			radeon_texture_image *image =
253				get_radeon_texture_image(texObj->Image[face][level]);
254			image->base.Data = NULL;
255		}
256	}
257	radeon_bo_unmap(t->mt->bo);
258}
259
260
261/**
262 * Map texture memory/buffer into user space.
263 * Note: the region of interest parameters are ignored here.
264 * \param mapOut  returns start of mapping of region of interest
265 * \param rowStrideOut  returns row stride in bytes
266 */
267static void
268radeon_map_texture_image(struct gl_context *ctx,
269			 struct gl_texture_image *texImage,
270			 GLuint slice,
271			 GLuint x, GLuint y, GLuint w, GLuint h,
272			 GLbitfield mode,
273			 GLubyte **map,
274			 GLint *stride)
275{
276	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
277	radeon_texture_image *image = get_radeon_texture_image(texImage);
278	radeon_mipmap_tree *mt = image->mt;
279	GLuint texel_size = _mesa_get_format_bytes(texImage->TexFormat);
280	GLuint width = texImage->Width;
281	GLuint height = texImage->Height;
282	struct radeon_bo *bo = !image->mt ? image->bo : image->mt->bo;
283	unsigned int bw, bh;
284	GLboolean write = (mode & GL_MAP_WRITE_BIT) != 0;
285
286	_mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
287	assert(y % bh == 0);
288	y /= bh;
289	height /= bh;
290
291	if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
292		radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
293			     "%s for texture that is "
294			     "queued for GPU processing.\n",
295			     __func__);
296		radeon_firevertices(rmesa);
297	}
298
299	if (image->bo) {
300		/* TFP case */
301		radeon_bo_map(image->bo, write);
302		*stride = get_texture_image_row_stride(rmesa, texImage->TexFormat, width, 0);
303		*map = bo->ptr;
304	} else if (likely(mt)) {
305		radeon_bo_map(mt->bo, write);
306		radeon_mipmap_level *lvl = &image->mt->levels[texImage->Level];
307		void *base = mt->bo->ptr + lvl->faces[image->mtface].offset;
308
309		*stride = lvl->rowstride;
310		*map = base + (slice * height) * *stride;
311	} else {
312		/* texture data is in malloc'd memory */
313
314		assert(map);
315
316		*stride = _mesa_format_row_stride(texImage->TexFormat, width);
317		*map = image->base.Buffer + (slice * height) * *stride;
318	}
319
320	*map += y * *stride + x * texel_size;
321}
322
323static void
324radeon_unmap_texture_image(struct gl_context *ctx,
325			   struct gl_texture_image *texImage, GLuint slice)
326{
327	radeon_texture_image *image = get_radeon_texture_image(texImage);
328
329	if (image->bo)
330		radeon_bo_unmap(image->bo);
331	else if (image->mt)
332		radeon_bo_unmap(image->mt->bo);
333}
334
335void radeonGenerateMipmap(struct gl_context* ctx, GLenum target, struct gl_texture_object *texObj)
336{
337	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
338	struct radeon_bo *bo;
339	GLuint face = _mesa_tex_target_to_face(target);
340	radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]);
341	bo = !baseimage->mt ? baseimage->bo : baseimage->mt->bo;
342
343	radeon_print(RADEON_TEXTURE, RADEON_TRACE,
344		"%s(%p, target %s, tex %p)\n",
345		__func__, ctx, _mesa_lookup_enum_by_nr(target),
346		texObj);
347
348	if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
349		radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
350			"%s(%p, tex %p) Trying to generate mipmap for texture "
351			"in processing by GPU.\n",
352			__func__, ctx, texObj);
353		radeon_firevertices(rmesa);
354	}
355
356	if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) {
357		_mesa_generate_mipmap(ctx, target, texObj);
358	} else {
359		_mesa_meta_GenerateMipmap(ctx, target, texObj);
360	}
361}
362
363
364/* try to find a format which will only need a memcopy */
365static gl_format radeonChoose8888TexFormat(radeonContextPtr rmesa,
366					   GLenum srcFormat,
367					   GLenum srcType, GLboolean fbo)
368{
369	const GLuint ui = 1;
370	const GLubyte littleEndian = *((const GLubyte *)&ui);
371
372	/* r100 can only do this */
373	if (IS_R100_CLASS(rmesa->radeonScreen) || fbo)
374	  return _dri_texformat_argb8888;
375
376	if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
377	    (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
378	    (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
379	    (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
380		return MESA_FORMAT_RGBA8888;
381	} else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
382		   (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
383		   (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
384		   (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
385		return MESA_FORMAT_RGBA8888_REV;
386	} else if (IS_R200_CLASS(rmesa->radeonScreen)) {
387		return _dri_texformat_argb8888;
388	} else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
389					    srcType == GL_UNSIGNED_INT_8_8_8_8)) {
390		return MESA_FORMAT_ARGB8888_REV;
391	} else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
392					    srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
393		return MESA_FORMAT_ARGB8888;
394	} else
395		return _dri_texformat_argb8888;
396}
397
398gl_format radeonChooseTextureFormat_mesa(struct gl_context * ctx,
399					 GLint internalFormat,
400					 GLenum format,
401					 GLenum type)
402{
403	return radeonChooseTextureFormat(ctx, internalFormat, format,
404					 type, 0);
405}
406
407gl_format radeonChooseTextureFormat(struct gl_context * ctx,
408				    GLint internalFormat,
409				    GLenum format,
410				    GLenum type, GLboolean fbo)
411{
412	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
413	const GLboolean do32bpt =
414	    (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32);
415	const GLboolean force16bpt =
416	    (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16);
417	(void)format;
418
419	radeon_print(RADEON_TEXTURE, RADEON_TRACE,
420		"%s InternalFormat=%s(%d) type=%s format=%s\n",
421		__func__,
422		_mesa_lookup_enum_by_nr(internalFormat), internalFormat,
423		_mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format));
424	radeon_print(RADEON_TEXTURE, RADEON_TRACE,
425			"%s do32bpt=%d force16bpt=%d\n",
426			__func__, do32bpt, force16bpt);
427
428	switch (internalFormat) {
429	case 4:
430	case GL_RGBA:
431	case GL_COMPRESSED_RGBA:
432		switch (type) {
433		case GL_UNSIGNED_INT_10_10_10_2:
434		case GL_UNSIGNED_INT_2_10_10_10_REV:
435			return do32bpt ? _dri_texformat_argb8888 :
436			    _dri_texformat_argb1555;
437		case GL_UNSIGNED_SHORT_4_4_4_4:
438		case GL_UNSIGNED_SHORT_4_4_4_4_REV:
439			return _dri_texformat_argb4444;
440		case GL_UNSIGNED_SHORT_5_5_5_1:
441		case GL_UNSIGNED_SHORT_1_5_5_5_REV:
442			return _dri_texformat_argb1555;
443		default:
444			return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type, fbo) :
445			    _dri_texformat_argb4444;
446		}
447
448	case 3:
449	case GL_RGB:
450	case GL_COMPRESSED_RGB:
451		switch (type) {
452		case GL_UNSIGNED_SHORT_4_4_4_4:
453		case GL_UNSIGNED_SHORT_4_4_4_4_REV:
454			return _dri_texformat_argb4444;
455		case GL_UNSIGNED_SHORT_5_5_5_1:
456		case GL_UNSIGNED_SHORT_1_5_5_5_REV:
457			return _dri_texformat_argb1555;
458		case GL_UNSIGNED_SHORT_5_6_5:
459		case GL_UNSIGNED_SHORT_5_6_5_REV:
460			return _dri_texformat_rgb565;
461		default:
462			return do32bpt ? _dri_texformat_argb8888 :
463			    _dri_texformat_rgb565;
464		}
465
466	case GL_RGBA8:
467	case GL_RGB10_A2:
468	case GL_RGBA12:
469	case GL_RGBA16:
470		return !force16bpt ?
471			radeonChoose8888TexFormat(rmesa, format, type, fbo) :
472			_dri_texformat_argb4444;
473
474	case GL_RGBA4:
475	case GL_RGBA2:
476		return _dri_texformat_argb4444;
477
478	case GL_RGB5_A1:
479		return _dri_texformat_argb1555;
480
481	case GL_RGB8:
482	case GL_RGB10:
483	case GL_RGB12:
484	case GL_RGB16:
485		return !force16bpt ? _dri_texformat_argb8888 :
486		    _dri_texformat_rgb565;
487
488	case GL_RGB5:
489	case GL_RGB4:
490	case GL_R3_G3_B2:
491		return _dri_texformat_rgb565;
492
493	case GL_ALPHA:
494	case GL_ALPHA4:
495	case GL_ALPHA8:
496	case GL_ALPHA12:
497	case GL_ALPHA16:
498	case GL_COMPRESSED_ALPHA:
499		/* r200: can't use a8 format since interpreting hw I8 as a8 would result
500		   in wrong rgb values (same as alpha value instead of 0). */
501		if (IS_R200_CLASS(rmesa->radeonScreen))
502			return _dri_texformat_al88;
503		else
504			return MESA_FORMAT_A8;
505	case 1:
506	case GL_LUMINANCE:
507	case GL_LUMINANCE4:
508	case GL_LUMINANCE8:
509	case GL_LUMINANCE12:
510	case GL_LUMINANCE16:
511	case GL_COMPRESSED_LUMINANCE:
512		return MESA_FORMAT_L8;
513
514	case 2:
515	case GL_LUMINANCE_ALPHA:
516	case GL_LUMINANCE4_ALPHA4:
517	case GL_LUMINANCE6_ALPHA2:
518	case GL_LUMINANCE8_ALPHA8:
519	case GL_LUMINANCE12_ALPHA4:
520	case GL_LUMINANCE12_ALPHA12:
521	case GL_LUMINANCE16_ALPHA16:
522	case GL_COMPRESSED_LUMINANCE_ALPHA:
523		return _dri_texformat_al88;
524
525	case GL_INTENSITY:
526	case GL_INTENSITY4:
527	case GL_INTENSITY8:
528	case GL_INTENSITY12:
529	case GL_INTENSITY16:
530	case GL_COMPRESSED_INTENSITY:
531		return MESA_FORMAT_I8;
532
533	case GL_YCBCR_MESA:
534		if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
535		    type == GL_UNSIGNED_BYTE)
536			return MESA_FORMAT_YCBCR;
537		else
538			return MESA_FORMAT_YCBCR_REV;
539
540	case GL_RGB_S3TC:
541	case GL_RGB4_S3TC:
542	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
543		return MESA_FORMAT_RGB_DXT1;
544
545	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
546		return MESA_FORMAT_RGBA_DXT1;
547
548	case GL_RGBA_S3TC:
549	case GL_RGBA4_S3TC:
550	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
551		return MESA_FORMAT_RGBA_DXT3;
552
553	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
554		return MESA_FORMAT_RGBA_DXT5;
555
556	case GL_ALPHA16F_ARB:
557		return MESA_FORMAT_ALPHA_FLOAT16;
558	case GL_ALPHA32F_ARB:
559		return MESA_FORMAT_ALPHA_FLOAT32;
560	case GL_LUMINANCE16F_ARB:
561		return MESA_FORMAT_LUMINANCE_FLOAT16;
562	case GL_LUMINANCE32F_ARB:
563		return MESA_FORMAT_LUMINANCE_FLOAT32;
564	case GL_LUMINANCE_ALPHA16F_ARB:
565		return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16;
566	case GL_LUMINANCE_ALPHA32F_ARB:
567		return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32;
568	case GL_INTENSITY16F_ARB:
569		return MESA_FORMAT_INTENSITY_FLOAT16;
570	case GL_INTENSITY32F_ARB:
571		return MESA_FORMAT_INTENSITY_FLOAT32;
572	case GL_RGB16F_ARB:
573		return MESA_FORMAT_RGBA_FLOAT16;
574	case GL_RGB32F_ARB:
575		return MESA_FORMAT_RGBA_FLOAT32;
576	case GL_RGBA16F_ARB:
577		return MESA_FORMAT_RGBA_FLOAT16;
578	case GL_RGBA32F_ARB:
579		return MESA_FORMAT_RGBA_FLOAT32;
580
581	case GL_DEPTH_COMPONENT:
582	case GL_DEPTH_COMPONENT16:
583	case GL_DEPTH_COMPONENT24:
584	case GL_DEPTH_COMPONENT32:
585	case GL_DEPTH_STENCIL_EXT:
586	case GL_DEPTH24_STENCIL8_EXT:
587		return MESA_FORMAT_S8_Z24;
588
589	/* EXT_texture_sRGB */
590	case GL_SRGB:
591	case GL_SRGB8:
592	case GL_SRGB_ALPHA:
593	case GL_SRGB8_ALPHA8:
594	case GL_COMPRESSED_SRGB:
595	case GL_COMPRESSED_SRGB_ALPHA:
596		return MESA_FORMAT_SARGB8;
597
598	case GL_SLUMINANCE:
599	case GL_SLUMINANCE8:
600	case GL_COMPRESSED_SLUMINANCE:
601		return MESA_FORMAT_SL8;
602
603	case GL_SLUMINANCE_ALPHA:
604	case GL_SLUMINANCE8_ALPHA8:
605	case GL_COMPRESSED_SLUMINANCE_ALPHA:
606		return MESA_FORMAT_SLA8;
607
608	case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
609		return MESA_FORMAT_SRGB_DXT1;
610	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
611		return MESA_FORMAT_SRGBA_DXT1;
612	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
613		return MESA_FORMAT_SRGBA_DXT3;
614	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
615		return MESA_FORMAT_SRGBA_DXT5;
616
617	default:
618		_mesa_problem(ctx,
619			      "unexpected internalFormat 0x%x in %s",
620			      (int)internalFormat, __func__);
621		return MESA_FORMAT_NONE;
622	}
623
624	return MESA_FORMAT_NONE;		/* never get here */
625}
626
627/** Check if given image is valid within current texture object.
628 */
629static int image_matches_texture_obj(struct gl_texture_object *texObj,
630	struct gl_texture_image *texImage,
631	unsigned level)
632{
633	const struct gl_texture_image *baseImage = texObj->Image[0][texObj->BaseLevel];
634
635	if (!baseImage)
636		return 0;
637
638	if (level < texObj->BaseLevel || level > texObj->MaxLevel)
639		return 0;
640
641	const unsigned levelDiff = level - texObj->BaseLevel;
642	const unsigned refWidth = MAX2(baseImage->Width >> levelDiff, 1);
643	const unsigned refHeight = MAX2(baseImage->Height >> levelDiff, 1);
644	const unsigned refDepth = MAX2(baseImage->Depth >> levelDiff, 1);
645
646	return (texImage->Width == refWidth &&
647			texImage->Height == refHeight &&
648			texImage->Depth == refDepth);
649}
650
651static void teximage_assign_miptree(radeonContextPtr rmesa,
652	struct gl_texture_object *texObj,
653	struct gl_texture_image *texImage,
654	unsigned face,
655	unsigned level)
656{
657	radeonTexObj *t = radeon_tex_obj(texObj);
658	radeon_texture_image* image = get_radeon_texture_image(texImage);
659
660	/* Since miptree holds only images for levels <BaseLevel..MaxLevel>
661	 * don't allocate the miptree if the teximage won't fit.
662	 */
663	if (!image_matches_texture_obj(texObj, texImage, level))
664		return;
665
666	/* Try using current miptree, or create new if there isn't any */
667	if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) {
668		radeon_miptree_unreference(&t->mt);
669		radeon_try_alloc_miptree(rmesa, t);
670		radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
671				"%s: texObj %p, texImage %p, face %d, level %d, "
672				"texObj miptree doesn't match, allocated new miptree %p\n",
673				__FUNCTION__, texObj, texImage, face, level, t->mt);
674	}
675
676	/* Miptree alocation may have failed,
677	 * when there was no image for baselevel specified */
678	if (t->mt) {
679		image->mtface = face;
680		image->mtlevel = level;
681		radeon_miptree_reference(t->mt, &image->mt);
682	} else
683		radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
684				"%s Failed to allocate miptree.\n", __func__);
685}
686
687
688/**
689 * Update a subregion of the given texture image.
690 */
691static void radeon_store_teximage(struct gl_context* ctx, int dims,
692		GLint xoffset, GLint yoffset, GLint zoffset,
693		GLsizei width, GLsizei height, GLsizei depth,
694		GLsizei imageSize,
695		GLenum format, GLenum type,
696		const GLvoid * pixels,
697		const struct gl_pixelstore_attrib *packing,
698		struct gl_texture_object *texObj,
699		struct gl_texture_image *texImage,
700		int compressed)
701{
702	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
703	radeonTexObj *t = radeon_tex_obj(texObj);
704	radeon_texture_image* image = get_radeon_texture_image(texImage);
705	GLuint texel_size = _mesa_get_format_bytes(texImage->TexFormat);
706
707	GLuint dstRowStride;
708	GLuint alignedWidth;
709	GLint i;
710
711	radeon_print(RADEON_TEXTURE, RADEON_TRACE,
712			"%s(%p, tex %p, image %p) compressed %d\n",
713			__func__, ctx, texObj, texImage, compressed);
714
715	if (image->mt) {
716		dstRowStride = image->mt->levels[image->mtlevel].rowstride;
717	} else if (t->bo) {
718		/* TFP case */
719		dstRowStride = get_texture_image_row_stride(rmesa, texImage->TexFormat, width, 0);
720	} else {
721		dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
722	}
723
724	assert(dstRowStride);
725
726	/* fill in the ImageOffsets array */
727	alignedWidth = dstRowStride / texel_size;
728	for (i = 0; i < texImage->Depth; ++i) {
729		image->base.ImageOffsets[i] = alignedWidth * texImage->Height * i;
730	}
731	/* and fill in RowStride (in texels) */
732	image->base.RowStride = alignedWidth;
733
734	radeon_teximage_map(image, GL_TRUE);
735
736	if (compressed) {
737		uint32_t srcRowStride, bytesPerRow, rows, block_width, block_height;
738		GLubyte *img_start;
739
740		_mesa_get_format_block_size(texImage->TexFormat, &block_width, &block_height);
741
742		if (!image->mt) {
743			dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
744			img_start = _mesa_compressed_image_address(xoffset, yoffset, 0,
745									texImage->TexFormat,
746									texImage->Width, image->base.Data);
747		}
748		else {
749			uint32_t offset;
750			offset = dstRowStride / texel_size * yoffset / block_height + xoffset / block_width;
751			offset *= texel_size;
752			img_start = image->base.Data + offset;
753		}
754		srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
755		bytesPerRow = srcRowStride;
756		rows = (height + block_height - 1) / block_height;
757
758		copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow);
759	}
760	else {
761		GLubyte *slices[512];
762		GLuint i;
763		assert(depth <= 512);
764		for (i = 0; i < depth; i++) {
765			slices[i] = (GLubyte *) image->base.Data
766				+ image->base.ImageOffsets[i] * texel_size;
767		}
768		if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
769					texImage->TexFormat,
770					xoffset, yoffset, zoffset,
771					dstRowStride,
772					slices,
773					width, height, depth,
774					format, type, pixels, packing)) {
775			_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
776		}
777	}
778
779	radeon_teximage_unmap(image);
780}
781
782/**
783 * All glTexImage calls go through this function.
784 */
785static void radeon_teximage(
786	struct gl_context *ctx, int dims,
787	GLenum target, GLint level,
788	GLint internalFormat,
789	GLint width, GLint height, GLint depth,
790	GLsizei imageSize,
791	GLenum format, GLenum type, const GLvoid * pixels,
792	const struct gl_pixelstore_attrib *packing,
793	struct gl_texture_object *texObj,
794	struct gl_texture_image *texImage,
795	int compressed)
796{
797	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
798	radeonTexObj* t = radeon_tex_obj(texObj);
799	radeon_texture_image* image = get_radeon_texture_image(texImage);
800	GLuint face = _mesa_tex_target_to_face(target);
801
802	radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
803			"%s %dd: texObj %p, texImage %p, face %d, level %d\n",
804			__func__, dims, texObj, texImage, face, level);
805
806	t->validated = GL_FALSE;
807
808	radeonFreeTextureImageBuffer(ctx, texImage);
809
810	if (!t->bo) {
811		teximage_assign_miptree(rmesa, texObj, texImage, face, level);
812		if (!image->mt) {
813			int size = _mesa_format_image_size(texImage->TexFormat,
814								texImage->Width,
815								texImage->Height,
816								texImage->Depth);
817			image->base.Buffer = _mesa_align_malloc(size, 512);
818
819			radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
820					"%s %dd: texObj %p, texImage %p, "
821					" no miptree assigned, using local memory %p\n",
822					__func__, dims, texObj, texImage, image->base.Buffer);
823		}
824	}
825
826	{
827		struct radeon_bo *bo;
828		bo = !image->mt ? image->bo : image->mt->bo;
829		if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
830			radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
831				"%s Calling teximage for texture that is "
832				"queued for GPU processing.\n",
833				__func__);
834			radeon_firevertices(rmesa);
835		}
836	}
837
838	image->base.ImageOffsets =
839		(GLuint *) malloc(texImage->Depth * sizeof(GLuint));
840
841
842	/* Upload texture image; note that the spec allows pixels to be NULL */
843	if (compressed) {
844		pixels = _mesa_validate_pbo_compressed_teximage(
845			ctx, imageSize, pixels, packing, "glCompressedTexImage");
846	} else {
847		pixels = _mesa_validate_pbo_teximage(
848			ctx, dims, width, height, depth,
849			format, type, pixels, packing, "glTexImage");
850	}
851
852	if (pixels) {
853		radeon_store_teximage(ctx, dims,
854			0, 0, 0,
855			width, height, depth,
856			imageSize, format, type,
857			pixels, packing,
858			texObj, texImage,
859			compressed);
860	}
861
862	_mesa_unmap_teximage_pbo(ctx, packing);
863}
864
865void radeonTexImage1D(struct gl_context * ctx, GLenum target, GLint level,
866		      GLint internalFormat,
867		      GLint width, GLint border,
868		      GLenum format, GLenum type, const GLvoid * pixels,
869		      const struct gl_pixelstore_attrib *packing,
870		      struct gl_texture_object *texObj,
871		      struct gl_texture_image *texImage)
872{
873	radeon_teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
874		0, format, type, pixels, packing, texObj, texImage, 0);
875}
876
877void radeonTexImage2D(struct gl_context * ctx, GLenum target, GLint level,
878			   GLint internalFormat,
879			   GLint width, GLint height, GLint border,
880			   GLenum format, GLenum type, const GLvoid * pixels,
881			   const struct gl_pixelstore_attrib *packing,
882			   struct gl_texture_object *texObj,
883			   struct gl_texture_image *texImage)
884
885{
886	radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
887		0, format, type, pixels, packing, texObj, texImage, 0);
888}
889
890void radeonCompressedTexImage2D(struct gl_context * ctx, GLenum target,
891				     GLint level, GLint internalFormat,
892				     GLint width, GLint height, GLint border,
893				     GLsizei imageSize, const GLvoid * data,
894				     struct gl_texture_object *texObj,
895				     struct gl_texture_image *texImage)
896{
897	radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
898		imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1);
899}
900
901void radeonTexImage3D(struct gl_context * ctx, GLenum target, GLint level,
902		      GLint internalFormat,
903		      GLint width, GLint height, GLint depth,
904		      GLint border,
905		      GLenum format, GLenum type, const GLvoid * pixels,
906		      const struct gl_pixelstore_attrib *packing,
907		      struct gl_texture_object *texObj,
908		      struct gl_texture_image *texImage)
909{
910	radeon_teximage(ctx, 3, target, level, internalFormat, width, height, depth,
911		0, format, type, pixels, packing, texObj, texImage, 0);
912}
913
914/**
915 * All glTexSubImage calls go through this function.
916 */
917static void radeon_texsubimage(struct gl_context* ctx, int dims, GLenum target, int level,
918		GLint xoffset, GLint yoffset, GLint zoffset,
919		GLsizei width, GLsizei height, GLsizei depth,
920		GLsizei imageSize,
921		GLenum format, GLenum type,
922		const GLvoid * pixels,
923		const struct gl_pixelstore_attrib *packing,
924		struct gl_texture_object *texObj,
925		struct gl_texture_image *texImage,
926		int compressed)
927{
928	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
929	radeonTexObj* t = radeon_tex_obj(texObj);
930	radeon_texture_image* image = get_radeon_texture_image(texImage);
931
932	radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
933			"%s %dd: texObj %p, texImage %p, face %d, level %d\n",
934			__func__, dims, texObj, texImage,
935			_mesa_tex_target_to_face(target), level);
936	{
937		struct radeon_bo *bo;
938		bo = !image->mt ? image->bo : image->mt->bo;
939		if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
940			radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
941				"%s Calling texsubimage for texture that is "
942				"queued for GPU processing.\n",
943				__func__);
944			radeon_firevertices(rmesa);
945		}
946	}
947
948
949	t->validated = GL_FALSE;
950	if (compressed) {
951		pixels = _mesa_validate_pbo_compressed_teximage(
952			ctx, imageSize, pixels, packing, "glCompressedTexSubImage");
953	} else {
954		pixels = _mesa_validate_pbo_teximage(ctx, dims,
955			width, height, depth, format, type, pixels, packing, "glTexSubImage");
956	}
957
958	if (pixels) {
959		radeon_store_teximage(ctx, dims,
960			xoffset, yoffset, zoffset,
961			width, height, depth,
962			imageSize, format, type,
963			pixels, packing,
964			texObj, texImage,
965			compressed);
966	}
967
968	_mesa_unmap_teximage_pbo(ctx, packing);
969}
970
971void radeonTexSubImage1D(struct gl_context * ctx, GLenum target, GLint level,
972			 GLint xoffset,
973			 GLsizei width,
974			 GLenum format, GLenum type,
975			 const GLvoid * pixels,
976			 const struct gl_pixelstore_attrib *packing,
977			 struct gl_texture_object *texObj,
978			 struct gl_texture_image *texImage)
979{
980	radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0,
981		format, type, pixels, packing, texObj, texImage, 0);
982}
983
984void radeonTexSubImage2D(struct gl_context * ctx, GLenum target, GLint level,
985			 GLint xoffset, GLint yoffset,
986			 GLsizei width, GLsizei height,
987			 GLenum format, GLenum type,
988			 const GLvoid * pixels,
989			 const struct gl_pixelstore_attrib *packing,
990			 struct gl_texture_object *texObj,
991			 struct gl_texture_image *texImage)
992{
993	radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
994			   0, format, type, pixels, packing, texObj, texImage,
995			   0);
996}
997
998void radeonCompressedTexSubImage2D(struct gl_context * ctx, GLenum target,
999				   GLint level, GLint xoffset,
1000				   GLint yoffset, GLsizei width,
1001				   GLsizei height, GLenum format,
1002				   GLsizei imageSize, const GLvoid * data,
1003				   struct gl_texture_object *texObj,
1004				   struct gl_texture_image *texImage)
1005{
1006	radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
1007		imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1);
1008}
1009
1010
1011void radeonTexSubImage3D(struct gl_context * ctx, GLenum target, GLint level,
1012			 GLint xoffset, GLint yoffset, GLint zoffset,
1013			 GLsizei width, GLsizei height, GLsizei depth,
1014			 GLenum format, GLenum type,
1015			 const GLvoid * pixels,
1016			 const struct gl_pixelstore_attrib *packing,
1017			 struct gl_texture_object *texObj,
1018			 struct gl_texture_image *texImage)
1019{
1020	radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0,
1021		format, type, pixels, packing, texObj, texImage, 0);
1022}
1023
1024unsigned radeonIsFormatRenderable(gl_format mesa_format)
1025{
1026	if (mesa_format == _dri_texformat_argb8888 || mesa_format == _dri_texformat_rgb565 ||
1027		mesa_format == _dri_texformat_argb1555 || mesa_format == _dri_texformat_argb4444)
1028		return 1;
1029
1030	switch (mesa_format)
1031	{
1032		case MESA_FORMAT_Z16:
1033		case MESA_FORMAT_S8_Z24:
1034			return 1;
1035		default:
1036			return 0;
1037	}
1038}
1039
1040#if FEATURE_OES_EGL_image
1041void radeon_image_target_texture_2d(struct gl_context *ctx, GLenum target,
1042				    struct gl_texture_object *texObj,
1043				    struct gl_texture_image *texImage,
1044				    GLeglImageOES image_handle)
1045{
1046	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
1047	radeonTexObj *t = radeon_tex_obj(texObj);
1048	radeon_texture_image *radeonImage = get_radeon_texture_image(texImage);
1049	__DRIscreen *screen;
1050	__DRIimage *image;
1051
1052	screen = radeon->dri.screen;
1053	image = screen->dri2.image->lookupEGLImage(screen, image_handle,
1054						   screen->loaderPrivate);
1055	if (image == NULL)
1056		return;
1057
1058	radeonFreeTextureImageBuffer(ctx, texImage);
1059
1060	texImage->Width = image->width;
1061	texImage->Height = image->height;
1062	texImage->Depth = 1;
1063	texImage->_BaseFormat = GL_RGBA;
1064	texImage->TexFormat = image->format;
1065	radeonImage->base.RowStride = image->pitch;
1066	texImage->InternalFormat = image->internal_format;
1067
1068	if(t->mt)
1069	{
1070		radeon_miptree_unreference(&t->mt);
1071		t->mt = NULL;
1072	}
1073
1074	/* NOTE: The following is *very* ugly and will probably break. But
1075	   I don't know how to deal with it, without creating a whole new
1076	   function like radeon_miptree_from_bo() so I'm going with the
1077	   easy but error-prone way. */
1078
1079	radeon_try_alloc_miptree(radeon, t);
1080
1081	radeonImage->mtface = _mesa_tex_target_to_face(target);
1082	radeonImage->mtlevel = 0;
1083	radeon_miptree_reference(t->mt, &radeonImage->mt);
1084
1085	if (t->mt == NULL)
1086	{
1087		radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
1088			     "%s Failed to allocate miptree.\n", __func__);
1089		return;
1090	}
1091
1092	/* Particularly ugly: this is guaranteed to break, if image->bo is
1093	   not of the required size for a miptree. */
1094	radeon_bo_unref(t->mt->bo);
1095	radeon_bo_ref(image->bo);
1096	t->mt->bo = image->bo;
1097
1098	if (!radeon_miptree_matches_image(t->mt, &radeonImage->base.Base,
1099					  radeonImage->mtface, 0))
1100		fprintf(stderr, "miptree doesn't match image\n");
1101}
1102#endif
1103
1104void
1105radeon_init_common_texture_funcs(radeonContextPtr radeon,
1106				 struct dd_function_table *functions)
1107{
1108	functions->NewTextureImage = radeonNewTextureImage;
1109	functions->DeleteTextureImage = radeonDeleteTextureImage;
1110	functions->FreeTextureImageBuffer = radeonFreeTextureImageBuffer;
1111	functions->MapTexture = radeonMapTexture;
1112	functions->UnmapTexture = radeonUnmapTexture;
1113	functions->MapTextureImage = radeon_map_texture_image;
1114	functions->UnmapTextureImage = radeon_unmap_texture_image;
1115
1116	functions->ChooseTextureFormat	= radeonChooseTextureFormat_mesa;
1117
1118	functions->TexImage1D = radeonTexImage1D;
1119	functions->TexImage2D = radeonTexImage2D;
1120	functions->TexImage3D = radeonTexImage3D;
1121	functions->TexSubImage1D = radeonTexSubImage1D;
1122	functions->TexSubImage2D = radeonTexSubImage2D;
1123	functions->TexSubImage3D = radeonTexSubImage3D;
1124	functions->CompressedTexImage2D = radeonCompressedTexImage2D;
1125	functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D;
1126
1127	functions->GenerateMipmap = radeonGenerateMipmap;
1128
1129	if (radeon->radeonScreen->kernel_mm) {
1130		functions->CopyTexSubImage2D = radeonCopyTexSubImage2D;
1131	}
1132
1133#if FEATURE_OES_EGL_image
1134	functions->EGLImageTargetTexture2D = radeon_image_target_texture_2d;
1135#endif
1136
1137	driInitTextureFormats();
1138}
1139