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