radeon_texture.c revision 11affafc75525c50a2b4ffc9f91c1fe620d328fb
1/* 2 * Copyright (C) 2009 Maciej Cencora. 3 * Copyright (C) 2008 Nicolai Haehnle. 4 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. 5 * 6 * The Weather Channel (TM) funded Tungsten Graphics to develop the 7 * initial release of the Radeon 8500 driver under the XFree86 license. 8 * This notice must be preserved. 9 * 10 * Permission is hereby granted, free of charge, to any person obtaining 11 * a copy of this software and associated documentation files (the 12 * "Software"), to deal in the Software without restriction, including 13 * without limitation the rights to use, copy, modify, merge, publish, 14 * distribute, sublicense, and/or sell copies of the Software, and to 15 * permit persons to whom the Software is furnished to do so, subject to 16 * the following conditions: 17 * 18 * The above copyright notice and this permission notice (including the 19 * next paragraph) shall be included in all copies or substantial 20 * portions of the Software. 21 * 22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 25 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 26 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 * 30 */ 31 32#include "main/glheader.h" 33#include "main/imports.h" 34#include "main/context.h" 35#include "main/convolve.h" 36#include "main/mipmap.h" 37#include "main/texcompress.h" 38#include "main/texstore.h" 39#include "main/teximage.h" 40#include "main/texobj.h" 41#include "main/texgetimage.h" 42 43#include "xmlpool.h" /* for symbolic values of enum-type options */ 44 45#include "radeon_common.h" 46 47#include "radeon_mipmap_tree.h" 48 49 50void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, 51 GLuint numrows, GLuint rowsize) 52{ 53 assert(rowsize <= dststride); 54 assert(rowsize <= srcstride); 55 56 if (rowsize == srcstride && rowsize == dststride) { 57 memcpy(dst, src, numrows*rowsize); 58 } else { 59 GLuint i; 60 for(i = 0; i < numrows; ++i) { 61 memcpy(dst, src, rowsize); 62 dst += dststride; 63 src += srcstride; 64 } 65 } 66} 67 68/* textures */ 69/** 70 * Allocate an empty texture image object. 71 */ 72struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx) 73{ 74 return CALLOC(sizeof(radeon_texture_image)); 75} 76 77/** 78 * Free memory associated with this texture image. 79 */ 80void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage) 81{ 82 radeon_texture_image* image = get_radeon_texture_image(timage); 83 84 if (image->mt) { 85 radeon_miptree_unreference(&image->mt); 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; 104 105 if (!image->mt) 106 return; 107 108 lvl = &image->mt->levels[image->mtlevel]; 109 110 image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset; 111 image->base.RowStride = lvl->rowstride / _mesa_get_format_bytes(image->base.TexFormat); 112} 113 114 115/** 116 * Map a single texture image for glTexImage and friends. 117 */ 118void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable) 119{ 120 if (image->mt) { 121 assert(!image->base.Data); 122 123 radeon_bo_map(image->mt->bo, write_enable); 124 teximage_set_map_data(image); 125 } 126} 127 128 129void radeon_teximage_unmap(radeon_texture_image *image) 130{ 131 if (image->mt) { 132 assert(image->base.Data); 133 134 image->base.Data = 0; 135 radeon_bo_unmap(image->mt->bo); 136 } 137} 138 139static void map_override(GLcontext *ctx, radeonTexObj *t) 140{ 141 radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]); 142 143 radeon_bo_map(t->bo, GL_FALSE); 144 145 img->base.Data = t->bo->ptr; 146} 147 148static void unmap_override(GLcontext *ctx, radeonTexObj *t) 149{ 150 radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]); 151 152 radeon_bo_unmap(t->bo); 153 154 img->base.Data = NULL; 155} 156 157/** 158 * Map a validated texture for reading during software rendering. 159 */ 160void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj) 161{ 162 radeonTexObj* t = radeon_tex_obj(texObj); 163 int face, level; 164 165 if (!radeon_validate_texture_miptree(ctx, texObj)) 166 return; 167 168 /* for r100 3D sw fallbacks don't have mt */ 169 if (t->image_override && t->bo) 170 map_override(ctx, t); 171 172 if (!t->mt) 173 return; 174 175 radeon_bo_map(t->mt->bo, GL_FALSE); 176 for(face = 0; face < t->mt->faces; ++face) { 177 for(level = t->minLod; level <= t->maxLod; ++level) 178 teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level])); 179 } 180} 181 182void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj) 183{ 184 radeonTexObj* t = radeon_tex_obj(texObj); 185 int face, level; 186 187 if (t->image_override && t->bo) 188 unmap_override(ctx, t); 189 /* for r100 3D sw fallbacks don't have mt */ 190 if (!t->mt) 191 return; 192 193 for(face = 0; face < t->mt->faces; ++face) { 194 for(level = t->minLod; level <= t->maxLod; ++level) 195 texObj->Image[face][level]->Data = 0; 196 } 197 radeon_bo_unmap(t->mt->bo); 198} 199 200/** 201 * Wraps Mesa's implementation to ensure that the base level image is mapped. 202 * 203 * This relies on internal details of _mesa_generate_mipmap, in particular 204 * the fact that the memory for recreated texture images is always freed. 205 */ 206static void radeon_generate_mipmap(GLcontext *ctx, GLenum target, 207 struct gl_texture_object *texObj) 208{ 209 radeonTexObj* t = radeon_tex_obj(texObj); 210 GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 211 int i, face; 212 213 214 _mesa_generate_mipmap(ctx, target, texObj); 215 216 for (face = 0; face < nr_faces; face++) { 217 for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) { 218 radeon_texture_image *image; 219 220 image = get_radeon_texture_image(texObj->Image[face][i]); 221 222 if (image == NULL) 223 break; 224 225 image->mtlevel = i; 226 image->mtface = face; 227 228 radeon_miptree_unreference(&image->mt); 229 } 230 } 231 232} 233 234void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj) 235{ 236 GLuint face = _mesa_tex_target_to_face(target); 237 radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]); 238 239 radeon_teximage_map(baseimage, GL_FALSE); 240 radeon_generate_mipmap(ctx, target, texObj); 241 radeon_teximage_unmap(baseimage); 242} 243 244 245/* try to find a format which will only need a memcopy */ 246static gl_format radeonChoose8888TexFormat(radeonContextPtr rmesa, 247 GLenum srcFormat, 248 GLenum srcType, GLboolean fbo) 249{ 250 const GLuint ui = 1; 251 const GLubyte littleEndian = *((const GLubyte *)&ui); 252 253 /* r100 can only do this */ 254 if (IS_R100_CLASS(rmesa->radeonScreen) || fbo) 255 return _dri_texformat_argb8888; 256 257 if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) || 258 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) || 259 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || 260 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) { 261 return MESA_FORMAT_RGBA8888; 262 } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || 263 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) || 264 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) || 265 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) { 266 return MESA_FORMAT_RGBA8888_REV; 267 } else if (IS_R200_CLASS(rmesa->radeonScreen)) { 268 return _dri_texformat_argb8888; 269 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) || 270 srcType == GL_UNSIGNED_INT_8_8_8_8)) { 271 return MESA_FORMAT_ARGB8888_REV; 272 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) || 273 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) { 274 return MESA_FORMAT_ARGB8888; 275 } else 276 return _dri_texformat_argb8888; 277} 278 279gl_format radeonChooseTextureFormat_mesa(GLcontext * ctx, 280 GLint internalFormat, 281 GLenum format, 282 GLenum type) 283{ 284 return radeonChooseTextureFormat(ctx, internalFormat, format, 285 type, 0); 286} 287 288gl_format radeonChooseTextureFormat(GLcontext * ctx, 289 GLint internalFormat, 290 GLenum format, 291 GLenum type, GLboolean fbo) 292{ 293 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 294 const GLboolean do32bpt = 295 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32); 296 const GLboolean force16bpt = 297 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16); 298 (void)format; 299 300#if 0 301 fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n", 302 _mesa_lookup_enum_by_nr(internalFormat), internalFormat, 303 _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format)); 304 fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt); 305#endif 306 307 switch (internalFormat) { 308 case 4: 309 case GL_RGBA: 310 case GL_COMPRESSED_RGBA: 311 switch (type) { 312 case GL_UNSIGNED_INT_10_10_10_2: 313 case GL_UNSIGNED_INT_2_10_10_10_REV: 314 return do32bpt ? _dri_texformat_argb8888 : 315 _dri_texformat_argb1555; 316 case GL_UNSIGNED_SHORT_4_4_4_4: 317 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 318 return _dri_texformat_argb4444; 319 case GL_UNSIGNED_SHORT_5_5_5_1: 320 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 321 return _dri_texformat_argb1555; 322 default: 323 return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type, fbo) : 324 _dri_texformat_argb4444; 325 } 326 327 case 3: 328 case GL_RGB: 329 case GL_COMPRESSED_RGB: 330 switch (type) { 331 case GL_UNSIGNED_SHORT_4_4_4_4: 332 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 333 return _dri_texformat_argb4444; 334 case GL_UNSIGNED_SHORT_5_5_5_1: 335 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 336 return _dri_texformat_argb1555; 337 case GL_UNSIGNED_SHORT_5_6_5: 338 case GL_UNSIGNED_SHORT_5_6_5_REV: 339 return _dri_texformat_rgb565; 340 default: 341 return do32bpt ? _dri_texformat_argb8888 : 342 _dri_texformat_rgb565; 343 } 344 345 case GL_RGBA8: 346 case GL_RGB10_A2: 347 case GL_RGBA12: 348 case GL_RGBA16: 349 return !force16bpt ? 350 radeonChoose8888TexFormat(rmesa, format, type, fbo) : 351 _dri_texformat_argb4444; 352 353 case GL_RGBA4: 354 case GL_RGBA2: 355 return _dri_texformat_argb4444; 356 357 case GL_RGB5_A1: 358 return _dri_texformat_argb1555; 359 360 case GL_RGB8: 361 case GL_RGB10: 362 case GL_RGB12: 363 case GL_RGB16: 364 return !force16bpt ? _dri_texformat_argb8888 : 365 _dri_texformat_rgb565; 366 367 case GL_RGB5: 368 case GL_RGB4: 369 case GL_R3_G3_B2: 370 return _dri_texformat_rgb565; 371 372 case GL_ALPHA: 373 case GL_ALPHA4: 374 case GL_ALPHA8: 375 case GL_ALPHA12: 376 case GL_ALPHA16: 377 case GL_COMPRESSED_ALPHA: 378 /* r200: can't use a8 format since interpreting hw I8 as a8 would result 379 in wrong rgb values (same as alpha value instead of 0). */ 380 if (IS_R200_CLASS(rmesa->radeonScreen)) 381 return _dri_texformat_al88; 382 else 383 return _dri_texformat_a8; 384 case 1: 385 case GL_LUMINANCE: 386 case GL_LUMINANCE4: 387 case GL_LUMINANCE8: 388 case GL_LUMINANCE12: 389 case GL_LUMINANCE16: 390 case GL_COMPRESSED_LUMINANCE: 391 return _dri_texformat_l8; 392 393 case 2: 394 case GL_LUMINANCE_ALPHA: 395 case GL_LUMINANCE4_ALPHA4: 396 case GL_LUMINANCE6_ALPHA2: 397 case GL_LUMINANCE8_ALPHA8: 398 case GL_LUMINANCE12_ALPHA4: 399 case GL_LUMINANCE12_ALPHA12: 400 case GL_LUMINANCE16_ALPHA16: 401 case GL_COMPRESSED_LUMINANCE_ALPHA: 402 return _dri_texformat_al88; 403 404 case GL_INTENSITY: 405 case GL_INTENSITY4: 406 case GL_INTENSITY8: 407 case GL_INTENSITY12: 408 case GL_INTENSITY16: 409 case GL_COMPRESSED_INTENSITY: 410 return _dri_texformat_i8; 411 412 case GL_YCBCR_MESA: 413 if (type == GL_UNSIGNED_SHORT_8_8_APPLE || 414 type == GL_UNSIGNED_BYTE) 415 return MESA_FORMAT_YCBCR; 416 else 417 return MESA_FORMAT_YCBCR_REV; 418 419 case GL_RGB_S3TC: 420 case GL_RGB4_S3TC: 421 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 422 return MESA_FORMAT_RGB_DXT1; 423 424 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 425 return MESA_FORMAT_RGBA_DXT1; 426 427 case GL_RGBA_S3TC: 428 case GL_RGBA4_S3TC: 429 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 430 return MESA_FORMAT_RGBA_DXT3; 431 432 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: 433 return MESA_FORMAT_RGBA_DXT5; 434 435 case GL_ALPHA16F_ARB: 436 return MESA_FORMAT_ALPHA_FLOAT16; 437 case GL_ALPHA32F_ARB: 438 return MESA_FORMAT_ALPHA_FLOAT32; 439 case GL_LUMINANCE16F_ARB: 440 return MESA_FORMAT_LUMINANCE_FLOAT16; 441 case GL_LUMINANCE32F_ARB: 442 return MESA_FORMAT_LUMINANCE_FLOAT32; 443 case GL_LUMINANCE_ALPHA16F_ARB: 444 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16; 445 case GL_LUMINANCE_ALPHA32F_ARB: 446 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32; 447 case GL_INTENSITY16F_ARB: 448 return MESA_FORMAT_INTENSITY_FLOAT16; 449 case GL_INTENSITY32F_ARB: 450 return MESA_FORMAT_INTENSITY_FLOAT32; 451 case GL_RGB16F_ARB: 452 return MESA_FORMAT_RGBA_FLOAT16; 453 case GL_RGB32F_ARB: 454 return MESA_FORMAT_RGBA_FLOAT32; 455 case GL_RGBA16F_ARB: 456 return MESA_FORMAT_RGBA_FLOAT16; 457 case GL_RGBA32F_ARB: 458 return MESA_FORMAT_RGBA_FLOAT32; 459 460#ifdef RADEON_R300 461 case GL_DEPTH_COMPONENT: 462 case GL_DEPTH_COMPONENT16: 463 return MESA_FORMAT_Z16; 464 case GL_DEPTH_COMPONENT24: 465 case GL_DEPTH_COMPONENT32: 466 case GL_DEPTH_STENCIL_EXT: 467 case GL_DEPTH24_STENCIL8_EXT: 468 if (rmesa->radeonScreen->chip_family >= CHIP_FAMILY_RV515) 469 return MESA_FORMAT_S8_Z24; 470 else 471 return MESA_FORMAT_Z16; 472#else 473 case GL_DEPTH_COMPONENT: 474 case GL_DEPTH_COMPONENT16: 475 case GL_DEPTH_COMPONENT24: 476 case GL_DEPTH_COMPONENT32: 477 case GL_DEPTH_STENCIL_EXT: 478 case GL_DEPTH24_STENCIL8_EXT: 479 return MESA_FORMAT_S8_Z24; 480#endif 481 482 /* EXT_texture_sRGB */ 483 case GL_SRGB: 484 case GL_SRGB8: 485 case GL_SRGB_ALPHA: 486 case GL_SRGB8_ALPHA8: 487 case GL_COMPRESSED_SRGB: 488 case GL_COMPRESSED_SRGB_ALPHA: 489 return MESA_FORMAT_SRGBA8; 490 491 case GL_SLUMINANCE: 492 case GL_SLUMINANCE8: 493 case GL_COMPRESSED_SLUMINANCE: 494 return MESA_FORMAT_SL8; 495 496 case GL_SLUMINANCE_ALPHA: 497 case GL_SLUMINANCE8_ALPHA8: 498 case GL_COMPRESSED_SLUMINANCE_ALPHA: 499 return MESA_FORMAT_SLA8; 500 501 default: 502 _mesa_problem(ctx, 503 "unexpected internalFormat 0x%x in %s", 504 (int)internalFormat, __func__); 505 return MESA_FORMAT_NONE; 506 } 507 508 return MESA_FORMAT_NONE; /* never get here */ 509} 510 511/** Check if given image is valid within current texture object. 512 */ 513static int image_matches_texture_obj(struct gl_texture_object *texObj, 514 struct gl_texture_image *texImage, 515 unsigned level) 516{ 517 const struct gl_texture_image *baseImage = texObj->Image[0][texObj->BaseLevel]; 518 519 if (!baseImage) 520 return 0; 521 522 if (level < texObj->BaseLevel || level > texObj->MaxLevel) 523 return 0; 524 525 const unsigned levelDiff = level - texObj->BaseLevel; 526 const unsigned refWidth = MAX2(baseImage->Width >> levelDiff, 1); 527 const unsigned refHeight = MAX2(baseImage->Height >> levelDiff, 1); 528 const unsigned refDepth = MAX2(baseImage->Depth >> levelDiff, 1); 529 530 return (texImage->Width == refWidth && 531 texImage->Height == refHeight && 532 texImage->Depth == refDepth); 533} 534 535static void teximage_assign_miptree(radeonContextPtr rmesa, 536 struct gl_texture_object *texObj, 537 struct gl_texture_image *texImage, 538 unsigned face, 539 unsigned level) 540{ 541 radeonTexObj *t = radeon_tex_obj(texObj); 542 radeon_texture_image* image = get_radeon_texture_image(texImage); 543 544 /* Since miptree holds only images for levels <BaseLevel..MaxLevel> 545 * don't allocate the miptree if the teximage won't fit. 546 */ 547 if (!image_matches_texture_obj(texObj, texImage, level)) 548 return; 549 550 /* Try using current miptree, or create new if there isn't any */ 551 if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) { 552 radeon_miptree_unreference(&t->mt); 553 radeon_try_alloc_miptree(rmesa, t); 554 if (RADEON_DEBUG & RADEON_TEXTURE) { 555 fprintf(stderr, "%s: texObj %p, texImage %p, face %d, level %d, " 556 "texObj miptree doesn't match, allocated new miptree %p\n", 557 __FUNCTION__, texObj, texImage, face, level, t->mt); 558 } 559 } 560 561 /* Miptree alocation may have failed, 562 * when there was no image for baselevel specified */ 563 if (t->mt) { 564 image->mtface = face; 565 image->mtlevel = level; 566 radeon_miptree_reference(t->mt, &image->mt); 567 } 568} 569 570static GLuint * allocate_image_offsets(GLcontext *ctx, 571 unsigned alignedWidth, 572 unsigned height, 573 unsigned depth) 574{ 575 int i; 576 GLuint *offsets; 577 578 offsets = _mesa_malloc(depth * sizeof(GLuint)) ; 579 if (!offsets) { 580 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex[Sub]Image"); 581 return NULL; 582 } 583 584 for (i = 0; i < depth; ++i) { 585 offsets[i] = alignedWidth * height * i; 586 } 587 588 return offsets; 589} 590 591/** 592 * Update a subregion of the given texture image. 593 */ 594static void radeon_store_teximage(GLcontext* ctx, int dims, 595 GLint xoffset, GLint yoffset, GLint zoffset, 596 GLsizei width, GLsizei height, GLsizei depth, 597 GLsizei imageSize, 598 GLenum format, GLenum type, 599 const GLvoid * pixels, 600 const struct gl_pixelstore_attrib *packing, 601 struct gl_texture_object *texObj, 602 struct gl_texture_image *texImage, 603 int compressed) 604{ 605 radeonTexObj *t = radeon_tex_obj(texObj); 606 radeon_texture_image* image = get_radeon_texture_image(texImage); 607 608 GLuint dstRowStride; 609 GLuint *dstImageOffsets; 610 611 if (image->mt) { 612 dstRowStride = image->mt->levels[image->mtlevel].rowstride; 613 } else if (t->bo) { 614 /* TFP case */ 615 /* TODO */ 616 assert(0); 617 } else { 618 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width); 619 } 620 621 assert(dstRowStride); 622 623 if (dims == 3) { 624 unsigned alignedWidth = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat); 625 dstImageOffsets = allocate_image_offsets(ctx, alignedWidth, texImage->Height, texImage->Depth); 626 if (!dstImageOffsets) { 627 return; 628 } 629 } else { 630 dstImageOffsets = texImage->ImageOffsets; 631 } 632 633 radeon_teximage_map(image, GL_TRUE); 634 635 if (compressed) { 636 uint32_t srcRowStride, bytesPerRow, rows, block_width, block_height; 637 GLubyte *img_start; 638 639 _mesa_get_format_block_size(texImage->TexFormat, &block_width, &block_height); 640 641 if (!image->mt) { 642 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width); 643 img_start = _mesa_compressed_image_address(xoffset, yoffset, 0, 644 texImage->TexFormat, 645 texImage->Width, texImage->Data); 646 } 647 else { 648 uint32_t offset; 649 offset = dstRowStride / _mesa_get_format_bytes(texImage->TexFormat) * yoffset / block_height + xoffset / block_width; 650 offset *= _mesa_get_format_bytes(texImage->TexFormat); 651 img_start = texImage->Data + offset; 652 } 653 srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width); 654 bytesPerRow = srcRowStride; 655 rows = (height + block_height - 1) / block_height; 656 657 copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow); 658 } 659 else { 660 if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat, 661 texImage->TexFormat, texImage->Data, 662 xoffset, yoffset, zoffset, 663 dstRowStride, 664 dstImageOffsets, 665 width, height, depth, 666 format, type, pixels, packing)) { 667 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 668 } 669 } 670 671 if (dims == 3) { 672 _mesa_free(dstImageOffsets); 673 } 674 675 radeon_teximage_unmap(image); 676} 677 678/** 679 * All glTexImage calls go through this function. 680 */ 681static void radeon_teximage( 682 GLcontext *ctx, int dims, 683 GLenum target, GLint level, 684 GLint internalFormat, 685 GLint width, GLint height, GLint depth, 686 GLsizei imageSize, 687 GLenum format, GLenum type, const GLvoid * pixels, 688 const struct gl_pixelstore_attrib *packing, 689 struct gl_texture_object *texObj, 690 struct gl_texture_image *texImage, 691 int compressed) 692{ 693 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 694 radeonTexObj* t = radeon_tex_obj(texObj); 695 radeon_texture_image* image = get_radeon_texture_image(texImage); 696 GLint postConvWidth = width; 697 GLint postConvHeight = height; 698 GLuint face = _mesa_tex_target_to_face(target); 699 700 { 701 struct radeon_bo *bo; 702 bo = !image->mt ? image->bo : image->mt->bo; 703 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { 704 radeon_firevertices(rmesa); 705 } 706 } 707 708 if (RADEON_DEBUG & RADEON_TEXTURE) { 709 fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, face %d, level %d\n", 710 dims, texObj, texImage, face, level); 711 } 712 713 t->validated = GL_FALSE; 714 715 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 716 _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth, 717 &postConvHeight); 718 } 719 720 if (!_mesa_is_format_compressed(texImage->TexFormat)) { 721 GLuint texelBytes = _mesa_get_format_bytes(texImage->TexFormat); 722 /* Minimum pitch of 32 bytes */ 723 if (postConvWidth * texelBytes < 32) { 724 postConvWidth = 32 / texelBytes; 725 texImage->RowStride = postConvWidth; 726 } 727 if (!image->mt) { 728 assert(texImage->RowStride == postConvWidth); 729 } 730 } 731 732 /* Mesa core only clears texImage->Data but not image->mt */ 733 radeonFreeTexImageData(ctx, texImage); 734 735 if (!t->bo) { 736 teximage_assign_miptree(rmesa, texObj, texImage, face, level); 737 if (!image->mt) { 738 int size = _mesa_format_image_size(texImage->TexFormat, 739 texImage->Width, 740 texImage->Height, 741 texImage->Depth); 742 texImage->Data = _mesa_alloc_texmemory(size); 743 if (RADEON_DEBUG & RADEON_TEXTURE) { 744 fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, " 745 " no miptree assigned, using local memory %p\n", 746 dims, texObj, texImage, texImage->Data); 747 } 748 } 749 } 750 751 /* Upload texture image; note that the spec allows pixels to be NULL */ 752 if (compressed) { 753 pixels = _mesa_validate_pbo_compressed_teximage( 754 ctx, imageSize, pixels, packing, "glCompressedTexImage"); 755 } else { 756 pixels = _mesa_validate_pbo_teximage( 757 ctx, dims, width, height, depth, 758 format, type, pixels, packing, "glTexImage"); 759 } 760 761 if (pixels) { 762 radeon_store_teximage(ctx, dims, 763 0, 0, 0, 764 width, height, depth, 765 imageSize, format, type, 766 pixels, packing, 767 texObj, texImage, 768 compressed); 769 } 770 771 _mesa_unmap_teximage_pbo(ctx, packing); 772} 773 774void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level, 775 GLint internalFormat, 776 GLint width, GLint border, 777 GLenum format, GLenum type, const GLvoid * pixels, 778 const struct gl_pixelstore_attrib *packing, 779 struct gl_texture_object *texObj, 780 struct gl_texture_image *texImage) 781{ 782 radeon_teximage(ctx, 1, target, level, internalFormat, width, 1, 1, 783 0, format, type, pixels, packing, texObj, texImage, 0); 784} 785 786void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level, 787 GLint internalFormat, 788 GLint width, GLint height, GLint border, 789 GLenum format, GLenum type, const GLvoid * pixels, 790 const struct gl_pixelstore_attrib *packing, 791 struct gl_texture_object *texObj, 792 struct gl_texture_image *texImage) 793 794{ 795 radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1, 796 0, format, type, pixels, packing, texObj, texImage, 0); 797} 798 799void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target, 800 GLint level, GLint internalFormat, 801 GLint width, GLint height, GLint border, 802 GLsizei imageSize, const GLvoid * data, 803 struct gl_texture_object *texObj, 804 struct gl_texture_image *texImage) 805{ 806 radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1, 807 imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1); 808} 809 810void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level, 811 GLint internalFormat, 812 GLint width, GLint height, GLint depth, 813 GLint border, 814 GLenum format, GLenum type, const GLvoid * pixels, 815 const struct gl_pixelstore_attrib *packing, 816 struct gl_texture_object *texObj, 817 struct gl_texture_image *texImage) 818{ 819 radeon_teximage(ctx, 3, target, level, internalFormat, width, height, depth, 820 0, format, type, pixels, packing, texObj, texImage, 0); 821} 822 823/** 824 * All glTexSubImage calls go through this function. 825 */ 826static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int level, 827 GLint xoffset, GLint yoffset, GLint zoffset, 828 GLsizei width, GLsizei height, GLsizei depth, 829 GLsizei imageSize, 830 GLenum format, GLenum type, 831 const GLvoid * pixels, 832 const struct gl_pixelstore_attrib *packing, 833 struct gl_texture_object *texObj, 834 struct gl_texture_image *texImage, 835 int compressed) 836{ 837 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 838 radeonTexObj* t = radeon_tex_obj(texObj); 839 radeon_texture_image* image = get_radeon_texture_image(texImage); 840 841 { 842 struct radeon_bo *bo; 843 bo = !image->mt ? image->bo : image->mt->bo; 844 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { 845 radeon_firevertices(rmesa); 846 } 847 } 848 849 if (RADEON_DEBUG & RADEON_TEXTURE) { 850 fprintf(stderr, "radeon_texsubimage%dd: texObj %p, texImage %p, face %d, level %d\n", 851 dims, texObj, texImage, _mesa_tex_target_to_face(target), level); 852 } 853 854 t->validated = GL_FALSE; 855 if (compressed) { 856 pixels = _mesa_validate_pbo_compressed_teximage( 857 ctx, imageSize, pixels, packing, "glCompressedTexSubImage"); 858 } else { 859 pixels = _mesa_validate_pbo_teximage(ctx, dims, 860 width, height, depth, format, type, pixels, packing, "glTexSubImage"); 861 } 862 863 if (pixels) { 864 radeon_store_teximage(ctx, dims, 865 xoffset, yoffset, zoffset, 866 width, height, depth, 867 imageSize, format, type, 868 pixels, packing, 869 texObj, texImage, 870 compressed); 871 } 872 873 _mesa_unmap_teximage_pbo(ctx, packing); 874} 875 876void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, 877 GLint xoffset, 878 GLsizei width, 879 GLenum format, GLenum type, 880 const GLvoid * pixels, 881 const struct gl_pixelstore_attrib *packing, 882 struct gl_texture_object *texObj, 883 struct gl_texture_image *texImage) 884{ 885 radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0, 886 format, type, pixels, packing, texObj, texImage, 0); 887} 888 889void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, 890 GLint xoffset, GLint yoffset, 891 GLsizei width, GLsizei height, 892 GLenum format, GLenum type, 893 const GLvoid * pixels, 894 const struct gl_pixelstore_attrib *packing, 895 struct gl_texture_object *texObj, 896 struct gl_texture_image *texImage) 897{ 898 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1, 899 0, format, type, pixels, packing, texObj, texImage, 900 0); 901} 902 903void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target, 904 GLint level, GLint xoffset, 905 GLint yoffset, GLsizei width, 906 GLsizei height, GLenum format, 907 GLsizei imageSize, const GLvoid * data, 908 struct gl_texture_object *texObj, 909 struct gl_texture_image *texImage) 910{ 911 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1, 912 imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1); 913} 914 915 916void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, 917 GLint xoffset, GLint yoffset, GLint zoffset, 918 GLsizei width, GLsizei height, GLsizei depth, 919 GLenum format, GLenum type, 920 const GLvoid * pixels, 921 const struct gl_pixelstore_attrib *packing, 922 struct gl_texture_object *texObj, 923 struct gl_texture_image *texImage) 924{ 925 radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0, 926 format, type, pixels, packing, texObj, texImage, 0); 927} 928 929/** 930 * Need to map texture image into memory before copying image data, 931 * then unmap it. 932 */ 933static void 934radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level, 935 GLenum format, GLenum type, GLvoid * pixels, 936 struct gl_texture_object *texObj, 937 struct gl_texture_image *texImage, int compressed) 938{ 939 radeon_texture_image *image = get_radeon_texture_image(texImage); 940 941 if (image->mt) { 942 /* Map the texture image read-only */ 943 radeon_teximage_map(image, GL_FALSE); 944 } else { 945 /* Image hasn't been uploaded to a miptree yet */ 946 assert(image->base.Data); 947 } 948 949 if (compressed) { 950 /* FIXME: this can't work for small textures (mips) which 951 use different hw stride */ 952 _mesa_get_compressed_teximage(ctx, target, level, pixels, 953 texObj, texImage); 954 } else { 955 _mesa_get_teximage(ctx, target, level, format, type, pixels, 956 texObj, texImage); 957 } 958 959 if (image->mt) { 960 radeon_teximage_unmap(image); 961 } 962} 963 964void 965radeonGetTexImage(GLcontext * ctx, GLenum target, GLint level, 966 GLenum format, GLenum type, GLvoid * pixels, 967 struct gl_texture_object *texObj, 968 struct gl_texture_image *texImage) 969{ 970 radeon_get_tex_image(ctx, target, level, format, type, pixels, 971 texObj, texImage, 0); 972} 973 974void 975radeonGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, 976 GLvoid *pixels, 977 struct gl_texture_object *texObj, 978 struct gl_texture_image *texImage) 979{ 980 radeon_get_tex_image(ctx, target, level, 0, 0, pixels, 981 texObj, texImage, 1); 982} 983