radeon_texture.c revision a34c28f1aa0e7c0f66bc45f18750eb7f7ca8d5cd
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 51 52void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, 53 GLuint numrows, GLuint rowsize) 54{ 55 assert(rowsize <= dststride); 56 assert(rowsize <= srcstride); 57 58 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 59 "%s dst %p, stride %u, src %p, stride %u, " 60 "numrows %u, rowsize %u.\n", 61 __func__, dst, dststride, 62 src, srcstride, 63 numrows, rowsize); 64 65 if (rowsize == srcstride && rowsize == dststride) { 66 memcpy(dst, src, numrows*rowsize); 67 } else { 68 GLuint i; 69 for(i = 0; i < numrows; ++i) { 70 memcpy(dst, src, rowsize); 71 dst += dststride; 72 src += srcstride; 73 } 74 } 75} 76 77/* textures */ 78/** 79 * Allocate an empty texture image object. 80 */ 81struct gl_texture_image *radeonNewTextureImage(struct gl_context *ctx) 82{ 83 return CALLOC(sizeof(radeon_texture_image)); 84} 85 86 87/** 88 * Delete a texture image object. 89 */ 90static void 91radeonDeleteTextureImage(struct gl_context *ctx, struct gl_texture_image *img) 92{ 93 /* nothing special (yet) for radeon_texture_image */ 94 _mesa_delete_texture_image(ctx, img); 95} 96 97 98/** 99 * Free memory associated with this texture image. 100 */ 101void radeonFreeTextureImageBuffer(struct gl_context *ctx, struct gl_texture_image *timage) 102{ 103 radeon_texture_image* image = get_radeon_texture_image(timage); 104 105 if (image->mt) { 106 radeon_miptree_unreference(&image->mt); 107 assert(!image->base.Buffer); 108 } else { 109 _swrast_free_texture_image_buffer(ctx, timage); 110 } 111 if (image->bo) { 112 radeon_bo_unref(image->bo); 113 image->bo = NULL; 114 } 115 if (image->base.Buffer) { 116 _mesa_align_free(image->base.Buffer); 117 image->base.Buffer = NULL; 118 } 119 120 if (image->base.ImageOffsets) { 121 free(image->base.ImageOffsets); 122 image->base.ImageOffsets = NULL; 123 } 124} 125 126/* Set Data pointer and additional data for mapped texture image */ 127static void teximage_set_map_data(radeon_texture_image *image) 128{ 129 radeon_mipmap_level *lvl; 130 131 if (!image->mt) { 132 radeon_warning("%s(%p) Trying to set map data without miptree.\n", 133 __func__, image); 134 135 return; 136 } 137 138 lvl = &image->mt->levels[image->mtlevel]; 139 140 image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset; 141 image->base.RowStride = lvl->rowstride / _mesa_get_format_bytes(image->base.Base.TexFormat); 142} 143 144 145/** 146 * Map a single texture image for glTexImage and friends. 147 */ 148void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable) 149{ 150 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, 151 "%s(img %p), write_enable %s.\n", 152 __func__, image, 153 write_enable ? "true": "false"); 154 if (image->mt) { 155 assert(!image->base.Data); 156 157 radeon_bo_map(image->mt->bo, write_enable); 158 teximage_set_map_data(image); 159 } 160} 161 162 163void radeon_teximage_unmap(radeon_texture_image *image) 164{ 165 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, 166 "%s(img %p)\n", 167 __func__, image); 168 if (image->mt) { 169 assert(image->base.Data); 170 171 image->base.Data = 0; 172 radeon_bo_unmap(image->mt->bo); 173 } 174} 175 176static void map_override(struct gl_context *ctx, radeonTexObj *t) 177{ 178 radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]); 179 180 radeon_bo_map(t->bo, GL_FALSE); 181 182 img->base.Data = t->bo->ptr; 183} 184 185static void unmap_override(struct gl_context *ctx, radeonTexObj *t) 186{ 187 radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]); 188 189 radeon_bo_unmap(t->bo); 190 191 img->base.Data = NULL; 192} 193 194/** 195 * Map a validated texture for reading during software rendering. 196 */ 197void radeonMapTexture(struct gl_context *ctx, struct gl_texture_object *texObj) 198{ 199 radeonTexObj* t = radeon_tex_obj(texObj); 200 int face, level; 201 202 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, 203 "%s(%p, tex %p)\n", 204 __func__, ctx, texObj); 205 206 if (!radeon_validate_texture_miptree(ctx, texObj)) { 207 radeon_error("%s(%p, tex %p) Failed to validate miptree for " 208 "sw fallback.\n", 209 __func__, ctx, texObj); 210 return; 211 } 212 213 if (t->image_override && t->bo) { 214 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, 215 "%s(%p, tex %p) Work around for missing miptree in r100.\n", 216 __func__, ctx, texObj); 217 218 map_override(ctx, t); 219 } 220 221 /* for r100 3D sw fallbacks don't have mt */ 222 if (!t->mt) { 223 radeon_warning("%s(%p, tex %p) No miptree in texture.\n", 224 __func__, ctx, texObj); 225 return; 226 } 227 228 radeon_bo_map(t->mt->bo, GL_FALSE); 229 for(face = 0; face < t->mt->faces; ++face) { 230 for(level = t->minLod; level <= t->maxLod; ++level) 231 teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level])); 232 } 233} 234 235void radeonUnmapTexture(struct gl_context *ctx, struct gl_texture_object *texObj) 236{ 237 radeonTexObj* t = radeon_tex_obj(texObj); 238 int face, level; 239 240 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, 241 "%s(%p, tex %p)\n", 242 __func__, ctx, texObj); 243 244 if (t->image_override && t->bo) 245 unmap_override(ctx, t); 246 /* for r100 3D sw fallbacks don't have mt */ 247 if (!t->mt) 248 return; 249 250 for(face = 0; face < t->mt->faces; ++face) { 251 for(level = t->minLod; level <= t->maxLod; ++level) { 252 radeon_texture_image *image = 253 get_radeon_texture_image(texObj->Image[face][level]); 254 image->base.Data = NULL; 255 } 256 } 257 radeon_bo_unmap(t->mt->bo); 258} 259 260 261/** 262 * Map texture memory/buffer into user space. 263 * Note: the region of interest parameters are ignored here. 264 * \param mapOut returns start of mapping of region of interest 265 * \param rowStrideOut returns row stride in bytes 266 */ 267static void 268radeon_map_texture_image(struct gl_context *ctx, 269 struct gl_texture_image *texImage, 270 GLuint slice, 271 GLuint x, GLuint y, GLuint w, GLuint h, 272 GLbitfield mode, 273 GLubyte **map, 274 GLint *stride) 275{ 276 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 277 radeon_texture_image *image = get_radeon_texture_image(texImage); 278 radeon_mipmap_tree *mt = image->mt; 279 GLuint texel_size = _mesa_get_format_bytes(texImage->TexFormat); 280 GLuint width = texImage->Width; 281 GLuint height = texImage->Height; 282 struct radeon_bo *bo = !image->mt ? image->bo : image->mt->bo; 283 unsigned int bw, bh; 284 GLboolean write = (mode & GL_MAP_WRITE_BIT) != 0; 285 286 _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh); 287 assert(y % bh == 0); 288 y /= bh; 289 height /= bh; 290 291 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { 292 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, 293 "%s for texture that is " 294 "queued for GPU processing.\n", 295 __func__); 296 radeon_firevertices(rmesa); 297 } 298 299 if (image->bo) { 300 /* TFP case */ 301 radeon_bo_map(image->bo, write); 302 *stride = get_texture_image_row_stride(rmesa, texImage->TexFormat, width, 0); 303 *map = bo->ptr; 304 } else if (likely(mt)) { 305 radeon_bo_map(mt->bo, write); 306 radeon_mipmap_level *lvl = &image->mt->levels[texImage->Level]; 307 void *base = mt->bo->ptr + lvl->faces[image->mtface].offset; 308 309 *stride = lvl->rowstride; 310 *map = base + (slice * height) * *stride; 311 } else { 312 /* texture data is in malloc'd memory */ 313 314 assert(map); 315 316 *stride = _mesa_format_row_stride(texImage->TexFormat, width); 317 *map = image->base.Buffer + (slice * height) * *stride; 318 } 319 320 *map += y * *stride + x * texel_size; 321} 322 323static void 324radeon_unmap_texture_image(struct gl_context *ctx, 325 struct gl_texture_image *texImage, GLuint slice) 326{ 327 radeon_texture_image *image = get_radeon_texture_image(texImage); 328 329 if (image->bo) 330 radeon_bo_unmap(image->bo); 331 else if (image->mt) 332 radeon_bo_unmap(image->mt->bo); 333} 334 335void radeonGenerateMipmap(struct gl_context* ctx, GLenum target, struct gl_texture_object *texObj) 336{ 337 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 338 struct radeon_bo *bo; 339 GLuint face = _mesa_tex_target_to_face(target); 340 radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]); 341 bo = !baseimage->mt ? baseimage->bo : baseimage->mt->bo; 342 343 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 344 "%s(%p, target %s, tex %p)\n", 345 __func__, ctx, _mesa_lookup_enum_by_nr(target), 346 texObj); 347 348 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { 349 radeon_print(RADEON_TEXTURE, RADEON_NORMAL, 350 "%s(%p, tex %p) Trying to generate mipmap for texture " 351 "in processing by GPU.\n", 352 __func__, ctx, texObj); 353 radeon_firevertices(rmesa); 354 } 355 356 if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) { 357 _mesa_generate_mipmap(ctx, target, texObj); 358 } else { 359 _mesa_meta_GenerateMipmap(ctx, target, texObj); 360 } 361} 362 363 364/* try to find a format which will only need a memcopy */ 365static gl_format radeonChoose8888TexFormat(radeonContextPtr rmesa, 366 GLenum srcFormat, 367 GLenum srcType, GLboolean fbo) 368{ 369 const GLuint ui = 1; 370 const GLubyte littleEndian = *((const GLubyte *)&ui); 371 372 /* r100 can only do this */ 373 if (IS_R100_CLASS(rmesa->radeonScreen) || fbo) 374 return _dri_texformat_argb8888; 375 376 if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) || 377 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) || 378 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || 379 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) { 380 return MESA_FORMAT_RGBA8888; 381 } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || 382 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) || 383 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) || 384 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) { 385 return MESA_FORMAT_RGBA8888_REV; 386 } else if (IS_R200_CLASS(rmesa->radeonScreen)) { 387 return _dri_texformat_argb8888; 388 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) || 389 srcType == GL_UNSIGNED_INT_8_8_8_8)) { 390 return MESA_FORMAT_ARGB8888_REV; 391 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) || 392 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) { 393 return MESA_FORMAT_ARGB8888; 394 } else 395 return _dri_texformat_argb8888; 396} 397 398gl_format radeonChooseTextureFormat_mesa(struct gl_context * ctx, 399 GLint internalFormat, 400 GLenum format, 401 GLenum type) 402{ 403 return radeonChooseTextureFormat(ctx, internalFormat, format, 404 type, 0); 405} 406 407gl_format radeonChooseTextureFormat(struct gl_context * ctx, 408 GLint internalFormat, 409 GLenum format, 410 GLenum type, GLboolean fbo) 411{ 412 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 413 const GLboolean do32bpt = 414 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32); 415 const GLboolean force16bpt = 416 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16); 417 (void)format; 418 419 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 420 "%s InternalFormat=%s(%d) type=%s format=%s\n", 421 __func__, 422 _mesa_lookup_enum_by_nr(internalFormat), internalFormat, 423 _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format)); 424 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 425 "%s do32bpt=%d force16bpt=%d\n", 426 __func__, do32bpt, force16bpt); 427 428 switch (internalFormat) { 429 case 4: 430 case GL_RGBA: 431 case GL_COMPRESSED_RGBA: 432 switch (type) { 433 case GL_UNSIGNED_INT_10_10_10_2: 434 case GL_UNSIGNED_INT_2_10_10_10_REV: 435 return do32bpt ? _dri_texformat_argb8888 : 436 _dri_texformat_argb1555; 437 case GL_UNSIGNED_SHORT_4_4_4_4: 438 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 439 return _dri_texformat_argb4444; 440 case GL_UNSIGNED_SHORT_5_5_5_1: 441 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 442 return _dri_texformat_argb1555; 443 default: 444 return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type, fbo) : 445 _dri_texformat_argb4444; 446 } 447 448 case 3: 449 case GL_RGB: 450 case GL_COMPRESSED_RGB: 451 switch (type) { 452 case GL_UNSIGNED_SHORT_4_4_4_4: 453 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 454 return _dri_texformat_argb4444; 455 case GL_UNSIGNED_SHORT_5_5_5_1: 456 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 457 return _dri_texformat_argb1555; 458 case GL_UNSIGNED_SHORT_5_6_5: 459 case GL_UNSIGNED_SHORT_5_6_5_REV: 460 return _dri_texformat_rgb565; 461 default: 462 return do32bpt ? _dri_texformat_argb8888 : 463 _dri_texformat_rgb565; 464 } 465 466 case GL_RGBA8: 467 case GL_RGB10_A2: 468 case GL_RGBA12: 469 case GL_RGBA16: 470 return !force16bpt ? 471 radeonChoose8888TexFormat(rmesa, format, type, fbo) : 472 _dri_texformat_argb4444; 473 474 case GL_RGBA4: 475 case GL_RGBA2: 476 return _dri_texformat_argb4444; 477 478 case GL_RGB5_A1: 479 return _dri_texformat_argb1555; 480 481 case GL_RGB8: 482 case GL_RGB10: 483 case GL_RGB12: 484 case GL_RGB16: 485 return !force16bpt ? _dri_texformat_argb8888 : 486 _dri_texformat_rgb565; 487 488 case GL_RGB5: 489 case GL_RGB4: 490 case GL_R3_G3_B2: 491 return _dri_texformat_rgb565; 492 493 case GL_ALPHA: 494 case GL_ALPHA4: 495 case GL_ALPHA8: 496 case GL_ALPHA12: 497 case GL_ALPHA16: 498 case GL_COMPRESSED_ALPHA: 499 /* r200: can't use a8 format since interpreting hw I8 as a8 would result 500 in wrong rgb values (same as alpha value instead of 0). */ 501 if (IS_R200_CLASS(rmesa->radeonScreen)) 502 return _dri_texformat_al88; 503 else 504 return MESA_FORMAT_A8; 505 case 1: 506 case GL_LUMINANCE: 507 case GL_LUMINANCE4: 508 case GL_LUMINANCE8: 509 case GL_LUMINANCE12: 510 case GL_LUMINANCE16: 511 case GL_COMPRESSED_LUMINANCE: 512 return MESA_FORMAT_L8; 513 514 case 2: 515 case GL_LUMINANCE_ALPHA: 516 case GL_LUMINANCE4_ALPHA4: 517 case GL_LUMINANCE6_ALPHA2: 518 case GL_LUMINANCE8_ALPHA8: 519 case GL_LUMINANCE12_ALPHA4: 520 case GL_LUMINANCE12_ALPHA12: 521 case GL_LUMINANCE16_ALPHA16: 522 case GL_COMPRESSED_LUMINANCE_ALPHA: 523 return _dri_texformat_al88; 524 525 case GL_INTENSITY: 526 case GL_INTENSITY4: 527 case GL_INTENSITY8: 528 case GL_INTENSITY12: 529 case GL_INTENSITY16: 530 case GL_COMPRESSED_INTENSITY: 531 return MESA_FORMAT_I8; 532 533 case GL_YCBCR_MESA: 534 if (type == GL_UNSIGNED_SHORT_8_8_APPLE || 535 type == GL_UNSIGNED_BYTE) 536 return MESA_FORMAT_YCBCR; 537 else 538 return MESA_FORMAT_YCBCR_REV; 539 540 case GL_RGB_S3TC: 541 case GL_RGB4_S3TC: 542 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 543 return MESA_FORMAT_RGB_DXT1; 544 545 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 546 return MESA_FORMAT_RGBA_DXT1; 547 548 case GL_RGBA_S3TC: 549 case GL_RGBA4_S3TC: 550 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 551 return MESA_FORMAT_RGBA_DXT3; 552 553 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: 554 return MESA_FORMAT_RGBA_DXT5; 555 556 case GL_ALPHA16F_ARB: 557 return MESA_FORMAT_ALPHA_FLOAT16; 558 case GL_ALPHA32F_ARB: 559 return MESA_FORMAT_ALPHA_FLOAT32; 560 case GL_LUMINANCE16F_ARB: 561 return MESA_FORMAT_LUMINANCE_FLOAT16; 562 case GL_LUMINANCE32F_ARB: 563 return MESA_FORMAT_LUMINANCE_FLOAT32; 564 case GL_LUMINANCE_ALPHA16F_ARB: 565 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16; 566 case GL_LUMINANCE_ALPHA32F_ARB: 567 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32; 568 case GL_INTENSITY16F_ARB: 569 return MESA_FORMAT_INTENSITY_FLOAT16; 570 case GL_INTENSITY32F_ARB: 571 return MESA_FORMAT_INTENSITY_FLOAT32; 572 case GL_RGB16F_ARB: 573 return MESA_FORMAT_RGBA_FLOAT16; 574 case GL_RGB32F_ARB: 575 return MESA_FORMAT_RGBA_FLOAT32; 576 case GL_RGBA16F_ARB: 577 return MESA_FORMAT_RGBA_FLOAT16; 578 case GL_RGBA32F_ARB: 579 return MESA_FORMAT_RGBA_FLOAT32; 580 581#ifdef RADEON_R300 582 case GL_DEPTH_COMPONENT: 583 case GL_DEPTH_COMPONENT16: 584 return MESA_FORMAT_Z16; 585 case GL_DEPTH_COMPONENT24: 586 case GL_DEPTH_COMPONENT32: 587 case GL_DEPTH_STENCIL_EXT: 588 case GL_DEPTH24_STENCIL8_EXT: 589 if (rmesa->radeonScreen->chip_family >= CHIP_FAMILY_RV515) 590 return MESA_FORMAT_S8_Z24; 591 else 592 return MESA_FORMAT_Z16; 593#else 594 case GL_DEPTH_COMPONENT: 595 case GL_DEPTH_COMPONENT16: 596 case GL_DEPTH_COMPONENT24: 597 case GL_DEPTH_COMPONENT32: 598 case GL_DEPTH_STENCIL_EXT: 599 case GL_DEPTH24_STENCIL8_EXT: 600 return MESA_FORMAT_S8_Z24; 601#endif 602 603 /* EXT_texture_sRGB */ 604 case GL_SRGB: 605 case GL_SRGB8: 606 case GL_SRGB_ALPHA: 607 case GL_SRGB8_ALPHA8: 608 case GL_COMPRESSED_SRGB: 609 case GL_COMPRESSED_SRGB_ALPHA: 610 return MESA_FORMAT_SARGB8; 611 612 case GL_SLUMINANCE: 613 case GL_SLUMINANCE8: 614 case GL_COMPRESSED_SLUMINANCE: 615 return MESA_FORMAT_SL8; 616 617 case GL_SLUMINANCE_ALPHA: 618 case GL_SLUMINANCE8_ALPHA8: 619 case GL_COMPRESSED_SLUMINANCE_ALPHA: 620 return MESA_FORMAT_SLA8; 621 622 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: 623 return MESA_FORMAT_SRGB_DXT1; 624 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: 625 return MESA_FORMAT_SRGBA_DXT1; 626 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: 627 return MESA_FORMAT_SRGBA_DXT3; 628 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: 629 return MESA_FORMAT_SRGBA_DXT5; 630 631 default: 632 _mesa_problem(ctx, 633 "unexpected internalFormat 0x%x in %s", 634 (int)internalFormat, __func__); 635 return MESA_FORMAT_NONE; 636 } 637 638 return MESA_FORMAT_NONE; /* never get here */ 639} 640 641/** Check if given image is valid within current texture object. 642 */ 643static int image_matches_texture_obj(struct gl_texture_object *texObj, 644 struct gl_texture_image *texImage, 645 unsigned level) 646{ 647 const struct gl_texture_image *baseImage = texObj->Image[0][texObj->BaseLevel]; 648 649 if (!baseImage) 650 return 0; 651 652 if (level < texObj->BaseLevel || level > texObj->MaxLevel) 653 return 0; 654 655 const unsigned levelDiff = level - texObj->BaseLevel; 656 const unsigned refWidth = MAX2(baseImage->Width >> levelDiff, 1); 657 const unsigned refHeight = MAX2(baseImage->Height >> levelDiff, 1); 658 const unsigned refDepth = MAX2(baseImage->Depth >> levelDiff, 1); 659 660 return (texImage->Width == refWidth && 661 texImage->Height == refHeight && 662 texImage->Depth == refDepth); 663} 664 665static void teximage_assign_miptree(radeonContextPtr rmesa, 666 struct gl_texture_object *texObj, 667 struct gl_texture_image *texImage, 668 unsigned face, 669 unsigned level) 670{ 671 radeonTexObj *t = radeon_tex_obj(texObj); 672 radeon_texture_image* image = get_radeon_texture_image(texImage); 673 674 /* Since miptree holds only images for levels <BaseLevel..MaxLevel> 675 * don't allocate the miptree if the teximage won't fit. 676 */ 677 if (!image_matches_texture_obj(texObj, texImage, level)) 678 return; 679 680 /* Try using current miptree, or create new if there isn't any */ 681 if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) { 682 radeon_miptree_unreference(&t->mt); 683 radeon_try_alloc_miptree(rmesa, t); 684 radeon_print(RADEON_TEXTURE, RADEON_NORMAL, 685 "%s: texObj %p, texImage %p, face %d, level %d, " 686 "texObj miptree doesn't match, allocated new miptree %p\n", 687 __FUNCTION__, texObj, texImage, face, level, t->mt); 688 } 689 690 /* Miptree alocation may have failed, 691 * when there was no image for baselevel specified */ 692 if (t->mt) { 693 image->mtface = face; 694 image->mtlevel = level; 695 radeon_miptree_reference(t->mt, &image->mt); 696 } else 697 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, 698 "%s Failed to allocate miptree.\n", __func__); 699} 700 701 702/** 703 * Update a subregion of the given texture image. 704 */ 705static void radeon_store_teximage(struct gl_context* ctx, int dims, 706 GLint xoffset, GLint yoffset, GLint zoffset, 707 GLsizei width, GLsizei height, GLsizei depth, 708 GLsizei imageSize, 709 GLenum format, GLenum type, 710 const GLvoid * pixels, 711 const struct gl_pixelstore_attrib *packing, 712 struct gl_texture_object *texObj, 713 struct gl_texture_image *texImage, 714 int compressed) 715{ 716 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 717 radeonTexObj *t = radeon_tex_obj(texObj); 718 radeon_texture_image* image = get_radeon_texture_image(texImage); 719 GLuint texel_size = _mesa_get_format_bytes(texImage->TexFormat); 720 721 GLuint dstRowStride; 722 GLuint alignedWidth; 723 GLint i; 724 725 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 726 "%s(%p, tex %p, image %p) compressed %d\n", 727 __func__, ctx, texObj, texImage, compressed); 728 729 if (image->mt) { 730 dstRowStride = image->mt->levels[image->mtlevel].rowstride; 731 } else if (t->bo) { 732 /* TFP case */ 733 dstRowStride = get_texture_image_row_stride(rmesa, texImage->TexFormat, width, 0); 734 } else { 735 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width); 736 } 737 738 assert(dstRowStride); 739 740 /* fill in the ImageOffsets array */ 741 alignedWidth = dstRowStride / texel_size; 742 for (i = 0; i < texImage->Depth; ++i) { 743 image->base.ImageOffsets[i] = alignedWidth * texImage->Height * i; 744 } 745 /* and fill in RowStride (in texels) */ 746 image->base.RowStride = alignedWidth; 747 748 radeon_teximage_map(image, GL_TRUE); 749 750 if (compressed) { 751 uint32_t srcRowStride, bytesPerRow, rows, block_width, block_height; 752 GLubyte *img_start; 753 754 _mesa_get_format_block_size(texImage->TexFormat, &block_width, &block_height); 755 756 if (!image->mt) { 757 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width); 758 img_start = _mesa_compressed_image_address(xoffset, yoffset, 0, 759 texImage->TexFormat, 760 texImage->Width, image->base.Data); 761 } 762 else { 763 uint32_t offset; 764 offset = dstRowStride / texel_size * yoffset / block_height + xoffset / block_width; 765 offset *= texel_size; 766 img_start = image->base.Data + offset; 767 } 768 srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width); 769 bytesPerRow = srcRowStride; 770 rows = (height + block_height - 1) / block_height; 771 772 copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow); 773 } 774 else { 775 GLubyte *slices[512]; 776 GLuint i; 777 assert(depth <= 512); 778 for (i = 0; i < depth; i++) { 779 slices[i] = (GLubyte *) image->base.Data 780 + image->base.ImageOffsets[i] * texel_size; 781 } 782 if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat, 783 texImage->TexFormat, 784 xoffset, yoffset, zoffset, 785 dstRowStride, 786 slices, 787 width, height, depth, 788 format, type, pixels, packing)) { 789 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 790 } 791 } 792 793 radeon_teximage_unmap(image); 794} 795 796/** 797 * All glTexImage calls go through this function. 798 */ 799static void radeon_teximage( 800 struct gl_context *ctx, int dims, 801 GLenum target, GLint level, 802 GLint internalFormat, 803 GLint width, GLint height, GLint depth, 804 GLsizei imageSize, 805 GLenum format, GLenum type, const GLvoid * pixels, 806 const struct gl_pixelstore_attrib *packing, 807 struct gl_texture_object *texObj, 808 struct gl_texture_image *texImage, 809 int compressed) 810{ 811 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 812 radeonTexObj* t = radeon_tex_obj(texObj); 813 radeon_texture_image* image = get_radeon_texture_image(texImage); 814 GLuint face = _mesa_tex_target_to_face(target); 815 816 radeon_print(RADEON_TEXTURE, RADEON_NORMAL, 817 "%s %dd: texObj %p, texImage %p, face %d, level %d\n", 818 __func__, dims, texObj, texImage, face, level); 819 820 t->validated = GL_FALSE; 821 822 radeonFreeTextureImageBuffer(ctx, texImage); 823 824 if (!t->bo) { 825 teximage_assign_miptree(rmesa, texObj, texImage, face, level); 826 if (!image->mt) { 827 int size = _mesa_format_image_size(texImage->TexFormat, 828 texImage->Width, 829 texImage->Height, 830 texImage->Depth); 831 image->base.Buffer = _mesa_align_malloc(size, 512); 832 833 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, 834 "%s %dd: texObj %p, texImage %p, " 835 " no miptree assigned, using local memory %p\n", 836 __func__, dims, texObj, texImage, image->base.Buffer); 837 } 838 } 839 840 { 841 struct radeon_bo *bo; 842 bo = !image->mt ? image->bo : image->mt->bo; 843 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { 844 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, 845 "%s Calling teximage for texture that is " 846 "queued for GPU processing.\n", 847 __func__); 848 radeon_firevertices(rmesa); 849 } 850 } 851 852 image->base.ImageOffsets = 853 (GLuint *) malloc(texImage->Depth * sizeof(GLuint)); 854 855 856 /* Upload texture image; note that the spec allows pixels to be NULL */ 857 if (compressed) { 858 pixels = _mesa_validate_pbo_compressed_teximage( 859 ctx, imageSize, pixels, packing, "glCompressedTexImage"); 860 } else { 861 pixels = _mesa_validate_pbo_teximage( 862 ctx, dims, width, height, depth, 863 format, type, pixels, packing, "glTexImage"); 864 } 865 866 if (pixels) { 867 radeon_store_teximage(ctx, dims, 868 0, 0, 0, 869 width, height, depth, 870 imageSize, format, type, 871 pixels, packing, 872 texObj, texImage, 873 compressed); 874 } 875 876 _mesa_unmap_teximage_pbo(ctx, packing); 877} 878 879void radeonTexImage1D(struct gl_context * ctx, GLenum target, GLint level, 880 GLint internalFormat, 881 GLint width, GLint border, 882 GLenum format, GLenum type, const GLvoid * pixels, 883 const struct gl_pixelstore_attrib *packing, 884 struct gl_texture_object *texObj, 885 struct gl_texture_image *texImage) 886{ 887 radeon_teximage(ctx, 1, target, level, internalFormat, width, 1, 1, 888 0, format, type, pixels, packing, texObj, texImage, 0); 889} 890 891void radeonTexImage2D(struct gl_context * ctx, GLenum target, GLint level, 892 GLint internalFormat, 893 GLint width, GLint height, GLint border, 894 GLenum format, GLenum type, const GLvoid * pixels, 895 const struct gl_pixelstore_attrib *packing, 896 struct gl_texture_object *texObj, 897 struct gl_texture_image *texImage) 898 899{ 900 radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1, 901 0, format, type, pixels, packing, texObj, texImage, 0); 902} 903 904void radeonCompressedTexImage2D(struct gl_context * ctx, GLenum target, 905 GLint level, GLint internalFormat, 906 GLint width, GLint height, GLint border, 907 GLsizei imageSize, const GLvoid * data, 908 struct gl_texture_object *texObj, 909 struct gl_texture_image *texImage) 910{ 911 radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1, 912 imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1); 913} 914 915void radeonTexImage3D(struct gl_context * ctx, GLenum target, GLint level, 916 GLint internalFormat, 917 GLint width, GLint height, GLint depth, 918 GLint border, 919 GLenum format, GLenum type, const GLvoid * pixels, 920 const struct gl_pixelstore_attrib *packing, 921 struct gl_texture_object *texObj, 922 struct gl_texture_image *texImage) 923{ 924 radeon_teximage(ctx, 3, target, level, internalFormat, width, height, depth, 925 0, format, type, pixels, packing, texObj, texImage, 0); 926} 927 928/** 929 * All glTexSubImage calls go through this function. 930 */ 931static void radeon_texsubimage(struct gl_context* ctx, int dims, GLenum target, int level, 932 GLint xoffset, GLint yoffset, GLint zoffset, 933 GLsizei width, GLsizei height, GLsizei depth, 934 GLsizei imageSize, 935 GLenum format, GLenum type, 936 const GLvoid * pixels, 937 const struct gl_pixelstore_attrib *packing, 938 struct gl_texture_object *texObj, 939 struct gl_texture_image *texImage, 940 int compressed) 941{ 942 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 943 radeonTexObj* t = radeon_tex_obj(texObj); 944 radeon_texture_image* image = get_radeon_texture_image(texImage); 945 946 radeon_print(RADEON_TEXTURE, RADEON_NORMAL, 947 "%s %dd: texObj %p, texImage %p, face %d, level %d\n", 948 __func__, dims, texObj, texImage, 949 _mesa_tex_target_to_face(target), level); 950 { 951 struct radeon_bo *bo; 952 bo = !image->mt ? image->bo : image->mt->bo; 953 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { 954 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, 955 "%s Calling texsubimage for texture that is " 956 "queued for GPU processing.\n", 957 __func__); 958 radeon_firevertices(rmesa); 959 } 960 } 961 962 963 t->validated = GL_FALSE; 964 if (compressed) { 965 pixels = _mesa_validate_pbo_compressed_teximage( 966 ctx, imageSize, pixels, packing, "glCompressedTexSubImage"); 967 } else { 968 pixels = _mesa_validate_pbo_teximage(ctx, dims, 969 width, height, depth, format, type, pixels, packing, "glTexSubImage"); 970 } 971 972 if (pixels) { 973 radeon_store_teximage(ctx, dims, 974 xoffset, yoffset, zoffset, 975 width, height, depth, 976 imageSize, format, type, 977 pixels, packing, 978 texObj, texImage, 979 compressed); 980 } 981 982 _mesa_unmap_teximage_pbo(ctx, packing); 983} 984 985void radeonTexSubImage1D(struct gl_context * ctx, GLenum target, GLint level, 986 GLint xoffset, 987 GLsizei width, 988 GLenum format, GLenum type, 989 const GLvoid * pixels, 990 const struct gl_pixelstore_attrib *packing, 991 struct gl_texture_object *texObj, 992 struct gl_texture_image *texImage) 993{ 994 radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0, 995 format, type, pixels, packing, texObj, texImage, 0); 996} 997 998void radeonTexSubImage2D(struct gl_context * ctx, GLenum target, GLint level, 999 GLint xoffset, GLint yoffset, 1000 GLsizei width, GLsizei height, 1001 GLenum format, GLenum type, 1002 const GLvoid * pixels, 1003 const struct gl_pixelstore_attrib *packing, 1004 struct gl_texture_object *texObj, 1005 struct gl_texture_image *texImage) 1006{ 1007 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1, 1008 0, format, type, pixels, packing, texObj, texImage, 1009 0); 1010} 1011 1012void radeonCompressedTexSubImage2D(struct gl_context * ctx, GLenum target, 1013 GLint level, GLint xoffset, 1014 GLint yoffset, GLsizei width, 1015 GLsizei height, GLenum format, 1016 GLsizei imageSize, const GLvoid * data, 1017 struct gl_texture_object *texObj, 1018 struct gl_texture_image *texImage) 1019{ 1020 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1, 1021 imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1); 1022} 1023 1024 1025void radeonTexSubImage3D(struct gl_context * ctx, GLenum target, GLint level, 1026 GLint xoffset, GLint yoffset, GLint zoffset, 1027 GLsizei width, GLsizei height, GLsizei depth, 1028 GLenum format, GLenum type, 1029 const GLvoid * pixels, 1030 const struct gl_pixelstore_attrib *packing, 1031 struct gl_texture_object *texObj, 1032 struct gl_texture_image *texImage) 1033{ 1034 radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0, 1035 format, type, pixels, packing, texObj, texImage, 0); 1036} 1037 1038unsigned radeonIsFormatRenderable(gl_format mesa_format) 1039{ 1040 if (mesa_format == _dri_texformat_argb8888 || mesa_format == _dri_texformat_rgb565 || 1041 mesa_format == _dri_texformat_argb1555 || mesa_format == _dri_texformat_argb4444) 1042 return 1; 1043 1044 switch (mesa_format) 1045 { 1046 case MESA_FORMAT_Z16: 1047 case MESA_FORMAT_S8_Z24: 1048 return 1; 1049 default: 1050 return 0; 1051 } 1052} 1053 1054#if FEATURE_OES_EGL_image 1055void radeon_image_target_texture_2d(struct gl_context *ctx, GLenum target, 1056 struct gl_texture_object *texObj, 1057 struct gl_texture_image *texImage, 1058 GLeglImageOES image_handle) 1059{ 1060 radeonContextPtr radeon = RADEON_CONTEXT(ctx); 1061 radeonTexObj *t = radeon_tex_obj(texObj); 1062 radeon_texture_image *radeonImage = get_radeon_texture_image(texImage); 1063 __DRIscreen *screen; 1064 __DRIimage *image; 1065 1066 screen = radeon->dri.screen; 1067 image = screen->dri2.image->lookupEGLImage(screen, image_handle, 1068 screen->loaderPrivate); 1069 if (image == NULL) 1070 return; 1071 1072 radeonFreeTextureImageBuffer(ctx, texImage); 1073 1074 texImage->Width = image->width; 1075 texImage->Height = image->height; 1076 texImage->Depth = 1; 1077 texImage->_BaseFormat = GL_RGBA; 1078 texImage->TexFormat = image->format; 1079 radeonImage->base.RowStride = image->pitch; 1080 texImage->InternalFormat = image->internal_format; 1081 1082 if(t->mt) 1083 { 1084 radeon_miptree_unreference(&t->mt); 1085 t->mt = NULL; 1086 } 1087 1088 /* NOTE: The following is *very* ugly and will probably break. But 1089 I don't know how to deal with it, without creating a whole new 1090 function like radeon_miptree_from_bo() so I'm going with the 1091 easy but error-prone way. */ 1092 1093 radeon_try_alloc_miptree(radeon, t); 1094 1095 radeonImage->mtface = _mesa_tex_target_to_face(target); 1096 radeonImage->mtlevel = 0; 1097 radeon_miptree_reference(t->mt, &radeonImage->mt); 1098 1099 if (t->mt == NULL) 1100 { 1101 radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, 1102 "%s Failed to allocate miptree.\n", __func__); 1103 return; 1104 } 1105 1106 /* Particularly ugly: this is guaranteed to break, if image->bo is 1107 not of the required size for a miptree. */ 1108 radeon_bo_unref(t->mt->bo); 1109 radeon_bo_ref(image->bo); 1110 t->mt->bo = image->bo; 1111 1112 if (!radeon_miptree_matches_image(t->mt, &radeonImage->base.Base, 1113 radeonImage->mtface, 0)) 1114 fprintf(stderr, "miptree doesn't match image\n"); 1115} 1116#endif 1117 1118void 1119radeon_init_common_texture_funcs(radeonContextPtr radeon, 1120 struct dd_function_table *functions) 1121{ 1122 functions->NewTextureImage = radeonNewTextureImage; 1123 functions->DeleteTextureImage = radeonDeleteTextureImage; 1124 functions->FreeTextureImageBuffer = radeonFreeTextureImageBuffer; 1125 functions->MapTexture = radeonMapTexture; 1126 functions->UnmapTexture = radeonUnmapTexture; 1127 functions->MapTextureImage = radeon_map_texture_image; 1128 functions->UnmapTextureImage = radeon_unmap_texture_image; 1129 1130 functions->ChooseTextureFormat = radeonChooseTextureFormat_mesa; 1131 1132 functions->TexImage1D = radeonTexImage1D; 1133 functions->TexImage2D = radeonTexImage2D; 1134 functions->TexImage3D = radeonTexImage3D; 1135 functions->TexSubImage1D = radeonTexSubImage1D; 1136 functions->TexSubImage2D = radeonTexSubImage2D; 1137 functions->TexSubImage3D = radeonTexSubImage3D; 1138 functions->CompressedTexImage2D = radeonCompressedTexImage2D; 1139 functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D; 1140 1141 functions->GenerateMipmap = radeonGenerateMipmap; 1142 1143 if (radeon->radeonScreen->kernel_mm) { 1144 functions->CopyTexSubImage2D = radeonCopyTexSubImage2D; 1145 } 1146 1147#if FEATURE_OES_EGL_image 1148 functions->EGLImageTargetTexture2D = radeon_image_target_texture_2d; 1149#endif 1150 1151 driInitTextureFormats(); 1152} 1153