i965 VS: Change nr_userclip to nr_userclip_planes.
[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 GLubyte *slices[512];
789 GLuint texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
790 GLuint i;
791 assert(depth <= 512);
792 for (i = 0; i < depth; i++) {
793 slices[i] = (GLubyte *) texImage->Data
794 + dstImageOffsets[i] * texelBytes;
795 }
796 if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
797 texImage->TexFormat,
798 xoffset, yoffset, zoffset,
799 dstRowStride,
800 slices,
801 width, height, depth,
802 format, type, pixels, packing)) {
803 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
804 }
805 }
806
807 if (dims == 3) {
808 free(dstImageOffsets);
809 }
810
811 radeon_teximage_unmap(image);
812 }
813
814 /**
815 * All glTexImage calls go through this function.
816 */
817 static void radeon_teximage(
818 struct gl_context *ctx, int dims,
819 GLenum target, GLint level,
820 GLint internalFormat,
821 GLint width, GLint height, GLint depth,
822 GLsizei imageSize,
823 GLenum format, GLenum type, const GLvoid * pixels,
824 const struct gl_pixelstore_attrib *packing,
825 struct gl_texture_object *texObj,
826 struct gl_texture_image *texImage,
827 int compressed)
828 {
829 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
830 radeonTexObj* t = radeon_tex_obj(texObj);
831 radeon_texture_image* image = get_radeon_texture_image(texImage);
832 GLuint face = _mesa_tex_target_to_face(target);
833
834 radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
835 "%s %dd: texObj %p, texImage %p, face %d, level %d\n",
836 __func__, dims, texObj, texImage, face, level);
837
838 t->validated = GL_FALSE;
839
840 /* Mesa core only clears texImage->Data but not image->mt */
841 radeonFreeTextureImageBuffer(ctx, texImage);
842
843 if (!t->bo) {
844 teximage_assign_miptree(rmesa, texObj, texImage, face, level);
845 if (!image->mt) {
846 int size = _mesa_format_image_size(texImage->TexFormat,
847 texImage->Width,
848 texImage->Height,
849 texImage->Depth);
850 texImage->Data = _mesa_alloc_texmemory(size);
851 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
852 "%s %dd: texObj %p, texImage %p, "
853 " no miptree assigned, using local memory %p\n",
854 __func__, dims, texObj, texImage, texImage->Data);
855 }
856 }
857
858 {
859 struct radeon_bo *bo;
860 bo = !image->mt ? image->bo : image->mt->bo;
861 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
862 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
863 "%s Calling teximage for texture that is "
864 "queued for GPU processing.\n",
865 __func__);
866 radeon_firevertices(rmesa);
867 }
868 }
869
870 /* Upload texture image; note that the spec allows pixels to be NULL */
871 if (compressed) {
872 pixels = _mesa_validate_pbo_compressed_teximage(
873 ctx, imageSize, pixels, packing, "glCompressedTexImage");
874 } else {
875 pixels = _mesa_validate_pbo_teximage(
876 ctx, dims, width, height, depth,
877 format, type, pixels, packing, "glTexImage");
878 }
879
880 if (pixels) {
881 radeon_store_teximage(ctx, dims,
882 0, 0, 0,
883 width, height, depth,
884 imageSize, format, type,
885 pixels, packing,
886 texObj, texImage,
887 compressed);
888 }
889
890 _mesa_unmap_teximage_pbo(ctx, packing);
891 }
892
893 void radeonTexImage1D(struct gl_context * ctx, GLenum target, GLint level,
894 GLint internalFormat,
895 GLint width, GLint border,
896 GLenum format, GLenum type, const GLvoid * pixels,
897 const struct gl_pixelstore_attrib *packing,
898 struct gl_texture_object *texObj,
899 struct gl_texture_image *texImage)
900 {
901 radeon_teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
902 0, format, type, pixels, packing, texObj, texImage, 0);
903 }
904
905 void radeonTexImage2D(struct gl_context * ctx, GLenum target, GLint level,
906 GLint internalFormat,
907 GLint width, GLint height, GLint border,
908 GLenum format, GLenum type, const GLvoid * pixels,
909 const struct gl_pixelstore_attrib *packing,
910 struct gl_texture_object *texObj,
911 struct gl_texture_image *texImage)
912
913 {
914 radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
915 0, format, type, pixels, packing, texObj, texImage, 0);
916 }
917
918 void radeonCompressedTexImage2D(struct gl_context * ctx, GLenum target,
919 GLint level, GLint internalFormat,
920 GLint width, GLint height, GLint border,
921 GLsizei imageSize, const GLvoid * data,
922 struct gl_texture_object *texObj,
923 struct gl_texture_image *texImage)
924 {
925 radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
926 imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1);
927 }
928
929 void radeonTexImage3D(struct gl_context * ctx, GLenum target, GLint level,
930 GLint internalFormat,
931 GLint width, GLint height, GLint depth,
932 GLint border,
933 GLenum format, GLenum type, const GLvoid * pixels,
934 const struct gl_pixelstore_attrib *packing,
935 struct gl_texture_object *texObj,
936 struct gl_texture_image *texImage)
937 {
938 radeon_teximage(ctx, 3, target, level, internalFormat, width, height, depth,
939 0, format, type, pixels, packing, texObj, texImage, 0);
940 }
941
942 /**
943 * All glTexSubImage calls go through this function.
944 */
945 static void radeon_texsubimage(struct gl_context* ctx, int dims, GLenum target, int level,
946 GLint xoffset, GLint yoffset, GLint zoffset,
947 GLsizei width, GLsizei height, GLsizei depth,
948 GLsizei imageSize,
949 GLenum format, GLenum type,
950 const GLvoid * pixels,
951 const struct gl_pixelstore_attrib *packing,
952 struct gl_texture_object *texObj,
953 struct gl_texture_image *texImage,
954 int compressed)
955 {
956 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
957 radeonTexObj* t = radeon_tex_obj(texObj);
958 radeon_texture_image* image = get_radeon_texture_image(texImage);
959
960 radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
961 "%s %dd: texObj %p, texImage %p, face %d, level %d\n",
962 __func__, dims, texObj, texImage,
963 _mesa_tex_target_to_face(target), level);
964 {
965 struct radeon_bo *bo;
966 bo = !image->mt ? image->bo : image->mt->bo;
967 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
968 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
969 "%s Calling texsubimage for texture that is "
970 "queued for GPU processing.\n",
971 __func__);
972 radeon_firevertices(rmesa);
973 }
974 }
975
976
977 t->validated = GL_FALSE;
978 if (compressed) {
979 pixels = _mesa_validate_pbo_compressed_teximage(
980 ctx, imageSize, pixels, packing, "glCompressedTexSubImage");
981 } else {
982 pixels = _mesa_validate_pbo_teximage(ctx, dims,
983 width, height, depth, format, type, pixels, packing, "glTexSubImage");
984 }
985
986 if (pixels) {
987 radeon_store_teximage(ctx, dims,
988 xoffset, yoffset, zoffset,
989 width, height, depth,
990 imageSize, format, type,
991 pixels, packing,
992 texObj, texImage,
993 compressed);
994 }
995
996 _mesa_unmap_teximage_pbo(ctx, packing);
997 }
998
999 void radeonTexSubImage1D(struct gl_context * ctx, GLenum target, GLint level,
1000 GLint xoffset,
1001 GLsizei width,
1002 GLenum format, GLenum type,
1003 const GLvoid * pixels,
1004 const struct gl_pixelstore_attrib *packing,
1005 struct gl_texture_object *texObj,
1006 struct gl_texture_image *texImage)
1007 {
1008 radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0,
1009 format, type, pixels, packing, texObj, texImage, 0);
1010 }
1011
1012 void radeonTexSubImage2D(struct gl_context * ctx, GLenum target, GLint level,
1013 GLint xoffset, GLint yoffset,
1014 GLsizei width, GLsizei height,
1015 GLenum format, GLenum type,
1016 const GLvoid * pixels,
1017 const struct gl_pixelstore_attrib *packing,
1018 struct gl_texture_object *texObj,
1019 struct gl_texture_image *texImage)
1020 {
1021 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
1022 0, format, type, pixels, packing, texObj, texImage,
1023 0);
1024 }
1025
1026 void radeonCompressedTexSubImage2D(struct gl_context * ctx, GLenum target,
1027 GLint level, GLint xoffset,
1028 GLint yoffset, GLsizei width,
1029 GLsizei height, GLenum format,
1030 GLsizei imageSize, const GLvoid * data,
1031 struct gl_texture_object *texObj,
1032 struct gl_texture_image *texImage)
1033 {
1034 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
1035 imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1);
1036 }
1037
1038
1039 void radeonTexSubImage3D(struct gl_context * ctx, GLenum target, GLint level,
1040 GLint xoffset, GLint yoffset, GLint zoffset,
1041 GLsizei width, GLsizei height, GLsizei depth,
1042 GLenum format, GLenum type,
1043 const GLvoid * pixels,
1044 const struct gl_pixelstore_attrib *packing,
1045 struct gl_texture_object *texObj,
1046 struct gl_texture_image *texImage)
1047 {
1048 radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0,
1049 format, type, pixels, packing, texObj, texImage, 0);
1050 }
1051
1052 unsigned radeonIsFormatRenderable(gl_format mesa_format)
1053 {
1054 if (mesa_format == _dri_texformat_argb8888 || mesa_format == _dri_texformat_rgb565 ||
1055 mesa_format == _dri_texformat_argb1555 || mesa_format == _dri_texformat_argb4444)
1056 return 1;
1057
1058 switch (mesa_format)
1059 {
1060 case MESA_FORMAT_Z16:
1061 case MESA_FORMAT_S8_Z24:
1062 return 1;
1063 default:
1064 return 0;
1065 }
1066 }
1067
1068 #if FEATURE_OES_EGL_image
1069 void radeon_image_target_texture_2d(struct gl_context *ctx, GLenum target,
1070 struct gl_texture_object *texObj,
1071 struct gl_texture_image *texImage,
1072 GLeglImageOES image_handle)
1073 {
1074 radeonContextPtr radeon = RADEON_CONTEXT(ctx);
1075 radeonTexObj *t = radeon_tex_obj(texObj);
1076 radeon_texture_image *radeonImage = get_radeon_texture_image(texImage);
1077 __DRIscreen *screen;
1078 __DRIimage *image;
1079
1080 screen = radeon->dri.screen;
1081 image = screen->dri2.image->lookupEGLImage(screen, image_handle,
1082 screen->loaderPrivate);
1083 if (image == NULL)
1084 return;
1085
1086 radeonFreeTextureImageBuffer(ctx, texImage);
1087
1088 texImage->Width = image->width;
1089 texImage->Height = image->height;
1090 texImage->Depth = 1;
1091 texImage->_BaseFormat = GL_RGBA;
1092 texImage->TexFormat = image->format;
1093 texImage->RowStride = image->pitch;
1094 texImage->InternalFormat = image->internal_format;
1095
1096 if(t->mt)
1097 {
1098 radeon_miptree_unreference(&t->mt);
1099 t->mt = NULL;
1100 }
1101
1102 /* NOTE: The following is *very* ugly and will probably break. But
1103 I don't know how to deal with it, without creating a whole new
1104 function like radeon_miptree_from_bo() so I'm going with the
1105 easy but error-prone way. */
1106
1107 radeon_try_alloc_miptree(radeon, t);
1108
1109 radeonImage->mtface = _mesa_tex_target_to_face(target);
1110 radeonImage->mtlevel = 0;
1111 radeon_miptree_reference(t->mt, &radeonImage->mt);
1112
1113 if (t->mt == NULL)
1114 {
1115 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
1116 "%s Failed to allocate miptree.\n", __func__);
1117 return;
1118 }
1119
1120 /* Particularly ugly: this is guaranteed to break, if image->bo is
1121 not of the required size for a miptree. */
1122 radeon_bo_unref(t->mt->bo);
1123 radeon_bo_ref(image->bo);
1124 t->mt->bo = image->bo;
1125
1126 if (!radeon_miptree_matches_image(t->mt, &radeonImage->base.Base,
1127 radeonImage->mtface, 0))
1128 fprintf(stderr, "miptree doesn't match image\n");
1129 }
1130 #endif
1131
1132 void
1133 radeon_init_common_texture_funcs(radeonContextPtr radeon,
1134 struct dd_function_table *functions)
1135 {
1136 functions->NewTextureImage = radeonNewTextureImage;
1137 functions->DeleteTextureImage = radeonDeleteTextureImage;
1138 functions->FreeTextureImageBuffer = radeonFreeTextureImageBuffer;
1139 functions->MapTexture = radeonMapTexture;
1140 functions->UnmapTexture = radeonUnmapTexture;
1141 functions->MapTextureImage = radeon_map_texture_image;
1142 functions->UnmapTextureImage = radeon_unmap_texture_image;
1143
1144 functions->ChooseTextureFormat = radeonChooseTextureFormat_mesa;
1145
1146 functions->TexImage1D = radeonTexImage1D;
1147 functions->TexImage2D = radeonTexImage2D;
1148 functions->TexImage3D = radeonTexImage3D;
1149 functions->TexSubImage1D = radeonTexSubImage1D;
1150 functions->TexSubImage2D = radeonTexSubImage2D;
1151 functions->TexSubImage3D = radeonTexSubImage3D;
1152 functions->CompressedTexImage2D = radeonCompressedTexImage2D;
1153 functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D;
1154
1155 functions->GenerateMipmap = radeonGenerateMipmap;
1156
1157 if (radeon->radeonScreen->kernel_mm) {
1158 functions->CopyTexSubImage2D = radeonCopyTexSubImage2D;
1159 }
1160
1161 #if FEATURE_OES_EGL_image
1162 functions->EGLImageTargetTexture2D = radeon_image_target_texture_2d;
1163 #endif
1164
1165 driInitTextureFormats();
1166 }