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