• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/mipmap.h"
37 #include "main/pbo.h"
38 #include "main/texcompress.h"
39 #include "main/texstore.h"
40 #include "main/teximage.h"
41 #include "main/texobj.h"
42 #include "drivers/common/meta.h"
43 
44 #include "xmlpool.h"		/* for symbolic values of enum-type options */
45 
46 #include "radeon_common.h"
47 
48 #include "radeon_mipmap_tree.h"
49 
50 static void teximage_assign_miptree(radeonContextPtr rmesa,
51 				    struct gl_texture_object *texObj,
52 				    struct gl_texture_image *texImage);
53 
54 static radeon_mipmap_tree *radeon_miptree_create_for_teximage(radeonContextPtr rmesa,
55 							      struct gl_texture_object *texObj,
56 							      struct gl_texture_image *texImage);
57 
copy_rows(void * dst,GLuint dststride,const void * src,GLuint srcstride,GLuint numrows,GLuint rowsize)58 void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
59 	GLuint numrows, GLuint rowsize)
60 {
61 	assert(rowsize <= dststride);
62 	assert(rowsize <= srcstride);
63 
64 	radeon_print(RADEON_TEXTURE, RADEON_TRACE,
65 		"%s dst %p, stride %u, src %p, stride %u, "
66 		"numrows %u, rowsize %u.\n",
67 		__func__, dst, dststride,
68 		src, srcstride,
69 		numrows, rowsize);
70 
71 	if (rowsize == srcstride && rowsize == dststride) {
72 		memcpy(dst, src, numrows*rowsize);
73 	} else {
74 		GLuint i;
75 		for(i = 0; i < numrows; ++i) {
76 			memcpy(dst, src, rowsize);
77 			dst += dststride;
78 			src += srcstride;
79 		}
80 	}
81 }
82 
83 /* textures */
84 /**
85  * Allocate an empty texture image object.
86  */
radeonNewTextureImage(struct gl_context * ctx)87 struct gl_texture_image *radeonNewTextureImage(struct gl_context *ctx)
88 {
89 	return calloc(1, sizeof(radeon_texture_image));
90 }
91 
92 
93 /**
94  * Delete a texture image object.
95  */
96 static void
radeonDeleteTextureImage(struct gl_context * ctx,struct gl_texture_image * img)97 radeonDeleteTextureImage(struct gl_context *ctx, struct gl_texture_image *img)
98 {
99 	/* nothing special (yet) for radeon_texture_image */
100 	_mesa_delete_texture_image(ctx, img);
101 }
102 
103 static GLboolean
radeonAllocTextureImageBuffer(struct gl_context * ctx,struct gl_texture_image * timage)104 radeonAllocTextureImageBuffer(struct gl_context *ctx,
105 			      struct gl_texture_image *timage)
106 {
107 	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
108 	struct gl_texture_object *texobj = timage->TexObject;
109 
110 	ctx->Driver.FreeTextureImageBuffer(ctx, timage);
111 
112 	if (!_swrast_init_texture_image(timage))
113 		return GL_FALSE;
114 
115 	teximage_assign_miptree(rmesa, texobj, timage);
116 
117 	return GL_TRUE;
118 }
119 
120 
121 /**
122  * Free memory associated with this texture image.
123  */
radeonFreeTextureImageBuffer(struct gl_context * ctx,struct gl_texture_image * timage)124 void radeonFreeTextureImageBuffer(struct gl_context *ctx, struct gl_texture_image *timage)
125 {
126 	radeon_texture_image* image = get_radeon_texture_image(timage);
127 
128 	if (image->mt) {
129 		radeon_miptree_unreference(&image->mt);
130 	}
131 	if (image->bo) {
132 		radeon_bo_unref(image->bo);
133 		image->bo = NULL;
134 	}
135 
136         _swrast_free_texture_image_buffer(ctx, timage);
137 }
138 
139 /**
140  * Map texture memory/buffer into user space.
141  * Note: the region of interest parameters are ignored here.
142  * \param mapOut  returns start of mapping of region of interest
143  * \param rowStrideOut  returns row stride in bytes
144  */
145 static void
radeon_map_texture_image(struct gl_context * ctx,struct gl_texture_image * texImage,GLuint slice,GLuint x,GLuint y,GLuint w,GLuint h,GLbitfield mode,GLubyte ** map,GLint * stride)146 radeon_map_texture_image(struct gl_context *ctx,
147 			 struct gl_texture_image *texImage,
148 			 GLuint slice,
149 			 GLuint x, GLuint y, GLuint w, GLuint h,
150 			 GLbitfield mode,
151 			 GLubyte **map,
152 			 GLint *stride)
153 {
154 	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
155 	radeon_texture_image *image = get_radeon_texture_image(texImage);
156 	radeon_mipmap_tree *mt = image->mt;
157 	GLuint texel_size = _mesa_get_format_bytes(texImage->TexFormat);
158 	GLuint width = texImage->Width;
159 	GLuint height = texImage->Height;
160 	struct radeon_bo *bo = !image->mt ? image->bo : image->mt->bo;
161 	unsigned int bw, bh;
162 	GLboolean write = (mode & GL_MAP_WRITE_BIT) != 0;
163 
164 	_mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
165 	assert(y % bh == 0);
166 	y /= bh;
167 	texel_size /= bw;
168 
169 	if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
170 		radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
171 			     "%s for texture that is "
172 			     "queued for GPU processing.\n",
173 			     __func__);
174 		radeon_firevertices(rmesa);
175 	}
176 
177 	if (image->bo) {
178 		/* TFP case */
179 		radeon_bo_map(image->bo, write);
180 		*stride = get_texture_image_row_stride(rmesa, texImage->TexFormat, width, 0, texImage->TexObject->Target);
181 		*map = bo->ptr;
182 	} else if (likely(mt)) {
183 		void *base;
184 		radeon_mipmap_level *lvl = &image->mt->levels[texImage->Level];
185 
186 		radeon_bo_map(mt->bo, write);
187 		base = mt->bo->ptr + lvl->faces[image->base.Base.Face].offset;
188 
189 		*stride = lvl->rowstride;
190 		*map = base + (slice * height) * *stride;
191 	} else {
192 		/* texture data is in malloc'd memory */
193 
194 		assert(map);
195 
196 		*stride = _mesa_format_row_stride(texImage->TexFormat, width);
197 		*map = image->base.Buffer + (slice * height) * *stride;
198 	}
199 
200 	*map += y * *stride + x * texel_size;
201 }
202 
203 static void
radeon_unmap_texture_image(struct gl_context * ctx,struct gl_texture_image * texImage,GLuint slice)204 radeon_unmap_texture_image(struct gl_context *ctx,
205 			   struct gl_texture_image *texImage, GLuint slice)
206 {
207 	radeon_texture_image *image = get_radeon_texture_image(texImage);
208 
209 	if (image->bo)
210 		radeon_bo_unmap(image->bo);
211 	else if (image->mt)
212 		radeon_bo_unmap(image->mt->bo);
213 }
214 
215 /* try to find a format which will only need a memcopy */
radeonChoose8888TexFormat(radeonContextPtr rmesa,GLenum srcFormat,GLenum srcType,GLboolean fbo)216 static mesa_format radeonChoose8888TexFormat(radeonContextPtr rmesa,
217 					   GLenum srcFormat,
218 					   GLenum srcType, GLboolean fbo)
219 {
220 #if defined(RADEON_R100)
221 	/* r100 can only do this */
222 	return _radeon_texformat_argb8888;
223 #elif defined(RADEON_R200)
224 	const GLuint ui = 1;
225 	const GLubyte littleEndian = *((const GLubyte *)&ui);
226 
227 
228 	/* Unfortunately, regardless the fbo flag, we might still be asked to
229 	 * attach a texture to a fbo later, which then won't succeed if we chose
230 	 * one which isn't renderable. And unlike more exotic formats, apps aren't
231 	 * really prepared for the incomplete framebuffer this results in (they'd
232 	 * have to retry with same internalFormat even, just different
233 	 * srcFormat/srcType, which can't really be expected anyway).
234 	 * Ideally, we'd defer format selection until later (if the texture is
235 	 * used as a rt it's likely there's never data uploaded to it before attached
236 	 * to a fbo), but this isn't really possible, so for now just always use
237 	 * a renderable format.
238 	 */
239 	if (1 || fbo)
240 		return _radeon_texformat_argb8888;
241 
242 	if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
243 	    (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
244 	    (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
245 	    (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
246 		return MESA_FORMAT_A8B8G8R8_UNORM;
247 	} else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
248 		   (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
249 		   (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
250 		   (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
251 		return MESA_FORMAT_R8G8B8A8_UNORM;
252 	} else
253 		return _radeon_texformat_argb8888;
254 #endif
255 }
256 
radeonChooseTextureFormat_mesa(struct gl_context * ctx,GLenum target,GLint internalFormat,GLenum format,GLenum type)257 mesa_format radeonChooseTextureFormat_mesa(struct gl_context * ctx,
258 					 GLenum target,
259 					 GLint internalFormat,
260 					 GLenum format,
261 					 GLenum type)
262 {
263 	return radeonChooseTextureFormat(ctx, internalFormat, format,
264 					 type, 0);
265 }
266 
radeonChooseTextureFormat(struct gl_context * ctx,GLint internalFormat,GLenum format,GLenum type,GLboolean fbo)267 mesa_format radeonChooseTextureFormat(struct gl_context * ctx,
268 				    GLint internalFormat,
269 				    GLenum format,
270 				    GLenum type, GLboolean fbo)
271 {
272 	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
273 	const GLboolean do32bpt =
274 	    (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32);
275 	const GLboolean force16bpt =
276 	    (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16);
277 	(void)format;
278 
279 	radeon_print(RADEON_TEXTURE, RADEON_TRACE,
280 		"%s InternalFormat=%s(%d) type=%s format=%s\n",
281 		__func__,
282 		_mesa_enum_to_string(internalFormat), internalFormat,
283 		_mesa_enum_to_string(type), _mesa_enum_to_string(format));
284 	radeon_print(RADEON_TEXTURE, RADEON_TRACE,
285 			"%s do32bpt=%d force16bpt=%d\n",
286 			__func__, do32bpt, force16bpt);
287 
288 	switch (internalFormat) {
289 	case 4:
290 	case GL_RGBA:
291 	case GL_COMPRESSED_RGBA:
292 		switch (type) {
293 		case GL_UNSIGNED_INT_10_10_10_2:
294 		case GL_UNSIGNED_INT_2_10_10_10_REV:
295 			return do32bpt ? _radeon_texformat_argb8888 :
296 			    _radeon_texformat_argb1555;
297 		case GL_UNSIGNED_SHORT_4_4_4_4:
298 		case GL_UNSIGNED_SHORT_4_4_4_4_REV:
299 			return _radeon_texformat_argb4444;
300 		case GL_UNSIGNED_SHORT_5_5_5_1:
301 		case GL_UNSIGNED_SHORT_1_5_5_5_REV:
302 			return _radeon_texformat_argb1555;
303 		default:
304 			return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type, fbo) :
305 			    _radeon_texformat_argb4444;
306 		}
307 
308 	case 3:
309 	case GL_RGB:
310 	case GL_COMPRESSED_RGB:
311 		switch (type) {
312 		case GL_UNSIGNED_SHORT_4_4_4_4:
313 		case GL_UNSIGNED_SHORT_4_4_4_4_REV:
314 			return _radeon_texformat_argb4444;
315 		case GL_UNSIGNED_SHORT_5_5_5_1:
316 		case GL_UNSIGNED_SHORT_1_5_5_5_REV:
317 			return _radeon_texformat_argb1555;
318 		case GL_UNSIGNED_SHORT_5_6_5:
319 		case GL_UNSIGNED_SHORT_5_6_5_REV:
320 			return _radeon_texformat_rgb565;
321 		default:
322 			return do32bpt ? _radeon_texformat_argb8888 :
323 			    _radeon_texformat_rgb565;
324 		}
325 
326 	case GL_RGBA8:
327 	case GL_RGB10_A2:
328 	case GL_RGBA12:
329 	case GL_RGBA16:
330 		return !force16bpt ?
331 			radeonChoose8888TexFormat(rmesa, format, type, fbo) :
332 			_radeon_texformat_argb4444;
333 
334 	case GL_RGBA4:
335 	case GL_RGBA2:
336 		return _radeon_texformat_argb4444;
337 
338 	case GL_RGB5_A1:
339 		return _radeon_texformat_argb1555;
340 
341 	case GL_RGB8:
342 	case GL_RGB10:
343 	case GL_RGB12:
344 	case GL_RGB16:
345 		return !force16bpt ? _radeon_texformat_argb8888 :
346 		    _radeon_texformat_rgb565;
347 
348 	case GL_RGB5:
349 	case GL_RGB4:
350 	case GL_R3_G3_B2:
351 		return _radeon_texformat_rgb565;
352 
353 	case GL_ALPHA:
354 	case GL_ALPHA4:
355 	case GL_ALPHA8:
356 	case GL_ALPHA12:
357 	case GL_ALPHA16:
358 	case GL_COMPRESSED_ALPHA:
359 #if defined(RADEON_R200)
360 		/* r200: can't use a8 format since interpreting hw I8 as a8 would result
361 		   in wrong rgb values (same as alpha value instead of 0). */
362 		return _radeon_texformat_al88;
363 #else
364 		return MESA_FORMAT_A_UNORM8;
365 #endif
366 	case 1:
367 	case GL_LUMINANCE:
368 	case GL_LUMINANCE4:
369 	case GL_LUMINANCE8:
370 	case GL_LUMINANCE12:
371 	case GL_LUMINANCE16:
372 	case GL_COMPRESSED_LUMINANCE:
373 		return MESA_FORMAT_L_UNORM8;
374 
375 	case 2:
376 	case GL_LUMINANCE_ALPHA:
377 	case GL_LUMINANCE4_ALPHA4:
378 	case GL_LUMINANCE6_ALPHA2:
379 	case GL_LUMINANCE8_ALPHA8:
380 	case GL_LUMINANCE12_ALPHA4:
381 	case GL_LUMINANCE12_ALPHA12:
382 	case GL_LUMINANCE16_ALPHA16:
383 	case GL_COMPRESSED_LUMINANCE_ALPHA:
384 		return _radeon_texformat_al88;
385 
386 	case GL_INTENSITY:
387 	case GL_INTENSITY4:
388 	case GL_INTENSITY8:
389 	case GL_INTENSITY12:
390 	case GL_INTENSITY16:
391 	case GL_COMPRESSED_INTENSITY:
392 		return MESA_FORMAT_I_UNORM8;
393 
394 	case GL_YCBCR_MESA:
395 		if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
396 		    type == GL_UNSIGNED_BYTE)
397 			return MESA_FORMAT_YCBCR;
398 		else
399 			return MESA_FORMAT_YCBCR_REV;
400 
401 	case GL_RGB_S3TC:
402 	case GL_RGB4_S3TC:
403 	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
404 		return MESA_FORMAT_RGB_DXT1;
405 
406 	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
407 		return MESA_FORMAT_RGBA_DXT1;
408 
409 	case GL_RGBA_S3TC:
410 	case GL_RGBA4_S3TC:
411 	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
412 		return MESA_FORMAT_RGBA_DXT3;
413 
414 	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
415 		return MESA_FORMAT_RGBA_DXT5;
416 
417 	case GL_ALPHA16F_ARB:
418 		return MESA_FORMAT_A_FLOAT16;
419 	case GL_ALPHA32F_ARB:
420 		return MESA_FORMAT_A_FLOAT32;
421 	case GL_LUMINANCE16F_ARB:
422 		return MESA_FORMAT_L_FLOAT16;
423 	case GL_LUMINANCE32F_ARB:
424 		return MESA_FORMAT_L_FLOAT32;
425 	case GL_LUMINANCE_ALPHA16F_ARB:
426 		return MESA_FORMAT_LA_FLOAT16;
427 	case GL_LUMINANCE_ALPHA32F_ARB:
428 		return MESA_FORMAT_LA_FLOAT32;
429 	case GL_INTENSITY16F_ARB:
430 		return MESA_FORMAT_I_FLOAT16;
431 	case GL_INTENSITY32F_ARB:
432 		return MESA_FORMAT_I_FLOAT32;
433 	case GL_RGB16F_ARB:
434 		return MESA_FORMAT_RGBA_FLOAT16;
435 	case GL_RGB32F_ARB:
436 		return MESA_FORMAT_RGBA_FLOAT32;
437 	case GL_RGBA16F_ARB:
438 		return MESA_FORMAT_RGBA_FLOAT16;
439 	case GL_RGBA32F_ARB:
440 		return MESA_FORMAT_RGBA_FLOAT32;
441 
442 	case GL_DEPTH_COMPONENT:
443 	case GL_DEPTH_COMPONENT16:
444 	case GL_DEPTH_COMPONENT24:
445 	case GL_DEPTH_COMPONENT32:
446 	case GL_DEPTH_STENCIL_EXT:
447 	case GL_DEPTH24_STENCIL8_EXT:
448 		return MESA_FORMAT_Z24_UNORM_S8_UINT;
449 
450 	/* EXT_texture_sRGB */
451 	case GL_SRGB:
452 	case GL_SRGB8:
453 	case GL_SRGB_ALPHA:
454 	case GL_SRGB8_ALPHA8:
455 	case GL_COMPRESSED_SRGB:
456 	case GL_COMPRESSED_SRGB_ALPHA:
457 		return MESA_FORMAT_B8G8R8A8_SRGB;
458 
459 	case GL_SLUMINANCE:
460 	case GL_SLUMINANCE8:
461 	case GL_COMPRESSED_SLUMINANCE:
462 		return MESA_FORMAT_L_SRGB8;
463 
464 	case GL_SLUMINANCE_ALPHA:
465 	case GL_SLUMINANCE8_ALPHA8:
466 	case GL_COMPRESSED_SLUMINANCE_ALPHA:
467       return MESA_FORMAT_L8A8_SRGB;
468 
469 	case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
470 		return MESA_FORMAT_SRGB_DXT1;
471 	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
472 		return MESA_FORMAT_SRGBA_DXT1;
473 	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
474 		return MESA_FORMAT_SRGBA_DXT3;
475 	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
476 		return MESA_FORMAT_SRGBA_DXT5;
477 
478 	default:
479 		_mesa_problem(ctx,
480 			      "unexpected internalFormat 0x%x in %s",
481 			      (int)internalFormat, __func__);
482 		return MESA_FORMAT_NONE;
483 	}
484 
485 	return MESA_FORMAT_NONE;		/* never get here */
486 }
487 
488 /** Check if given image is valid within current texture object.
489  */
teximage_assign_miptree(radeonContextPtr rmesa,struct gl_texture_object * texObj,struct gl_texture_image * texImage)490 static void teximage_assign_miptree(radeonContextPtr rmesa,
491 				    struct gl_texture_object *texObj,
492 				    struct gl_texture_image *texImage)
493 {
494 	radeonTexObj *t = radeon_tex_obj(texObj);
495 	radeon_texture_image* image = get_radeon_texture_image(texImage);
496 
497 	/* Try using current miptree, or create new if there isn't any */
498 	if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage)) {
499 		radeon_miptree_unreference(&t->mt);
500 		t->mt = radeon_miptree_create_for_teximage(rmesa,
501 							   texObj,
502 							   texImage);
503 
504 		radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
505 			     "%s: texObj %p, texImage %p, "
506 				"texObj miptree doesn't match, allocated new miptree %p\n",
507 				__func__, texObj, texImage, t->mt);
508 	}
509 
510 	/* Miptree alocation may have failed,
511 	 * when there was no image for baselevel specified */
512 	if (t->mt) {
513 		radeon_miptree_reference(t->mt, &image->mt);
514 	} else
515 		radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
516 				"%s Failed to allocate miptree.\n", __func__);
517 }
518 
radeonIsFormatRenderable(mesa_format mesa_format)519 unsigned radeonIsFormatRenderable(mesa_format mesa_format)
520 {
521 	if (mesa_format == _radeon_texformat_argb8888 || mesa_format == _radeon_texformat_rgb565 ||
522 		mesa_format == _radeon_texformat_argb1555 || mesa_format == _radeon_texformat_argb4444)
523 		return 1;
524 
525 	switch (mesa_format)
526 	{
527 		case MESA_FORMAT_Z_UNORM16:
528 		case MESA_FORMAT_Z24_UNORM_S8_UINT:
529 			return 1;
530 		default:
531 			return 0;
532 	}
533 }
534 
radeon_image_target_texture_2d(struct gl_context * ctx,GLenum target,struct gl_texture_object * texObj,struct gl_texture_image * texImage,GLeglImageOES image_handle)535 void radeon_image_target_texture_2d(struct gl_context *ctx, GLenum target,
536 				    struct gl_texture_object *texObj,
537 				    struct gl_texture_image *texImage,
538 				    GLeglImageOES image_handle)
539 {
540 	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
541 	radeonTexObj *t = radeon_tex_obj(texObj);
542 	radeon_texture_image *radeonImage = get_radeon_texture_image(texImage);
543 	__DRIscreen *screen;
544 	__DRIimage *image;
545 
546 	screen = radeon->radeonScreen->driScreen;
547 	image = screen->dri2.image->lookupEGLImage(screen, image_handle,
548 						   screen->loaderPrivate);
549 	if (image == NULL)
550 		return;
551 
552 	radeonFreeTextureImageBuffer(ctx, texImage);
553 
554 	texImage->Width = image->width;
555 	texImage->Height = image->height;
556 	texImage->Depth = 1;
557 	texImage->_BaseFormat = GL_RGBA;
558 	texImage->TexFormat = image->format;
559 	radeonImage->base.RowStride = image->pitch;
560 	texImage->InternalFormat = image->internal_format;
561 
562 	if(t->mt)
563 	{
564 		radeon_miptree_unreference(&t->mt);
565 		t->mt = NULL;
566 	}
567 
568 	/* NOTE: The following is *very* ugly and will probably break. But
569 	   I don't know how to deal with it, without creating a whole new
570 	   function like radeon_miptree_from_bo() so I'm going with the
571 	   easy but error-prone way. */
572 
573 	radeon_try_alloc_miptree(radeon, t);
574 
575 	radeon_miptree_reference(t->mt, &radeonImage->mt);
576 
577 	if (t->mt == NULL)
578 	{
579 		radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
580 			     "%s Failed to allocate miptree.\n", __func__);
581 		return;
582 	}
583 
584 	/* Particularly ugly: this is guaranteed to break, if image->bo is
585 	   not of the required size for a miptree. */
586 	radeon_bo_unref(t->mt->bo);
587 	radeon_bo_ref(image->bo);
588 	t->mt->bo = image->bo;
589 
590 	if (!radeon_miptree_matches_image(t->mt, &radeonImage->base.Base))
591 		fprintf(stderr, "miptree doesn't match image\n");
592 }
593 
594 mesa_format _radeon_texformat_rgba8888 = MESA_FORMAT_NONE;
595 mesa_format _radeon_texformat_argb8888 = MESA_FORMAT_NONE;
596 mesa_format _radeon_texformat_rgb565 = MESA_FORMAT_NONE;
597 mesa_format _radeon_texformat_argb4444 = MESA_FORMAT_NONE;
598 mesa_format _radeon_texformat_argb1555 = MESA_FORMAT_NONE;
599 mesa_format _radeon_texformat_al88 = MESA_FORMAT_NONE;
600 /*@}*/
601 
602 
603 static void
radeonInitTextureFormats(void)604 radeonInitTextureFormats(void)
605 {
606    if (_mesa_little_endian()) {
607       _radeon_texformat_rgba8888	= MESA_FORMAT_A8B8G8R8_UNORM;
608       _radeon_texformat_argb8888	= MESA_FORMAT_B8G8R8A8_UNORM;
609       _radeon_texformat_rgb565		= MESA_FORMAT_B5G6R5_UNORM;
610       _radeon_texformat_argb4444	= MESA_FORMAT_B4G4R4A4_UNORM;
611       _radeon_texformat_argb1555	= MESA_FORMAT_B5G5R5A1_UNORM;
612       _radeon_texformat_al88		= MESA_FORMAT_L8A8_UNORM;
613    }
614    else {
615       _radeon_texformat_rgba8888	= MESA_FORMAT_R8G8B8A8_UNORM;
616       _radeon_texformat_argb8888	= MESA_FORMAT_A8R8G8B8_UNORM;
617       _radeon_texformat_rgb565		= MESA_FORMAT_R5G6B5_UNORM;
618       _radeon_texformat_argb4444	= MESA_FORMAT_A4R4G4B4_UNORM;
619       _radeon_texformat_argb1555	= MESA_FORMAT_A1R5G5B5_UNORM;
620       _radeon_texformat_al88		= MESA_FORMAT_A8L8_UNORM;
621    }
622 }
623 
624 void
radeon_init_common_texture_funcs(radeonContextPtr radeon,struct dd_function_table * functions)625 radeon_init_common_texture_funcs(radeonContextPtr radeon,
626 				 struct dd_function_table *functions)
627 {
628 	functions->NewTextureImage = radeonNewTextureImage;
629 	functions->DeleteTextureImage = radeonDeleteTextureImage;
630 	functions->AllocTextureImageBuffer = radeonAllocTextureImageBuffer;
631 	functions->FreeTextureImageBuffer = radeonFreeTextureImageBuffer;
632 	functions->MapTextureImage = radeon_map_texture_image;
633 	functions->UnmapTextureImage = radeon_unmap_texture_image;
634 
635 	functions->ChooseTextureFormat	= radeonChooseTextureFormat_mesa;
636 
637 	functions->CopyTexSubImage = radeonCopyTexSubImage;
638 
639 	functions->Bitmap = _mesa_meta_Bitmap;
640 	functions->EGLImageTargetTexture2D = radeon_image_target_texture_2d;
641 
642 	radeonInitTextureFormats();
643 }
644 
radeon_miptree_create_for_teximage(radeonContextPtr rmesa,struct gl_texture_object * texObj,struct gl_texture_image * texImage)645 static radeon_mipmap_tree *radeon_miptree_create_for_teximage(radeonContextPtr rmesa,
646 						       struct gl_texture_object *texObj,
647 						       struct gl_texture_image *texImage)
648 {
649 	radeonTexObj *t = radeon_tex_obj(texObj);
650 	GLuint firstLevel;
651 	GLuint lastLevel;
652 	int width, height, depth;
653 	int i;
654 
655 	width = texImage->Width;
656 	height = texImage->Height;
657 	depth = texImage->Depth;
658 
659 	if (texImage->Level > texObj->BaseLevel &&
660 	    (width == 1 ||
661 	     (texObj->Target != GL_TEXTURE_1D && height == 1) ||
662 	     (texObj->Target == GL_TEXTURE_3D && depth == 1))) {
663 		/* For this combination, we're at some lower mipmap level and
664 		 * some important dimension is 1.  We can't extrapolate up to a
665 		 * likely base level width/height/depth for a full mipmap stack
666 		 * from this info, so just allocate this one level.
667 		 */
668 		firstLevel = texImage->Level;
669 		lastLevel = texImage->Level;
670 	} else {
671 		if (texImage->Level < texObj->BaseLevel)
672 			firstLevel = 0;
673 		else
674 			firstLevel = texObj->BaseLevel;
675 
676 		for (i = texImage->Level; i > firstLevel; i--) {
677 			width <<= 1;
678 			if (height != 1)
679 				height <<= 1;
680 			if (depth != 1)
681 				depth <<= 1;
682 		}
683 		if ((texObj->Sampler.MinFilter == GL_NEAREST ||
684 		     texObj->Sampler.MinFilter == GL_LINEAR) &&
685 		    texImage->Level == firstLevel) {
686 			lastLevel = firstLevel;
687 		} else {
688 			lastLevel = firstLevel + _mesa_logbase2(MAX2(MAX2(width, height), depth));
689 		}
690 	}
691 
692 	return  radeon_miptree_create(rmesa, texObj->Target,
693 				      texImage->TexFormat, firstLevel, lastLevel - firstLevel + 1,
694 				      width, height, depth,
695 				      t->tile_bits);
696 }
697