radeon_texture.c revision a34c28f1aa0e7c0f66bc45f18750eb7f7ca8d5cd
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#ifdef RADEON_R300
582	case GL_DEPTH_COMPONENT:
583	case GL_DEPTH_COMPONENT16:
584		return MESA_FORMAT_Z16;
585	case GL_DEPTH_COMPONENT24:
586	case GL_DEPTH_COMPONENT32:
587	case GL_DEPTH_STENCIL_EXT:
588	case GL_DEPTH24_STENCIL8_EXT:
589		if (rmesa->radeonScreen->chip_family >= CHIP_FAMILY_RV515)
590			return MESA_FORMAT_S8_Z24;
591		else
592			return MESA_FORMAT_Z16;
593#else
594	case GL_DEPTH_COMPONENT:
595	case GL_DEPTH_COMPONENT16:
596	case GL_DEPTH_COMPONENT24:
597	case GL_DEPTH_COMPONENT32:
598	case GL_DEPTH_STENCIL_EXT:
599	case GL_DEPTH24_STENCIL8_EXT:
600		return MESA_FORMAT_S8_Z24;
601#endif
602
603	/* EXT_texture_sRGB */
604	case GL_SRGB:
605	case GL_SRGB8:
606	case GL_SRGB_ALPHA:
607	case GL_SRGB8_ALPHA8:
608	case GL_COMPRESSED_SRGB:
609	case GL_COMPRESSED_SRGB_ALPHA:
610		return MESA_FORMAT_SARGB8;
611
612	case GL_SLUMINANCE:
613	case GL_SLUMINANCE8:
614	case GL_COMPRESSED_SLUMINANCE:
615		return MESA_FORMAT_SL8;
616
617	case GL_SLUMINANCE_ALPHA:
618	case GL_SLUMINANCE8_ALPHA8:
619	case GL_COMPRESSED_SLUMINANCE_ALPHA:
620		return MESA_FORMAT_SLA8;
621
622	case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
623		return MESA_FORMAT_SRGB_DXT1;
624	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
625		return MESA_FORMAT_SRGBA_DXT1;
626	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
627		return MESA_FORMAT_SRGBA_DXT3;
628	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
629		return MESA_FORMAT_SRGBA_DXT5;
630
631	default:
632		_mesa_problem(ctx,
633			      "unexpected internalFormat 0x%x in %s",
634			      (int)internalFormat, __func__);
635		return MESA_FORMAT_NONE;
636	}
637
638	return MESA_FORMAT_NONE;		/* never get here */
639}
640
641/** Check if given image is valid within current texture object.
642 */
643static int image_matches_texture_obj(struct gl_texture_object *texObj,
644	struct gl_texture_image *texImage,
645	unsigned level)
646{
647	const struct gl_texture_image *baseImage = texObj->Image[0][texObj->BaseLevel];
648
649	if (!baseImage)
650		return 0;
651
652	if (level < texObj->BaseLevel || level > texObj->MaxLevel)
653		return 0;
654
655	const unsigned levelDiff = level - texObj->BaseLevel;
656	const unsigned refWidth = MAX2(baseImage->Width >> levelDiff, 1);
657	const unsigned refHeight = MAX2(baseImage->Height >> levelDiff, 1);
658	const unsigned refDepth = MAX2(baseImage->Depth >> levelDiff, 1);
659
660	return (texImage->Width == refWidth &&
661			texImage->Height == refHeight &&
662			texImage->Depth == refDepth);
663}
664
665static void teximage_assign_miptree(radeonContextPtr rmesa,
666	struct gl_texture_object *texObj,
667	struct gl_texture_image *texImage,
668	unsigned face,
669	unsigned level)
670{
671	radeonTexObj *t = radeon_tex_obj(texObj);
672	radeon_texture_image* image = get_radeon_texture_image(texImage);
673
674	/* Since miptree holds only images for levels <BaseLevel..MaxLevel>
675	 * don't allocate the miptree if the teximage won't fit.
676	 */
677	if (!image_matches_texture_obj(texObj, texImage, level))
678		return;
679
680	/* Try using current miptree, or create new if there isn't any */
681	if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) {
682		radeon_miptree_unreference(&t->mt);
683		radeon_try_alloc_miptree(rmesa, t);
684		radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
685				"%s: texObj %p, texImage %p, face %d, level %d, "
686				"texObj miptree doesn't match, allocated new miptree %p\n",
687				__FUNCTION__, texObj, texImage, face, level, t->mt);
688	}
689
690	/* Miptree alocation may have failed,
691	 * when there was no image for baselevel specified */
692	if (t->mt) {
693		image->mtface = face;
694		image->mtlevel = level;
695		radeon_miptree_reference(t->mt, &image->mt);
696	} else
697		radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
698				"%s Failed to allocate miptree.\n", __func__);
699}
700
701
702/**
703 * Update a subregion of the given texture image.
704 */
705static void radeon_store_teximage(struct gl_context* ctx, int dims,
706		GLint xoffset, GLint yoffset, GLint zoffset,
707		GLsizei width, GLsizei height, GLsizei depth,
708		GLsizei imageSize,
709		GLenum format, GLenum type,
710		const GLvoid * pixels,
711		const struct gl_pixelstore_attrib *packing,
712		struct gl_texture_object *texObj,
713		struct gl_texture_image *texImage,
714		int compressed)
715{
716	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
717	radeonTexObj *t = radeon_tex_obj(texObj);
718	radeon_texture_image* image = get_radeon_texture_image(texImage);
719	GLuint texel_size = _mesa_get_format_bytes(texImage->TexFormat);
720
721	GLuint dstRowStride;
722	GLuint alignedWidth;
723	GLint i;
724
725	radeon_print(RADEON_TEXTURE, RADEON_TRACE,
726			"%s(%p, tex %p, image %p) compressed %d\n",
727			__func__, ctx, texObj, texImage, compressed);
728
729	if (image->mt) {
730		dstRowStride = image->mt->levels[image->mtlevel].rowstride;
731	} else if (t->bo) {
732		/* TFP case */
733		dstRowStride = get_texture_image_row_stride(rmesa, texImage->TexFormat, width, 0);
734	} else {
735		dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
736	}
737
738	assert(dstRowStride);
739
740	/* fill in the ImageOffsets array */
741	alignedWidth = dstRowStride / texel_size;
742	for (i = 0; i < texImage->Depth; ++i) {
743		image->base.ImageOffsets[i] = alignedWidth * texImage->Height * i;
744	}
745	/* and fill in RowStride (in texels) */
746	image->base.RowStride = alignedWidth;
747
748	radeon_teximage_map(image, GL_TRUE);
749
750	if (compressed) {
751		uint32_t srcRowStride, bytesPerRow, rows, block_width, block_height;
752		GLubyte *img_start;
753
754		_mesa_get_format_block_size(texImage->TexFormat, &block_width, &block_height);
755
756		if (!image->mt) {
757			dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
758			img_start = _mesa_compressed_image_address(xoffset, yoffset, 0,
759									texImage->TexFormat,
760									texImage->Width, image->base.Data);
761		}
762		else {
763			uint32_t offset;
764			offset = dstRowStride / texel_size * yoffset / block_height + xoffset / block_width;
765			offset *= texel_size;
766			img_start = image->base.Data + offset;
767		}
768		srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
769		bytesPerRow = srcRowStride;
770		rows = (height + block_height - 1) / block_height;
771
772		copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow);
773	}
774	else {
775		GLubyte *slices[512];
776		GLuint i;
777		assert(depth <= 512);
778		for (i = 0; i < depth; i++) {
779			slices[i] = (GLubyte *) image->base.Data
780				+ image->base.ImageOffsets[i] * texel_size;
781		}
782		if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
783					texImage->TexFormat,
784					xoffset, yoffset, zoffset,
785					dstRowStride,
786					slices,
787					width, height, depth,
788					format, type, pixels, packing)) {
789			_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
790		}
791	}
792
793	radeon_teximage_unmap(image);
794}
795
796/**
797 * All glTexImage calls go through this function.
798 */
799static void radeon_teximage(
800	struct gl_context *ctx, int dims,
801	GLenum target, GLint level,
802	GLint internalFormat,
803	GLint width, GLint height, GLint depth,
804	GLsizei imageSize,
805	GLenum format, GLenum type, const GLvoid * pixels,
806	const struct gl_pixelstore_attrib *packing,
807	struct gl_texture_object *texObj,
808	struct gl_texture_image *texImage,
809	int compressed)
810{
811	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
812	radeonTexObj* t = radeon_tex_obj(texObj);
813	radeon_texture_image* image = get_radeon_texture_image(texImage);
814	GLuint face = _mesa_tex_target_to_face(target);
815
816	radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
817			"%s %dd: texObj %p, texImage %p, face %d, level %d\n",
818			__func__, dims, texObj, texImage, face, level);
819
820	t->validated = GL_FALSE;
821
822	radeonFreeTextureImageBuffer(ctx, texImage);
823
824	if (!t->bo) {
825		teximage_assign_miptree(rmesa, texObj, texImage, face, level);
826		if (!image->mt) {
827			int size = _mesa_format_image_size(texImage->TexFormat,
828								texImage->Width,
829								texImage->Height,
830								texImage->Depth);
831			image->base.Buffer = _mesa_align_malloc(size, 512);
832
833			radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
834					"%s %dd: texObj %p, texImage %p, "
835					" no miptree assigned, using local memory %p\n",
836					__func__, dims, texObj, texImage, image->base.Buffer);
837		}
838	}
839
840	{
841		struct radeon_bo *bo;
842		bo = !image->mt ? image->bo : image->mt->bo;
843		if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
844			radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
845				"%s Calling teximage for texture that is "
846				"queued for GPU processing.\n",
847				__func__);
848			radeon_firevertices(rmesa);
849		}
850	}
851
852	image->base.ImageOffsets =
853		(GLuint *) malloc(texImage->Depth * sizeof(GLuint));
854
855
856	/* Upload texture image; note that the spec allows pixels to be NULL */
857	if (compressed) {
858		pixels = _mesa_validate_pbo_compressed_teximage(
859			ctx, imageSize, pixels, packing, "glCompressedTexImage");
860	} else {
861		pixels = _mesa_validate_pbo_teximage(
862			ctx, dims, width, height, depth,
863			format, type, pixels, packing, "glTexImage");
864	}
865
866	if (pixels) {
867		radeon_store_teximage(ctx, dims,
868			0, 0, 0,
869			width, height, depth,
870			imageSize, format, type,
871			pixels, packing,
872			texObj, texImage,
873			compressed);
874	}
875
876	_mesa_unmap_teximage_pbo(ctx, packing);
877}
878
879void radeonTexImage1D(struct gl_context * ctx, GLenum target, GLint level,
880		      GLint internalFormat,
881		      GLint width, GLint border,
882		      GLenum format, GLenum type, const GLvoid * pixels,
883		      const struct gl_pixelstore_attrib *packing,
884		      struct gl_texture_object *texObj,
885		      struct gl_texture_image *texImage)
886{
887	radeon_teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
888		0, format, type, pixels, packing, texObj, texImage, 0);
889}
890
891void radeonTexImage2D(struct gl_context * ctx, GLenum target, GLint level,
892			   GLint internalFormat,
893			   GLint width, GLint height, GLint border,
894			   GLenum format, GLenum type, const GLvoid * pixels,
895			   const struct gl_pixelstore_attrib *packing,
896			   struct gl_texture_object *texObj,
897			   struct gl_texture_image *texImage)
898
899{
900	radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
901		0, format, type, pixels, packing, texObj, texImage, 0);
902}
903
904void radeonCompressedTexImage2D(struct gl_context * ctx, GLenum target,
905				     GLint level, GLint internalFormat,
906				     GLint width, GLint height, GLint border,
907				     GLsizei imageSize, const GLvoid * data,
908				     struct gl_texture_object *texObj,
909				     struct gl_texture_image *texImage)
910{
911	radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
912		imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1);
913}
914
915void radeonTexImage3D(struct gl_context * ctx, GLenum target, GLint level,
916		      GLint internalFormat,
917		      GLint width, GLint height, GLint depth,
918		      GLint border,
919		      GLenum format, GLenum type, const GLvoid * pixels,
920		      const struct gl_pixelstore_attrib *packing,
921		      struct gl_texture_object *texObj,
922		      struct gl_texture_image *texImage)
923{
924	radeon_teximage(ctx, 3, target, level, internalFormat, width, height, depth,
925		0, format, type, pixels, packing, texObj, texImage, 0);
926}
927
928/**
929 * All glTexSubImage calls go through this function.
930 */
931static void radeon_texsubimage(struct gl_context* ctx, int dims, GLenum target, int level,
932		GLint xoffset, GLint yoffset, GLint zoffset,
933		GLsizei width, GLsizei height, GLsizei depth,
934		GLsizei imageSize,
935		GLenum format, GLenum type,
936		const GLvoid * pixels,
937		const struct gl_pixelstore_attrib *packing,
938		struct gl_texture_object *texObj,
939		struct gl_texture_image *texImage,
940		int compressed)
941{
942	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
943	radeonTexObj* t = radeon_tex_obj(texObj);
944	radeon_texture_image* image = get_radeon_texture_image(texImage);
945
946	radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
947			"%s %dd: texObj %p, texImage %p, face %d, level %d\n",
948			__func__, dims, texObj, texImage,
949			_mesa_tex_target_to_face(target), level);
950	{
951		struct radeon_bo *bo;
952		bo = !image->mt ? image->bo : image->mt->bo;
953		if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
954			radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
955				"%s Calling texsubimage for texture that is "
956				"queued for GPU processing.\n",
957				__func__);
958			radeon_firevertices(rmesa);
959		}
960	}
961
962
963	t->validated = GL_FALSE;
964	if (compressed) {
965		pixels = _mesa_validate_pbo_compressed_teximage(
966			ctx, imageSize, pixels, packing, "glCompressedTexSubImage");
967	} else {
968		pixels = _mesa_validate_pbo_teximage(ctx, dims,
969			width, height, depth, format, type, pixels, packing, "glTexSubImage");
970	}
971
972	if (pixels) {
973		radeon_store_teximage(ctx, dims,
974			xoffset, yoffset, zoffset,
975			width, height, depth,
976			imageSize, format, type,
977			pixels, packing,
978			texObj, texImage,
979			compressed);
980	}
981
982	_mesa_unmap_teximage_pbo(ctx, packing);
983}
984
985void radeonTexSubImage1D(struct gl_context * ctx, GLenum target, GLint level,
986			 GLint xoffset,
987			 GLsizei width,
988			 GLenum format, GLenum type,
989			 const GLvoid * pixels,
990			 const struct gl_pixelstore_attrib *packing,
991			 struct gl_texture_object *texObj,
992			 struct gl_texture_image *texImage)
993{
994	radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0,
995		format, type, pixels, packing, texObj, texImage, 0);
996}
997
998void radeonTexSubImage2D(struct gl_context * ctx, GLenum target, GLint level,
999			 GLint xoffset, GLint yoffset,
1000			 GLsizei width, GLsizei height,
1001			 GLenum format, GLenum type,
1002			 const GLvoid * pixels,
1003			 const struct gl_pixelstore_attrib *packing,
1004			 struct gl_texture_object *texObj,
1005			 struct gl_texture_image *texImage)
1006{
1007	radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
1008			   0, format, type, pixels, packing, texObj, texImage,
1009			   0);
1010}
1011
1012void radeonCompressedTexSubImage2D(struct gl_context * ctx, GLenum target,
1013				   GLint level, GLint xoffset,
1014				   GLint yoffset, GLsizei width,
1015				   GLsizei height, GLenum format,
1016				   GLsizei imageSize, const GLvoid * data,
1017				   struct gl_texture_object *texObj,
1018				   struct gl_texture_image *texImage)
1019{
1020	radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
1021		imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1);
1022}
1023
1024
1025void radeonTexSubImage3D(struct gl_context * ctx, GLenum target, GLint level,
1026			 GLint xoffset, GLint yoffset, GLint zoffset,
1027			 GLsizei width, GLsizei height, GLsizei depth,
1028			 GLenum format, GLenum type,
1029			 const GLvoid * pixels,
1030			 const struct gl_pixelstore_attrib *packing,
1031			 struct gl_texture_object *texObj,
1032			 struct gl_texture_image *texImage)
1033{
1034	radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0,
1035		format, type, pixels, packing, texObj, texImage, 0);
1036}
1037
1038unsigned radeonIsFormatRenderable(gl_format mesa_format)
1039{
1040	if (mesa_format == _dri_texformat_argb8888 || mesa_format == _dri_texformat_rgb565 ||
1041		mesa_format == _dri_texformat_argb1555 || mesa_format == _dri_texformat_argb4444)
1042		return 1;
1043
1044	switch (mesa_format)
1045	{
1046		case MESA_FORMAT_Z16:
1047		case MESA_FORMAT_S8_Z24:
1048			return 1;
1049		default:
1050			return 0;
1051	}
1052}
1053
1054#if FEATURE_OES_EGL_image
1055void radeon_image_target_texture_2d(struct gl_context *ctx, GLenum target,
1056				    struct gl_texture_object *texObj,
1057				    struct gl_texture_image *texImage,
1058				    GLeglImageOES image_handle)
1059{
1060	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
1061	radeonTexObj *t = radeon_tex_obj(texObj);
1062	radeon_texture_image *radeonImage = get_radeon_texture_image(texImage);
1063	__DRIscreen *screen;
1064	__DRIimage *image;
1065
1066	screen = radeon->dri.screen;
1067	image = screen->dri2.image->lookupEGLImage(screen, image_handle,
1068						   screen->loaderPrivate);
1069	if (image == NULL)
1070		return;
1071
1072	radeonFreeTextureImageBuffer(ctx, texImage);
1073
1074	texImage->Width = image->width;
1075	texImage->Height = image->height;
1076	texImage->Depth = 1;
1077	texImage->_BaseFormat = GL_RGBA;
1078	texImage->TexFormat = image->format;
1079	radeonImage->base.RowStride = image->pitch;
1080	texImage->InternalFormat = image->internal_format;
1081
1082	if(t->mt)
1083	{
1084		radeon_miptree_unreference(&t->mt);
1085		t->mt = NULL;
1086	}
1087
1088	/* NOTE: The following is *very* ugly and will probably break. But
1089	   I don't know how to deal with it, without creating a whole new
1090	   function like radeon_miptree_from_bo() so I'm going with the
1091	   easy but error-prone way. */
1092
1093	radeon_try_alloc_miptree(radeon, t);
1094
1095	radeonImage->mtface = _mesa_tex_target_to_face(target);
1096	radeonImage->mtlevel = 0;
1097	radeon_miptree_reference(t->mt, &radeonImage->mt);
1098
1099	if (t->mt == NULL)
1100	{
1101		radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
1102			     "%s Failed to allocate miptree.\n", __func__);
1103		return;
1104	}
1105
1106	/* Particularly ugly: this is guaranteed to break, if image->bo is
1107	   not of the required size for a miptree. */
1108	radeon_bo_unref(t->mt->bo);
1109	radeon_bo_ref(image->bo);
1110	t->mt->bo = image->bo;
1111
1112	if (!radeon_miptree_matches_image(t->mt, &radeonImage->base.Base,
1113					  radeonImage->mtface, 0))
1114		fprintf(stderr, "miptree doesn't match image\n");
1115}
1116#endif
1117
1118void
1119radeon_init_common_texture_funcs(radeonContextPtr radeon,
1120				 struct dd_function_table *functions)
1121{
1122	functions->NewTextureImage = radeonNewTextureImage;
1123	functions->DeleteTextureImage = radeonDeleteTextureImage;
1124	functions->FreeTextureImageBuffer = radeonFreeTextureImageBuffer;
1125	functions->MapTexture = radeonMapTexture;
1126	functions->UnmapTexture = radeonUnmapTexture;
1127	functions->MapTextureImage = radeon_map_texture_image;
1128	functions->UnmapTextureImage = radeon_unmap_texture_image;
1129
1130	functions->ChooseTextureFormat	= radeonChooseTextureFormat_mesa;
1131
1132	functions->TexImage1D = radeonTexImage1D;
1133	functions->TexImage2D = radeonTexImage2D;
1134	functions->TexImage3D = radeonTexImage3D;
1135	functions->TexSubImage1D = radeonTexSubImage1D;
1136	functions->TexSubImage2D = radeonTexSubImage2D;
1137	functions->TexSubImage3D = radeonTexSubImage3D;
1138	functions->CompressedTexImage2D = radeonCompressedTexImage2D;
1139	functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D;
1140
1141	functions->GenerateMipmap = radeonGenerateMipmap;
1142
1143	if (radeon->radeonScreen->kernel_mm) {
1144		functions->CopyTexSubImage2D = radeonCopyTexSubImage2D;
1145	}
1146
1147#if FEATURE_OES_EGL_image
1148	functions->EGLImageTargetTexture2D = radeon_image_target_texture_2d;
1149#endif
1150
1151	driInitTextureFormats();
1152}
1153