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