• 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/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 static void teximage_assign_miptree(radeonContextPtr rmesa,
52 				    struct gl_texture_object *texObj,
53 				    struct gl_texture_image *texImage);
54 
55 static radeon_mipmap_tree *radeon_miptree_create_for_teximage(radeonContextPtr rmesa,
56 							      struct gl_texture_object *texObj,
57 							      struct gl_texture_image *texImage);
58 
copy_rows(void * dst,GLuint dststride,const void * src,GLuint srcstride,GLuint numrows,GLuint rowsize)59 void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
60 	GLuint numrows, GLuint rowsize)
61 {
62 	assert(rowsize <= dststride);
63 	assert(rowsize <= srcstride);
64 
65 	radeon_print(RADEON_TEXTURE, RADEON_TRACE,
66 		"%s dst %p, stride %u, src %p, stride %u, "
67 		"numrows %u, rowsize %u.\n",
68 		__func__, dst, dststride,
69 		src, srcstride,
70 		numrows, rowsize);
71 
72 	if (rowsize == srcstride && rowsize == dststride) {
73 		memcpy(dst, src, numrows*rowsize);
74 	} else {
75 		GLuint i;
76 		for(i = 0; i < numrows; ++i) {
77 			memcpy(dst, src, rowsize);
78 			dst += dststride;
79 			src += srcstride;
80 		}
81 	}
82 }
83 
84 /* textures */
85 /**
86  * Allocate an empty texture image object.
87  */
radeonNewTextureImage(struct gl_context * ctx)88 struct gl_texture_image *radeonNewTextureImage(struct gl_context *ctx)
89 {
90 	return CALLOC(sizeof(radeon_texture_image));
91 }
92 
93 
94 /**
95  * Delete a texture image object.
96  */
97 static void
radeonDeleteTextureImage(struct gl_context * ctx,struct gl_texture_image * img)98 radeonDeleteTextureImage(struct gl_context *ctx, struct gl_texture_image *img)
99 {
100 	/* nothing special (yet) for radeon_texture_image */
101 	_mesa_delete_texture_image(ctx, img);
102 }
103 
104 static GLboolean
radeonAllocTextureImageBuffer(struct gl_context * ctx,struct gl_texture_image * timage)105 radeonAllocTextureImageBuffer(struct gl_context *ctx,
106 			      struct gl_texture_image *timage)
107 {
108 	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
109 	radeon_texture_image *image = get_radeon_texture_image(timage);
110 	struct gl_texture_object *texobj = timage->TexObject;
111 	int slices;
112 
113 	ctx->Driver.FreeTextureImageBuffer(ctx, timage);
114 
115 	switch (texobj->Target) {
116 	case GL_TEXTURE_3D:
117 		slices = timage->Depth;
118 		break;
119 	default:
120 		slices = 1;
121 	}
122 	assert(!image->base.ImageOffsets);
123 	image->base.ImageOffsets = malloc(slices * sizeof(GLuint));
124 	teximage_assign_miptree(rmesa, texobj, timage);
125 
126 	return GL_TRUE;
127 }
128 
129 
130 /**
131  * Free memory associated with this texture image.
132  */
radeonFreeTextureImageBuffer(struct gl_context * ctx,struct gl_texture_image * timage)133 void radeonFreeTextureImageBuffer(struct gl_context *ctx, struct gl_texture_image *timage)
134 {
135 	radeon_texture_image* image = get_radeon_texture_image(timage);
136 
137 	if (image->mt) {
138 		radeon_miptree_unreference(&image->mt);
139 	} else {
140 		_swrast_free_texture_image_buffer(ctx, timage);
141 	}
142 	if (image->bo) {
143 		radeon_bo_unref(image->bo);
144 		image->bo = NULL;
145 	}
146 	if (image->base.Buffer) {
147 		_mesa_align_free(image->base.Buffer);
148 		image->base.Buffer = NULL;
149 	}
150 
151 	if (image->base.ImageOffsets) {
152 		free(image->base.ImageOffsets);
153 		image->base.ImageOffsets = NULL;
154 	}
155 }
156 
157 /* Set Data pointer and additional data for mapped texture image */
teximage_set_map_data(radeon_texture_image * image)158 static void teximage_set_map_data(radeon_texture_image *image)
159 {
160 	radeon_mipmap_level *lvl;
161 
162 	if (!image->mt) {
163 		radeon_warning("%s(%p) Trying to set map data without miptree.\n",
164 				__func__, image);
165 
166 		return;
167 	}
168 
169 	lvl = &image->mt->levels[image->base.Base.Level];
170 
171 	image->base.Map = image->mt->bo->ptr + lvl->faces[image->base.Base.Face].offset;
172 	image->base.RowStride = lvl->rowstride / _mesa_get_format_bytes(image->base.Base.TexFormat);
173 }
174 
175 
176 /**
177  * Map a single texture image for glTexImage and friends.
178  */
radeon_teximage_map(radeon_texture_image * image,GLboolean write_enable)179 void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable)
180 {
181 	radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
182 			"%s(img %p), write_enable %s.\n",
183 			__func__, image,
184 			write_enable ? "true": "false");
185 	if (image->mt) {
186 		assert(!image->base.Map);
187 
188 		radeon_bo_map(image->mt->bo, write_enable);
189 		teximage_set_map_data(image);
190 	}
191 }
192 
193 
radeon_teximage_unmap(radeon_texture_image * image)194 void radeon_teximage_unmap(radeon_texture_image *image)
195 {
196 	radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
197 			"%s(img %p)\n",
198 			__func__, image);
199 	if (image->mt) {
200 		assert(image->base.Map);
201 
202 		image->base.Map = 0;
203 		radeon_bo_unmap(image->mt->bo);
204 	}
205 }
206 
207 /**
208  * Map texture memory/buffer into user space.
209  * Note: the region of interest parameters are ignored here.
210  * \param mapOut  returns start of mapping of region of interest
211  * \param rowStrideOut  returns row stride in bytes
212  */
213 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)214 radeon_map_texture_image(struct gl_context *ctx,
215 			 struct gl_texture_image *texImage,
216 			 GLuint slice,
217 			 GLuint x, GLuint y, GLuint w, GLuint h,
218 			 GLbitfield mode,
219 			 GLubyte **map,
220 			 GLint *stride)
221 {
222 	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
223 	radeon_texture_image *image = get_radeon_texture_image(texImage);
224 	radeon_mipmap_tree *mt = image->mt;
225 	GLuint texel_size = _mesa_get_format_bytes(texImage->TexFormat);
226 	GLuint width = texImage->Width;
227 	GLuint height = texImage->Height;
228 	struct radeon_bo *bo = !image->mt ? image->bo : image->mt->bo;
229 	unsigned int bw, bh;
230 	GLboolean write = (mode & GL_MAP_WRITE_BIT) != 0;
231 
232 	_mesa_get_format_block_size(texImage->TexFormat, &bw, &bh);
233 	assert(y % bh == 0);
234 	y /= bh;
235 	texel_size /= bw;
236 
237 	if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
238 		radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
239 			     "%s for texture that is "
240 			     "queued for GPU processing.\n",
241 			     __func__);
242 		radeon_firevertices(rmesa);
243 	}
244 
245 	if (image->bo) {
246 		/* TFP case */
247 		radeon_bo_map(image->bo, write);
248 		*stride = get_texture_image_row_stride(rmesa, texImage->TexFormat, width, 0, texImage->TexObject->Target);
249 		*map = bo->ptr;
250 	} else if (likely(mt)) {
251 		void *base;
252 		radeon_mipmap_level *lvl = &image->mt->levels[texImage->Level];
253 
254 		radeon_bo_map(mt->bo, write);
255 		base = mt->bo->ptr + lvl->faces[image->base.Base.Face].offset;
256 
257 		*stride = lvl->rowstride;
258 		*map = base + (slice * height) * *stride;
259 	} else {
260 		/* texture data is in malloc'd memory */
261 
262 		assert(map);
263 
264 		*stride = _mesa_format_row_stride(texImage->TexFormat, width);
265 		*map = image->base.Buffer + (slice * height) * *stride;
266 	}
267 
268 	*map += y * *stride + x * texel_size;
269 }
270 
271 static void
radeon_unmap_texture_image(struct gl_context * ctx,struct gl_texture_image * texImage,GLuint slice)272 radeon_unmap_texture_image(struct gl_context *ctx,
273 			   struct gl_texture_image *texImage, GLuint slice)
274 {
275 	radeon_texture_image *image = get_radeon_texture_image(texImage);
276 
277 	if (image->bo)
278 		radeon_bo_unmap(image->bo);
279 	else if (image->mt)
280 		radeon_bo_unmap(image->mt->bo);
281 }
282 
283 /* try to find a format which will only need a memcopy */
radeonChoose8888TexFormat(radeonContextPtr rmesa,GLenum srcFormat,GLenum srcType,GLboolean fbo)284 static gl_format radeonChoose8888TexFormat(radeonContextPtr rmesa,
285 					   GLenum srcFormat,
286 					   GLenum srcType, GLboolean fbo)
287 {
288 #if defined(RADEON_R100)
289 	/* r100 can only do this */
290 	return _radeon_texformat_argb8888;
291 #elif defined(RADEON_R200)
292 	const GLuint ui = 1;
293 	const GLubyte littleEndian = *((const GLubyte *)&ui);
294 
295 	if (fbo)
296 		return _radeon_texformat_argb8888;
297 
298 	if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
299 	    (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
300 	    (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
301 	    (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
302 		return MESA_FORMAT_RGBA8888;
303 	} else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
304 		   (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
305 		   (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
306 		   (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
307 		return MESA_FORMAT_RGBA8888_REV;
308 	} else
309 		return _radeon_texformat_argb8888;
310 #endif
311 }
312 
radeonChooseTextureFormat_mesa(struct gl_context * ctx,GLenum target,GLint internalFormat,GLenum format,GLenum type)313 gl_format radeonChooseTextureFormat_mesa(struct gl_context * ctx,
314 					 GLenum target,
315 					 GLint internalFormat,
316 					 GLenum format,
317 					 GLenum type)
318 {
319 	return radeonChooseTextureFormat(ctx, internalFormat, format,
320 					 type, 0);
321 }
322 
radeonChooseTextureFormat(struct gl_context * ctx,GLint internalFormat,GLenum format,GLenum type,GLboolean fbo)323 gl_format radeonChooseTextureFormat(struct gl_context * ctx,
324 				    GLint internalFormat,
325 				    GLenum format,
326 				    GLenum type, GLboolean fbo)
327 {
328 	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
329 	const GLboolean do32bpt =
330 	    (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32);
331 	const GLboolean force16bpt =
332 	    (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16);
333 	(void)format;
334 
335 	radeon_print(RADEON_TEXTURE, RADEON_TRACE,
336 		"%s InternalFormat=%s(%d) type=%s format=%s\n",
337 		__func__,
338 		_mesa_lookup_enum_by_nr(internalFormat), internalFormat,
339 		_mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format));
340 	radeon_print(RADEON_TEXTURE, RADEON_TRACE,
341 			"%s do32bpt=%d force16bpt=%d\n",
342 			__func__, do32bpt, force16bpt);
343 
344 	switch (internalFormat) {
345 	case 4:
346 	case GL_RGBA:
347 	case GL_COMPRESSED_RGBA:
348 		switch (type) {
349 		case GL_UNSIGNED_INT_10_10_10_2:
350 		case GL_UNSIGNED_INT_2_10_10_10_REV:
351 			return do32bpt ? _radeon_texformat_argb8888 :
352 			    _radeon_texformat_argb1555;
353 		case GL_UNSIGNED_SHORT_4_4_4_4:
354 		case GL_UNSIGNED_SHORT_4_4_4_4_REV:
355 			return _radeon_texformat_argb4444;
356 		case GL_UNSIGNED_SHORT_5_5_5_1:
357 		case GL_UNSIGNED_SHORT_1_5_5_5_REV:
358 			return _radeon_texformat_argb1555;
359 		default:
360 			return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type, fbo) :
361 			    _radeon_texformat_argb4444;
362 		}
363 
364 	case 3:
365 	case GL_RGB:
366 	case GL_COMPRESSED_RGB:
367 		switch (type) {
368 		case GL_UNSIGNED_SHORT_4_4_4_4:
369 		case GL_UNSIGNED_SHORT_4_4_4_4_REV:
370 			return _radeon_texformat_argb4444;
371 		case GL_UNSIGNED_SHORT_5_5_5_1:
372 		case GL_UNSIGNED_SHORT_1_5_5_5_REV:
373 			return _radeon_texformat_argb1555;
374 		case GL_UNSIGNED_SHORT_5_6_5:
375 		case GL_UNSIGNED_SHORT_5_6_5_REV:
376 			return _radeon_texformat_rgb565;
377 		default:
378 			return do32bpt ? _radeon_texformat_argb8888 :
379 			    _radeon_texformat_rgb565;
380 		}
381 
382 	case GL_RGBA8:
383 	case GL_RGB10_A2:
384 	case GL_RGBA12:
385 	case GL_RGBA16:
386 		return !force16bpt ?
387 			radeonChoose8888TexFormat(rmesa, format, type, fbo) :
388 			_radeon_texformat_argb4444;
389 
390 	case GL_RGBA4:
391 	case GL_RGBA2:
392 		return _radeon_texformat_argb4444;
393 
394 	case GL_RGB5_A1:
395 		return _radeon_texformat_argb1555;
396 
397 	case GL_RGB8:
398 	case GL_RGB10:
399 	case GL_RGB12:
400 	case GL_RGB16:
401 		return !force16bpt ? _radeon_texformat_argb8888 :
402 		    _radeon_texformat_rgb565;
403 
404 	case GL_RGB5:
405 	case GL_RGB4:
406 	case GL_R3_G3_B2:
407 		return _radeon_texformat_rgb565;
408 
409 	case GL_ALPHA:
410 	case GL_ALPHA4:
411 	case GL_ALPHA8:
412 	case GL_ALPHA12:
413 	case GL_ALPHA16:
414 	case GL_COMPRESSED_ALPHA:
415 #if defined(RADEON_R200)
416 		/* r200: can't use a8 format since interpreting hw I8 as a8 would result
417 		   in wrong rgb values (same as alpha value instead of 0). */
418 		return _radeon_texformat_al88;
419 #else
420 		return MESA_FORMAT_A8;
421 #endif
422 	case 1:
423 	case GL_LUMINANCE:
424 	case GL_LUMINANCE4:
425 	case GL_LUMINANCE8:
426 	case GL_LUMINANCE12:
427 	case GL_LUMINANCE16:
428 	case GL_COMPRESSED_LUMINANCE:
429 		return MESA_FORMAT_L8;
430 
431 	case 2:
432 	case GL_LUMINANCE_ALPHA:
433 	case GL_LUMINANCE4_ALPHA4:
434 	case GL_LUMINANCE6_ALPHA2:
435 	case GL_LUMINANCE8_ALPHA8:
436 	case GL_LUMINANCE12_ALPHA4:
437 	case GL_LUMINANCE12_ALPHA12:
438 	case GL_LUMINANCE16_ALPHA16:
439 	case GL_COMPRESSED_LUMINANCE_ALPHA:
440 		return _radeon_texformat_al88;
441 
442 	case GL_INTENSITY:
443 	case GL_INTENSITY4:
444 	case GL_INTENSITY8:
445 	case GL_INTENSITY12:
446 	case GL_INTENSITY16:
447 	case GL_COMPRESSED_INTENSITY:
448 		return MESA_FORMAT_I8;
449 
450 	case GL_YCBCR_MESA:
451 		if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
452 		    type == GL_UNSIGNED_BYTE)
453 			return MESA_FORMAT_YCBCR;
454 		else
455 			return MESA_FORMAT_YCBCR_REV;
456 
457 	case GL_RGB_S3TC:
458 	case GL_RGB4_S3TC:
459 	case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
460 		return MESA_FORMAT_RGB_DXT1;
461 
462 	case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
463 		return MESA_FORMAT_RGBA_DXT1;
464 
465 	case GL_RGBA_S3TC:
466 	case GL_RGBA4_S3TC:
467 	case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
468 		return MESA_FORMAT_RGBA_DXT3;
469 
470 	case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
471 		return MESA_FORMAT_RGBA_DXT5;
472 
473 	case GL_ALPHA16F_ARB:
474 		return MESA_FORMAT_ALPHA_FLOAT16;
475 	case GL_ALPHA32F_ARB:
476 		return MESA_FORMAT_ALPHA_FLOAT32;
477 	case GL_LUMINANCE16F_ARB:
478 		return MESA_FORMAT_LUMINANCE_FLOAT16;
479 	case GL_LUMINANCE32F_ARB:
480 		return MESA_FORMAT_LUMINANCE_FLOAT32;
481 	case GL_LUMINANCE_ALPHA16F_ARB:
482 		return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16;
483 	case GL_LUMINANCE_ALPHA32F_ARB:
484 		return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32;
485 	case GL_INTENSITY16F_ARB:
486 		return MESA_FORMAT_INTENSITY_FLOAT16;
487 	case GL_INTENSITY32F_ARB:
488 		return MESA_FORMAT_INTENSITY_FLOAT32;
489 	case GL_RGB16F_ARB:
490 		return MESA_FORMAT_RGBA_FLOAT16;
491 	case GL_RGB32F_ARB:
492 		return MESA_FORMAT_RGBA_FLOAT32;
493 	case GL_RGBA16F_ARB:
494 		return MESA_FORMAT_RGBA_FLOAT16;
495 	case GL_RGBA32F_ARB:
496 		return MESA_FORMAT_RGBA_FLOAT32;
497 
498 	case GL_DEPTH_COMPONENT:
499 	case GL_DEPTH_COMPONENT16:
500 	case GL_DEPTH_COMPONENT24:
501 	case GL_DEPTH_COMPONENT32:
502 	case GL_DEPTH_STENCIL_EXT:
503 	case GL_DEPTH24_STENCIL8_EXT:
504 		return MESA_FORMAT_S8_Z24;
505 
506 	/* EXT_texture_sRGB */
507 	case GL_SRGB:
508 	case GL_SRGB8:
509 	case GL_SRGB_ALPHA:
510 	case GL_SRGB8_ALPHA8:
511 	case GL_COMPRESSED_SRGB:
512 	case GL_COMPRESSED_SRGB_ALPHA:
513 		return MESA_FORMAT_SARGB8;
514 
515 	case GL_SLUMINANCE:
516 	case GL_SLUMINANCE8:
517 	case GL_COMPRESSED_SLUMINANCE:
518 		return MESA_FORMAT_SL8;
519 
520 	case GL_SLUMINANCE_ALPHA:
521 	case GL_SLUMINANCE8_ALPHA8:
522 	case GL_COMPRESSED_SLUMINANCE_ALPHA:
523 		return MESA_FORMAT_SLA8;
524 
525 	case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
526 		return MESA_FORMAT_SRGB_DXT1;
527 	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
528 		return MESA_FORMAT_SRGBA_DXT1;
529 	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
530 		return MESA_FORMAT_SRGBA_DXT3;
531 	case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
532 		return MESA_FORMAT_SRGBA_DXT5;
533 
534 	default:
535 		_mesa_problem(ctx,
536 			      "unexpected internalFormat 0x%x in %s",
537 			      (int)internalFormat, __func__);
538 		return MESA_FORMAT_NONE;
539 	}
540 
541 	return MESA_FORMAT_NONE;		/* never get here */
542 }
543 
544 /** Check if given image is valid within current texture object.
545  */
teximage_assign_miptree(radeonContextPtr rmesa,struct gl_texture_object * texObj,struct gl_texture_image * texImage)546 static void teximage_assign_miptree(radeonContextPtr rmesa,
547 				    struct gl_texture_object *texObj,
548 				    struct gl_texture_image *texImage)
549 {
550 	radeonTexObj *t = radeon_tex_obj(texObj);
551 	radeon_texture_image* image = get_radeon_texture_image(texImage);
552 
553 	/* Try using current miptree, or create new if there isn't any */
554 	if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage)) {
555 		radeon_miptree_unreference(&t->mt);
556 		t->mt = radeon_miptree_create_for_teximage(rmesa,
557 							   texObj,
558 							   texImage);
559 
560 		radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
561 			     "%s: texObj %p, texImage %p, "
562 				"texObj miptree doesn't match, allocated new miptree %p\n",
563 				__FUNCTION__, texObj, texImage, t->mt);
564 	}
565 
566 	/* Miptree alocation may have failed,
567 	 * when there was no image for baselevel specified */
568 	if (t->mt) {
569 		radeon_miptree_reference(t->mt, &image->mt);
570 	} else
571 		radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
572 				"%s Failed to allocate miptree.\n", __func__);
573 }
574 
radeonIsFormatRenderable(gl_format mesa_format)575 unsigned radeonIsFormatRenderable(gl_format mesa_format)
576 {
577 	if (mesa_format == _radeon_texformat_argb8888 || mesa_format == _radeon_texformat_rgb565 ||
578 		mesa_format == _radeon_texformat_argb1555 || mesa_format == _radeon_texformat_argb4444)
579 		return 1;
580 
581 	switch (mesa_format)
582 	{
583 		case MESA_FORMAT_Z16:
584 		case MESA_FORMAT_S8_Z24:
585 			return 1;
586 		default:
587 			return 0;
588 	}
589 }
590 
591 #if FEATURE_OES_EGL_image
radeon_image_target_texture_2d(struct gl_context * ctx,GLenum target,struct gl_texture_object * texObj,struct gl_texture_image * texImage,GLeglImageOES image_handle)592 void radeon_image_target_texture_2d(struct gl_context *ctx, GLenum target,
593 				    struct gl_texture_object *texObj,
594 				    struct gl_texture_image *texImage,
595 				    GLeglImageOES image_handle)
596 {
597 	radeonContextPtr radeon = RADEON_CONTEXT(ctx);
598 	radeonTexObj *t = radeon_tex_obj(texObj);
599 	radeon_texture_image *radeonImage = get_radeon_texture_image(texImage);
600 	__DRIscreen *screen;
601 	__DRIimage *image;
602 
603 	screen = radeon->dri.screen;
604 	image = screen->dri2.image->lookupEGLImage(screen, image_handle,
605 						   screen->loaderPrivate);
606 	if (image == NULL)
607 		return;
608 
609 	radeonFreeTextureImageBuffer(ctx, texImage);
610 
611 	texImage->Width = image->width;
612 	texImage->Height = image->height;
613 	texImage->Depth = 1;
614 	texImage->_BaseFormat = GL_RGBA;
615 	texImage->TexFormat = image->format;
616 	radeonImage->base.RowStride = image->pitch;
617 	texImage->InternalFormat = image->internal_format;
618 
619 	if(t->mt)
620 	{
621 		radeon_miptree_unreference(&t->mt);
622 		t->mt = NULL;
623 	}
624 
625 	/* NOTE: The following is *very* ugly and will probably break. But
626 	   I don't know how to deal with it, without creating a whole new
627 	   function like radeon_miptree_from_bo() so I'm going with the
628 	   easy but error-prone way. */
629 
630 	radeon_try_alloc_miptree(radeon, t);
631 
632 	radeon_miptree_reference(t->mt, &radeonImage->mt);
633 
634 	if (t->mt == NULL)
635 	{
636 		radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
637 			     "%s Failed to allocate miptree.\n", __func__);
638 		return;
639 	}
640 
641 	/* Particularly ugly: this is guaranteed to break, if image->bo is
642 	   not of the required size for a miptree. */
643 	radeon_bo_unref(t->mt->bo);
644 	radeon_bo_ref(image->bo);
645 	t->mt->bo = image->bo;
646 
647 	if (!radeon_miptree_matches_image(t->mt, &radeonImage->base.Base))
648 		fprintf(stderr, "miptree doesn't match image\n");
649 }
650 #endif
651 
652 gl_format _radeon_texformat_rgba8888 = MESA_FORMAT_NONE;
653 gl_format _radeon_texformat_argb8888 = MESA_FORMAT_NONE;
654 gl_format _radeon_texformat_rgb565 = MESA_FORMAT_NONE;
655 gl_format _radeon_texformat_argb4444 = MESA_FORMAT_NONE;
656 gl_format _radeon_texformat_argb1555 = MESA_FORMAT_NONE;
657 gl_format _radeon_texformat_al88 = MESA_FORMAT_NONE;
658 /*@}*/
659 
660 
661 static void
radeonInitTextureFormats(void)662 radeonInitTextureFormats(void)
663 {
664    if (_mesa_little_endian()) {
665       _radeon_texformat_rgba8888	= MESA_FORMAT_RGBA8888;
666       _radeon_texformat_argb8888	= MESA_FORMAT_ARGB8888;
667       _radeon_texformat_rgb565		= MESA_FORMAT_RGB565;
668       _radeon_texformat_argb4444	= MESA_FORMAT_ARGB4444;
669       _radeon_texformat_argb1555	= MESA_FORMAT_ARGB1555;
670       _radeon_texformat_al88		= MESA_FORMAT_AL88;
671    }
672    else {
673       _radeon_texformat_rgba8888	= MESA_FORMAT_RGBA8888_REV;
674       _radeon_texformat_argb8888	= MESA_FORMAT_ARGB8888_REV;
675       _radeon_texformat_rgb565		= MESA_FORMAT_RGB565_REV;
676       _radeon_texformat_argb4444	= MESA_FORMAT_ARGB4444_REV;
677       _radeon_texformat_argb1555	= MESA_FORMAT_ARGB1555_REV;
678       _radeon_texformat_al88		= MESA_FORMAT_AL88_REV;
679    }
680 }
681 
682 void
radeon_init_common_texture_funcs(radeonContextPtr radeon,struct dd_function_table * functions)683 radeon_init_common_texture_funcs(radeonContextPtr radeon,
684 				 struct dd_function_table *functions)
685 {
686 	functions->NewTextureImage = radeonNewTextureImage;
687 	functions->DeleteTextureImage = radeonDeleteTextureImage;
688 	functions->AllocTextureImageBuffer = radeonAllocTextureImageBuffer;
689 	functions->FreeTextureImageBuffer = radeonFreeTextureImageBuffer;
690 	functions->MapTextureImage = radeon_map_texture_image;
691 	functions->UnmapTextureImage = radeon_unmap_texture_image;
692 
693 	functions->ChooseTextureFormat	= radeonChooseTextureFormat_mesa;
694 
695 	functions->CopyTexSubImage = radeonCopyTexSubImage;
696 
697 	functions->Bitmap = _mesa_meta_Bitmap;
698 #if FEATURE_OES_EGL_image
699 	functions->EGLImageTargetTexture2D = radeon_image_target_texture_2d;
700 #endif
701 
702 	radeonInitTextureFormats();
703 }
704 
705 static void
radeon_swrast_map_image(radeonContextPtr rmesa,radeon_texture_image * image)706 radeon_swrast_map_image(radeonContextPtr rmesa,
707 			radeon_texture_image *image)
708 {
709 	GLuint level, face;
710 	radeon_mipmap_tree *mt;
711 	GLuint texel_size;
712 	radeon_mipmap_level *lvl;
713 	int rs;
714 
715 	if (!image || !image->mt)
716 		return;
717 
718 	texel_size = _mesa_get_format_bytes(image->base.Base.TexFormat);
719 	level = image->base.Base.Level;
720 	face = image->base.Base.Face;
721 	mt = image->mt;
722 
723 	lvl = &image->mt->levels[level];
724 
725 	rs = lvl->rowstride / texel_size;
726 
727 	radeon_bo_map(mt->bo, 1);
728 
729 	image->base.Map = mt->bo->ptr + lvl->faces[face].offset;
730 	if (mt->target == GL_TEXTURE_3D) {
731 		int i;
732 
733 		for (i = 0; i < mt->levels[level].depth; i++)
734 			image->base.ImageOffsets[i] = rs * lvl->height * i;
735 	}
736 	image->base.RowStride = rs;
737 }
738 
739 static void
radeon_swrast_unmap_image(radeonContextPtr rmesa,radeon_texture_image * image)740 radeon_swrast_unmap_image(radeonContextPtr rmesa,
741 			  radeon_texture_image *image)
742 {
743 	if (image && image->mt) {
744 		image->base.Map = NULL;
745 		radeon_bo_unmap(image->mt->bo);
746 	}
747 }
748 
749 void
radeon_swrast_map_texture_images(struct gl_context * ctx,struct gl_texture_object * texObj)750 radeon_swrast_map_texture_images(struct gl_context *ctx,
751 				 struct gl_texture_object *texObj)
752 {
753 	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
754 	GLuint nr_faces = _mesa_num_tex_faces(texObj->Target);
755 	int i, face;
756 
757 	for (i = texObj->BaseLevel; i <= texObj->_MaxLevel; i++) {
758 		for (face = 0; face < nr_faces; face++) {
759 			radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][i]);
760 			radeon_swrast_map_image(rmesa, image);
761 		}
762 	}
763 }
764 
765 void
radeon_swrast_unmap_texture_images(struct gl_context * ctx,struct gl_texture_object * texObj)766 radeon_swrast_unmap_texture_images(struct gl_context *ctx,
767 				   struct gl_texture_object *texObj)
768 {
769 	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
770 	GLuint nr_faces = _mesa_num_tex_faces(texObj->Target);
771 	int i, face;
772 
773 	for (i = texObj->BaseLevel; i <= texObj->_MaxLevel; i++) {
774 		for (face = 0; face < nr_faces; face++) {
775 			radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][i]);
776 			radeon_swrast_unmap_image(rmesa, image);
777 		}
778 	}
779 
780 }
781 
radeon_miptree_create_for_teximage(radeonContextPtr rmesa,struct gl_texture_object * texObj,struct gl_texture_image * texImage)782 static radeon_mipmap_tree *radeon_miptree_create_for_teximage(radeonContextPtr rmesa,
783 						       struct gl_texture_object *texObj,
784 						       struct gl_texture_image *texImage)
785 {
786 	radeonTexObj *t = radeon_tex_obj(texObj);
787 	GLuint firstLevel;
788 	GLuint lastLevel;
789 	int width, height, depth;
790 	int i;
791 
792 	width = texImage->Width;
793 	height = texImage->Height;
794 	depth = texImage->Depth;
795 
796 	if (texImage->Level > texObj->BaseLevel &&
797 	    (width == 1 ||
798 	     (texObj->Target != GL_TEXTURE_1D && height == 1) ||
799 	     (texObj->Target == GL_TEXTURE_3D && depth == 1))) {
800 		/* For this combination, we're at some lower mipmap level and
801 		 * some important dimension is 1.  We can't extrapolate up to a
802 		 * likely base level width/height/depth for a full mipmap stack
803 		 * from this info, so just allocate this one level.
804 		 */
805 		firstLevel = texImage->Level;
806 		lastLevel = texImage->Level;
807 	} else {
808 		if (texImage->Level < texObj->BaseLevel)
809 			firstLevel = 0;
810 		else
811 			firstLevel = texObj->BaseLevel;
812 
813 		for (i = texImage->Level; i > firstLevel; i--) {
814 			width <<= 1;
815 			if (height != 1)
816 				height <<= 1;
817 			if (depth != 1)
818 				depth <<= 1;
819 		}
820 		if ((texObj->Sampler.MinFilter == GL_NEAREST ||
821 		     texObj->Sampler.MinFilter == GL_LINEAR) &&
822 		    texImage->Level == firstLevel) {
823 			lastLevel = firstLevel;
824 		} else {
825 			lastLevel = firstLevel + _mesa_logbase2(MAX2(MAX2(width, height), depth));
826 		}
827 	}
828 
829 	return  radeon_miptree_create(rmesa, texObj->Target,
830 				      texImage->TexFormat, firstLevel, lastLevel - firstLevel + 1,
831 				      width, height, depth,
832 				      t->tile_bits);
833 }
834