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