radeon_texture.c revision 278ad74fe060ab8ba21d21b675a40f6758edaeca
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 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 237 struct radeon_bo *bo; 238 GLuint face = _mesa_tex_target_to_face(target); 239 radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]); 240 bo = !baseimage->mt ? baseimage->bo : baseimage->mt->bo; 241 242 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { 243 radeon_firevertices(rmesa); 244 } 245 246 radeon_teximage_map(baseimage, GL_FALSE); 247 radeon_generate_mipmap(ctx, target, texObj); 248 radeon_teximage_unmap(baseimage); 249} 250 251 252/* try to find a format which will only need a memcopy */ 253static gl_format radeonChoose8888TexFormat(radeonContextPtr rmesa, 254 GLenum srcFormat, 255 GLenum srcType, GLboolean fbo) 256{ 257 const GLuint ui = 1; 258 const GLubyte littleEndian = *((const GLubyte *)&ui); 259 260 /* r100 can only do this */ 261 if (IS_R100_CLASS(rmesa->radeonScreen) || fbo) 262 return _dri_texformat_argb8888; 263 264 if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) || 265 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) || 266 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || 267 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) { 268 return MESA_FORMAT_RGBA8888; 269 } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || 270 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) || 271 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) || 272 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) { 273 return MESA_FORMAT_RGBA8888_REV; 274 } else if (IS_R200_CLASS(rmesa->radeonScreen)) { 275 return _dri_texformat_argb8888; 276 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) || 277 srcType == GL_UNSIGNED_INT_8_8_8_8)) { 278 return MESA_FORMAT_ARGB8888_REV; 279 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) || 280 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) { 281 return MESA_FORMAT_ARGB8888; 282 } else 283 return _dri_texformat_argb8888; 284} 285 286gl_format radeonChooseTextureFormat_mesa(GLcontext * ctx, 287 GLint internalFormat, 288 GLenum format, 289 GLenum type) 290{ 291 return radeonChooseTextureFormat(ctx, internalFormat, format, 292 type, 0); 293} 294 295gl_format radeonChooseTextureFormat(GLcontext * ctx, 296 GLint internalFormat, 297 GLenum format, 298 GLenum type, GLboolean fbo) 299{ 300 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 301 const GLboolean do32bpt = 302 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32); 303 const GLboolean force16bpt = 304 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16); 305 (void)format; 306 307#if 0 308 fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n", 309 _mesa_lookup_enum_by_nr(internalFormat), internalFormat, 310 _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format)); 311 fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt); 312#endif 313 314 switch (internalFormat) { 315 case 4: 316 case GL_RGBA: 317 case GL_COMPRESSED_RGBA: 318 switch (type) { 319 case GL_UNSIGNED_INT_10_10_10_2: 320 case GL_UNSIGNED_INT_2_10_10_10_REV: 321 return do32bpt ? _dri_texformat_argb8888 : 322 _dri_texformat_argb1555; 323 case GL_UNSIGNED_SHORT_4_4_4_4: 324 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 325 return _dri_texformat_argb4444; 326 case GL_UNSIGNED_SHORT_5_5_5_1: 327 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 328 return _dri_texformat_argb1555; 329 default: 330 return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type, fbo) : 331 _dri_texformat_argb4444; 332 } 333 334 case 3: 335 case GL_RGB: 336 case GL_COMPRESSED_RGB: 337 switch (type) { 338 case GL_UNSIGNED_SHORT_4_4_4_4: 339 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 340 return _dri_texformat_argb4444; 341 case GL_UNSIGNED_SHORT_5_5_5_1: 342 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 343 return _dri_texformat_argb1555; 344 case GL_UNSIGNED_SHORT_5_6_5: 345 case GL_UNSIGNED_SHORT_5_6_5_REV: 346 return _dri_texformat_rgb565; 347 default: 348 return do32bpt ? _dri_texformat_argb8888 : 349 _dri_texformat_rgb565; 350 } 351 352 case GL_RGBA8: 353 case GL_RGB10_A2: 354 case GL_RGBA12: 355 case GL_RGBA16: 356 return !force16bpt ? 357 radeonChoose8888TexFormat(rmesa, format, type, fbo) : 358 _dri_texformat_argb4444; 359 360 case GL_RGBA4: 361 case GL_RGBA2: 362 return _dri_texformat_argb4444; 363 364 case GL_RGB5_A1: 365 return _dri_texformat_argb1555; 366 367 case GL_RGB8: 368 case GL_RGB10: 369 case GL_RGB12: 370 case GL_RGB16: 371 return !force16bpt ? _dri_texformat_argb8888 : 372 _dri_texformat_rgb565; 373 374 case GL_RGB5: 375 case GL_RGB4: 376 case GL_R3_G3_B2: 377 return _dri_texformat_rgb565; 378 379 case GL_ALPHA: 380 case GL_ALPHA4: 381 case GL_ALPHA8: 382 case GL_ALPHA12: 383 case GL_ALPHA16: 384 case GL_COMPRESSED_ALPHA: 385 /* r200: can't use a8 format since interpreting hw I8 as a8 would result 386 in wrong rgb values (same as alpha value instead of 0). */ 387 if (IS_R200_CLASS(rmesa->radeonScreen)) 388 return _dri_texformat_al88; 389 else 390 return _dri_texformat_a8; 391 case 1: 392 case GL_LUMINANCE: 393 case GL_LUMINANCE4: 394 case GL_LUMINANCE8: 395 case GL_LUMINANCE12: 396 case GL_LUMINANCE16: 397 case GL_COMPRESSED_LUMINANCE: 398 return _dri_texformat_l8; 399 400 case 2: 401 case GL_LUMINANCE_ALPHA: 402 case GL_LUMINANCE4_ALPHA4: 403 case GL_LUMINANCE6_ALPHA2: 404 case GL_LUMINANCE8_ALPHA8: 405 case GL_LUMINANCE12_ALPHA4: 406 case GL_LUMINANCE12_ALPHA12: 407 case GL_LUMINANCE16_ALPHA16: 408 case GL_COMPRESSED_LUMINANCE_ALPHA: 409 return _dri_texformat_al88; 410 411 case GL_INTENSITY: 412 case GL_INTENSITY4: 413 case GL_INTENSITY8: 414 case GL_INTENSITY12: 415 case GL_INTENSITY16: 416 case GL_COMPRESSED_INTENSITY: 417 return _dri_texformat_i8; 418 419 case GL_YCBCR_MESA: 420 if (type == GL_UNSIGNED_SHORT_8_8_APPLE || 421 type == GL_UNSIGNED_BYTE) 422 return MESA_FORMAT_YCBCR; 423 else 424 return MESA_FORMAT_YCBCR_REV; 425 426 case GL_RGB_S3TC: 427 case GL_RGB4_S3TC: 428 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 429 return MESA_FORMAT_RGB_DXT1; 430 431 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 432 return MESA_FORMAT_RGBA_DXT1; 433 434 case GL_RGBA_S3TC: 435 case GL_RGBA4_S3TC: 436 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 437 return MESA_FORMAT_RGBA_DXT3; 438 439 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: 440 return MESA_FORMAT_RGBA_DXT5; 441 442 case GL_ALPHA16F_ARB: 443 return MESA_FORMAT_ALPHA_FLOAT16; 444 case GL_ALPHA32F_ARB: 445 return MESA_FORMAT_ALPHA_FLOAT32; 446 case GL_LUMINANCE16F_ARB: 447 return MESA_FORMAT_LUMINANCE_FLOAT16; 448 case GL_LUMINANCE32F_ARB: 449 return MESA_FORMAT_LUMINANCE_FLOAT32; 450 case GL_LUMINANCE_ALPHA16F_ARB: 451 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16; 452 case GL_LUMINANCE_ALPHA32F_ARB: 453 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32; 454 case GL_INTENSITY16F_ARB: 455 return MESA_FORMAT_INTENSITY_FLOAT16; 456 case GL_INTENSITY32F_ARB: 457 return MESA_FORMAT_INTENSITY_FLOAT32; 458 case GL_RGB16F_ARB: 459 return MESA_FORMAT_RGBA_FLOAT16; 460 case GL_RGB32F_ARB: 461 return MESA_FORMAT_RGBA_FLOAT32; 462 case GL_RGBA16F_ARB: 463 return MESA_FORMAT_RGBA_FLOAT16; 464 case GL_RGBA32F_ARB: 465 return MESA_FORMAT_RGBA_FLOAT32; 466 467#ifdef RADEON_R300 468 case GL_DEPTH_COMPONENT: 469 case GL_DEPTH_COMPONENT16: 470 return MESA_FORMAT_Z16; 471 case GL_DEPTH_COMPONENT24: 472 case GL_DEPTH_COMPONENT32: 473 case GL_DEPTH_STENCIL_EXT: 474 case GL_DEPTH24_STENCIL8_EXT: 475 if (rmesa->radeonScreen->chip_family >= CHIP_FAMILY_RV515) 476 return MESA_FORMAT_S8_Z24; 477 else 478 return MESA_FORMAT_Z16; 479#else 480 case GL_DEPTH_COMPONENT: 481 case GL_DEPTH_COMPONENT16: 482 case GL_DEPTH_COMPONENT24: 483 case GL_DEPTH_COMPONENT32: 484 case GL_DEPTH_STENCIL_EXT: 485 case GL_DEPTH24_STENCIL8_EXT: 486 return MESA_FORMAT_S8_Z24; 487#endif 488 489 /* EXT_texture_sRGB */ 490 case GL_SRGB: 491 case GL_SRGB8: 492 case GL_SRGB_ALPHA: 493 case GL_SRGB8_ALPHA8: 494 case GL_COMPRESSED_SRGB: 495 case GL_COMPRESSED_SRGB_ALPHA: 496 return MESA_FORMAT_SRGBA8; 497 498 case GL_SLUMINANCE: 499 case GL_SLUMINANCE8: 500 case GL_COMPRESSED_SLUMINANCE: 501 return MESA_FORMAT_SL8; 502 503 case GL_SLUMINANCE_ALPHA: 504 case GL_SLUMINANCE8_ALPHA8: 505 case GL_COMPRESSED_SLUMINANCE_ALPHA: 506 return MESA_FORMAT_SLA8; 507 508 default: 509 _mesa_problem(ctx, 510 "unexpected internalFormat 0x%x in %s", 511 (int)internalFormat, __func__); 512 return MESA_FORMAT_NONE; 513 } 514 515 return MESA_FORMAT_NONE; /* never get here */ 516} 517 518/** Check if given image is valid within current texture object. 519 */ 520static int image_matches_texture_obj(struct gl_texture_object *texObj, 521 struct gl_texture_image *texImage, 522 unsigned level) 523{ 524 const struct gl_texture_image *baseImage = texObj->Image[0][texObj->BaseLevel]; 525 526 if (!baseImage) 527 return 0; 528 529 if (level < texObj->BaseLevel || level > texObj->MaxLevel) 530 return 0; 531 532 const unsigned levelDiff = level - texObj->BaseLevel; 533 const unsigned refWidth = MAX2(baseImage->Width >> levelDiff, 1); 534 const unsigned refHeight = MAX2(baseImage->Height >> levelDiff, 1); 535 const unsigned refDepth = MAX2(baseImage->Depth >> levelDiff, 1); 536 537 return (texImage->Width == refWidth && 538 texImage->Height == refHeight && 539 texImage->Depth == refDepth); 540} 541 542static void teximage_assign_miptree(radeonContextPtr rmesa, 543 struct gl_texture_object *texObj, 544 struct gl_texture_image *texImage, 545 unsigned face, 546 unsigned level) 547{ 548 radeonTexObj *t = radeon_tex_obj(texObj); 549 radeon_texture_image* image = get_radeon_texture_image(texImage); 550 551 /* Since miptree holds only images for levels <BaseLevel..MaxLevel> 552 * don't allocate the miptree if the teximage won't fit. 553 */ 554 if (!image_matches_texture_obj(texObj, texImage, level)) 555 return; 556 557 /* Try using current miptree, or create new if there isn't any */ 558 if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) { 559 radeon_miptree_unreference(&t->mt); 560 radeon_try_alloc_miptree(rmesa, t); 561 if (RADEON_DEBUG & RADEON_TEXTURE) { 562 fprintf(stderr, "%s: texObj %p, texImage %p, face %d, level %d, " 563 "texObj miptree doesn't match, allocated new miptree %p\n", 564 __FUNCTION__, texObj, texImage, face, level, t->mt); 565 } 566 } 567 568 /* Miptree alocation may have failed, 569 * when there was no image for baselevel specified */ 570 if (t->mt) { 571 image->mtface = face; 572 image->mtlevel = level; 573 radeon_miptree_reference(t->mt, &image->mt); 574 } 575} 576 577static GLuint * allocate_image_offsets(GLcontext *ctx, 578 unsigned alignedWidth, 579 unsigned height, 580 unsigned depth) 581{ 582 int i; 583 GLuint *offsets; 584 585 offsets = _mesa_malloc(depth * sizeof(GLuint)) ; 586 if (!offsets) { 587 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex[Sub]Image"); 588 return NULL; 589 } 590 591 for (i = 0; i < depth; ++i) { 592 offsets[i] = alignedWidth * height * i; 593 } 594 595 return offsets; 596} 597 598/** 599 * Update a subregion of the given texture image. 600 */ 601static void radeon_store_teximage(GLcontext* ctx, int dims, 602 GLint xoffset, GLint yoffset, GLint zoffset, 603 GLsizei width, GLsizei height, GLsizei depth, 604 GLsizei imageSize, 605 GLenum format, GLenum type, 606 const GLvoid * pixels, 607 const struct gl_pixelstore_attrib *packing, 608 struct gl_texture_object *texObj, 609 struct gl_texture_image *texImage, 610 int compressed) 611{ 612 radeonTexObj *t = radeon_tex_obj(texObj); 613 radeon_texture_image* image = get_radeon_texture_image(texImage); 614 615 GLuint dstRowStride; 616 GLuint *dstImageOffsets; 617 618 if (image->mt) { 619 dstRowStride = image->mt->levels[image->mtlevel].rowstride; 620 } else if (t->bo) { 621 /* TFP case */ 622 /* TODO */ 623 assert(0); 624 } else { 625 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width); 626 } 627 628 assert(dstRowStride); 629 630 if (dims == 3) { 631 unsigned alignedWidth = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat); 632 dstImageOffsets = allocate_image_offsets(ctx, alignedWidth, texImage->Height, texImage->Depth); 633 if (!dstImageOffsets) { 634 return; 635 } 636 } else { 637 dstImageOffsets = texImage->ImageOffsets; 638 } 639 640 radeon_teximage_map(image, GL_TRUE); 641 642 if (compressed) { 643 uint32_t srcRowStride, bytesPerRow, rows, block_width, block_height; 644 GLubyte *img_start; 645 646 _mesa_get_format_block_size(texImage->TexFormat, &block_width, &block_height); 647 648 if (!image->mt) { 649 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width); 650 img_start = _mesa_compressed_image_address(xoffset, yoffset, 0, 651 texImage->TexFormat, 652 texImage->Width, texImage->Data); 653 } 654 else { 655 uint32_t offset; 656 offset = dstRowStride / _mesa_get_format_bytes(texImage->TexFormat) * yoffset / block_height + xoffset / block_width; 657 offset *= _mesa_get_format_bytes(texImage->TexFormat); 658 img_start = texImage->Data + offset; 659 } 660 srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width); 661 bytesPerRow = srcRowStride; 662 rows = (height + block_height - 1) / block_height; 663 664 copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow); 665 } 666 else { 667 if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat, 668 texImage->TexFormat, texImage->Data, 669 xoffset, yoffset, zoffset, 670 dstRowStride, 671 dstImageOffsets, 672 width, height, depth, 673 format, type, pixels, packing)) { 674 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 675 } 676 } 677 678 if (dims == 3) { 679 _mesa_free(dstImageOffsets); 680 } 681 682 radeon_teximage_unmap(image); 683} 684 685/** 686 * All glTexImage calls go through this function. 687 */ 688static void radeon_teximage( 689 GLcontext *ctx, int dims, 690 GLenum target, GLint level, 691 GLint internalFormat, 692 GLint width, GLint height, GLint depth, 693 GLsizei imageSize, 694 GLenum format, GLenum type, const GLvoid * pixels, 695 const struct gl_pixelstore_attrib *packing, 696 struct gl_texture_object *texObj, 697 struct gl_texture_image *texImage, 698 int compressed) 699{ 700 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 701 radeonTexObj* t = radeon_tex_obj(texObj); 702 radeon_texture_image* image = get_radeon_texture_image(texImage); 703 GLint postConvWidth = width; 704 GLint postConvHeight = height; 705 GLuint face = _mesa_tex_target_to_face(target); 706 707 { 708 struct radeon_bo *bo; 709 bo = !image->mt ? image->bo : image->mt->bo; 710 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { 711 radeon_firevertices(rmesa); 712 } 713 } 714 715 if (RADEON_DEBUG & RADEON_TEXTURE) { 716 fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, face %d, level %d\n", 717 dims, texObj, texImage, face, level); 718 } 719 720 t->validated = GL_FALSE; 721 722 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 723 _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth, 724 &postConvHeight); 725 } 726 727 if (!_mesa_is_format_compressed(texImage->TexFormat)) { 728 GLuint texelBytes = _mesa_get_format_bytes(texImage->TexFormat); 729 /* Minimum pitch of 32 bytes */ 730 if (postConvWidth * texelBytes < 32) { 731 postConvWidth = 32 / texelBytes; 732 texImage->RowStride = postConvWidth; 733 } 734 if (!image->mt) { 735 assert(texImage->RowStride == postConvWidth); 736 } 737 } 738 739 /* Mesa core only clears texImage->Data but not image->mt */ 740 radeonFreeTexImageData(ctx, texImage); 741 742 if (!t->bo) { 743 teximage_assign_miptree(rmesa, texObj, texImage, face, level); 744 if (!image->mt) { 745 int size = _mesa_format_image_size(texImage->TexFormat, 746 texImage->Width, 747 texImage->Height, 748 texImage->Depth); 749 texImage->Data = _mesa_alloc_texmemory(size); 750 if (RADEON_DEBUG & RADEON_TEXTURE) { 751 fprintf(stderr, "radeon_teximage%dd: texObj %p, texImage %p, " 752 " no miptree assigned, using local memory %p\n", 753 dims, texObj, texImage, texImage->Data); 754 } 755 } 756 } 757 758 /* Upload texture image; note that the spec allows pixels to be NULL */ 759 if (compressed) { 760 pixels = _mesa_validate_pbo_compressed_teximage( 761 ctx, imageSize, pixels, packing, "glCompressedTexImage"); 762 } else { 763 pixels = _mesa_validate_pbo_teximage( 764 ctx, dims, width, height, depth, 765 format, type, pixels, packing, "glTexImage"); 766 } 767 768 if (pixels) { 769 radeon_store_teximage(ctx, dims, 770 0, 0, 0, 771 width, height, depth, 772 imageSize, format, type, 773 pixels, packing, 774 texObj, texImage, 775 compressed); 776 } 777 778 _mesa_unmap_teximage_pbo(ctx, packing); 779} 780 781void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level, 782 GLint internalFormat, 783 GLint width, GLint border, 784 GLenum format, GLenum type, const GLvoid * pixels, 785 const struct gl_pixelstore_attrib *packing, 786 struct gl_texture_object *texObj, 787 struct gl_texture_image *texImage) 788{ 789 radeon_teximage(ctx, 1, target, level, internalFormat, width, 1, 1, 790 0, format, type, pixels, packing, texObj, texImage, 0); 791} 792 793void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level, 794 GLint internalFormat, 795 GLint width, GLint height, GLint border, 796 GLenum format, GLenum type, const GLvoid * pixels, 797 const struct gl_pixelstore_attrib *packing, 798 struct gl_texture_object *texObj, 799 struct gl_texture_image *texImage) 800 801{ 802 radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1, 803 0, format, type, pixels, packing, texObj, texImage, 0); 804} 805 806void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target, 807 GLint level, GLint internalFormat, 808 GLint width, GLint height, GLint border, 809 GLsizei imageSize, const GLvoid * data, 810 struct gl_texture_object *texObj, 811 struct gl_texture_image *texImage) 812{ 813 radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1, 814 imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1); 815} 816 817void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level, 818 GLint internalFormat, 819 GLint width, GLint height, GLint depth, 820 GLint border, 821 GLenum format, GLenum type, const GLvoid * pixels, 822 const struct gl_pixelstore_attrib *packing, 823 struct gl_texture_object *texObj, 824 struct gl_texture_image *texImage) 825{ 826 radeon_teximage(ctx, 3, target, level, internalFormat, width, height, depth, 827 0, format, type, pixels, packing, texObj, texImage, 0); 828} 829 830/** 831 * All glTexSubImage calls go through this function. 832 */ 833static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int level, 834 GLint xoffset, GLint yoffset, GLint zoffset, 835 GLsizei width, GLsizei height, GLsizei depth, 836 GLsizei imageSize, 837 GLenum format, GLenum type, 838 const GLvoid * pixels, 839 const struct gl_pixelstore_attrib *packing, 840 struct gl_texture_object *texObj, 841 struct gl_texture_image *texImage, 842 int compressed) 843{ 844 radeonContextPtr rmesa = RADEON_CONTEXT(ctx); 845 radeonTexObj* t = radeon_tex_obj(texObj); 846 radeon_texture_image* image = get_radeon_texture_image(texImage); 847 848 { 849 struct radeon_bo *bo; 850 bo = !image->mt ? image->bo : image->mt->bo; 851 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { 852 radeon_firevertices(rmesa); 853 } 854 } 855 856 if (RADEON_DEBUG & RADEON_TEXTURE) { 857 fprintf(stderr, "radeon_texsubimage%dd: texObj %p, texImage %p, face %d, level %d\n", 858 dims, texObj, texImage, _mesa_tex_target_to_face(target), level); 859 } 860 861 t->validated = GL_FALSE; 862 if (compressed) { 863 pixels = _mesa_validate_pbo_compressed_teximage( 864 ctx, imageSize, pixels, packing, "glCompressedTexSubImage"); 865 } else { 866 pixels = _mesa_validate_pbo_teximage(ctx, dims, 867 width, height, depth, format, type, pixels, packing, "glTexSubImage"); 868 } 869 870 if (pixels) { 871 radeon_store_teximage(ctx, dims, 872 xoffset, yoffset, zoffset, 873 width, height, depth, 874 imageSize, format, type, 875 pixels, packing, 876 texObj, texImage, 877 compressed); 878 } 879 880 _mesa_unmap_teximage_pbo(ctx, packing); 881} 882 883void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, 884 GLint xoffset, 885 GLsizei width, 886 GLenum format, GLenum type, 887 const GLvoid * pixels, 888 const struct gl_pixelstore_attrib *packing, 889 struct gl_texture_object *texObj, 890 struct gl_texture_image *texImage) 891{ 892 radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0, 893 format, type, pixels, packing, texObj, texImage, 0); 894} 895 896void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, 897 GLint xoffset, GLint yoffset, 898 GLsizei width, GLsizei height, 899 GLenum format, GLenum type, 900 const GLvoid * pixels, 901 const struct gl_pixelstore_attrib *packing, 902 struct gl_texture_object *texObj, 903 struct gl_texture_image *texImage) 904{ 905 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1, 906 0, format, type, pixels, packing, texObj, texImage, 907 0); 908} 909 910void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target, 911 GLint level, GLint xoffset, 912 GLint yoffset, GLsizei width, 913 GLsizei height, GLenum format, 914 GLsizei imageSize, const GLvoid * data, 915 struct gl_texture_object *texObj, 916 struct gl_texture_image *texImage) 917{ 918 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1, 919 imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1); 920} 921 922 923void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, 924 GLint xoffset, GLint yoffset, GLint zoffset, 925 GLsizei width, GLsizei height, GLsizei depth, 926 GLenum format, GLenum type, 927 const GLvoid * pixels, 928 const struct gl_pixelstore_attrib *packing, 929 struct gl_texture_object *texObj, 930 struct gl_texture_image *texImage) 931{ 932 radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0, 933 format, type, pixels, packing, texObj, texImage, 0); 934} 935 936/** 937 * Need to map texture image into memory before copying image data, 938 * then unmap it. 939 */ 940static void 941radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level, 942 GLenum format, GLenum type, GLvoid * pixels, 943 struct gl_texture_object *texObj, 944 struct gl_texture_image *texImage, int compressed) 945{ 946 radeon_texture_image *image = get_radeon_texture_image(texImage); 947 948 if (image->mt) { 949 /* Map the texture image read-only */ 950 radeon_teximage_map(image, GL_FALSE); 951 } else { 952 /* Image hasn't been uploaded to a miptree yet */ 953 assert(image->base.Data); 954 } 955 956 if (compressed) { 957 /* FIXME: this can't work for small textures (mips) which 958 use different hw stride */ 959 _mesa_get_compressed_teximage(ctx, target, level, pixels, 960 texObj, texImage); 961 } else { 962 _mesa_get_teximage(ctx, target, level, format, type, pixels, 963 texObj, texImage); 964 } 965 966 if (image->mt) { 967 radeon_teximage_unmap(image); 968 } 969} 970 971void 972radeonGetTexImage(GLcontext * ctx, GLenum target, GLint level, 973 GLenum format, GLenum type, GLvoid * pixels, 974 struct gl_texture_object *texObj, 975 struct gl_texture_image *texImage) 976{ 977 radeon_get_tex_image(ctx, target, level, format, type, pixels, 978 texObj, texImage, 0); 979} 980 981void 982radeonGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, 983 GLvoid *pixels, 984 struct gl_texture_object *texObj, 985 struct gl_texture_image *texImage) 986{ 987 radeon_get_tex_image(ctx, target, level, 0, 0, pixels, 988 texObj, texImage, 1); 989} 990