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