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