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