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