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