st_cb_texture.c revision afc54983370033b65e3a7cbb29bd9c87156f0881
1/************************************************************************** 2 * 3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28#include "main/imports.h" 29#include "main/convolve.h" 30#include "main/enums.h" 31#include "main/image.h" 32#include "main/macros.h" 33#include "main/texcompress.h" 34#include "main/texformat.h" 35#include "main/teximage.h" 36#include "main/texobj.h" 37#include "main/texstore.h" 38 39#include "state_tracker/st_context.h" 40#include "state_tracker/st_cb_fbo.h" 41#include "state_tracker/st_cb_texture.h" 42#include "state_tracker/st_format.h" 43#include "state_tracker/st_texture.h" 44 45#include "pipe/p_context.h" 46#include "pipe/p_defines.h" 47#include "pipe/p_inlines.h" 48#include "pipe/util/p_tile.h" 49 50 51#define DBG if (0) printf 52 53 54struct st_texture_object 55{ 56 struct gl_texture_object base; /* The "parent" object */ 57 58 /* The texture must include at least these levels once validated: 59 */ 60 GLuint firstLevel; 61 GLuint lastLevel; 62 63 /* Offset for firstLevel image: 64 */ 65 GLuint textureOffset; 66 67 /* On validation any active images held in main memory or in other 68 * textures will be copied to this texture and the old storage freed. 69 */ 70 struct pipe_texture *pt; 71 72 GLboolean imageOverride; 73 GLint depthOverride; 74 GLuint pitchOverride; 75}; 76 77 78 79static INLINE struct st_texture_object * 80st_texture_object(struct gl_texture_object *obj) 81{ 82 return (struct st_texture_object *) obj; 83} 84 85 86static INLINE struct st_texture_image * 87st_texture_image(struct gl_texture_image *img) 88{ 89 return (struct st_texture_image *) img; 90} 91 92 93struct pipe_texture * 94st_get_texobj_texture(struct gl_texture_object *texObj) 95{ 96 struct st_texture_object *stObj = st_texture_object(texObj); 97 return stObj->pt; 98} 99 100 101static enum pipe_texture_target 102gl_target_to_pipe(GLenum target) 103{ 104 switch (target) { 105 case GL_TEXTURE_1D: 106 return PIPE_TEXTURE_1D; 107 108 case GL_TEXTURE_2D: 109 case GL_TEXTURE_RECTANGLE_NV: 110 return PIPE_TEXTURE_2D; 111 112 case GL_TEXTURE_3D: 113 return PIPE_TEXTURE_3D; 114 115 case GL_TEXTURE_CUBE_MAP_ARB: 116 return PIPE_TEXTURE_CUBE; 117 118 default: 119 assert(0); 120 return 0; 121 } 122} 123 124 125/** 126 * Return nominal bytes per texel for a compressed format, 0 for non-compressed 127 * format. 128 */ 129static int 130compressed_num_bytes(GLuint mesaFormat) 131{ 132 switch(mesaFormat) { 133 case MESA_FORMAT_RGB_FXT1: 134 case MESA_FORMAT_RGBA_FXT1: 135 case MESA_FORMAT_RGB_DXT1: 136 case MESA_FORMAT_RGBA_DXT1: 137 return 2; 138 case MESA_FORMAT_RGBA_DXT3: 139 case MESA_FORMAT_RGBA_DXT5: 140 return 4; 141 default: 142 return 0; 143 } 144} 145 146 147static GLboolean 148st_IsTextureResident(GLcontext * ctx, struct gl_texture_object *texObj) 149{ 150#if 0 151 struct intel_context *intel = intel_context(ctx); 152 struct st_texture_object *stObj = st_texture_object(texObj); 153 154 return 155 stObj->pt && 156 stObj->pt->region && 157 intel_is_region_resident(intel, stObj->pt->region); 158#endif 159 return 1; 160} 161 162 163static struct gl_texture_image * 164st_NewTextureImage(GLcontext * ctx) 165{ 166 DBG("%s\n", __FUNCTION__); 167 (void) ctx; 168 return (struct gl_texture_image *) CALLOC_STRUCT(st_texture_image); 169} 170 171 172static struct gl_texture_object * 173st_NewTextureObject(GLcontext * ctx, GLuint name, GLenum target) 174{ 175 struct st_texture_object *obj = CALLOC_STRUCT(st_texture_object); 176 177 DBG("%s\n", __FUNCTION__); 178 _mesa_initialize_texture_object(&obj->base, name, target); 179 180 return &obj->base; 181} 182 183static void 184st_DeleteTextureObject(GLcontext *ctx, 185 struct gl_texture_object *texObj) 186{ 187 struct st_texture_object *stObj = st_texture_object(texObj); 188 189 if (stObj->pt) 190 ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt); 191 192 _mesa_delete_texture_object(ctx, texObj); 193} 194 195 196static void 197st_FreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage) 198{ 199 struct st_texture_image *stImage = st_texture_image(texImage); 200 201 DBG("%s\n", __FUNCTION__); 202 203 if (stImage->pt) { 204 ctx->st->pipe->texture_release(ctx->st->pipe, &stImage->pt); 205 } 206 207 if (texImage->Data) { 208 free(texImage->Data); 209 texImage->Data = NULL; 210 } 211} 212 213 214/* ================================================================ 215 * From linux kernel i386 header files, copes with odd sizes better 216 * than COPY_DWORDS would: 217 * XXX Put this in src/mesa/main/imports.h ??? 218 */ 219#if defined(i386) || defined(__i386__) 220static INLINE void * 221__memcpy(void *to, const void *from, size_t n) 222{ 223 int d0, d1, d2; 224 __asm__ __volatile__("rep ; movsl\n\t" 225 "testb $2,%b4\n\t" 226 "je 1f\n\t" 227 "movsw\n" 228 "1:\ttestb $1,%b4\n\t" 229 "je 2f\n\t" 230 "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2) 231 :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from) 232 :"memory"); 233 return (to); 234} 235#else 236#define __memcpy(a,b,c) memcpy(a,b,c) 237#endif 238 239 240/* The system memcpy (at least on ubuntu 5.10) has problems copying 241 * to agp (writecombined) memory from a source which isn't 64-byte 242 * aligned - there is a 4x performance falloff. 243 * 244 * The x86 __memcpy is immune to this but is slightly slower 245 * (10%-ish) than the system memcpy. 246 * 247 * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but 248 * isn't much faster than x86_memcpy for agp copies. 249 * 250 * TODO: switch dynamically. 251 */ 252static void * 253do_memcpy(void *dest, const void *src, size_t n) 254{ 255 if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) { 256 return __memcpy(dest, src, n); 257 } 258 else 259 return memcpy(dest, src, n); 260} 261 262 263/* Functions to store texture images. Where possible, textures 264 * will be created or further instantiated with image data, otherwise 265 * images will be stored in malloc'd memory. A validation step is 266 * required to pull those images into a texture, or otherwise 267 * decide a fallback is required. 268 */ 269 270 271static int 272logbase2(int n) 273{ 274 GLint i = 1; 275 GLint log2 = 0; 276 277 while (n > i) { 278 i *= 2; 279 log2++; 280 } 281 282 return log2; 283} 284 285 286/* Otherwise, store it in memory if (Border != 0) or (any dimension == 287 * 1). 288 * 289 * Otherwise, if max_level >= level >= min_level, create texture with 290 * space for images from min_level down to max_level. 291 * 292 * Otherwise, create texture with space for images from (level 0)..(1x1). 293 * Consider pruning this texture at a validation if the saving is worth it. 294 */ 295static void 296guess_and_alloc_texture(struct st_context *st, 297 struct st_texture_object *stObj, 298 const struct st_texture_image *stImage) 299{ 300 GLuint firstLevel; 301 GLuint lastLevel; 302 GLuint width = stImage->base.Width; 303 GLuint height = stImage->base.Height; 304 GLuint depth = stImage->base.Depth; 305 GLuint l2width, l2height, l2depth; 306 GLuint i, comp_byte = 0; 307 308 DBG("%s\n", __FUNCTION__); 309 310 if (stImage->base.Border) 311 return; 312 313 if (stImage->level > stObj->base.BaseLevel && 314 (stImage->base.Width == 1 || 315 (stObj->base.Target != GL_TEXTURE_1D && 316 stImage->base.Height == 1) || 317 (stObj->base.Target == GL_TEXTURE_3D && 318 stImage->base.Depth == 1))) 319 return; 320 321 /* If this image disrespects BaseLevel, allocate from level zero. 322 * Usually BaseLevel == 0, so it's unlikely to happen. 323 */ 324 if (stImage->level < stObj->base.BaseLevel) 325 firstLevel = 0; 326 else 327 firstLevel = stObj->base.BaseLevel; 328 329 330 /* Figure out image dimensions at start level. 331 */ 332 for (i = stImage->level; i > firstLevel; i--) { 333 width <<= 1; 334 if (height != 1) 335 height <<= 1; 336 if (depth != 1) 337 depth <<= 1; 338 } 339 340 /* Guess a reasonable value for lastLevel. This is probably going 341 * to be wrong fairly often and might mean that we have to look at 342 * resizable buffers, or require that buffers implement lazy 343 * pagetable arrangements. 344 */ 345 if ((stObj->base.MinFilter == GL_NEAREST || 346 stObj->base.MinFilter == GL_LINEAR) && 347 stImage->level == firstLevel) { 348 lastLevel = firstLevel; 349 } 350 else { 351 l2width = logbase2(width); 352 l2height = logbase2(height); 353 l2depth = logbase2(depth); 354 lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth); 355 } 356 357 assert(!stObj->pt); 358 if (stImage->base.IsCompressed) 359 comp_byte = compressed_num_bytes(stImage->base.TexFormat->MesaFormat); 360 stObj->pt = st_texture_create(st, 361 gl_target_to_pipe(stObj->base.Target), 362 st_mesa_format_to_pipe_format(stImage->base.TexFormat->MesaFormat), 363 firstLevel, 364 lastLevel, 365 width, 366 height, 367 depth, 368 comp_byte); 369 370 DBG("%s - success\n", __FUNCTION__); 371} 372 373 374 375 376static GLuint 377target_to_face(GLenum target) 378{ 379 switch (target) { 380 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 381 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 382 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 383 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 384 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 385 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 386 return ((GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X); 387 default: 388 return 0; 389 } 390} 391 392 393 394/* There are actually quite a few combinations this will work for, 395 * more than what I've listed here. 396 */ 397static GLboolean 398check_pbo_format(GLint internalFormat, 399 GLenum format, GLenum type, 400 const struct gl_texture_format *mesa_format) 401{ 402 switch (internalFormat) { 403 case 4: 404 case GL_RGBA: 405 return (format == GL_BGRA && 406 (type == GL_UNSIGNED_BYTE || 407 type == GL_UNSIGNED_INT_8_8_8_8_REV) && 408 mesa_format == &_mesa_texformat_argb8888); 409 case 3: 410 case GL_RGB: 411 return (format == GL_RGB && 412 type == GL_UNSIGNED_SHORT_5_6_5 && 413 mesa_format == &_mesa_texformat_rgb565); 414 case GL_YCBCR_MESA: 415 return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE); 416 default: 417 return GL_FALSE; 418 } 419} 420 421 422/* XXX: Do this for TexSubImage also: 423 */ 424static GLboolean 425try_pbo_upload(GLcontext *ctx, 426 struct st_texture_image *stImage, 427 const struct gl_pixelstore_attrib *unpack, 428 GLint internalFormat, 429 GLint width, GLint height, 430 GLenum format, GLenum type, const void *pixels) 431{ 432 return GL_FALSE; /* XXX fix flushing/locking/blitting below */ 433#if 000 434 struct intel_context *intel = intel_context(ctx); 435 struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); 436 GLuint src_offset, src_stride; 437 GLuint dst_offset, dst_stride; 438 439 if (!pbo || 440 ctx._ImageTransferState || 441 unpack->SkipPixels || unpack->SkipRows) { 442 _mesa_printf("%s: failure 1\n", __FUNCTION__); 443 return GL_FALSE; 444 } 445 446 src_offset = (GLuint) pixels; 447 448 if (unpack->RowLength > 0) 449 src_stride = unpack->RowLength; 450 else 451 src_stride = width; 452 453 dst_offset = st_texture_image_offset(stImage->pt, 454 stImage->face, 455 stImage->level); 456 457 dst_stride = stImage->pt->pitch; 458 459 { 460 struct _DriBufferObject *src_buffer = 461 intel_bufferobj_buffer(intel, pbo, INTEL_READ); 462 463 /* Temporary hack: cast to _DriBufferObject: 464 */ 465 struct _DriBufferObject *dst_buffer = 466 (struct _DriBufferObject *)stImage->pt->region->buffer; 467 468 469 intelEmitCopyBlit(intel, 470 stImage->pt->cpp, 471 src_stride, src_buffer, src_offset, 472 dst_stride, dst_buffer, dst_offset, 473 0, 0, 0, 0, width, height, 474 GL_COPY); 475 } 476 477 return GL_TRUE; 478#endif 479} 480 481 482 483static void 484st_TexImage(GLcontext * ctx, 485 GLint dims, 486 GLenum target, GLint level, 487 GLint internalFormat, 488 GLint width, GLint height, GLint depth, 489 GLint border, 490 GLenum format, GLenum type, const void *pixels, 491 const struct gl_pixelstore_attrib *unpack, 492 struct gl_texture_object *texObj, 493 struct gl_texture_image *texImage, 494 GLsizei imageSize, int compressed) 495{ 496 struct st_texture_object *stObj = st_texture_object(texObj); 497 struct st_texture_image *stImage = st_texture_image(texImage); 498 GLint postConvWidth = width; 499 GLint postConvHeight = height; 500 GLint texelBytes, sizeInBytes; 501 GLuint dstRowStride; 502 503 504 DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, 505 _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); 506 507 stImage->face = target_to_face(target); 508 stImage->level = level; 509 510 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 511 _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth, 512 &postConvHeight); 513 } 514 515 /* choose the texture format */ 516 texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat, 517 format, type); 518 519 _mesa_set_fetch_functions(texImage, dims); 520 521 if (texImage->TexFormat->TexelBytes == 0) { 522 /* must be a compressed format */ 523 texelBytes = 0; 524 texImage->IsCompressed = GL_TRUE; 525 texImage->CompressedSize = 526 ctx->Driver.CompressedTextureSize(ctx, texImage->Width, 527 texImage->Height, texImage->Depth, 528 texImage->TexFormat->MesaFormat); 529 } 530 else { 531 texelBytes = texImage->TexFormat->TexelBytes; 532 533 /* Minimum pitch of 32 bytes */ 534 if (postConvWidth * texelBytes < 32) { 535 postConvWidth = 32 / texelBytes; 536 texImage->RowStride = postConvWidth; 537 } 538 539 assert(texImage->RowStride == postConvWidth); 540 } 541 542 /* Release the reference to a potentially orphaned buffer. 543 * Release any old malloced memory. 544 */ 545 if (stImage->pt) { 546 ctx->st->pipe->texture_release(ctx->st->pipe, &stImage->pt); 547 assert(!texImage->Data); 548 } 549 else if (texImage->Data) { 550 _mesa_align_free(texImage->Data); 551 } 552 553 /* If this is the only texture image in the texture, could call 554 * bmBufferData with NULL data to free the old block and avoid 555 * waiting on any outstanding fences. 556 */ 557 if (stObj->pt && 558 stObj->pt->first_level == level && 559 stObj->pt->last_level == level && 560 stObj->pt->target != PIPE_TEXTURE_CUBE && 561 !st_texture_match_image(stObj->pt, &stImage->base, 562 stImage->face, stImage->level)) { 563 564 DBG("release it\n"); 565 ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt); 566 assert(!stObj->pt); 567 } 568 569 if (!stObj->pt) { 570 guess_and_alloc_texture(ctx->st, stObj, stImage); 571 if (!stObj->pt) { 572 DBG("guess_and_alloc_texture: failed\n"); 573 } 574 } 575 576 assert(!stImage->pt); 577 578 if (stObj->pt && 579 st_texture_match_image(stObj->pt, &stImage->base, 580 stImage->face, stImage->level)) { 581 582 pipe_texture_reference(ctx->st->pipe, &stImage->pt, stObj->pt); 583 assert(stImage->pt); 584 } 585 586 if (!stImage->pt) 587 DBG("XXX: Image did not fit into texture - storing in local memory!\n"); 588 589#if 0 /* XXX FIX when st_buffer_objects are in place */ 590 /* PBO fastpaths: 591 */ 592 if (dims <= 2 && 593 stImage->pt && 594 intel_buffer_object(unpack->BufferObj) && 595 check_pbo_format(internalFormat, format, 596 type, texImage->TexFormat)) { 597 598 DBG("trying pbo upload\n"); 599 600 601 602 /* Otherwise, attempt to use the blitter for PBO image uploads. 603 */ 604 if (try_pbo_upload(intel, stImage, unpack, 605 internalFormat, 606 width, height, format, type, pixels)) { 607 DBG("pbo upload succeeded\n"); 608 return; 609 } 610 611 DBG("pbo upload failed\n"); 612 } 613#else 614 (void) try_pbo_upload; 615 (void) check_pbo_format; 616#endif 617 618 619 /* st_CopyTexImage calls this function with pixels == NULL, with 620 * the expectation that the texture will be set up but nothing 621 * more will be done. This is where those calls return: 622 */ 623 if (compressed) { 624 pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels, 625 unpack, 626 "glCompressedTexImage"); 627 } else { 628 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, 629 format, type, 630 pixels, unpack, "glTexImage"); 631 } 632 if (!pixels) 633 return; 634 635 if (stImage->pt) { 636 texImage->Data = st_texture_image_map(ctx->st, stImage, 0); 637 dstRowStride = stImage->surface->pitch * stImage->surface->cpp; 638 } 639 else { 640 /* Allocate regular memory and store the image there temporarily. */ 641 if (texImage->IsCompressed) { 642 sizeInBytes = texImage->CompressedSize; 643 dstRowStride = 644 _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width); 645 assert(dims != 3); 646 } 647 else { 648 dstRowStride = postConvWidth * texelBytes; 649 sizeInBytes = depth * dstRowStride * postConvHeight; 650 } 651 652 texImage->Data = malloc(sizeInBytes); 653 } 654 655 DBG("Upload image %dx%dx%d row_len %x pitch %x\n", 656 width, height, depth, width * texelBytes, dstRowStride); 657 658 /* Copy data. Would like to know when it's ok for us to eg. use 659 * the blitter to copy. Or, use the hardware to do the format 660 * conversion and copy: 661 */ 662 if (compressed) { 663 memcpy(texImage->Data, pixels, imageSize); 664 } 665 else { 666 GLuint srcImageStride = _mesa_image_image_stride(unpack, width, height, 667 format, type); 668 int i; 669 const GLubyte *src = (const GLubyte *) pixels; 670 671 for (i = 0; i++ < depth;) { 672 if (!texImage->TexFormat->StoreImage(ctx, dims, 673 texImage->_BaseFormat, 674 texImage->TexFormat, 675 texImage->Data, 676 0, 0, 0, /* dstX/Y/Zoffset */ 677 dstRowStride, 678 texImage->ImageOffsets, 679 width, height, 1, 680 format, type, src, unpack)) { 681 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 682 } 683 684 if (stImage->pt && i < depth) { 685 st_texture_image_unmap(stImage); 686 texImage->Data = st_texture_image_map(ctx->st, stImage, i); 687 src += srcImageStride; 688 } 689 } 690 } 691 692 _mesa_unmap_teximage_pbo(ctx, unpack); 693 694 if (stImage->pt) { 695 st_texture_image_unmap(stImage); 696 texImage->Data = NULL; 697 } 698 699#if 0 700 /* GL_SGIS_generate_mipmap -- this can be accelerated now. 701 */ 702 if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 703 intel_generate_mipmap(ctx, target, 704 &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 705 texObj); 706 } 707#endif 708} 709 710 711static void 712st_TexImage3D(GLcontext * ctx, 713 GLenum target, GLint level, 714 GLint internalFormat, 715 GLint width, GLint height, GLint depth, 716 GLint border, 717 GLenum format, GLenum type, const void *pixels, 718 const struct gl_pixelstore_attrib *unpack, 719 struct gl_texture_object *texObj, 720 struct gl_texture_image *texImage) 721{ 722 st_TexImage(ctx, 3, target, level, 723 internalFormat, width, height, depth, border, 724 format, type, pixels, unpack, texObj, texImage, 0, 0); 725} 726 727 728static void 729st_TexImage2D(GLcontext * ctx, 730 GLenum target, GLint level, 731 GLint internalFormat, 732 GLint width, GLint height, GLint border, 733 GLenum format, GLenum type, const void *pixels, 734 const struct gl_pixelstore_attrib *unpack, 735 struct gl_texture_object *texObj, 736 struct gl_texture_image *texImage) 737{ 738 st_TexImage(ctx, 2, target, level, 739 internalFormat, width, height, 1, border, 740 format, type, pixels, unpack, texObj, texImage, 0, 0); 741} 742 743 744static void 745st_TexImage1D(GLcontext * ctx, 746 GLenum target, GLint level, 747 GLint internalFormat, 748 GLint width, GLint border, 749 GLenum format, GLenum type, const void *pixels, 750 const struct gl_pixelstore_attrib *unpack, 751 struct gl_texture_object *texObj, 752 struct gl_texture_image *texImage) 753{ 754 st_TexImage(ctx, 1, target, level, 755 internalFormat, width, 1, 1, border, 756 format, type, pixels, unpack, texObj, texImage, 0, 0); 757} 758 759 760static void 761st_CompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, 762 GLint internalFormat, 763 GLint width, GLint height, GLint border, 764 GLsizei imageSize, const GLvoid *data, 765 struct gl_texture_object *texObj, 766 struct gl_texture_image *texImage ) 767{ 768 st_TexImage(ctx, 2, target, level, 769 internalFormat, width, height, 1, border, 770 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1); 771} 772 773 774/** 775 * Need to map texture image into memory before copying image data, 776 * then unmap it. 777 */ 778static void 779st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, 780 GLenum format, GLenum type, GLvoid * pixels, 781 struct gl_texture_object *texObj, 782 struct gl_texture_image *texImage, int compressed) 783{ 784 struct st_texture_image *stImage = st_texture_image(texImage); 785 GLuint dstImageStride = _mesa_image_image_stride(&ctx->Pack, texImage->Width, 786 texImage->Height, format, 787 type); 788 GLuint depth; 789 int i; 790 GLubyte *dest; 791 792 /* Map */ 793 if (stImage->pt) { 794 /* Image is stored in hardware format in a buffer managed by the 795 * kernel. Need to explicitly map and unmap it. 796 */ 797 texImage->Data = st_texture_image_map(ctx->st, stImage, 0); 798 texImage->RowStride = stImage->surface->pitch; 799 } 800 else { 801 /* Otherwise, the image should actually be stored in 802 * texImage->Data. This is pretty confusing for 803 * everybody, I'd much prefer to separate the two functions of 804 * texImage->Data - storage for texture images in main memory 805 * and access (ie mappings) of images. In other words, we'd 806 * create a new texImage->Map field and leave Data simply for 807 * storage. 808 */ 809 assert(texImage->Data); 810 } 811 812 depth = texImage->Depth; 813 texImage->Depth = 1; 814 815 dest = (GLubyte *) pixels; 816 817 for (i = 0; i++ < depth;) { 818 if (compressed) { 819 _mesa_get_compressed_teximage(ctx, target, level, dest, 820 texObj, texImage); 821 } else { 822 _mesa_get_teximage(ctx, target, level, format, type, dest, 823 texObj, texImage); 824 } 825 826 if (stImage->pt && i < depth) { 827 st_texture_image_unmap(stImage); 828 texImage->Data = st_texture_image_map(ctx->st, stImage, i); 829 dest += dstImageStride; 830 } 831 } 832 833 texImage->Depth = depth; 834 835 /* Unmap */ 836 if (stImage->pt) { 837 st_texture_image_unmap(stImage); 838 texImage->Data = NULL; 839 } 840} 841 842 843static void 844st_GetTexImage(GLcontext * ctx, GLenum target, GLint level, 845 GLenum format, GLenum type, GLvoid * pixels, 846 struct gl_texture_object *texObj, 847 struct gl_texture_image *texImage) 848{ 849 st_get_tex_image(ctx, target, level, format, type, pixels, 850 texObj, texImage, 0); 851} 852 853 854static void 855st_GetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, 856 GLvoid *pixels, 857 const struct gl_texture_object *texObj, 858 const struct gl_texture_image *texImage) 859{ 860 st_get_tex_image(ctx, target, level, 0, 0, pixels, 861 (struct gl_texture_object *) texObj, 862 (struct gl_texture_image *) texImage, 1); 863} 864 865 866 867static void 868st_TexSubimage(GLcontext * ctx, 869 GLint dims, 870 GLenum target, GLint level, 871 GLint xoffset, GLint yoffset, GLint zoffset, 872 GLint width, GLint height, GLint depth, 873 GLenum format, GLenum type, const void *pixels, 874 const struct gl_pixelstore_attrib *packing, 875 struct gl_texture_object *texObj, 876 struct gl_texture_image *texImage) 877{ 878 struct st_texture_image *stImage = st_texture_image(texImage); 879 GLuint dstRowStride; 880 GLuint srcImageStride = _mesa_image_image_stride(packing, width, height, 881 format, type); 882 int i; 883 const GLubyte *src; 884 885 DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__, 886 _mesa_lookup_enum_by_nr(target), 887 level, xoffset, yoffset, width, height); 888 889 pixels = 890 _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format, 891 type, pixels, packing, "glTexSubImage2D"); 892 if (!pixels) 893 return; 894 895 /* Map buffer if necessary. Need to lock to prevent other contexts 896 * from uploading the buffer under us. 897 */ 898 if (stImage->pt) { 899 texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset); 900 dstRowStride = stImage->surface->pitch * stImage->surface->cpp; 901 } 902 903 src = (const GLubyte *) pixels; 904 905 for (i = 0; i++ < depth;) { 906 if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, 907 texImage->TexFormat, 908 texImage->Data, 909 xoffset, yoffset, 0, 910 dstRowStride, 911 texImage->ImageOffsets, 912 width, height, 1, 913 format, type, src, packing)) { 914 _mesa_error(ctx, GL_OUT_OF_MEMORY, "st_TexSubImage"); 915 } 916 917 if (stImage->pt && i < depth) { 918 st_texture_image_unmap(stImage); 919 texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i); 920 src += srcImageStride; 921 } 922 } 923 924#if 0 925 /* GL_SGIS_generate_mipmap */ 926 if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 927 _mesa_generate_mipmap(ctx, target, 928 &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 929 texObj); 930 } 931#endif 932 933 _mesa_unmap_teximage_pbo(ctx, packing); 934 935 if (stImage->pt) { 936 st_texture_image_unmap(stImage); 937 texImage->Data = NULL; 938 } 939} 940 941 942 943static void 944st_TexSubImage3D(GLcontext * ctx, 945 GLenum target, 946 GLint level, 947 GLint xoffset, GLint yoffset, GLint zoffset, 948 GLsizei width, GLsizei height, GLsizei depth, 949 GLenum format, GLenum type, 950 const GLvoid * pixels, 951 const struct gl_pixelstore_attrib *packing, 952 struct gl_texture_object *texObj, 953 struct gl_texture_image *texImage) 954{ 955 st_TexSubimage(ctx, 3, target, level, 956 xoffset, yoffset, zoffset, 957 width, height, depth, 958 format, type, pixels, packing, texObj, texImage); 959} 960 961 962 963static void 964st_TexSubImage2D(GLcontext * ctx, 965 GLenum target, 966 GLint level, 967 GLint xoffset, GLint yoffset, 968 GLsizei width, GLsizei height, 969 GLenum format, GLenum type, 970 const GLvoid * pixels, 971 const struct gl_pixelstore_attrib *packing, 972 struct gl_texture_object *texObj, 973 struct gl_texture_image *texImage) 974{ 975 st_TexSubimage(ctx, 2, target, level, 976 xoffset, yoffset, 0, 977 width, height, 1, 978 format, type, pixels, packing, texObj, texImage); 979} 980 981 982static void 983st_TexSubImage1D(GLcontext * ctx, 984 GLenum target, 985 GLint level, 986 GLint xoffset, 987 GLsizei width, 988 GLenum format, GLenum type, 989 const GLvoid * pixels, 990 const struct gl_pixelstore_attrib *packing, 991 struct gl_texture_object *texObj, 992 struct gl_texture_image *texImage) 993{ 994 st_TexSubimage(ctx, 1, target, level, 995 xoffset, 0, 0, 996 width, 1, 1, 997 format, type, pixels, packing, texObj, texImage); 998} 999 1000 1001 1002/** 1003 * Return 0 for GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1004 * 1 for GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 1005 * etc. 1006 * XXX duplicated from main/teximage.c 1007 */ 1008static uint 1009texture_face(GLenum target) 1010{ 1011 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 1012 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) 1013 return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; 1014 else 1015 return 0; 1016} 1017 1018 1019 1020/** 1021 * Do a CopyTexSubImage operation by mapping the source surface and 1022 * dest surface and using get_tile()/put_tile() to access the pixels/texels. 1023 * 1024 * Note: srcY=0=TOP of renderbuffer 1025 */ 1026static void 1027fallback_copy_texsubimage(GLcontext *ctx, 1028 GLenum target, 1029 GLint level, 1030 struct st_renderbuffer *strb, 1031 struct st_texture_image *stImage, 1032 GLenum baseFormat, 1033 GLint destX, GLint destY, GLint destZ, 1034 GLint srcX, GLint srcY, 1035 GLsizei width, GLsizei height) 1036{ 1037 struct pipe_context *pipe = ctx->st->pipe; 1038 const uint face = texture_face(target); 1039 struct pipe_texture *pt = stImage->pt; 1040 struct pipe_surface *src_surf, *dest_surf; 1041 GLfloat *data; 1042 GLint row, yStep; 1043 1044 /* determine bottom-to-top vs. top-to-bottom order */ 1045 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 1046 destY = height - 1 - destY; 1047 yStep = -1; 1048 } 1049 else { 1050 yStep = 1; 1051 } 1052 1053 src_surf = strb->surface; 1054 1055 dest_surf = pipe->get_tex_surface(pipe, pt, 1056 face, level, destZ); 1057 1058 /* buffer for one row */ 1059 data = (GLfloat *) malloc(width * 4 * sizeof(GLfloat)); 1060 1061 /* do copy row by row */ 1062 for (row = 0; row < height; row++) { 1063 pipe_get_tile_rgba(pipe, src_surf, srcX, srcY + row, width, 1, data); 1064 1065 /* XXX we're ignoring convolution for now */ 1066 if (ctx->_ImageTransferState) { 1067 _mesa_apply_rgba_transfer_ops(ctx, 1068 ctx->_ImageTransferState & ~IMAGE_CONVOLUTION_BIT, 1069 width, (GLfloat (*)[4])data); 1070 } 1071 1072 pipe_put_tile_rgba(pipe, dest_surf, destX, destY, width, 1, data); 1073 destY += yStep; 1074 } 1075 1076 free(data); 1077} 1078 1079 1080 1081 1082/** 1083 * Do a CopyTex[Sub]Image using an optimized hardware (blit) path. 1084 * Note that the region to copy has already been clip tested. 1085 * 1086 * Note: srcY=0=Bottom of renderbuffer 1087 * 1088 * \return GL_TRUE if success, GL_FALSE if failure (use a fallback) 1089 */ 1090static void 1091do_copy_texsubimage(GLcontext *ctx, 1092 GLenum target, GLint level, 1093 GLint destX, GLint destY, GLint destZ, 1094 GLint srcX, GLint srcY, 1095 GLsizei width, GLsizei height) 1096{ 1097 struct gl_texture_unit *texUnit = 1098 &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1099 struct gl_texture_object *texObj = 1100 _mesa_select_tex_object(ctx, texUnit, target); 1101 struct gl_texture_image *texImage = 1102 _mesa_select_tex_image(ctx, texObj, target, level); 1103 struct st_texture_image *stImage = st_texture_image(texImage); 1104 GLenum baseFormat = texImage->InternalFormat; 1105 struct gl_framebuffer *fb = ctx->ReadBuffer; 1106 struct st_renderbuffer *strb; 1107 struct pipe_context *pipe = ctx->st->pipe; 1108 struct pipe_surface *dest_surface; 1109 uint dest_format, src_format; 1110 1111 (void) texImage; 1112 1113 /* determine if copying depth or color data */ 1114 if (baseFormat == GL_DEPTH_COMPONENT) { 1115 strb = st_renderbuffer(fb->_DepthBuffer); 1116 } 1117 else if (baseFormat == GL_DEPTH_STENCIL_EXT) { 1118 strb = st_renderbuffer(fb->_StencilBuffer); 1119 } 1120 else { 1121 /* baseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */ 1122 strb = st_renderbuffer(fb->_ColorReadBuffer); 1123 } 1124 1125 assert(strb); 1126 assert(strb->surface); 1127 assert(stImage->pt); 1128 1129 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 1130 srcY = strb->Base.Height - srcY - height; 1131 } 1132 1133 src_format = strb->surface->format; 1134 dest_format = stImage->pt->format; 1135 1136 dest_surface = pipe->get_tex_surface(pipe, stImage->pt, stImage->face, 1137 stImage->level, destZ); 1138 1139 if (src_format == dest_format && 1140 ctx->_ImageTransferState == 0x0 && 1141 strb->surface->buffer && 1142 dest_surface->buffer && 1143 strb->surface->cpp == stImage->pt->cpp) { 1144 /* do blit-style copy */ 1145 1146 /* XXX may need to invert image depending on window 1147 * vs. user-created FBO 1148 */ 1149 1150#if 0 1151 /* A bit of fiddling to get the blitter to work with -ve 1152 * pitches. But we get a nice inverted blit this way, so it's 1153 * worth it: 1154 */ 1155 intelEmitCopyBlit(intel, 1156 stImage->pt->cpp, 1157 -src->pitch, 1158 src->buffer, 1159 src->height * src->pitch * src->cpp, 1160 stImage->pt->pitch, 1161 stImage->pt->region->buffer, 1162 dest_offset, 1163 x, y + height, dstx, dsty, width, height, 1164 GL_COPY); /* ? */ 1165#else 1166 1167 pipe->surface_copy(pipe, 1168 /* dest */ 1169 dest_surface, 1170 destX, destY, 1171 /* src */ 1172 strb->surface, 1173 srcX, srcY, 1174 /* size */ 1175 width, height); 1176#endif 1177 } 1178 else { 1179 fallback_copy_texsubimage(ctx, target, level, 1180 strb, stImage, baseFormat, 1181 destX, destY, destZ, 1182 srcX, srcY, width, height); 1183 } 1184 1185 pipe_surface_reference(&dest_surface, NULL); 1186 1187#if 0 1188 /* GL_SGIS_generate_mipmap -- this can be accelerated now. 1189 * XXX Add a ctx->Driver.GenerateMipmaps() function? 1190 */ 1191 if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 1192 intel_generate_mipmap(ctx, target, 1193 &ctx->Texture.Unit[ctx->Texture.CurrentUnit], 1194 texObj); 1195 } 1196#endif 1197 1198} 1199 1200 1201 1202static void 1203st_CopyTexImage1D(GLcontext * ctx, GLenum target, GLint level, 1204 GLenum internalFormat, 1205 GLint x, GLint y, GLsizei width, GLint border) 1206{ 1207 struct gl_texture_unit *texUnit = 1208 &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1209 struct gl_texture_object *texObj = 1210 _mesa_select_tex_object(ctx, texUnit, target); 1211 struct gl_texture_image *texImage = 1212 _mesa_select_tex_image(ctx, texObj, target, level); 1213 1214#if 0 1215 if (border) 1216 goto fail; 1217#endif 1218 1219 /* Setup or redefine the texture object, texture and texture 1220 * image. Don't populate yet. 1221 */ 1222 ctx->Driver.TexImage1D(ctx, target, level, internalFormat, 1223 width, border, 1224 GL_RGBA, CHAN_TYPE, NULL, 1225 &ctx->DefaultPacking, texObj, texImage); 1226 1227 do_copy_texsubimage(ctx, target, level, 1228 0, 0, 0, 1229 x, y, width, 1); 1230} 1231 1232 1233static void 1234st_CopyTexImage2D(GLcontext * ctx, GLenum target, GLint level, 1235 GLenum internalFormat, 1236 GLint x, GLint y, GLsizei width, GLsizei height, 1237 GLint border) 1238{ 1239 struct gl_texture_unit *texUnit = 1240 &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1241 struct gl_texture_object *texObj = 1242 _mesa_select_tex_object(ctx, texUnit, target); 1243 struct gl_texture_image *texImage = 1244 _mesa_select_tex_image(ctx, texObj, target, level); 1245 1246#if 0 1247 if (border) 1248 goto fail; 1249#endif 1250 1251 /* Setup or redefine the texture object, texture and texture 1252 * image. Don't populate yet. 1253 */ 1254 ctx->Driver.TexImage2D(ctx, target, level, internalFormat, 1255 width, height, border, 1256 GL_RGBA, CHAN_TYPE, NULL, 1257 &ctx->DefaultPacking, texObj, texImage); 1258 1259 1260 do_copy_texsubimage(ctx, target, level, 1261 0, 0, 0, 1262 x, y, width, height); 1263} 1264 1265 1266static void 1267st_CopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level, 1268 GLint xoffset, GLint x, GLint y, GLsizei width) 1269{ 1270 const GLint yoffset = 0, zoffset = 0; 1271 const GLsizei height = 1; 1272 do_copy_texsubimage(ctx, target, level, 1273 xoffset, yoffset, zoffset, 1274 x, y, width, height); 1275} 1276 1277 1278static void 1279st_CopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level, 1280 GLint xoffset, GLint yoffset, 1281 GLint x, GLint y, GLsizei width, GLsizei height) 1282{ 1283 const GLint zoffset = 0; 1284 do_copy_texsubimage(ctx, target, level, 1285 xoffset, yoffset, zoffset, 1286 x, y, width, height); 1287} 1288 1289 1290static void 1291st_CopyTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, 1292 GLint xoffset, GLint yoffset, GLint zoffset, 1293 GLint x, GLint y, GLsizei width, GLsizei height) 1294{ 1295 do_copy_texsubimage(ctx, target, level, 1296 xoffset, yoffset, zoffset, 1297 x, y, width, height); 1298} 1299 1300 1301 1302 1303/** 1304 * Compute which mipmap levels that really need to be sent to the hardware. 1305 * This depends on the base image size, GL_TEXTURE_MIN_LOD, 1306 * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. 1307 */ 1308static void 1309calculate_first_last_level(struct st_texture_object *stObj) 1310{ 1311 struct gl_texture_object *tObj = &stObj->base; 1312 const struct gl_texture_image *const baseImage = 1313 tObj->Image[0][tObj->BaseLevel]; 1314 1315 /* These must be signed values. MinLod and MaxLod can be negative numbers, 1316 * and having firstLevel and lastLevel as signed prevents the need for 1317 * extra sign checks. 1318 */ 1319 int firstLevel; 1320 int lastLevel; 1321 1322 /* Yes, this looks overly complicated, but it's all needed. 1323 */ 1324 switch (tObj->Target) { 1325 case GL_TEXTURE_1D: 1326 case GL_TEXTURE_2D: 1327 case GL_TEXTURE_3D: 1328 case GL_TEXTURE_CUBE_MAP: 1329 if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) { 1330 /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL. 1331 */ 1332 firstLevel = lastLevel = tObj->BaseLevel; 1333 } 1334 else { 1335 firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5); 1336 firstLevel = MAX2(firstLevel, tObj->BaseLevel); 1337 lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5); 1338 lastLevel = MAX2(lastLevel, tObj->BaseLevel); 1339 lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); 1340 lastLevel = MIN2(lastLevel, tObj->MaxLevel); 1341 lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ 1342 } 1343 break; 1344 case GL_TEXTURE_RECTANGLE_NV: 1345 case GL_TEXTURE_4D_SGIS: 1346 firstLevel = lastLevel = 0; 1347 break; 1348 default: 1349 return; 1350 } 1351 1352 /* save these values */ 1353 stObj->firstLevel = firstLevel; 1354 stObj->lastLevel = lastLevel; 1355} 1356 1357 1358static void 1359copy_image_data_to_texture(struct st_context *st, 1360 struct st_texture_object *stObj, 1361 struct st_texture_image *stImage) 1362{ 1363 if (stImage->pt) { 1364 /* Copy potentially with the blitter: 1365 */ 1366 st_texture_image_copy(st->pipe, 1367 stObj->pt, /* dest texture */ 1368 stImage->face, stImage->level, 1369 stImage->pt /* src texture */ 1370 ); 1371 1372 st->pipe->texture_release(st->pipe, &stImage->pt); 1373 } 1374 else { 1375 assert(stImage->base.Data != NULL); 1376 1377 /* More straightforward upload. 1378 */ 1379 st_texture_image_data(st->pipe, 1380 stObj->pt, 1381 stImage->face, 1382 stImage->level, 1383 stImage->base.Data, 1384 stImage->base.RowStride, 1385 stImage->base.RowStride * 1386 stImage->base.Height); 1387 _mesa_align_free(stImage->base.Data); 1388 stImage->base.Data = NULL; 1389 } 1390 1391 pipe_texture_reference(st->pipe, &stImage->pt, stObj->pt); 1392} 1393 1394 1395/** 1396 * Called during state validation. When this function is finished, 1397 * the texture object should be ready for rendering. 1398 * \return GL_FALSE if a texture border is present, GL_TRUE otherwise 1399 */ 1400GLboolean 1401st_finalize_texture(GLcontext *ctx, 1402 struct pipe_context *pipe, 1403 struct gl_texture_object *tObj, 1404 GLboolean *needFlush) 1405{ 1406 struct st_texture_object *stObj = st_texture_object(tObj); 1407 const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 1408 int comp_byte = 0; 1409 int cpp; 1410 GLuint face, i; 1411 struct st_texture_image *firstImage; 1412 1413 *needFlush = GL_FALSE; 1414 1415 /* We know/require this is true by now: 1416 */ 1417 assert(stObj->base._Complete); 1418 1419 /* What levels must the texture include at a minimum? 1420 */ 1421 calculate_first_last_level(stObj); 1422 firstImage = st_texture_image(stObj->base.Image[0][stObj->firstLevel]); 1423 1424 /* Fallback case: 1425 */ 1426 if (firstImage->base.Border) { 1427 if (stObj->pt) { 1428 ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt); 1429 } 1430 return GL_FALSE; 1431 } 1432 1433 1434 /* If both firstImage and stObj point to a texture which can contain 1435 * all active images, favour firstImage. Note that because of the 1436 * completeness requirement, we know that the image dimensions 1437 * will match. 1438 */ 1439 if (firstImage->pt && 1440 firstImage->pt != stObj->pt && 1441 firstImage->pt->first_level <= stObj->firstLevel && 1442 firstImage->pt->last_level >= stObj->lastLevel) { 1443 1444 if (stObj->pt) 1445 ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt); 1446 1447 pipe_texture_reference(ctx->st->pipe, &stObj->pt, firstImage->pt); 1448 } 1449 1450 if (firstImage->base.IsCompressed) { 1451 comp_byte = compressed_num_bytes(firstImage->base.TexFormat->MesaFormat); 1452 cpp = comp_byte; 1453 } 1454 else { 1455 cpp = firstImage->base.TexFormat->TexelBytes; 1456 } 1457 1458 /* Check texture can hold all active levels. Check texture matches 1459 * target, imageFormat, etc. 1460 * 1461 * XXX: For some layouts (eg i945?), the test might have to be 1462 * first_level == firstLevel, as the texture isn't valid except at the 1463 * original start level. Hope to get around this by 1464 * programming minLod, maxLod, baseLevel into the hardware and 1465 * leaving the texture alone. 1466 */ 1467 if (stObj->pt && 1468 (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) || 1469 stObj->pt->format != 1470 st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat) || 1471 stObj->pt->first_level != stObj->firstLevel || 1472 stObj->pt->last_level != stObj->lastLevel || 1473 stObj->pt->width[0] != firstImage->base.Width || 1474 stObj->pt->height[0] != firstImage->base.Height || 1475 stObj->pt->depth[0] != firstImage->base.Depth || 1476 stObj->pt->cpp != cpp || 1477 stObj->pt->compressed != firstImage->base.IsCompressed)) { 1478 ctx->st->pipe->texture_release(ctx->st->pipe, &stObj->pt); 1479 } 1480 1481 1482 /* May need to create a new texture: 1483 */ 1484 if (!stObj->pt) { 1485 stObj->pt = st_texture_create(ctx->st, 1486 gl_target_to_pipe(stObj->base.Target), 1487 st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat), 1488 stObj->firstLevel, 1489 stObj->lastLevel, 1490 firstImage->base.Width, 1491 firstImage->base.Height, 1492 firstImage->base.Depth, 1493 comp_byte); 1494 } 1495 1496 /* Pull in any images not in the object's texture: 1497 */ 1498 for (face = 0; face < nr_faces; face++) { 1499 for (i = stObj->firstLevel; i <= stObj->lastLevel; i++) { 1500 struct st_texture_image *stImage = 1501 st_texture_image(stObj->base.Image[face][i]); 1502 1503 /* Need to import images in main memory or held in other textures. 1504 */ 1505 if (stObj->pt != stImage->pt) { 1506 copy_image_data_to_texture(ctx->st, stObj, stImage); 1507 *needFlush = GL_TRUE; 1508 } 1509 } 1510 } 1511 1512 1513 return GL_TRUE; 1514} 1515 1516 1517 1518 1519void 1520st_init_texture_functions(struct dd_function_table *functions) 1521{ 1522 functions->ChooseTextureFormat = st_ChooseTextureFormat; 1523 functions->TexImage1D = st_TexImage1D; 1524 functions->TexImage2D = st_TexImage2D; 1525 functions->TexImage3D = st_TexImage3D; 1526 functions->TexSubImage1D = st_TexSubImage1D; 1527 functions->TexSubImage2D = st_TexSubImage2D; 1528 functions->TexSubImage3D = st_TexSubImage3D; 1529 functions->CopyTexImage1D = st_CopyTexImage1D; 1530 functions->CopyTexImage2D = st_CopyTexImage2D; 1531 functions->CopyTexSubImage1D = st_CopyTexSubImage1D; 1532 functions->CopyTexSubImage2D = st_CopyTexSubImage2D; 1533 functions->CopyTexSubImage3D = st_CopyTexSubImage3D; 1534 1535 functions->GetTexImage = st_GetTexImage; 1536 1537 /* compressed texture functions */ 1538 functions->CompressedTexImage2D = st_CompressedTexImage2D; 1539 functions->GetCompressedTexImage = st_GetCompressedTexImage; 1540 1541 functions->NewTextureObject = st_NewTextureObject; 1542 functions->NewTextureImage = st_NewTextureImage; 1543 functions->DeleteTexture = st_DeleteTextureObject; 1544 functions->FreeTexImageData = st_FreeTextureImageData; 1545 functions->UpdateTexturePalette = 0; 1546 functions->IsTextureResident = st_IsTextureResident; 1547 1548 functions->TextureMemCpy = do_memcpy; 1549 1550 /* XXX Temporary until we can query pipe's texture sizes */ 1551 functions->TestProxyTexImage = _mesa_test_proxy_teximage; 1552} 1553