radeon_texture.c revision 23d3559bd4ece1fcab5513ebdaa38600d6654374
1/* 2 * Copyright (C) 2008 Nicolai Haehnle. 3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. 4 * 5 * The Weather Channel (TM) funded Tungsten Graphics to develop the 6 * initial release of the Radeon 8500 driver under the XFree86 license. 7 * This notice must be preserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining 10 * a copy of this software and associated documentation files (the 11 * "Software"), to deal in the Software without restriction, including 12 * without limitation the rights to use, copy, modify, merge, publish, 13 * distribute, sublicense, and/or sell copies of the Software, and to 14 * permit persons to whom the Software is furnished to do so, subject to 15 * the following conditions: 16 * 17 * The above copyright notice and this permission notice (including the 18 * next paragraph) shall be included in all copies or substantial 19 * portions of the Software. 20 * 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 24 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 25 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 * 29 */ 30 31#include "main/glheader.h" 32#include "main/imports.h" 33#include "main/context.h" 34#include "main/mipmap.h" 35#include "main/texformat.h" 36#include "main/texstore.h" 37#include "main/teximage.h" 38#include "main/texobj.h" 39 40#include "xmlpool.h" /* for symbolic values of enum-type options */ 41 42#include "radeon_common.h" 43 44#include "radeon_mipmap_tree.h" 45 46/* textures */ 47/** 48 * Allocate an empty texture image object. 49 */ 50struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx) 51{ 52 return CALLOC(sizeof(radeon_texture_image)); 53} 54 55/** 56 * Free memory associated with this texture image. 57 */ 58void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage) 59{ 60 radeon_texture_image* image = get_radeon_texture_image(timage); 61 62 if (image->mt) { 63 radeon_miptree_unreference(image->mt); 64 image->mt = 0; 65 assert(!image->base.Data); 66 } else { 67 _mesa_free_texture_image_data(ctx, timage); 68 } 69 if (image->bo) { 70 radeon_bo_unref(image->bo); 71 image->bo = NULL; 72 } 73 if (timage->Data) { 74 _mesa_free_texmemory(timage->Data); 75 timage->Data = NULL; 76 } 77} 78 79/* Set Data pointer and additional data for mapped texture image */ 80static void teximage_set_map_data(radeon_texture_image *image) 81{ 82 radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; 83 84 image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset; 85 image->base.RowStride = lvl->rowstride / image->mt->bpp; 86} 87 88 89/** 90 * Map a single texture image for glTexImage and friends. 91 */ 92void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable) 93{ 94 if (image->mt) { 95 assert(!image->base.Data); 96 97 radeon_bo_map(image->mt->bo, write_enable); 98 teximage_set_map_data(image); 99 } 100} 101 102 103void radeon_teximage_unmap(radeon_texture_image *image) 104{ 105 if (image->mt) { 106 assert(image->base.Data); 107 108 image->base.Data = 0; 109 radeon_bo_unmap(image->mt->bo); 110 } 111} 112 113/** 114 * Map a validated texture for reading during software rendering. 115 */ 116void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj) 117{ 118 radeonTexObj* t = radeon_tex_obj(texObj); 119 int face, level; 120 121 /* for r100 3D sw fallbacks don't have mt */ 122 if (!t->mt) 123 return; 124 125 radeon_bo_map(t->mt->bo, GL_FALSE); 126 for(face = 0; face < t->mt->faces; ++face) { 127 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) 128 teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level])); 129 } 130} 131 132void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj) 133{ 134 radeonTexObj* t = radeon_tex_obj(texObj); 135 int face, level; 136 137 /* for r100 3D sw fallbacks don't have mt */ 138 if (!t->mt) 139 return; 140 141 for(face = 0; face < t->mt->faces; ++face) { 142 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) 143 texObj->Image[face][level]->Data = 0; 144 } 145 radeon_bo_unmap(t->mt->bo); 146} 147 148GLuint radeon_face_for_target(GLenum target) 149{ 150 switch (target) { 151 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 152 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 153 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 154 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 155 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 156 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 157 return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; 158 default: 159 return 0; 160 } 161} 162 163/** 164 * Wraps Mesa's implementation to ensure that the base level image is mapped. 165 * 166 * This relies on internal details of _mesa_generate_mipmap, in particular 167 * the fact that the memory for recreated texture images is always freed. 168 */ 169static void radeon_generate_mipmap(GLcontext *ctx, GLenum target, 170 struct gl_texture_object *texObj) 171{ 172 radeonTexObj* t = radeon_tex_obj(texObj); 173 GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 174 int i, face; 175 176 177 _mesa_generate_mipmap(ctx, target, texObj); 178 179 for (face = 0; face < nr_faces; face++) { 180 for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) { 181 radeon_texture_image *image; 182 183 image = get_radeon_texture_image(texObj->Image[face][i]); 184 185 if (image == NULL) 186 break; 187 188 image->mtlevel = i; 189 image->mtface = face; 190 191 radeon_miptree_unreference(image->mt); 192 image->mt = NULL; 193 } 194 } 195 196} 197 198void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj) 199{ 200 GLuint face = radeon_face_for_target(target); 201 radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]); 202 203 radeon_teximage_map(baseimage, GL_FALSE); 204 radeon_generate_mipmap(ctx, target, texObj); 205 radeon_teximage_unmap(baseimage); 206} 207 208 209/* try to find a format which will only need a memcopy */ 210static const struct gl_texture_format *radeonChoose8888TexFormat(radeonContextPtr rmesa, 211 GLenum srcFormat, 212 GLenum srcType) 213{ 214 const GLuint ui = 1; 215 const GLubyte littleEndian = *((const GLubyte *)&ui); 216 217 /* r100 can only do this */ 218 if (IS_R100_CLASS(rmesa->radeonScreen)) 219 return _dri_texformat_argb8888; 220 221 if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) || 222 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) || 223 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || 224 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) { 225 return &_mesa_texformat_rgba8888; 226 } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || 227 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) || 228 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) || 229 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) { 230 return &_mesa_texformat_rgba8888_rev; 231 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) || 232 srcType == GL_UNSIGNED_INT_8_8_8_8)) { 233 return &_mesa_texformat_argb8888_rev; 234 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) || 235 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) { 236 return &_mesa_texformat_argb8888; 237 } else 238 return _dri_texformat_argb8888; 239} 240 241const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx, 242 GLint internalFormat, 243 GLenum format, 244 GLenum type) 245{ 246 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 247 const GLboolean do32bpt = 248 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32); 249 const GLboolean force16bpt = 250 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16); 251 (void)format; 252 253#if 0 254 fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n", 255 _mesa_lookup_enum_by_nr(internalFormat), internalFormat, 256 _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format)); 257 fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt); 258#endif 259 260 switch (internalFormat) { 261 case 4: 262 case GL_RGBA: 263 case GL_COMPRESSED_RGBA: 264 switch (type) { 265 case GL_UNSIGNED_INT_10_10_10_2: 266 case GL_UNSIGNED_INT_2_10_10_10_REV: 267 return do32bpt ? _dri_texformat_argb8888 : 268 _dri_texformat_argb1555; 269 case GL_UNSIGNED_SHORT_4_4_4_4: 270 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 271 return _dri_texformat_argb4444; 272 case GL_UNSIGNED_SHORT_5_5_5_1: 273 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 274 return _dri_texformat_argb1555; 275 default: 276 return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type) : 277 _dri_texformat_argb4444; 278 } 279 280 case 3: 281 case GL_RGB: 282 case GL_COMPRESSED_RGB: 283 switch (type) { 284 case GL_UNSIGNED_SHORT_4_4_4_4: 285 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 286 return _dri_texformat_argb4444; 287 case GL_UNSIGNED_SHORT_5_5_5_1: 288 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 289 return _dri_texformat_argb1555; 290 case GL_UNSIGNED_SHORT_5_6_5: 291 case GL_UNSIGNED_SHORT_5_6_5_REV: 292 return _dri_texformat_rgb565; 293 default: 294 return do32bpt ? _dri_texformat_argb8888 : 295 _dri_texformat_rgb565; 296 } 297 298 case GL_RGBA8: 299 case GL_RGB10_A2: 300 case GL_RGBA12: 301 case GL_RGBA16: 302 return !force16bpt ? 303 radeonChoose8888TexFormat(rmesa, format,type) : 304 _dri_texformat_argb4444; 305 306 case GL_RGBA4: 307 case GL_RGBA2: 308 return _dri_texformat_argb4444; 309 310 case GL_RGB5_A1: 311 return _dri_texformat_argb1555; 312 313 case GL_RGB8: 314 case GL_RGB10: 315 case GL_RGB12: 316 case GL_RGB16: 317 return !force16bpt ? _dri_texformat_argb8888 : 318 _dri_texformat_rgb565; 319 320 case GL_RGB5: 321 case GL_RGB4: 322 case GL_R3_G3_B2: 323 return _dri_texformat_rgb565; 324 325 case GL_ALPHA: 326 case GL_ALPHA4: 327 case GL_ALPHA8: 328 case GL_ALPHA12: 329 case GL_ALPHA16: 330 case GL_COMPRESSED_ALPHA: 331 return _dri_texformat_a8; 332 333 case 1: 334 case GL_LUMINANCE: 335 case GL_LUMINANCE4: 336 case GL_LUMINANCE8: 337 case GL_LUMINANCE12: 338 case GL_LUMINANCE16: 339 case GL_COMPRESSED_LUMINANCE: 340 return _dri_texformat_l8; 341 342 case 2: 343 case GL_LUMINANCE_ALPHA: 344 case GL_LUMINANCE4_ALPHA4: 345 case GL_LUMINANCE6_ALPHA2: 346 case GL_LUMINANCE8_ALPHA8: 347 case GL_LUMINANCE12_ALPHA4: 348 case GL_LUMINANCE12_ALPHA12: 349 case GL_LUMINANCE16_ALPHA16: 350 case GL_COMPRESSED_LUMINANCE_ALPHA: 351 return _dri_texformat_al88; 352 353 case GL_INTENSITY: 354 case GL_INTENSITY4: 355 case GL_INTENSITY8: 356 case GL_INTENSITY12: 357 case GL_INTENSITY16: 358 case GL_COMPRESSED_INTENSITY: 359 return _dri_texformat_i8; 360 361 case GL_YCBCR_MESA: 362 if (type == GL_UNSIGNED_SHORT_8_8_APPLE || 363 type == GL_UNSIGNED_BYTE) 364 return &_mesa_texformat_ycbcr; 365 else 366 return &_mesa_texformat_ycbcr_rev; 367 368 case GL_RGB_S3TC: 369 case GL_RGB4_S3TC: 370 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 371 return &_mesa_texformat_rgb_dxt1; 372 373 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 374 return &_mesa_texformat_rgba_dxt1; 375 376 case GL_RGBA_S3TC: 377 case GL_RGBA4_S3TC: 378 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 379 return &_mesa_texformat_rgba_dxt3; 380 381 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: 382 return &_mesa_texformat_rgba_dxt5; 383 384 case GL_ALPHA16F_ARB: 385 return &_mesa_texformat_alpha_float16; 386 case GL_ALPHA32F_ARB: 387 return &_mesa_texformat_alpha_float32; 388 case GL_LUMINANCE16F_ARB: 389 return &_mesa_texformat_luminance_float16; 390 case GL_LUMINANCE32F_ARB: 391 return &_mesa_texformat_luminance_float32; 392 case GL_LUMINANCE_ALPHA16F_ARB: 393 return &_mesa_texformat_luminance_alpha_float16; 394 case GL_LUMINANCE_ALPHA32F_ARB: 395 return &_mesa_texformat_luminance_alpha_float32; 396 case GL_INTENSITY16F_ARB: 397 return &_mesa_texformat_intensity_float16; 398 case GL_INTENSITY32F_ARB: 399 return &_mesa_texformat_intensity_float32; 400 case GL_RGB16F_ARB: 401 return &_mesa_texformat_rgba_float16; 402 case GL_RGB32F_ARB: 403 return &_mesa_texformat_rgba_float32; 404 case GL_RGBA16F_ARB: 405 return &_mesa_texformat_rgba_float16; 406 case GL_RGBA32F_ARB: 407 return &_mesa_texformat_rgba_float32; 408 409 case GL_DEPTH_COMPONENT: 410 case GL_DEPTH_COMPONENT16: 411 case GL_DEPTH_COMPONENT24: 412 case GL_DEPTH_COMPONENT32: 413#if 0 414 switch (type) { 415 case GL_UNSIGNED_BYTE: 416 case GL_UNSIGNED_SHORT: 417 return &_mesa_texformat_z16; 418 case GL_UNSIGNED_INT: 419 return &_mesa_texformat_z32; 420 case GL_UNSIGNED_INT_24_8_EXT: 421 default: 422 return &_mesa_texformat_z24_s8; 423 } 424#else 425 return &_mesa_texformat_z16; 426#endif 427 428 default: 429 _mesa_problem(ctx, 430 "unexpected internalFormat 0x%x in r300ChooseTextureFormat", 431 (int)internalFormat); 432 return NULL; 433 } 434 435 return NULL; /* never get here */ 436} 437 438/** 439 * All glTexImage calls go through this function. 440 */ 441static void radeon_teximage( 442 GLcontext *ctx, int dims, 443 GLint face, GLint level, 444 GLint internalFormat, 445 GLint width, GLint height, GLint depth, 446 GLsizei imageSize, 447 GLenum format, GLenum type, const GLvoid * pixels, 448 const struct gl_pixelstore_attrib *packing, 449 struct gl_texture_object *texObj, 450 struct gl_texture_image *texImage, 451 int compressed) 452{ 453 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 454 radeonTexObj* t = radeon_tex_obj(texObj); 455 radeon_texture_image* image = get_radeon_texture_image(texImage); 456 457 radeon_firevertices(rmesa); 458 459 t->validated = GL_FALSE; 460 461 /* Choose and fill in the texture format for this image */ 462 texImage->TexFormat = radeonChooseTextureFormat(ctx, internalFormat, format, type); 463 _mesa_set_fetch_functions(texImage, dims); 464 465 if (texImage->TexFormat->TexelBytes == 0) { 466 texImage->IsCompressed = GL_TRUE; 467 texImage->CompressedSize = 468 ctx->Driver.CompressedTextureSize(ctx, texImage->Width, 469 texImage->Height, texImage->Depth, 470 texImage->TexFormat->MesaFormat); 471 } else { 472 texImage->IsCompressed = GL_FALSE; 473 texImage->CompressedSize = 0; 474 } 475 476 /* Allocate memory for image */ 477 radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */ 478 479 if (!t->mt) 480 radeon_try_alloc_miptree(rmesa, t, texImage, face, level); 481 if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) { 482 image->mt = t->mt; 483 image->mtlevel = level - t->mt->firstLevel; 484 image->mtface = face; 485 radeon_miptree_reference(t->mt); 486 } else { 487 int size; 488 if (texImage->IsCompressed) { 489 size = texImage->CompressedSize; 490 } else { 491 size = texImage->Width * texImage->Height * texImage->Depth * texImage->TexFormat->TexelBytes; 492 } 493 texImage->Data = _mesa_alloc_texmemory(size); 494 } 495 496 /* Upload texture image; note that the spec allows pixels to be NULL */ 497 if (compressed) { 498 pixels = _mesa_validate_pbo_compressed_teximage( 499 ctx, imageSize, pixels, packing, "glCompressedTexImage"); 500 } else { 501 pixels = _mesa_validate_pbo_teximage( 502 ctx, dims, width, height, depth, 503 format, type, pixels, packing, "glTexImage"); 504 } 505 506 if (pixels) { 507 radeon_teximage_map(image, GL_TRUE); 508 509 if (compressed) { 510 memcpy(texImage->Data, pixels, imageSize); 511 } else { 512 GLuint dstRowStride; 513 if (image->mt) { 514 radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; 515 dstRowStride = lvl->rowstride; 516 } else { 517 dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes; 518 } 519 if (!texImage->TexFormat->StoreImage(ctx, dims, 520 texImage->_BaseFormat, 521 texImage->TexFormat, 522 texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ 523 dstRowStride, 524 texImage->ImageOffsets, 525 width, height, depth, 526 format, type, pixels, packing)) 527 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 528 } 529 530 } 531 532 /* SGIS_generate_mipmap */ 533 if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 534 radeon_generate_mipmap(ctx, texObj->Target, texObj); 535 } 536 537 if (pixels) 538 radeon_teximage_unmap(image); 539 540 _mesa_unmap_teximage_pbo(ctx, packing); 541 542 543} 544 545void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level, 546 GLint internalFormat, 547 GLint width, GLint border, 548 GLenum format, GLenum type, const GLvoid * pixels, 549 const struct gl_pixelstore_attrib *packing, 550 struct gl_texture_object *texObj, 551 struct gl_texture_image *texImage) 552{ 553 radeon_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1, 554 0, format, type, pixels, packing, texObj, texImage, 0); 555} 556 557void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level, 558 GLint internalFormat, 559 GLint width, GLint height, GLint border, 560 GLenum format, GLenum type, const GLvoid * pixels, 561 const struct gl_pixelstore_attrib *packing, 562 struct gl_texture_object *texObj, 563 struct gl_texture_image *texImage) 564 565{ 566 GLuint face = radeon_face_for_target(target); 567 568 radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1, 569 0, format, type, pixels, packing, texObj, texImage, 0); 570} 571 572void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target, 573 GLint level, GLint internalFormat, 574 GLint width, GLint height, GLint border, 575 GLsizei imageSize, const GLvoid * data, 576 struct gl_texture_object *texObj, 577 struct gl_texture_image *texImage) 578{ 579 GLuint face = radeon_face_for_target(target); 580 581 radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1, 582 imageSize, 0, 0, data, 0, texObj, texImage, 1); 583} 584 585void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level, 586 GLint internalFormat, 587 GLint width, GLint height, GLint depth, 588 GLint border, 589 GLenum format, GLenum type, const GLvoid * pixels, 590 const struct gl_pixelstore_attrib *packing, 591 struct gl_texture_object *texObj, 592 struct gl_texture_image *texImage) 593{ 594 radeon_teximage(ctx, 3, 0, level, internalFormat, width, height, depth, 595 0, format, type, pixels, packing, texObj, texImage, 0); 596} 597 598/** 599 * Update a subregion of the given texture image. 600 */ 601static void radeon_texsubimage(GLcontext* ctx, int dims, int level, 602 GLint xoffset, GLint yoffset, GLint zoffset, 603 GLsizei width, GLsizei height, GLsizei depth, 604 GLenum format, GLenum type, 605 const GLvoid * pixels, 606 const struct gl_pixelstore_attrib *packing, 607 struct gl_texture_object *texObj, 608 struct gl_texture_image *texImage, 609 int compressed) 610{ 611 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 612 radeonTexObj* t = radeon_tex_obj(texObj); 613 radeon_texture_image* image = get_radeon_texture_image(texImage); 614 615 radeon_firevertices(rmesa); 616 617 t->validated = GL_FALSE; 618 pixels = _mesa_validate_pbo_teximage(ctx, dims, 619 width, height, depth, format, type, pixels, packing, "glTexSubImage1D"); 620 621 if (pixels) { 622 GLint dstRowStride; 623 radeon_teximage_map(image, GL_TRUE); 624 625 if (image->mt) { 626 radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; 627 dstRowStride = lvl->rowstride; 628 } else { 629 dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes; 630 } 631 632 if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, 633 texImage->TexFormat, texImage->Data, 634 xoffset, yoffset, zoffset, 635 dstRowStride, 636 texImage->ImageOffsets, 637 width, height, depth, 638 format, type, pixels, packing)) 639 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 640 641 642 } 643 644 /* GL_SGIS_generate_mipmap */ 645 if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 646 radeon_generate_mipmap(ctx, texObj->Target, texObj); 647 } 648 radeon_teximage_unmap(image); 649 650 _mesa_unmap_teximage_pbo(ctx, packing); 651 652 653} 654 655void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, 656 GLint xoffset, 657 GLsizei width, 658 GLenum format, GLenum type, 659 const GLvoid * pixels, 660 const struct gl_pixelstore_attrib *packing, 661 struct gl_texture_object *texObj, 662 struct gl_texture_image *texImage) 663{ 664 radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1, 665 format, type, pixels, packing, texObj, texImage, 0); 666} 667 668void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, 669 GLint xoffset, GLint yoffset, 670 GLsizei width, GLsizei height, 671 GLenum format, GLenum type, 672 const GLvoid * pixels, 673 const struct gl_pixelstore_attrib *packing, 674 struct gl_texture_object *texObj, 675 struct gl_texture_image *texImage) 676{ 677 radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 678 1, format, type, pixels, packing, texObj, texImage, 679 0); 680} 681 682void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target, 683 GLint level, GLint xoffset, 684 GLint yoffset, GLsizei width, 685 GLsizei height, GLenum format, 686 GLsizei imageSize, const GLvoid * data, 687 struct gl_texture_object *texObj, 688 struct gl_texture_image *texImage) 689{ 690 radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1, 691 format, 0, data, 0, texObj, texImage, 1); 692} 693 694 695void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, 696 GLint xoffset, GLint yoffset, GLint zoffset, 697 GLsizei width, GLsizei height, GLsizei depth, 698 GLenum format, GLenum type, 699 const GLvoid * pixels, 700 const struct gl_pixelstore_attrib *packing, 701 struct gl_texture_object *texObj, 702 struct gl_texture_image *texImage) 703{ 704 radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth, 705 format, type, pixels, packing, texObj, texImage, 0); 706} 707 708static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, 709 GLuint numrows, GLuint rowsize) 710{ 711 assert(rowsize <= dststride); 712 assert(rowsize <= srcstride); 713 714 if (rowsize == srcstride && rowsize == dststride) { 715 memcpy(dst, src, numrows*rowsize); 716 } else { 717 GLuint i; 718 for(i = 0; i < numrows; ++i) { 719 memcpy(dst, src, rowsize); 720 dst += dststride; 721 src += srcstride; 722 } 723 } 724} 725 726 727/** 728 * Ensure that the given image is stored in the given miptree from now on. 729 */ 730static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, int face, int level) 731{ 732 radeon_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel]; 733 unsigned char *dest; 734 735 assert(image->mt != mt); 736 assert(dstlvl->width == image->base.Width); 737 assert(dstlvl->height == image->base.Height); 738 assert(dstlvl->depth == image->base.Depth); 739 740 741 radeon_bo_map(mt->bo, GL_TRUE); 742 dest = mt->bo->ptr + dstlvl->faces[face].offset; 743 744 if (image->mt) { 745 /* Format etc. should match, so we really just need a memcpy(). 746 * In fact, that memcpy() could be done by the hardware in many 747 * cases, provided that we have a proper memory manager. 748 */ 749 radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel]; 750 751 assert(srclvl->size == dstlvl->size); 752 assert(srclvl->rowstride == dstlvl->rowstride); 753 754 radeon_bo_map(image->mt->bo, GL_FALSE); 755 756 memcpy(dest, 757 image->mt->bo->ptr + srclvl->faces[face].offset, 758 dstlvl->size); 759 radeon_bo_unmap(image->mt->bo); 760 761 radeon_miptree_unreference(image->mt); 762 } else { 763 uint srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes; 764 765// if (mt->tilebits) 766// WARN_ONCE("%s: tiling not supported yet", __FUNCTION__); 767 768 copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride, 769 image->base.Height * image->base.Depth, srcrowstride); 770 771 _mesa_free_texmemory(image->base.Data); 772 image->base.Data = 0; 773 } 774 775 radeon_bo_unmap(mt->bo); 776 777 image->mt = mt; 778 image->mtface = face; 779 image->mtlevel = level; 780 radeon_miptree_reference(image->mt); 781} 782 783int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj) 784{ 785 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 786 radeonTexObj *t = radeon_tex_obj(texObj); 787 radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[0][texObj->BaseLevel]); 788 int face, level; 789 790 if (t->validated || t->image_override) 791 return GL_TRUE; 792 793 if (RADEON_DEBUG & DEBUG_TEXTURE) 794 fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj); 795 796 if (baseimage->base.Border > 0) 797 return GL_FALSE; 798 799 /* Ensure a matching miptree exists. 800 * 801 * Differing mipmap trees can result when the app uses TexImage to 802 * change texture dimensions. 803 * 804 * Prefer to use base image's miptree if it 805 * exists, since that most likely contains more valid data (remember 806 * that the base level is usually significantly larger than the rest 807 * of the miptree, so cubemaps are the only possible exception). 808 */ 809 if (baseimage->mt && 810 baseimage->mt != t->mt && 811 radeon_miptree_matches_texture(baseimage->mt, &t->base)) { 812 radeon_miptree_unreference(t->mt); 813 t->mt = baseimage->mt; 814 radeon_miptree_reference(t->mt); 815 } else if (t->mt && !radeon_miptree_matches_texture(t->mt, &t->base)) { 816 radeon_miptree_unreference(t->mt); 817 t->mt = 0; 818 } 819 820 if (!t->mt) { 821 if (RADEON_DEBUG & DEBUG_TEXTURE) 822 fprintf(stderr, " Allocate new miptree\n"); 823 radeon_try_alloc_miptree(rmesa, t, &baseimage->base, 0, texObj->BaseLevel); 824 if (!t->mt) { 825 _mesa_problem(ctx, "r300_validate_texture failed to alloc miptree"); 826 return GL_FALSE; 827 } 828 } 829 830 /* Ensure all images are stored in the single main miptree */ 831 for(face = 0; face < t->mt->faces; ++face) { 832 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) { 833 radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]); 834 if (RADEON_DEBUG & DEBUG_TEXTURE) 835 fprintf(stderr, " face %i, level %i... %p vs %p ", face, level, t->mt, image->mt); 836 if (t->mt == image->mt) { 837 if (RADEON_DEBUG & DEBUG_TEXTURE) 838 fprintf(stderr, "OK\n"); 839 continue; 840 } 841 842 if (RADEON_DEBUG & DEBUG_TEXTURE) 843 fprintf(stderr, "migrating\n"); 844 migrate_image_to_miptree(t->mt, image, face, level); 845 } 846 } 847 848 return GL_TRUE; 849} 850