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/mipmap.h" 37 #include "main/pbo.h" 38 #include "main/texcompress.h" 39 #include "main/texstore.h" 40 #include "main/teximage.h" 41 #include "main/texobj.h" 42 #include "drivers/common/meta.h" 43 44 #include "xmlpool.h" /* for symbolic values of enum-type options */ 45 46 #include "radeon_common.h" 47 48 #include "radeon_mipmap_tree.h" 49 50 static void teximage_assign_miptree(radeonContextPtr rmesa, 51 struct gl_texture_object *texObj, 52 struct gl_texture_image *texImage); 53 54 static radeon_mipmap_tree *radeon_miptree_create_for_teximage(radeonContextPtr rmesa, 55 struct gl_texture_object *texObj, 56 struct gl_texture_image *texImage); 57 58 void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, 59 GLuint numrows, GLuint rowsize) 60 { 61 assert(rowsize <= dststride); 62 assert(rowsize <= srcstride); 63 64 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 65 "%s dst %p, stride %u, src %p, stride %u, " 66 "numrows %u, rowsize %u.\n", 67 __func__, dst, dststride, 68 src, srcstride, 69 numrows, rowsize); 70 71 if (rowsize == srcstride && rowsize == dststride) { 72 memcpy(dst, src, numrows*rowsize); 73 } else { 74 GLuint i; 75 for(i = 0; i < numrows; ++i) { 76 memcpy(dst, src, rowsize); 77 dst += dststride; 78 src += srcstride; 79 } 80 } 81 } 82 83 /* textures */ 84 /** 85 * Allocate an empty texture image object. 86 */ 87 struct gl_texture_image *radeonNewTextureImage(struct gl_context *ctx) 88 { 89 return calloc(1, sizeof(radeon_texture_image)); 90 } 91 92 93 /** 94 * Delete a texture image object. 95 */ 96 static void 97 radeonDeleteTextureImage(struct gl_context *ctx, struct gl_texture_image *img) 98 { 99 /* nothing special (yet) for radeon_texture_image */ 100 _mesa_delete_texture_image(ctx, img); 101 } 102 103 static GLboolean 104 radeonAllocTextureImageBuffer(struct gl_context *ctx, 105 struct gl_texture_image *timage) 106 { 107 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 108 struct gl_texture_object *texobj = timage->TexObject; 109 110 ctx->Driver.FreeTextureImageBuffer(ctx, timage); 111 112 if (!_swrast_init_texture_image(timage)) 113 return GL_FALSE; 114 115 teximage_assign_miptree(rmesa, texobj, timage); 116 117 return GL_TRUE; 118 } 119 120 121 /** 122 * Free memory associated with this texture image. 123 */ 124 void radeonFreeTextureImageBuffer(struct gl_context *ctx, struct gl_texture_image *timage) 125 { 126 radeon_texture_image* image = get_radeon_texture_image(timage); 127 128 if (image->mt) { 129 radeon_miptree_unreference(&image->mt); 130 } 131 if (image->bo) { 132 radeon_bo_unref(image->bo); 133 image->bo = NULL; 134 } 135 136 _swrast_free_texture_image_buffer(ctx, timage); 137 } 138 139 /** 140 * Map texture memory/buffer into user space. 141 * Note: the region of interest parameters are ignored here. 142 * \param mapOut returns start of mapping of region of interest 143 * \param rowStrideOut returns row stride in bytes 144 */ 145 static void 146 radeon_map_texture_image(struct gl_context *ctx, 147 struct gl_texture_image *texImage, 148 GLuint slice, 149 GLuint x, GLuint y, GLuint w, GLuint h, 150 GLbitfield mode, 151 GLubyte **map, 152 GLint *stride) 153 { 154 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 155 radeon_texture_image *image = get_radeon_texture_image(texImage); 156 radeon_mipmap_tree *mt = image->mt; 157 GLuint texel_size = _mesa_get_format_bytes(texImage->TexFormat); 158 GLuint width = texImage->Width; 159 GLuint height = texImage->Height; 160 struct radeon_bo *bo = !image->mt ? image->bo : image->mt->bo; 161 unsigned int bw, bh; 162 GLboolean write = (mode & GL_MAP_WRITE_BIT) != 0; 163 164 _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh); 165 assert(y % bh == 0); 166 y /= bh; 167 texel_size /= bw; 168 169 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { 170 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, 171 "%s for texture that is " 172 "queued for GPU processing.\n", 173 __func__); 174 radeon_firevertices(rmesa); 175 } 176 177 if (image->bo) { 178 /* TFP case */ 179 radeon_bo_map(image->bo, write); 180 *stride = get_texture_image_row_stride(rmesa, texImage->TexFormat, width, 0, texImage->TexObject->Target); 181 *map = bo->ptr; 182 } else if (likely(mt)) { 183 void *base; 184 radeon_mipmap_level *lvl = &image->mt->levels[texImage->Level]; 185 186 radeon_bo_map(mt->bo, write); 187 base = mt->bo->ptr + lvl->faces[image->base.Base.Face].offset; 188 189 *stride = lvl->rowstride; 190 *map = base + (slice * height) * *stride; 191 } else { 192 /* texture data is in malloc'd memory */ 193 194 assert(map); 195 196 *stride = _mesa_format_row_stride(texImage->TexFormat, width); 197 *map = image->base.Buffer + (slice * height) * *stride; 198 } 199 200 *map += y * *stride + x * texel_size; 201 } 202 203 static void 204 radeon_unmap_texture_image(struct gl_context *ctx, 205 struct gl_texture_image *texImage, GLuint slice) 206 { 207 radeon_texture_image *image = get_radeon_texture_image(texImage); 208 209 if (image->bo) 210 radeon_bo_unmap(image->bo); 211 else if (image->mt) 212 radeon_bo_unmap(image->mt->bo); 213 } 214 215 /* try to find a format which will only need a memcopy */ 216 static mesa_format radeonChoose8888TexFormat(radeonContextPtr rmesa, 217 GLenum srcFormat, 218 GLenum srcType, GLboolean fbo) 219 { 220 #if defined(RADEON_R100) 221 /* r100 can only do this */ 222 return _radeon_texformat_argb8888; 223 #elif defined(RADEON_R200) 224 const GLuint ui = 1; 225 const GLubyte littleEndian = *((const GLubyte *)&ui); 226 227 228 /* Unfortunately, regardless the fbo flag, we might still be asked to 229 * attach a texture to a fbo later, which then won't succeed if we chose 230 * one which isn't renderable. And unlike more exotic formats, apps aren't 231 * really prepared for the incomplete framebuffer this results in (they'd 232 * have to retry with same internalFormat even, just different 233 * srcFormat/srcType, which can't really be expected anyway). 234 * Ideally, we'd defer format selection until later (if the texture is 235 * used as a rt it's likely there's never data uploaded to it before attached 236 * to a fbo), but this isn't really possible, so for now just always use 237 * a renderable format. 238 */ 239 if (1 || fbo) 240 return _radeon_texformat_argb8888; 241 242 if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) || 243 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) || 244 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || 245 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) { 246 return MESA_FORMAT_A8B8G8R8_UNORM; 247 } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || 248 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) || 249 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) || 250 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) { 251 return MESA_FORMAT_R8G8B8A8_UNORM; 252 } else 253 return _radeon_texformat_argb8888; 254 #endif 255 } 256 257 mesa_format radeonChooseTextureFormat_mesa(struct gl_context * ctx, 258 GLenum target, 259 GLint internalFormat, 260 GLenum format, 261 GLenum type) 262 { 263 return radeonChooseTextureFormat(ctx, internalFormat, format, 264 type, 0); 265 } 266 267 mesa_format radeonChooseTextureFormat(struct gl_context * ctx, 268 GLint internalFormat, 269 GLenum format, 270 GLenum type, GLboolean fbo) 271 { 272 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 273 const GLboolean do32bpt = 274 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32); 275 const GLboolean force16bpt = 276 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16); 277 (void)format; 278 279 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 280 "%s InternalFormat=%s(%d) type=%s format=%s\n", 281 __func__, 282 _mesa_enum_to_string(internalFormat), internalFormat, 283 _mesa_enum_to_string(type), _mesa_enum_to_string(format)); 284 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 285 "%s do32bpt=%d force16bpt=%d\n", 286 __func__, do32bpt, force16bpt); 287 288 switch (internalFormat) { 289 case 4: 290 case GL_RGBA: 291 case GL_COMPRESSED_RGBA: 292 switch (type) { 293 case GL_UNSIGNED_INT_10_10_10_2: 294 case GL_UNSIGNED_INT_2_10_10_10_REV: 295 return do32bpt ? _radeon_texformat_argb8888 : 296 _radeon_texformat_argb1555; 297 case GL_UNSIGNED_SHORT_4_4_4_4: 298 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 299 return _radeon_texformat_argb4444; 300 case GL_UNSIGNED_SHORT_5_5_5_1: 301 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 302 return _radeon_texformat_argb1555; 303 default: 304 return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type, fbo) : 305 _radeon_texformat_argb4444; 306 } 307 308 case 3: 309 case GL_RGB: 310 case GL_COMPRESSED_RGB: 311 switch (type) { 312 case GL_UNSIGNED_SHORT_4_4_4_4: 313 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 314 return _radeon_texformat_argb4444; 315 case GL_UNSIGNED_SHORT_5_5_5_1: 316 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 317 return _radeon_texformat_argb1555; 318 case GL_UNSIGNED_SHORT_5_6_5: 319 case GL_UNSIGNED_SHORT_5_6_5_REV: 320 return _radeon_texformat_rgb565; 321 default: 322 return do32bpt ? _radeon_texformat_argb8888 : 323 _radeon_texformat_rgb565; 324 } 325 326 case GL_RGBA8: 327 case GL_RGB10_A2: 328 case GL_RGBA12: 329 case GL_RGBA16: 330 return !force16bpt ? 331 radeonChoose8888TexFormat(rmesa, format, type, fbo) : 332 _radeon_texformat_argb4444; 333 334 case GL_RGBA4: 335 case GL_RGBA2: 336 return _radeon_texformat_argb4444; 337 338 case GL_RGB5_A1: 339 return _radeon_texformat_argb1555; 340 341 case GL_RGB8: 342 case GL_RGB10: 343 case GL_RGB12: 344 case GL_RGB16: 345 return !force16bpt ? _radeon_texformat_argb8888 : 346 _radeon_texformat_rgb565; 347 348 case GL_RGB5: 349 case GL_RGB4: 350 case GL_R3_G3_B2: 351 return _radeon_texformat_rgb565; 352 353 case GL_ALPHA: 354 case GL_ALPHA4: 355 case GL_ALPHA8: 356 case GL_ALPHA12: 357 case GL_ALPHA16: 358 case GL_COMPRESSED_ALPHA: 359 #if defined(RADEON_R200) 360 /* r200: can't use a8 format since interpreting hw I8 as a8 would result 361 in wrong rgb values (same as alpha value instead of 0). */ 362 return _radeon_texformat_al88; 363 #else 364 return MESA_FORMAT_A_UNORM8; 365 #endif 366 case 1: 367 case GL_LUMINANCE: 368 case GL_LUMINANCE4: 369 case GL_LUMINANCE8: 370 case GL_LUMINANCE12: 371 case GL_LUMINANCE16: 372 case GL_COMPRESSED_LUMINANCE: 373 return MESA_FORMAT_L_UNORM8; 374 375 case 2: 376 case GL_LUMINANCE_ALPHA: 377 case GL_LUMINANCE4_ALPHA4: 378 case GL_LUMINANCE6_ALPHA2: 379 case GL_LUMINANCE8_ALPHA8: 380 case GL_LUMINANCE12_ALPHA4: 381 case GL_LUMINANCE12_ALPHA12: 382 case GL_LUMINANCE16_ALPHA16: 383 case GL_COMPRESSED_LUMINANCE_ALPHA: 384 return _radeon_texformat_al88; 385 386 case GL_INTENSITY: 387 case GL_INTENSITY4: 388 case GL_INTENSITY8: 389 case GL_INTENSITY12: 390 case GL_INTENSITY16: 391 case GL_COMPRESSED_INTENSITY: 392 return MESA_FORMAT_I_UNORM8; 393 394 case GL_YCBCR_MESA: 395 if (type == GL_UNSIGNED_SHORT_8_8_APPLE || 396 type == GL_UNSIGNED_BYTE) 397 return MESA_FORMAT_YCBCR; 398 else 399 return MESA_FORMAT_YCBCR_REV; 400 401 case GL_RGB_S3TC: 402 case GL_RGB4_S3TC: 403 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 404 return MESA_FORMAT_RGB_DXT1; 405 406 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 407 return MESA_FORMAT_RGBA_DXT1; 408 409 case GL_RGBA_S3TC: 410 case GL_RGBA4_S3TC: 411 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 412 return MESA_FORMAT_RGBA_DXT3; 413 414 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: 415 return MESA_FORMAT_RGBA_DXT5; 416 417 case GL_ALPHA16F_ARB: 418 return MESA_FORMAT_A_FLOAT16; 419 case GL_ALPHA32F_ARB: 420 return MESA_FORMAT_A_FLOAT32; 421 case GL_LUMINANCE16F_ARB: 422 return MESA_FORMAT_L_FLOAT16; 423 case GL_LUMINANCE32F_ARB: 424 return MESA_FORMAT_L_FLOAT32; 425 case GL_LUMINANCE_ALPHA16F_ARB: 426 return MESA_FORMAT_LA_FLOAT16; 427 case GL_LUMINANCE_ALPHA32F_ARB: 428 return MESA_FORMAT_LA_FLOAT32; 429 case GL_INTENSITY16F_ARB: 430 return MESA_FORMAT_I_FLOAT16; 431 case GL_INTENSITY32F_ARB: 432 return MESA_FORMAT_I_FLOAT32; 433 case GL_RGB16F_ARB: 434 return MESA_FORMAT_RGBA_FLOAT16; 435 case GL_RGB32F_ARB: 436 return MESA_FORMAT_RGBA_FLOAT32; 437 case GL_RGBA16F_ARB: 438 return MESA_FORMAT_RGBA_FLOAT16; 439 case GL_RGBA32F_ARB: 440 return MESA_FORMAT_RGBA_FLOAT32; 441 442 case GL_DEPTH_COMPONENT: 443 case GL_DEPTH_COMPONENT16: 444 case GL_DEPTH_COMPONENT24: 445 case GL_DEPTH_COMPONENT32: 446 case GL_DEPTH_STENCIL_EXT: 447 case GL_DEPTH24_STENCIL8_EXT: 448 return MESA_FORMAT_Z24_UNORM_S8_UINT; 449 450 /* EXT_texture_sRGB */ 451 case GL_SRGB: 452 case GL_SRGB8: 453 case GL_SRGB_ALPHA: 454 case GL_SRGB8_ALPHA8: 455 case GL_COMPRESSED_SRGB: 456 case GL_COMPRESSED_SRGB_ALPHA: 457 return MESA_FORMAT_B8G8R8A8_SRGB; 458 459 case GL_SLUMINANCE: 460 case GL_SLUMINANCE8: 461 case GL_COMPRESSED_SLUMINANCE: 462 return MESA_FORMAT_L_SRGB8; 463 464 case GL_SLUMINANCE_ALPHA: 465 case GL_SLUMINANCE8_ALPHA8: 466 case GL_COMPRESSED_SLUMINANCE_ALPHA: 467 return MESA_FORMAT_L8A8_SRGB; 468 469 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: 470 return MESA_FORMAT_SRGB_DXT1; 471 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: 472 return MESA_FORMAT_SRGBA_DXT1; 473 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: 474 return MESA_FORMAT_SRGBA_DXT3; 475 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: 476 return MESA_FORMAT_SRGBA_DXT5; 477 478 default: 479 _mesa_problem(ctx, 480 "unexpected internalFormat 0x%x in %s", 481 (int)internalFormat, __func__); 482 return MESA_FORMAT_NONE; 483 } 484 485 return MESA_FORMAT_NONE; /* never get here */ 486 } 487 488 /** Check if given image is valid within current texture object. 489 */ 490 static void teximage_assign_miptree(radeonContextPtr rmesa, 491 struct gl_texture_object *texObj, 492 struct gl_texture_image *texImage) 493 { 494 radeonTexObj *t = radeon_tex_obj(texObj); 495 radeon_texture_image* image = get_radeon_texture_image(texImage); 496 497 /* Try using current miptree, or create new if there isn't any */ 498 if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage)) { 499 radeon_miptree_unreference(&t->mt); 500 t->mt = radeon_miptree_create_for_teximage(rmesa, 501 texObj, 502 texImage); 503 504 radeon_print(RADEON_TEXTURE, RADEON_NORMAL, 505 "%s: texObj %p, texImage %p, " 506 "texObj miptree doesn't match, allocated new miptree %p\n", 507 __func__, texObj, texImage, t->mt); 508 } 509 510 /* Miptree alocation may have failed, 511 * when there was no image for baselevel specified */ 512 if (t->mt) { 513 radeon_miptree_reference(t->mt, &image->mt); 514 } else 515 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, 516 "%s Failed to allocate miptree.\n", __func__); 517 } 518 519 unsigned radeonIsFormatRenderable(mesa_format mesa_format) 520 { 521 if (mesa_format == _radeon_texformat_argb8888 || mesa_format == _radeon_texformat_rgb565 || 522 mesa_format == _radeon_texformat_argb1555 || mesa_format == _radeon_texformat_argb4444) 523 return 1; 524 525 switch (mesa_format) 526 { 527 case MESA_FORMAT_Z_UNORM16: 528 case MESA_FORMAT_Z24_UNORM_S8_UINT: 529 return 1; 530 default: 531 return 0; 532 } 533 } 534 535 void radeon_image_target_texture_2d(struct gl_context *ctx, GLenum target, 536 struct gl_texture_object *texObj, 537 struct gl_texture_image *texImage, 538 GLeglImageOES image_handle) 539 { 540 radeonContextPtr radeon = RADEON_CONTEXT(ctx); 541 radeonTexObj *t = radeon_tex_obj(texObj); 542 radeon_texture_image *radeonImage = get_radeon_texture_image(texImage); 543 __DRIscreen *screen; 544 __DRIimage *image; 545 546 screen = radeon->radeonScreen->driScreen; 547 image = screen->dri2.image->lookupEGLImage(screen, image_handle, 548 screen->loaderPrivate); 549 if (image == NULL) 550 return; 551 552 radeonFreeTextureImageBuffer(ctx, texImage); 553 554 texImage->Width = image->width; 555 texImage->Height = image->height; 556 texImage->Depth = 1; 557 texImage->_BaseFormat = GL_RGBA; 558 texImage->TexFormat = image->format; 559 radeonImage->base.RowStride = image->pitch; 560 texImage->InternalFormat = image->internal_format; 561 562 if(t->mt) 563 { 564 radeon_miptree_unreference(&t->mt); 565 t->mt = NULL; 566 } 567 568 /* NOTE: The following is *very* ugly and will probably break. But 569 I don't know how to deal with it, without creating a whole new 570 function like radeon_miptree_from_bo() so I'm going with the 571 easy but error-prone way. */ 572 573 radeon_try_alloc_miptree(radeon, t); 574 575 radeon_miptree_reference(t->mt, &radeonImage->mt); 576 577 if (t->mt == NULL) 578 { 579 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, 580 "%s Failed to allocate miptree.\n", __func__); 581 return; 582 } 583 584 /* Particularly ugly: this is guaranteed to break, if image->bo is 585 not of the required size for a miptree. */ 586 radeon_bo_unref(t->mt->bo); 587 radeon_bo_ref(image->bo); 588 t->mt->bo = image->bo; 589 590 if (!radeon_miptree_matches_image(t->mt, &radeonImage->base.Base)) 591 fprintf(stderr, "miptree doesn't match image\n"); 592 } 593 594 mesa_format _radeon_texformat_rgba8888 = MESA_FORMAT_NONE; 595 mesa_format _radeon_texformat_argb8888 = MESA_FORMAT_NONE; 596 mesa_format _radeon_texformat_rgb565 = MESA_FORMAT_NONE; 597 mesa_format _radeon_texformat_argb4444 = MESA_FORMAT_NONE; 598 mesa_format _radeon_texformat_argb1555 = MESA_FORMAT_NONE; 599 mesa_format _radeon_texformat_al88 = MESA_FORMAT_NONE; 600 /*@}*/ 601 602 603 static void 604 radeonInitTextureFormats(void) 605 { 606 if (_mesa_little_endian()) { 607 _radeon_texformat_rgba8888 = MESA_FORMAT_A8B8G8R8_UNORM; 608 _radeon_texformat_argb8888 = MESA_FORMAT_B8G8R8A8_UNORM; 609 _radeon_texformat_rgb565 = MESA_FORMAT_B5G6R5_UNORM; 610 _radeon_texformat_argb4444 = MESA_FORMAT_B4G4R4A4_UNORM; 611 _radeon_texformat_argb1555 = MESA_FORMAT_B5G5R5A1_UNORM; 612 _radeon_texformat_al88 = MESA_FORMAT_L8A8_UNORM; 613 } 614 else { 615 _radeon_texformat_rgba8888 = MESA_FORMAT_R8G8B8A8_UNORM; 616 _radeon_texformat_argb8888 = MESA_FORMAT_A8R8G8B8_UNORM; 617 _radeon_texformat_rgb565 = MESA_FORMAT_R5G6B5_UNORM; 618 _radeon_texformat_argb4444 = MESA_FORMAT_A4R4G4B4_UNORM; 619 _radeon_texformat_argb1555 = MESA_FORMAT_A1R5G5B5_UNORM; 620 _radeon_texformat_al88 = MESA_FORMAT_A8L8_UNORM; 621 } 622 } 623 624 void 625 radeon_init_common_texture_funcs(radeonContextPtr radeon, 626 struct dd_function_table *functions) 627 { 628 functions->NewTextureImage = radeonNewTextureImage; 629 functions->DeleteTextureImage = radeonDeleteTextureImage; 630 functions->AllocTextureImageBuffer = radeonAllocTextureImageBuffer; 631 functions->FreeTextureImageBuffer = radeonFreeTextureImageBuffer; 632 functions->MapTextureImage = radeon_map_texture_image; 633 functions->UnmapTextureImage = radeon_unmap_texture_image; 634 635 functions->ChooseTextureFormat = radeonChooseTextureFormat_mesa; 636 637 functions->CopyTexSubImage = radeonCopyTexSubImage; 638 639 functions->Bitmap = _mesa_meta_Bitmap; 640 functions->EGLImageTargetTexture2D = radeon_image_target_texture_2d; 641 642 radeonInitTextureFormats(); 643 } 644 645 static radeon_mipmap_tree *radeon_miptree_create_for_teximage(radeonContextPtr rmesa, 646 struct gl_texture_object *texObj, 647 struct gl_texture_image *texImage) 648 { 649 radeonTexObj *t = radeon_tex_obj(texObj); 650 GLuint firstLevel; 651 GLuint lastLevel; 652 int width, height, depth; 653 int i; 654 655 width = texImage->Width; 656 height = texImage->Height; 657 depth = texImage->Depth; 658 659 if (texImage->Level > texObj->BaseLevel && 660 (width == 1 || 661 (texObj->Target != GL_TEXTURE_1D && height == 1) || 662 (texObj->Target == GL_TEXTURE_3D && depth == 1))) { 663 /* For this combination, we're at some lower mipmap level and 664 * some important dimension is 1. We can't extrapolate up to a 665 * likely base level width/height/depth for a full mipmap stack 666 * from this info, so just allocate this one level. 667 */ 668 firstLevel = texImage->Level; 669 lastLevel = texImage->Level; 670 } else { 671 if (texImage->Level < texObj->BaseLevel) 672 firstLevel = 0; 673 else 674 firstLevel = texObj->BaseLevel; 675 676 for (i = texImage->Level; i > firstLevel; i--) { 677 width <<= 1; 678 if (height != 1) 679 height <<= 1; 680 if (depth != 1) 681 depth <<= 1; 682 } 683 if ((texObj->Sampler.MinFilter == GL_NEAREST || 684 texObj->Sampler.MinFilter == GL_LINEAR) && 685 texImage->Level == firstLevel) { 686 lastLevel = firstLevel; 687 } else { 688 lastLevel = firstLevel + _mesa_logbase2(MAX2(MAX2(width, height), depth)); 689 } 690 } 691 692 return radeon_miptree_create(rmesa, texObj->Target, 693 texImage->TexFormat, firstLevel, lastLevel - firstLevel + 1, 694 width, height, depth, 695 t->tile_bits); 696 } 697