radeon_texture.c revision e7ecc11311d142a8ac919627011372a265224bcd
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 50static void teximage_assign_miptree(radeonContextPtr rmesa, 51 struct gl_texture_object *texObj, 52 struct gl_texture_image *texImage); 53 54static radeon_mipmap_tree *radeon_miptree_create_for_teximage(radeonContextPtr rmesa, 55 struct gl_texture_object *texObj, 56 struct gl_texture_image *texImage); 57 58void 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 */ 87struct 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 */ 96static void 97radeonDeleteTextureImage(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 103static GLboolean 104radeonAllocTextureImageBuffer(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 */ 124void 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 */ 145static void 146radeon_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 203static void 204radeon_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 */ 216static gl_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 if (fbo) 228 return _radeon_texformat_argb8888; 229 230 if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) || 231 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) || 232 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || 233 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) { 234 return MESA_FORMAT_RGBA8888; 235 } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || 236 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) || 237 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) || 238 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) { 239 return MESA_FORMAT_RGBA8888_REV; 240 } else 241 return _radeon_texformat_argb8888; 242#endif 243} 244 245gl_format radeonChooseTextureFormat_mesa(struct gl_context * ctx, 246 GLenum target, 247 GLint internalFormat, 248 GLenum format, 249 GLenum type) 250{ 251 return radeonChooseTextureFormat(ctx, internalFormat, format, 252 type, 0); 253} 254 255gl_format radeonChooseTextureFormat(struct gl_context * ctx, 256 GLint internalFormat, 257 GLenum format, 258 GLenum type, GLboolean fbo) 259{ 260 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 261 const GLboolean do32bpt = 262 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32); 263 const GLboolean force16bpt = 264 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16); 265 (void)format; 266 267 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 268 "%s InternalFormat=%s(%d) type=%s format=%s\n", 269 __func__, 270 _mesa_lookup_enum_by_nr(internalFormat), internalFormat, 271 _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format)); 272 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 273 "%s do32bpt=%d force16bpt=%d\n", 274 __func__, do32bpt, force16bpt); 275 276 switch (internalFormat) { 277 case 4: 278 case GL_RGBA: 279 case GL_COMPRESSED_RGBA: 280 switch (type) { 281 case GL_UNSIGNED_INT_10_10_10_2: 282 case GL_UNSIGNED_INT_2_10_10_10_REV: 283 return do32bpt ? _radeon_texformat_argb8888 : 284 _radeon_texformat_argb1555; 285 case GL_UNSIGNED_SHORT_4_4_4_4: 286 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 287 return _radeon_texformat_argb4444; 288 case GL_UNSIGNED_SHORT_5_5_5_1: 289 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 290 return _radeon_texformat_argb1555; 291 default: 292 return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type, fbo) : 293 _radeon_texformat_argb4444; 294 } 295 296 case 3: 297 case GL_RGB: 298 case GL_COMPRESSED_RGB: 299 switch (type) { 300 case GL_UNSIGNED_SHORT_4_4_4_4: 301 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 302 return _radeon_texformat_argb4444; 303 case GL_UNSIGNED_SHORT_5_5_5_1: 304 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 305 return _radeon_texformat_argb1555; 306 case GL_UNSIGNED_SHORT_5_6_5: 307 case GL_UNSIGNED_SHORT_5_6_5_REV: 308 return _radeon_texformat_rgb565; 309 default: 310 return do32bpt ? _radeon_texformat_argb8888 : 311 _radeon_texformat_rgb565; 312 } 313 314 case GL_RGBA8: 315 case GL_RGB10_A2: 316 case GL_RGBA12: 317 case GL_RGBA16: 318 return !force16bpt ? 319 radeonChoose8888TexFormat(rmesa, format, type, fbo) : 320 _radeon_texformat_argb4444; 321 322 case GL_RGBA4: 323 case GL_RGBA2: 324 return _radeon_texformat_argb4444; 325 326 case GL_RGB5_A1: 327 return _radeon_texformat_argb1555; 328 329 case GL_RGB8: 330 case GL_RGB10: 331 case GL_RGB12: 332 case GL_RGB16: 333 return !force16bpt ? _radeon_texformat_argb8888 : 334 _radeon_texformat_rgb565; 335 336 case GL_RGB5: 337 case GL_RGB4: 338 case GL_R3_G3_B2: 339 return _radeon_texformat_rgb565; 340 341 case GL_ALPHA: 342 case GL_ALPHA4: 343 case GL_ALPHA8: 344 case GL_ALPHA12: 345 case GL_ALPHA16: 346 case GL_COMPRESSED_ALPHA: 347#if defined(RADEON_R200) 348 /* r200: can't use a8 format since interpreting hw I8 as a8 would result 349 in wrong rgb values (same as alpha value instead of 0). */ 350 return _radeon_texformat_al88; 351#else 352 return MESA_FORMAT_A8; 353#endif 354 case 1: 355 case GL_LUMINANCE: 356 case GL_LUMINANCE4: 357 case GL_LUMINANCE8: 358 case GL_LUMINANCE12: 359 case GL_LUMINANCE16: 360 case GL_COMPRESSED_LUMINANCE: 361 return MESA_FORMAT_L8; 362 363 case 2: 364 case GL_LUMINANCE_ALPHA: 365 case GL_LUMINANCE4_ALPHA4: 366 case GL_LUMINANCE6_ALPHA2: 367 case GL_LUMINANCE8_ALPHA8: 368 case GL_LUMINANCE12_ALPHA4: 369 case GL_LUMINANCE12_ALPHA12: 370 case GL_LUMINANCE16_ALPHA16: 371 case GL_COMPRESSED_LUMINANCE_ALPHA: 372 return _radeon_texformat_al88; 373 374 case GL_INTENSITY: 375 case GL_INTENSITY4: 376 case GL_INTENSITY8: 377 case GL_INTENSITY12: 378 case GL_INTENSITY16: 379 case GL_COMPRESSED_INTENSITY: 380 return MESA_FORMAT_I8; 381 382 case GL_YCBCR_MESA: 383 if (type == GL_UNSIGNED_SHORT_8_8_APPLE || 384 type == GL_UNSIGNED_BYTE) 385 return MESA_FORMAT_YCBCR; 386 else 387 return MESA_FORMAT_YCBCR_REV; 388 389 case GL_RGB_S3TC: 390 case GL_RGB4_S3TC: 391 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 392 return MESA_FORMAT_RGB_DXT1; 393 394 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 395 return MESA_FORMAT_RGBA_DXT1; 396 397 case GL_RGBA_S3TC: 398 case GL_RGBA4_S3TC: 399 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 400 return MESA_FORMAT_RGBA_DXT3; 401 402 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: 403 return MESA_FORMAT_RGBA_DXT5; 404 405 case GL_ALPHA16F_ARB: 406 return MESA_FORMAT_ALPHA_FLOAT16; 407 case GL_ALPHA32F_ARB: 408 return MESA_FORMAT_ALPHA_FLOAT32; 409 case GL_LUMINANCE16F_ARB: 410 return MESA_FORMAT_LUMINANCE_FLOAT16; 411 case GL_LUMINANCE32F_ARB: 412 return MESA_FORMAT_LUMINANCE_FLOAT32; 413 case GL_LUMINANCE_ALPHA16F_ARB: 414 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16; 415 case GL_LUMINANCE_ALPHA32F_ARB: 416 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32; 417 case GL_INTENSITY16F_ARB: 418 return MESA_FORMAT_INTENSITY_FLOAT16; 419 case GL_INTENSITY32F_ARB: 420 return MESA_FORMAT_INTENSITY_FLOAT32; 421 case GL_RGB16F_ARB: 422 return MESA_FORMAT_RGBA_FLOAT16; 423 case GL_RGB32F_ARB: 424 return MESA_FORMAT_RGBA_FLOAT32; 425 case GL_RGBA16F_ARB: 426 return MESA_FORMAT_RGBA_FLOAT16; 427 case GL_RGBA32F_ARB: 428 return MESA_FORMAT_RGBA_FLOAT32; 429 430 case GL_DEPTH_COMPONENT: 431 case GL_DEPTH_COMPONENT16: 432 case GL_DEPTH_COMPONENT24: 433 case GL_DEPTH_COMPONENT32: 434 case GL_DEPTH_STENCIL_EXT: 435 case GL_DEPTH24_STENCIL8_EXT: 436 return MESA_FORMAT_S8_Z24; 437 438 /* EXT_texture_sRGB */ 439 case GL_SRGB: 440 case GL_SRGB8: 441 case GL_SRGB_ALPHA: 442 case GL_SRGB8_ALPHA8: 443 case GL_COMPRESSED_SRGB: 444 case GL_COMPRESSED_SRGB_ALPHA: 445 return MESA_FORMAT_SARGB8; 446 447 case GL_SLUMINANCE: 448 case GL_SLUMINANCE8: 449 case GL_COMPRESSED_SLUMINANCE: 450 return MESA_FORMAT_SL8; 451 452 case GL_SLUMINANCE_ALPHA: 453 case GL_SLUMINANCE8_ALPHA8: 454 case GL_COMPRESSED_SLUMINANCE_ALPHA: 455 return MESA_FORMAT_SLA8; 456 457 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: 458 return MESA_FORMAT_SRGB_DXT1; 459 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: 460 return MESA_FORMAT_SRGBA_DXT1; 461 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: 462 return MESA_FORMAT_SRGBA_DXT3; 463 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: 464 return MESA_FORMAT_SRGBA_DXT5; 465 466 default: 467 _mesa_problem(ctx, 468 "unexpected internalFormat 0x%x in %s", 469 (int)internalFormat, __func__); 470 return MESA_FORMAT_NONE; 471 } 472 473 return MESA_FORMAT_NONE; /* never get here */ 474} 475 476/** Check if given image is valid within current texture object. 477 */ 478static void teximage_assign_miptree(radeonContextPtr rmesa, 479 struct gl_texture_object *texObj, 480 struct gl_texture_image *texImage) 481{ 482 radeonTexObj *t = radeon_tex_obj(texObj); 483 radeon_texture_image* image = get_radeon_texture_image(texImage); 484 485 /* Try using current miptree, or create new if there isn't any */ 486 if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage)) { 487 radeon_miptree_unreference(&t->mt); 488 t->mt = radeon_miptree_create_for_teximage(rmesa, 489 texObj, 490 texImage); 491 492 radeon_print(RADEON_TEXTURE, RADEON_NORMAL, 493 "%s: texObj %p, texImage %p, " 494 "texObj miptree doesn't match, allocated new miptree %p\n", 495 __FUNCTION__, texObj, texImage, t->mt); 496 } 497 498 /* Miptree alocation may have failed, 499 * when there was no image for baselevel specified */ 500 if (t->mt) { 501 radeon_miptree_reference(t->mt, &image->mt); 502 } else 503 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, 504 "%s Failed to allocate miptree.\n", __func__); 505} 506 507unsigned radeonIsFormatRenderable(gl_format mesa_format) 508{ 509 if (mesa_format == _radeon_texformat_argb8888 || mesa_format == _radeon_texformat_rgb565 || 510 mesa_format == _radeon_texformat_argb1555 || mesa_format == _radeon_texformat_argb4444) 511 return 1; 512 513 switch (mesa_format) 514 { 515 case MESA_FORMAT_Z16: 516 case MESA_FORMAT_S8_Z24: 517 return 1; 518 default: 519 return 0; 520 } 521} 522 523void radeon_image_target_texture_2d(struct gl_context *ctx, GLenum target, 524 struct gl_texture_object *texObj, 525 struct gl_texture_image *texImage, 526 GLeglImageOES image_handle) 527{ 528 radeonContextPtr radeon = RADEON_CONTEXT(ctx); 529 radeonTexObj *t = radeon_tex_obj(texObj); 530 radeon_texture_image *radeonImage = get_radeon_texture_image(texImage); 531 __DRIscreen *screen; 532 __DRIimage *image; 533 534 screen = radeon->dri.screen; 535 image = screen->dri2.image->lookupEGLImage(screen, image_handle, 536 screen->loaderPrivate); 537 if (image == NULL) 538 return; 539 540 radeonFreeTextureImageBuffer(ctx, texImage); 541 542 texImage->Width = image->width; 543 texImage->Height = image->height; 544 texImage->Depth = 1; 545 texImage->_BaseFormat = GL_RGBA; 546 texImage->TexFormat = image->format; 547 radeonImage->base.RowStride = image->pitch; 548 texImage->InternalFormat = image->internal_format; 549 550 if(t->mt) 551 { 552 radeon_miptree_unreference(&t->mt); 553 t->mt = NULL; 554 } 555 556 /* NOTE: The following is *very* ugly and will probably break. But 557 I don't know how to deal with it, without creating a whole new 558 function like radeon_miptree_from_bo() so I'm going with the 559 easy but error-prone way. */ 560 561 radeon_try_alloc_miptree(radeon, t); 562 563 radeon_miptree_reference(t->mt, &radeonImage->mt); 564 565 if (t->mt == NULL) 566 { 567 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, 568 "%s Failed to allocate miptree.\n", __func__); 569 return; 570 } 571 572 /* Particularly ugly: this is guaranteed to break, if image->bo is 573 not of the required size for a miptree. */ 574 radeon_bo_unref(t->mt->bo); 575 radeon_bo_ref(image->bo); 576 t->mt->bo = image->bo; 577 578 if (!radeon_miptree_matches_image(t->mt, &radeonImage->base.Base)) 579 fprintf(stderr, "miptree doesn't match image\n"); 580} 581 582gl_format _radeon_texformat_rgba8888 = MESA_FORMAT_NONE; 583gl_format _radeon_texformat_argb8888 = MESA_FORMAT_NONE; 584gl_format _radeon_texformat_rgb565 = MESA_FORMAT_NONE; 585gl_format _radeon_texformat_argb4444 = MESA_FORMAT_NONE; 586gl_format _radeon_texformat_argb1555 = MESA_FORMAT_NONE; 587gl_format _radeon_texformat_al88 = MESA_FORMAT_NONE; 588/*@}*/ 589 590 591static void 592radeonInitTextureFormats(void) 593{ 594 if (_mesa_little_endian()) { 595 _radeon_texformat_rgba8888 = MESA_FORMAT_RGBA8888; 596 _radeon_texformat_argb8888 = MESA_FORMAT_ARGB8888; 597 _radeon_texformat_rgb565 = MESA_FORMAT_RGB565; 598 _radeon_texformat_argb4444 = MESA_FORMAT_ARGB4444; 599 _radeon_texformat_argb1555 = MESA_FORMAT_ARGB1555; 600 _radeon_texformat_al88 = MESA_FORMAT_AL88; 601 } 602 else { 603 _radeon_texformat_rgba8888 = MESA_FORMAT_RGBA8888_REV; 604 _radeon_texformat_argb8888 = MESA_FORMAT_ARGB8888_REV; 605 _radeon_texformat_rgb565 = MESA_FORMAT_RGB565_REV; 606 _radeon_texformat_argb4444 = MESA_FORMAT_ARGB4444_REV; 607 _radeon_texformat_argb1555 = MESA_FORMAT_ARGB1555_REV; 608 _radeon_texformat_al88 = MESA_FORMAT_AL88_REV; 609 } 610} 611 612void 613radeon_init_common_texture_funcs(radeonContextPtr radeon, 614 struct dd_function_table *functions) 615{ 616 functions->NewTextureImage = radeonNewTextureImage; 617 functions->DeleteTextureImage = radeonDeleteTextureImage; 618 functions->AllocTextureImageBuffer = radeonAllocTextureImageBuffer; 619 functions->FreeTextureImageBuffer = radeonFreeTextureImageBuffer; 620 functions->MapTextureImage = radeon_map_texture_image; 621 functions->UnmapTextureImage = radeon_unmap_texture_image; 622 623 functions->ChooseTextureFormat = radeonChooseTextureFormat_mesa; 624 625 functions->CopyTexSubImage = radeonCopyTexSubImage; 626 627 functions->Bitmap = _mesa_meta_Bitmap; 628 functions->EGLImageTargetTexture2D = radeon_image_target_texture_2d; 629 630 radeonInitTextureFormats(); 631} 632 633static void 634radeon_swrast_map_image(radeonContextPtr rmesa, 635 radeon_texture_image *image) 636{ 637 GLuint level, face; 638 radeon_mipmap_tree *mt; 639 GLuint texel_size; 640 radeon_mipmap_level *lvl; 641 int rs; 642 643 if (!image || !image->mt) 644 return; 645 646 texel_size = _mesa_get_format_bytes(image->base.Base.TexFormat); 647 level = image->base.Base.Level; 648 face = image->base.Base.Face; 649 mt = image->mt; 650 651 lvl = &image->mt->levels[level]; 652 653 rs = lvl->rowstride / texel_size; 654 655 radeon_bo_map(mt->bo, 1); 656 657 image->base.Map = mt->bo->ptr + lvl->faces[face].offset; 658 if (mt->target == GL_TEXTURE_3D) { 659 int i; 660 661 for (i = 0; i < mt->levels[level].depth; i++) 662 image->base.ImageOffsets[i] = rs * lvl->height * i; 663 } 664 image->base.RowStride = rs; 665} 666 667static void 668radeon_swrast_unmap_image(radeonContextPtr rmesa, 669 radeon_texture_image *image) 670{ 671 if (image && image->mt) { 672 image->base.Map = NULL; 673 radeon_bo_unmap(image->mt->bo); 674 } 675} 676 677void 678radeon_swrast_map_texture_images(struct gl_context *ctx, 679 struct gl_texture_object *texObj) 680{ 681 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 682 GLuint nr_faces = _mesa_num_tex_faces(texObj->Target); 683 int i, face; 684 685 for (i = texObj->BaseLevel; i <= texObj->_MaxLevel; i++) { 686 for (face = 0; face < nr_faces; face++) { 687 radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][i]); 688 radeon_swrast_map_image(rmesa, image); 689 } 690 } 691} 692 693void 694radeon_swrast_unmap_texture_images(struct gl_context *ctx, 695 struct gl_texture_object *texObj) 696{ 697 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 698 GLuint nr_faces = _mesa_num_tex_faces(texObj->Target); 699 int i, face; 700 701 for (i = texObj->BaseLevel; i <= texObj->_MaxLevel; i++) { 702 for (face = 0; face < nr_faces; face++) { 703 radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][i]); 704 radeon_swrast_unmap_image(rmesa, image); 705 } 706 } 707 708} 709 710static radeon_mipmap_tree *radeon_miptree_create_for_teximage(radeonContextPtr rmesa, 711 struct gl_texture_object *texObj, 712 struct gl_texture_image *texImage) 713{ 714 radeonTexObj *t = radeon_tex_obj(texObj); 715 GLuint firstLevel; 716 GLuint lastLevel; 717 int width, height, depth; 718 int i; 719 720 width = texImage->Width; 721 height = texImage->Height; 722 depth = texImage->Depth; 723 724 if (texImage->Level > texObj->BaseLevel && 725 (width == 1 || 726 (texObj->Target != GL_TEXTURE_1D && height == 1) || 727 (texObj->Target == GL_TEXTURE_3D && depth == 1))) { 728 /* For this combination, we're at some lower mipmap level and 729 * some important dimension is 1. We can't extrapolate up to a 730 * likely base level width/height/depth for a full mipmap stack 731 * from this info, so just allocate this one level. 732 */ 733 firstLevel = texImage->Level; 734 lastLevel = texImage->Level; 735 } else { 736 if (texImage->Level < texObj->BaseLevel) 737 firstLevel = 0; 738 else 739 firstLevel = texObj->BaseLevel; 740 741 for (i = texImage->Level; i > firstLevel; i--) { 742 width <<= 1; 743 if (height != 1) 744 height <<= 1; 745 if (depth != 1) 746 depth <<= 1; 747 } 748 if ((texObj->Sampler.MinFilter == GL_NEAREST || 749 texObj->Sampler.MinFilter == GL_LINEAR) && 750 texImage->Level == firstLevel) { 751 lastLevel = firstLevel; 752 } else { 753 lastLevel = firstLevel + _mesa_logbase2(MAX2(MAX2(width, height), depth)); 754 } 755 } 756 757 return radeon_miptree_create(rmesa, texObj->Target, 758 texImage->TexFormat, firstLevel, lastLevel - firstLevel + 1, 759 width, height, depth, 760 t->tile_bits); 761} 762