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