st_cb_texture.c revision 0823ef84a5c3a6332ea76d0001febf6aaa440dc3
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/mfeatures.h" 29#include "main/bufferobj.h" 30#include "main/enums.h" 31#include "main/fbobject.h" 32#include "main/formats.h" 33#include "main/image.h" 34#include "main/imports.h" 35#include "main/macros.h" 36#include "main/mipmap.h" 37#include "main/pack.h" 38#include "main/pbo.h" 39#include "main/pixeltransfer.h" 40#include "main/texcompress.h" 41#include "main/texfetch.h" 42#include "main/texgetimage.h" 43#include "main/teximage.h" 44#include "main/texobj.h" 45#include "main/texstore.h" 46 47#include "state_tracker/st_debug.h" 48#include "state_tracker/st_context.h" 49#include "state_tracker/st_cb_fbo.h" 50#include "state_tracker/st_cb_flush.h" 51#include "state_tracker/st_cb_texture.h" 52#include "state_tracker/st_format.h" 53#include "state_tracker/st_texture.h" 54#include "state_tracker/st_gen_mipmap.h" 55#include "state_tracker/st_atom.h" 56 57#include "pipe/p_context.h" 58#include "pipe/p_defines.h" 59#include "util/u_inlines.h" 60#include "pipe/p_shader_tokens.h" 61#include "util/u_tile.h" 62#include "util/u_blit.h" 63#include "util/u_format.h" 64#include "util/u_surface.h" 65#include "util/u_sampler.h" 66#include "util/u_math.h" 67#include "util/u_box.h" 68 69#define DBG if (0) printf 70 71 72static enum pipe_texture_target 73gl_target_to_pipe(GLenum target) 74{ 75 switch (target) { 76 case GL_TEXTURE_1D: 77 return PIPE_TEXTURE_1D; 78 case GL_TEXTURE_2D: 79 return PIPE_TEXTURE_2D; 80 case GL_TEXTURE_RECTANGLE_NV: 81 return PIPE_TEXTURE_RECT; 82 case GL_TEXTURE_3D: 83 return PIPE_TEXTURE_3D; 84 case GL_TEXTURE_CUBE_MAP_ARB: 85 return PIPE_TEXTURE_CUBE; 86 case GL_TEXTURE_1D_ARRAY_EXT: 87 return PIPE_TEXTURE_1D_ARRAY; 88 case GL_TEXTURE_2D_ARRAY_EXT: 89 return PIPE_TEXTURE_2D_ARRAY; 90 case GL_TEXTURE_BUFFER: 91 return PIPE_BUFFER; 92 default: 93 assert(0); 94 return 0; 95 } 96} 97 98 99/** called via ctx->Driver.NewTextureImage() */ 100static struct gl_texture_image * 101st_NewTextureImage(struct gl_context * ctx) 102{ 103 DBG("%s\n", __FUNCTION__); 104 (void) ctx; 105 return (struct gl_texture_image *) ST_CALLOC_STRUCT(st_texture_image); 106} 107 108 109/** called via ctx->Driver.NewTextureObject() */ 110static struct gl_texture_object * 111st_NewTextureObject(struct gl_context * ctx, GLuint name, GLenum target) 112{ 113 struct st_texture_object *obj = ST_CALLOC_STRUCT(st_texture_object); 114 115 DBG("%s\n", __FUNCTION__); 116 _mesa_initialize_texture_object(&obj->base, name, target); 117 118 return &obj->base; 119} 120 121/** called via ctx->Driver.DeleteTextureObject() */ 122static void 123st_DeleteTextureObject(struct gl_context *ctx, 124 struct gl_texture_object *texObj) 125{ 126 struct st_context *st = st_context(ctx); 127 struct st_texture_object *stObj = st_texture_object(texObj); 128 if (stObj->pt) 129 pipe_resource_reference(&stObj->pt, NULL); 130 if (stObj->sampler_view) { 131 if (stObj->sampler_view->context != st->pipe) { 132 /* Take "ownership" of this texture sampler view by setting 133 * its context pointer to this context. This avoids potential 134 * crashes when the texture object is shared among contexts 135 * and the original/owner context has already been destroyed. 136 */ 137 stObj->sampler_view->context = st->pipe; 138 } 139 pipe_sampler_view_reference(&stObj->sampler_view, NULL); 140 } 141 _mesa_delete_texture_object(ctx, texObj); 142} 143 144 145/** called via ctx->Driver.FreeTexImageData() */ 146static void 147st_FreeTextureImageData(struct gl_context * ctx, struct gl_texture_image *texImage) 148{ 149 struct st_texture_image *stImage = st_texture_image(texImage); 150 151 DBG("%s\n", __FUNCTION__); 152 153 if (stImage->pt) { 154 pipe_resource_reference(&stImage->pt, NULL); 155 } 156 157 if (texImage->Data) { 158 _mesa_align_free(texImage->Data); 159 texImage->Data = NULL; 160 } 161} 162 163 164/** 165 * From linux kernel i386 header files, copes with odd sizes better 166 * than COPY_DWORDS would: 167 * XXX Put this in src/mesa/main/imports.h ??? 168 */ 169#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86) 170static INLINE void * 171__memcpy(void *to, const void *from, size_t n) 172{ 173 int d0, d1, d2; 174 __asm__ __volatile__("rep ; movsl\n\t" 175 "testb $2,%b4\n\t" 176 "je 1f\n\t" 177 "movsw\n" 178 "1:\ttestb $1,%b4\n\t" 179 "je 2f\n\t" 180 "movsb\n" "2:":"=&c"(d0), "=&D"(d1), "=&S"(d2) 181 :"0"(n / 4), "q"(n), "1"((long) to), "2"((long) from) 182 :"memory"); 183 return (to); 184} 185#else 186#define __memcpy(a,b,c) memcpy(a,b,c) 187#endif 188 189 190/** 191 * The system memcpy (at least on ubuntu 5.10) has problems copying 192 * to agp (writecombined) memory from a source which isn't 64-byte 193 * aligned - there is a 4x performance falloff. 194 * 195 * The x86 __memcpy is immune to this but is slightly slower 196 * (10%-ish) than the system memcpy. 197 * 198 * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but 199 * isn't much faster than x86_memcpy for agp copies. 200 * 201 * TODO: switch dynamically. 202 */ 203static void * 204do_memcpy(void *dest, const void *src, size_t n) 205{ 206 if ((((unsigned long) src) & 63) || (((unsigned long) dest) & 63)) { 207 return __memcpy(dest, src, n); 208 } 209 else 210 return memcpy(dest, src, n); 211} 212 213 214/** 215 * Return default texture resource binding bitmask for the given format. 216 */ 217static GLuint 218default_bindings(struct st_context *st, enum pipe_format format) 219{ 220 struct pipe_screen *screen = st->pipe->screen; 221 const unsigned target = PIPE_TEXTURE_2D; 222 unsigned bindings; 223 224 if (util_format_is_depth_or_stencil(format)) 225 bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_DEPTH_STENCIL; 226 else 227 bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; 228 229 if (screen->is_format_supported(screen, format, target, 0, bindings)) 230 return bindings; 231 else { 232 /* Try non-sRGB. */ 233 format = util_format_linear(format); 234 235 if (screen->is_format_supported(screen, format, target, 0, bindings)) 236 return bindings; 237 else 238 return PIPE_BIND_SAMPLER_VIEW; 239 } 240} 241 242 243/** Return number of image dimensions (1, 2 or 3) for a texture target. */ 244static GLuint 245get_texture_dims(GLenum target) 246{ 247 switch (target) { 248 case GL_TEXTURE_1D: 249 case GL_TEXTURE_1D_ARRAY_EXT: 250 case GL_TEXTURE_BUFFER: 251 return 1; 252 case GL_TEXTURE_2D: 253 case GL_TEXTURE_CUBE_MAP_ARB: 254 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 255 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 256 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 257 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 258 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 259 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 260 case GL_TEXTURE_RECTANGLE_NV: 261 case GL_TEXTURE_2D_ARRAY_EXT: 262 return 2; 263 case GL_TEXTURE_3D: 264 return 3; 265 default: 266 assert(0 && "invalid texture target in get_texture_dims()"); 267 return 1; 268 } 269} 270 271 272/** 273 * Given the size of a mipmap image, try to compute the size of the level=0 274 * mipmap image. 275 * 276 * Note that this isn't always accurate for odd-sized, non-POW textures. 277 * For example, if level=1 and width=40 then the level=0 width may be 80 or 81. 278 * 279 * \return GL_TRUE for success, GL_FALSE for failure 280 */ 281static GLboolean 282guess_base_level_size(GLenum target, 283 GLuint width, GLuint height, GLuint depth, GLuint level, 284 GLuint *width0, GLuint *height0, GLuint *depth0) 285{ 286 const GLuint dims = get_texture_dims(target); 287 288 assert(width >= 1); 289 assert(height >= 1); 290 assert(depth >= 1); 291 292 if (level > 0) { 293 /* Depending on the image's size, we can't always make a guess here */ 294 if ((dims >= 1 && width == 1) || 295 (dims >= 2 && height == 1) || 296 (dims >= 3 && depth == 1)) { 297 /* we can't determine the image size at level=0 */ 298 return GL_FALSE; 299 } 300 301 /* grow the image size until we hit level = 0 */ 302 while (level > 0) { 303 if (width > 1) 304 width <<= 1; 305 if (height > 1) 306 height <<= 1; 307 if (depth > 1) 308 depth <<= 1; 309 level--; 310 } 311 } 312 313 *width0 = width; 314 *height0 = height; 315 *depth0 = depth; 316 317 return GL_TRUE; 318} 319 320 321/** 322 * Try to allocate a pipe_resource object for the given st_texture_object. 323 * 324 * We use the given st_texture_image as a clue to determine the size of the 325 * mipmap image at level=0. 326 * 327 * \return GL_TRUE for success, GL_FALSE if out of memory. 328 */ 329static GLboolean 330guess_and_alloc_texture(struct st_context *st, 331 struct st_texture_object *stObj, 332 const struct st_texture_image *stImage) 333{ 334 GLuint lastLevel, width, height, depth; 335 GLuint bindings; 336 GLuint ptWidth, ptHeight, ptDepth, ptLayers; 337 enum pipe_format fmt; 338 339 DBG("%s\n", __FUNCTION__); 340 341 assert(!stObj->pt); 342 343 if (!guess_base_level_size(stObj->base.Target, 344 stImage->base.Width2, 345 stImage->base.Height2, 346 stImage->base.Depth2, 347 stImage->level, 348 &width, &height, &depth)) { 349 /* we can't determine the image size at level=0 */ 350 stObj->width0 = stObj->height0 = stObj->depth0 = 0; 351 /* this is not an out of memory error */ 352 return GL_TRUE; 353 } 354 355 /* At this point, (width x height x depth) is the expected size of 356 * the level=0 mipmap image. 357 */ 358 359 /* Guess a reasonable value for lastLevel. With OpenGL we have no 360 * idea how many mipmap levels will be in a texture until we start 361 * to render with it. Make an educated guess here but be prepared 362 * to re-allocating a texture buffer with space for more (or fewer) 363 * mipmap levels later. 364 */ 365 if ((stObj->base.Sampler.MinFilter == GL_NEAREST || 366 stObj->base.Sampler.MinFilter == GL_LINEAR || 367 stImage->base._BaseFormat == GL_DEPTH_COMPONENT || 368 stImage->base._BaseFormat == GL_DEPTH_STENCIL_EXT) && 369 !stObj->base.GenerateMipmap && 370 stImage->level == 0) { 371 /* only alloc space for a single mipmap level */ 372 lastLevel = 0; 373 } 374 else { 375 /* alloc space for a full mipmap */ 376 GLuint l2width = util_logbase2(width); 377 GLuint l2height = util_logbase2(height); 378 GLuint l2depth = util_logbase2(depth); 379 lastLevel = MAX2(MAX2(l2width, l2height), l2depth); 380 } 381 382 /* Save the level=0 dimensions */ 383 stObj->width0 = width; 384 stObj->height0 = height; 385 stObj->depth0 = depth; 386 387 fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat); 388 389 bindings = default_bindings(st, fmt); 390 391 st_gl_texture_dims_to_pipe_dims(stObj->base.Target, 392 width, height, depth, 393 &ptWidth, &ptHeight, &ptDepth, &ptLayers); 394 395 stObj->pt = st_texture_create(st, 396 gl_target_to_pipe(stObj->base.Target), 397 fmt, 398 lastLevel, 399 ptWidth, 400 ptHeight, 401 ptDepth, 402 ptLayers, 403 bindings); 404 405 DBG("%s returning %d\n", __FUNCTION__, (stObj->pt != NULL)); 406 407 return stObj->pt != NULL; 408} 409 410 411/** 412 * Adjust pixel unpack params and image dimensions to strip off the 413 * texture border. 414 * Gallium doesn't support texture borders. They've seldem been used 415 * and seldom been implemented correctly anyway. 416 * \param unpackNew returns the new pixel unpack parameters 417 */ 418static void 419strip_texture_border(GLint border, 420 GLint *width, GLint *height, GLint *depth, 421 const struct gl_pixelstore_attrib *unpack, 422 struct gl_pixelstore_attrib *unpackNew) 423{ 424 assert(border > 0); /* sanity check */ 425 426 *unpackNew = *unpack; 427 428 if (unpackNew->RowLength == 0) 429 unpackNew->RowLength = *width; 430 431 if (depth && unpackNew->ImageHeight == 0) 432 unpackNew->ImageHeight = *height; 433 434 unpackNew->SkipPixels += border; 435 if (height) 436 unpackNew->SkipRows += border; 437 if (depth) 438 unpackNew->SkipImages += border; 439 440 assert(*width >= 3); 441 *width = *width - 2 * border; 442 if (height && *height >= 3) 443 *height = *height - 2 * border; 444 if (depth && *depth >= 3) 445 *depth = *depth - 2 * border; 446} 447 448 449/** 450 * Do glTexImage1/2/3D(). 451 */ 452static void 453st_TexImage(struct gl_context * ctx, 454 GLint dims, 455 GLenum target, GLint level, 456 GLint internalFormat, 457 GLint width, GLint height, GLint depth, 458 GLint border, 459 GLenum format, GLenum type, const void *pixels, 460 const struct gl_pixelstore_attrib *unpack, 461 struct gl_texture_object *texObj, 462 struct gl_texture_image *texImage, 463 GLsizei imageSize, GLboolean compressed_src) 464{ 465 struct st_context *st = st_context(ctx); 466 struct st_texture_object *stObj = st_texture_object(texObj); 467 struct st_texture_image *stImage = st_texture_image(texImage); 468 GLuint dstRowStride = 0; 469 struct gl_pixelstore_attrib unpackNB; 470 enum pipe_transfer_usage transfer_usage = 0; 471 472 DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, 473 _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); 474 475 /* switch to "normal" */ 476 if (stObj->surface_based) { 477 gl_format texFormat; 478 479 _mesa_clear_texture_object(ctx, texObj); 480 pipe_resource_reference(&stObj->pt, NULL); 481 482 /* oops, need to init this image again */ 483 texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, 484 internalFormat, format, type); 485 486 _mesa_init_teximage_fields(ctx, target, texImage, 487 width, height, depth, border, 488 internalFormat, texFormat); 489 490 stObj->surface_based = GL_FALSE; 491 } 492 493 /* gallium does not support texture borders, strip it off */ 494 if (border) { 495 strip_texture_border(border, &width, &height, &depth, unpack, &unpackNB); 496 unpack = &unpackNB; 497 texImage->Width = width; 498 texImage->Height = height; 499 texImage->Depth = depth; 500 texImage->Border = 0; 501 border = 0; 502 } 503 else { 504 assert(texImage->Width == width); 505 assert(texImage->Height == height); 506 assert(texImage->Depth == depth); 507 } 508 509 stImage->face = _mesa_tex_target_to_face(target); 510 stImage->level = level; 511 512 _mesa_set_fetch_functions(texImage, dims); 513 514 /* Release the reference to a potentially orphaned buffer. 515 * Release any old malloced memory. 516 */ 517 if (stImage->pt) { 518 pipe_resource_reference(&stImage->pt, NULL); 519 assert(!texImage->Data); 520 } 521 else if (texImage->Data) { 522 _mesa_align_free(texImage->Data); 523 } 524 525 /* 526 * See if the new image is somehow incompatible with the existing 527 * mipmap. If so, free the old mipmap. 528 */ 529 if (stObj->pt) { 530 if (level > (GLint) stObj->pt->last_level || 531 !st_texture_match_image(stObj->pt, &stImage->base, 532 stImage->face, stImage->level)) { 533 DBG("release it\n"); 534 pipe_resource_reference(&stObj->pt, NULL); 535 assert(!stObj->pt); 536 pipe_sampler_view_reference(&stObj->sampler_view, NULL); 537 } 538 } 539 540 if (width == 0 || height == 0 || depth == 0) { 541 /* stop after freeing old image */ 542 return; 543 } 544 545 if (!stObj->pt) { 546 if (!guess_and_alloc_texture(st, stObj, stImage)) { 547 /* Probably out of memory. 548 * Try flushing any pending rendering, then retry. 549 */ 550 st_finish(st); 551 if (!guess_and_alloc_texture(st, stObj, stImage)) { 552 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 553 return; 554 } 555 } 556 } 557 558 assert(!stImage->pt); 559 560 /* Check if this texture image can live inside the texture object's buffer. 561 * If so, store the image there. Otherwise the image will temporarily live 562 * in its own buffer. 563 */ 564 if (stObj->pt && 565 st_texture_match_image(stObj->pt, &stImage->base, 566 stImage->face, stImage->level)) { 567 568 pipe_resource_reference(&stImage->pt, stObj->pt); 569 assert(stImage->pt); 570 } 571 572 if (!stImage->pt) 573 DBG("XXX: Image did not fit into texture - storing in local memory!\n"); 574 575 /* Pixel data may come from regular user memory or a PBO. For the later, 576 * do bounds checking and map the PBO to read pixels data from it. 577 * 578 * XXX we should try to use a GPU-accelerated path to copy the image data 579 * from the PBO to the texture. 580 */ 581 if (compressed_src) { 582 pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels, 583 unpack, 584 "glCompressedTexImage"); 585 } 586 else { 587 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, 588 format, type, 589 pixels, unpack, "glTexImage"); 590 } 591 592 /* for a 1D array upload the image as a series of layer with height = 1 */ 593 if (target == GL_TEXTURE_1D_ARRAY) { 594 depth = height; 595 height = 1; 596 } 597 598 /* 599 * Prepare to store the texture data. Either map the gallium texture buffer 600 * memory or malloc space for it. 601 */ 602 if (stImage->pt) { 603 if (!pixels) { 604 /* We've allocated texture resource, but have no pixel data - all done. */ 605 goto done; 606 } 607 608 /* Store the image in the gallium transfer object */ 609 if (format == GL_DEPTH_COMPONENT && 610 util_format_is_depth_and_stencil(stImage->pt->format)) 611 transfer_usage = PIPE_TRANSFER_READ_WRITE; 612 else 613 transfer_usage = PIPE_TRANSFER_WRITE; 614 615 texImage->Data = st_texture_image_map(st, stImage, 0, 616 transfer_usage, 0, 0, width, height); 617 if(stImage->transfer) 618 dstRowStride = stImage->transfer->stride; 619 } 620 else { 621 /* Allocate regular memory and store the image there temporarily. */ 622 GLuint imageSize = _mesa_format_image_size(texImage->TexFormat, 623 width, height, depth); 624 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, width); 625 626 texImage->Data = _mesa_align_malloc(imageSize, 16); 627 } 628 629 if (!texImage->Data) { 630 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 631 return; 632 } 633 634 if (!pixels) { 635 /* We've allocated texture memory, but have no pixel data - all done. */ 636 goto done; 637 } 638 639 DBG("Upload image %dx%dx%d row_len %x pitch %x\n", 640 width, height, depth, width, dstRowStride); 641 642 /* Copy user texture image into the texture buffer. 643 */ 644 if (compressed_src) { 645 const GLuint srcRowStride = 646 _mesa_format_row_stride(texImage->TexFormat, width); 647 if (dstRowStride == srcRowStride) { 648 memcpy(texImage->Data, pixels, imageSize); 649 } 650 else { 651 char *dst = texImage->Data; 652 const char *src = pixels; 653 GLuint i, bw, bh, lines; 654 _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh); 655 lines = (height + bh - 1) / bh; 656 657 for (i = 0; i < lines; ++i) { 658 memcpy(dst, src, srcRowStride); 659 dst += dstRowStride; 660 src += srcRowStride; 661 } 662 } 663 } 664 else { 665 const GLuint srcImageStride = 666 _mesa_image_image_stride(unpack, width, height, format, type); 667 GLint i; 668 const GLubyte *src = (const GLubyte *) pixels; 669 670 for (i = 0; i < depth; i++) { 671 if (!_mesa_texstore(ctx, dims, 672 texImage->_BaseFormat, 673 texImage->TexFormat, 674 texImage->Data, 675 0, 0, 0, /* dstX/Y/Zoffset */ 676 dstRowStride, 677 texImage->ImageOffsets, 678 width, height, 1, 679 format, type, src, unpack)) { 680 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 681 } 682 683 if (stImage->pt && i + 1 < depth) { 684 /* unmap this slice */ 685 st_texture_image_unmap(st, stImage); 686 /* map next slice of 3D texture */ 687 texImage->Data = st_texture_image_map(st, stImage, i + 1, 688 transfer_usage, 0, 0, 689 width, height); 690 src += srcImageStride; 691 } 692 } 693 } 694 695done: 696 _mesa_unmap_teximage_pbo(ctx, unpack); 697 698 if (stImage->pt && texImage->Data) { 699 st_texture_image_unmap(st, stImage); 700 texImage->Data = NULL; 701 } 702} 703 704 705static void 706st_TexImage3D(struct gl_context * ctx, 707 GLenum target, GLint level, 708 GLint internalFormat, 709 GLint width, GLint height, GLint depth, 710 GLint border, 711 GLenum format, GLenum type, const void *pixels, 712 const struct gl_pixelstore_attrib *unpack, 713 struct gl_texture_object *texObj, 714 struct gl_texture_image *texImage) 715{ 716 st_TexImage(ctx, 3, target, level, internalFormat, width, height, depth, 717 border, format, type, pixels, unpack, texObj, texImage, 718 0, GL_FALSE); 719} 720 721 722static void 723st_TexImage2D(struct gl_context * ctx, 724 GLenum target, GLint level, 725 GLint internalFormat, 726 GLint width, GLint height, GLint border, 727 GLenum format, GLenum type, const void *pixels, 728 const struct gl_pixelstore_attrib *unpack, 729 struct gl_texture_object *texObj, 730 struct gl_texture_image *texImage) 731{ 732 st_TexImage(ctx, 2, target, level, internalFormat, width, height, 1, border, 733 format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE); 734} 735 736 737static void 738st_TexImage1D(struct gl_context * ctx, 739 GLenum target, GLint level, 740 GLint internalFormat, 741 GLint width, GLint border, 742 GLenum format, GLenum type, const void *pixels, 743 const struct gl_pixelstore_attrib *unpack, 744 struct gl_texture_object *texObj, 745 struct gl_texture_image *texImage) 746{ 747 st_TexImage(ctx, 1, target, level, internalFormat, width, 1, 1, border, 748 format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE); 749} 750 751 752static void 753st_CompressedTexImage2D(struct gl_context *ctx, GLenum target, GLint level, 754 GLint internalFormat, 755 GLint width, GLint height, GLint border, 756 GLsizei imageSize, const GLvoid *data, 757 struct gl_texture_object *texObj, 758 struct gl_texture_image *texImage) 759{ 760 st_TexImage(ctx, 2, target, level, internalFormat, width, height, 1, border, 761 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, GL_TRUE); 762} 763 764 765 766/** 767 * glGetTexImage() helper: decompress a compressed texture by rendering 768 * a textured quad. Store the results in the user's buffer. 769 */ 770static void 771decompress_with_blit(struct gl_context * ctx, GLenum target, GLint level, 772 GLenum format, GLenum type, GLvoid *pixels, 773 struct gl_texture_object *texObj, 774 struct gl_texture_image *texImage) 775{ 776 struct st_context *st = st_context(ctx); 777 struct pipe_context *pipe = st->pipe; 778 struct st_texture_image *stImage = st_texture_image(texImage); 779 struct st_texture_object *stObj = st_texture_object(texObj); 780 struct pipe_sampler_view *src_view = 781 st_get_texture_sampler_view(stObj, pipe); 782 const GLuint width = texImage->Width; 783 const GLuint height = texImage->Height; 784 struct pipe_surface *dst_surface; 785 struct pipe_resource *dst_texture; 786 struct pipe_transfer *tex_xfer; 787 unsigned bind = (PIPE_BIND_RENDER_TARGET | /* util_blit may choose to render */ 788 PIPE_BIND_TRANSFER_READ); 789 790 /* create temp / dest surface */ 791 if (!util_create_rgba_surface(pipe, width, height, bind, 792 &dst_texture, &dst_surface)) { 793 _mesa_problem(ctx, "util_create_rgba_surface() failed " 794 "in decompress_with_blit()"); 795 return; 796 } 797 798 /* Disable conditional rendering. */ 799 if (st->render_condition) { 800 pipe->render_condition(pipe, NULL, 0); 801 } 802 803 /* blit/render/decompress */ 804 util_blit_pixels_tex(st->blit, 805 src_view, /* pipe_resource (src) */ 806 0, 0, /* src x0, y0 */ 807 width, height, /* src x1, y1 */ 808 dst_surface, /* pipe_surface (dst) */ 809 0, 0, /* dst x0, y0 */ 810 width, height, /* dst x1, y1 */ 811 0.0, /* z */ 812 PIPE_TEX_MIPFILTER_NEAREST); 813 814 /* Restore conditional rendering state. */ 815 if (st->render_condition) { 816 pipe->render_condition(pipe, st->render_condition, 817 st->condition_mode); 818 } 819 820 /* map the dst_surface so we can read from it */ 821 tex_xfer = pipe_get_transfer(pipe, 822 dst_texture, 0, 0, 823 PIPE_TRANSFER_READ, 824 0, 0, width, height); 825 826 pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels); 827 828 /* copy/pack data into user buffer */ 829 if (st_equal_formats(stImage->pt->format, format, type)) { 830 /* memcpy */ 831 const uint bytesPerRow = width * util_format_get_blocksize(stImage->pt->format); 832 ubyte *map = pipe_transfer_map(pipe, tex_xfer); 833 GLuint row; 834 for (row = 0; row < height; row++) { 835 GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width, 836 height, format, type, row, 0); 837 memcpy(dest, map, bytesPerRow); 838 map += tex_xfer->stride; 839 } 840 pipe_transfer_unmap(pipe, tex_xfer); 841 } 842 else { 843 /* format translation via floats */ 844 GLuint row; 845 enum pipe_format pformat = util_format_linear(dst_texture->format); 846 for (row = 0; row < height; row++) { 847 const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */ 848 GLfloat rgba[4 * MAX_WIDTH]; 849 GLvoid *dest = _mesa_image_address2d(&ctx->Pack, pixels, width, 850 height, format, type, row, 0); 851 852 if (ST_DEBUG & DEBUG_FALLBACK) 853 debug_printf("%s: fallback format translation\n", __FUNCTION__); 854 855 /* get float[4] rgba row from surface */ 856 pipe_get_tile_rgba_format(pipe, tex_xfer, 0, row, width, 1, 857 pformat, rgba); 858 859 _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, 860 type, dest, &ctx->Pack, transferOps); 861 } 862 } 863 864 _mesa_unmap_pbo_dest(ctx, &ctx->Pack); 865 866 pipe->transfer_destroy(pipe, tex_xfer); 867 868 /* destroy the temp / dest surface */ 869 util_destroy_rgba_surface(dst_texture, dst_surface); 870} 871 872 873 874/** 875 * Need to map texture image into memory before copying image data, 876 * then unmap it. 877 */ 878static void 879st_get_tex_image(struct gl_context * ctx, GLenum target, GLint level, 880 GLenum format, GLenum type, GLvoid * pixels, 881 struct gl_texture_object *texObj, 882 struct gl_texture_image *texImage, GLboolean compressed_dst) 883{ 884 struct st_context *st = st_context(ctx); 885 struct st_texture_image *stImage = st_texture_image(texImage); 886 const GLuint dstImageStride = 887 _mesa_image_image_stride(&ctx->Pack, texImage->Width, texImage->Height, 888 format, type); 889 GLuint depth, i; 890 GLubyte *dest; 891 892 if (stImage->pt && 893 util_format_is_s3tc(stImage->pt->format) && 894 !compressed_dst) { 895 /* Need to decompress the texture. 896 * We'll do this by rendering a textured quad. 897 * Note that we only expect RGBA formats (no Z/depth formats). 898 */ 899 decompress_with_blit(ctx, target, level, format, type, pixels, 900 texObj, texImage); 901 return; 902 } 903 904 /* Map */ 905 if (stImage->pt) { 906 /* Image is stored in hardware format in a buffer managed by the 907 * kernel. Need to explicitly map and unmap it. 908 */ 909 texImage->Data = st_texture_image_map(st, stImage, 0, 910 PIPE_TRANSFER_READ, 0, 0, 911 stImage->base.Width, 912 stImage->base.Height); 913 /* compute stride in texels from stride in bytes */ 914 texImage->RowStride = stImage->transfer->stride 915 * util_format_get_blockwidth(stImage->pt->format) 916 / util_format_get_blocksize(stImage->pt->format); 917 } 918 else { 919 /* Otherwise, the image should actually be stored in 920 * texImage->Data. This is pretty confusing for 921 * everybody, I'd much prefer to separate the two functions of 922 * texImage->Data - storage for texture images in main memory 923 * and access (ie mappings) of images. In other words, we'd 924 * create a new texImage->Map field and leave Data simply for 925 * storage. 926 */ 927 assert(texImage->Data); 928 } 929 930 depth = texImage->Depth; 931 texImage->Depth = 1; 932 933 dest = (GLubyte *) pixels; 934 935 _mesa_set_fetch_functions(texImage, get_texture_dims(target)); 936 937 for (i = 0; i < depth; i++) { 938 if (compressed_dst) { 939 _mesa_get_compressed_teximage(ctx, target, level, dest, 940 texObj, texImage); 941 } 942 else { 943 _mesa_get_teximage(ctx, target, level, format, type, dest, 944 texObj, texImage); 945 } 946 947 if (stImage->pt && i + 1 < depth) { 948 /* unmap this slice */ 949 st_texture_image_unmap(st, stImage); 950 /* map next slice of 3D texture */ 951 texImage->Data = st_texture_image_map(st, stImage, i + 1, 952 PIPE_TRANSFER_READ, 0, 0, 953 stImage->base.Width, 954 stImage->base.Height); 955 dest += dstImageStride; 956 } 957 } 958 959 texImage->Depth = depth; 960 961 /* Unmap */ 962 if (stImage->pt) { 963 st_texture_image_unmap(st, stImage); 964 texImage->Data = NULL; 965 } 966} 967 968 969static void 970st_GetTexImage(struct gl_context * ctx, GLenum target, GLint level, 971 GLenum format, GLenum type, GLvoid * pixels, 972 struct gl_texture_object *texObj, 973 struct gl_texture_image *texImage) 974{ 975 st_get_tex_image(ctx, target, level, format, type, pixels, texObj, texImage, 976 GL_FALSE); 977} 978 979 980static void 981st_GetCompressedTexImage(struct gl_context *ctx, GLenum target, GLint level, 982 GLvoid *pixels, 983 struct gl_texture_object *texObj, 984 struct gl_texture_image *texImage) 985{ 986 st_get_tex_image(ctx, target, level, 0, 0, pixels, texObj, texImage, 987 GL_TRUE); 988} 989 990 991 992static void 993st_TexSubimage(struct gl_context *ctx, GLint dims, GLenum target, GLint level, 994 GLint xoffset, GLint yoffset, GLint zoffset, 995 GLint width, GLint height, GLint depth, 996 GLenum format, GLenum type, const void *pixels, 997 const struct gl_pixelstore_attrib *packing, 998 struct gl_texture_object *texObj, 999 struct gl_texture_image *texImage) 1000{ 1001 struct st_context *st = st_context(ctx); 1002 struct st_texture_image *stImage = st_texture_image(texImage); 1003 GLuint dstRowStride; 1004 const GLuint srcImageStride = 1005 _mesa_image_image_stride(packing, width, height, format, type); 1006 GLint i; 1007 const GLubyte *src; 1008 /* init to silence warning only: */ 1009 enum pipe_transfer_usage transfer_usage = PIPE_TRANSFER_WRITE; 1010 1011 DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__, 1012 _mesa_lookup_enum_by_nr(target), 1013 level, xoffset, yoffset, width, height); 1014 1015 pixels = 1016 _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format, 1017 type, pixels, packing, "glTexSubImage2D"); 1018 if (!pixels) 1019 return; 1020 1021 /* for a 1D array upload the image as a series of layer with height = 1 */ 1022 if (target == GL_TEXTURE_1D_ARRAY) { 1023 depth = height; 1024 height = 1; 1025 } 1026 1027 /* Map buffer if necessary. Need to lock to prevent other contexts 1028 * from uploading the buffer under us. 1029 */ 1030 if (stImage->pt) { 1031 if (format == GL_DEPTH_COMPONENT && 1032 util_format_is_depth_and_stencil(stImage->pt->format)) 1033 transfer_usage = PIPE_TRANSFER_READ_WRITE; 1034 else 1035 transfer_usage = PIPE_TRANSFER_WRITE; 1036 1037 texImage->Data = st_texture_image_map(st, stImage, zoffset, 1038 transfer_usage, 1039 xoffset, yoffset, 1040 width, height); 1041 } 1042 1043 if (!texImage->Data) { 1044 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 1045 goto done; 1046 } 1047 1048 src = (const GLubyte *) pixels; 1049 dstRowStride = stImage->transfer->stride; 1050 1051 for (i = 0; i < depth; i++) { 1052 if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat, 1053 texImage->TexFormat, 1054 texImage->Data, 1055 0, 0, 0, 1056 dstRowStride, 1057 texImage->ImageOffsets, 1058 width, height, 1, 1059 format, type, src, packing)) { 1060 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 1061 } 1062 1063 if (stImage->pt && i + 1 < depth) { 1064 /* unmap this slice */ 1065 st_texture_image_unmap(st, stImage); 1066 /* map next slice of 3D texture */ 1067 texImage->Data = st_texture_image_map(st, stImage, 1068 zoffset + i + 1, 1069 transfer_usage, 1070 xoffset, yoffset, 1071 width, height); 1072 src += srcImageStride; 1073 } 1074 } 1075 1076done: 1077 _mesa_unmap_teximage_pbo(ctx, packing); 1078 1079 if (stImage->pt && texImage->Data) { 1080 st_texture_image_unmap(st, stImage); 1081 texImage->Data = NULL; 1082 } 1083} 1084 1085 1086 1087static void 1088st_TexSubImage3D(struct gl_context *ctx, GLenum target, GLint level, 1089 GLint xoffset, GLint yoffset, GLint zoffset, 1090 GLsizei width, GLsizei height, GLsizei depth, 1091 GLenum format, GLenum type, const GLvoid *pixels, 1092 const struct gl_pixelstore_attrib *packing, 1093 struct gl_texture_object *texObj, 1094 struct gl_texture_image *texImage) 1095{ 1096 st_TexSubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, 1097 width, height, depth, format, type, 1098 pixels, packing, texObj, texImage); 1099} 1100 1101 1102static void 1103st_TexSubImage2D(struct gl_context *ctx, GLenum target, GLint level, 1104 GLint xoffset, GLint yoffset, 1105 GLsizei width, GLsizei height, 1106 GLenum format, GLenum type, const GLvoid * pixels, 1107 const struct gl_pixelstore_attrib *packing, 1108 struct gl_texture_object *texObj, 1109 struct gl_texture_image *texImage) 1110{ 1111 st_TexSubimage(ctx, 2, target, level, xoffset, yoffset, 0, 1112 width, height, 1, format, type, 1113 pixels, packing, texObj, texImage); 1114} 1115 1116 1117static void 1118st_TexSubImage1D(struct gl_context *ctx, GLenum target, GLint level, 1119 GLint xoffset, GLsizei width, GLenum format, GLenum type, 1120 const GLvoid * pixels, 1121 const struct gl_pixelstore_attrib *packing, 1122 struct gl_texture_object *texObj, 1123 struct gl_texture_image *texImage) 1124{ 1125 st_TexSubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 1126 format, type, pixels, packing, texObj, texImage); 1127} 1128 1129 1130static void 1131st_CompressedTexSubImage1D(struct gl_context *ctx, GLenum target, GLint level, 1132 GLint xoffset, GLsizei width, 1133 GLenum format, 1134 GLsizei imageSize, const GLvoid *data, 1135 struct gl_texture_object *texObj, 1136 struct gl_texture_image *texImage) 1137{ 1138 assert(0); 1139} 1140 1141 1142static void 1143st_CompressedTexSubImage2D(struct gl_context *ctx, GLenum target, GLint level, 1144 GLint xoffset, GLint yoffset, 1145 GLsizei width, GLint height, 1146 GLenum format, 1147 GLsizei imageSize, const GLvoid *data, 1148 struct gl_texture_object *texObj, 1149 struct gl_texture_image *texImage) 1150{ 1151 struct st_context *st = st_context(ctx); 1152 struct st_texture_image *stImage = st_texture_image(texImage); 1153 int srcBlockStride; 1154 int dstBlockStride; 1155 int y; 1156 enum pipe_format pformat; 1157 1158 if (stImage->pt) { 1159 pformat = stImage->pt->format; 1160 1161 texImage->Data = st_texture_image_map(st, stImage, 0, 1162 PIPE_TRANSFER_WRITE, 1163 xoffset, yoffset, 1164 width, height); 1165 1166 srcBlockStride = util_format_get_stride(pformat, width); 1167 dstBlockStride = stImage->transfer->stride; 1168 } else { 1169 assert(stImage->pt); 1170 /* TODO find good values for block and strides */ 1171 /* TODO also adjust texImage->data for yoffset/xoffset */ 1172 return; 1173 } 1174 1175 if (!texImage->Data) { 1176 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage"); 1177 return; 1178 } 1179 1180 assert(xoffset % util_format_get_blockwidth(pformat) == 0); 1181 assert(yoffset % util_format_get_blockheight(pformat) == 0); 1182 1183 for (y = 0; y < height; y += util_format_get_blockheight(pformat)) { 1184 /* don't need to adjust for xoffset and yoffset as st_texture_image_map does that */ 1185 const char *src = (const char*)data + srcBlockStride * util_format_get_nblocksy(pformat, y); 1186 char *dst = (char*)texImage->Data + dstBlockStride * util_format_get_nblocksy(pformat, y); 1187 memcpy(dst, src, util_format_get_stride(pformat, width)); 1188 } 1189 1190 if (stImage->pt) { 1191 st_texture_image_unmap(st, stImage); 1192 texImage->Data = NULL; 1193 } 1194} 1195 1196 1197static void 1198st_CompressedTexSubImage3D(struct gl_context *ctx, GLenum target, GLint level, 1199 GLint xoffset, GLint yoffset, GLint zoffset, 1200 GLsizei width, GLint height, GLint depth, 1201 GLenum format, 1202 GLsizei imageSize, const GLvoid *data, 1203 struct gl_texture_object *texObj, 1204 struct gl_texture_image *texImage) 1205{ 1206 assert(0); 1207} 1208 1209 1210 1211/** 1212 * Do a CopyTexSubImage operation using a read transfer from the source, 1213 * a write transfer to the destination and get_tile()/put_tile() to access 1214 * the pixels/texels. 1215 * 1216 * Note: srcY=0=TOP of renderbuffer 1217 */ 1218static void 1219fallback_copy_texsubimage(struct gl_context *ctx, GLenum target, GLint level, 1220 struct st_renderbuffer *strb, 1221 struct st_texture_image *stImage, 1222 GLenum baseFormat, 1223 GLint destX, GLint destY, GLint destZ, 1224 GLint srcX, GLint srcY, 1225 GLsizei width, GLsizei height) 1226{ 1227 struct st_context *st = st_context(ctx); 1228 struct pipe_context *pipe = st->pipe; 1229 struct pipe_transfer *src_trans; 1230 GLvoid *texDest; 1231 enum pipe_transfer_usage transfer_usage; 1232 1233 if (ST_DEBUG & DEBUG_FALLBACK) 1234 debug_printf("%s: fallback processing\n", __FUNCTION__); 1235 1236 assert(width <= MAX_WIDTH); 1237 1238 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 1239 srcY = strb->Base.Height - srcY - height; 1240 } 1241 1242 src_trans = pipe_get_transfer(pipe, 1243 strb->texture, 1244 strb->rtt_level, 1245 strb->rtt_face + strb->rtt_slice, 1246 PIPE_TRANSFER_READ, 1247 srcX, srcY, 1248 width, height); 1249 1250 if ((baseFormat == GL_DEPTH_COMPONENT || 1251 baseFormat == GL_DEPTH_STENCIL) && 1252 util_format_is_depth_and_stencil(stImage->pt->format)) 1253 transfer_usage = PIPE_TRANSFER_READ_WRITE; 1254 else 1255 transfer_usage = PIPE_TRANSFER_WRITE; 1256 1257 /* XXX this used to ignore destZ param */ 1258 texDest = st_texture_image_map(st, stImage, destZ, transfer_usage, 1259 destX, destY, width, height); 1260 1261 if (baseFormat == GL_DEPTH_COMPONENT || 1262 baseFormat == GL_DEPTH_STENCIL) { 1263 const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F || 1264 ctx->Pixel.DepthBias != 0.0F); 1265 GLint row, yStep; 1266 1267 /* determine bottom-to-top vs. top-to-bottom order for src buffer */ 1268 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 1269 srcY = height - 1; 1270 yStep = -1; 1271 } 1272 else { 1273 srcY = 0; 1274 yStep = 1; 1275 } 1276 1277 /* To avoid a large temp memory allocation, do copy row by row */ 1278 for (row = 0; row < height; row++, srcY += yStep) { 1279 uint data[MAX_WIDTH]; 1280 pipe_get_tile_z(pipe, src_trans, 0, srcY, width, 1, data); 1281 if (scaleOrBias) { 1282 _mesa_scale_and_bias_depth_uint(ctx, width, data); 1283 } 1284 pipe_put_tile_z(pipe, stImage->transfer, 0, row, width, 1, data); 1285 } 1286 } 1287 else { 1288 /* RGBA format */ 1289 GLfloat *tempSrc = 1290 (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); 1291 1292 if (tempSrc && texDest) { 1293 const GLint dims = 2; 1294 const GLint dstRowStride = stImage->transfer->stride; 1295 struct gl_texture_image *texImage = &stImage->base; 1296 struct gl_pixelstore_attrib unpack = ctx->DefaultPacking; 1297 1298 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 1299 unpack.Invert = GL_TRUE; 1300 } 1301 1302 /* get float/RGBA image from framebuffer */ 1303 /* XXX this usually involves a lot of int/float conversion. 1304 * try to avoid that someday. 1305 */ 1306 pipe_get_tile_rgba_format(pipe, src_trans, 0, 0, width, height, 1307 util_format_linear(strb->texture->format), 1308 tempSrc); 1309 1310 /* Store into texture memory. 1311 * Note that this does some special things such as pixel transfer 1312 * ops and format conversion. In particular, if the dest tex format 1313 * is actually RGBA but the user created the texture as GL_RGB we 1314 * need to fill-in/override the alpha channel with 1.0. 1315 */ 1316 _mesa_texstore(ctx, dims, 1317 texImage->_BaseFormat, 1318 texImage->TexFormat, 1319 texDest, 1320 0, 0, 0, 1321 dstRowStride, 1322 texImage->ImageOffsets, 1323 width, height, 1, 1324 GL_RGBA, GL_FLOAT, tempSrc, /* src */ 1325 &unpack); 1326 } 1327 else { 1328 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 1329 } 1330 1331 if (tempSrc) 1332 free(tempSrc); 1333 } 1334 1335 st_texture_image_unmap(st, stImage); 1336 pipe->transfer_destroy(pipe, src_trans); 1337} 1338 1339 1340 1341/** 1342 * If the format of the src renderbuffer and the format of the dest 1343 * texture are compatible (in terms of blitting), return a TGSI writemask 1344 * to be used during the blit. 1345 * If the src/dest are incompatible, return 0. 1346 */ 1347static unsigned 1348compatible_src_dst_formats(struct gl_context *ctx, 1349 const struct gl_renderbuffer *src, 1350 const struct gl_texture_image *dst) 1351{ 1352 /* Get logical base formats for the src and dest. 1353 * That is, use the user-requested formats and not the actual, device- 1354 * chosen formats. 1355 * For example, the user may have requested an A8 texture but the 1356 * driver may actually be using an RGBA texture format. When we 1357 * copy/blit to that texture, we only want to copy the Alpha channel 1358 * and not the RGB channels. 1359 * 1360 * Similarly, when the src FBO was created an RGB format may have been 1361 * requested but the driver actually chose an RGBA format. In that case, 1362 * we don't want to copy the undefined Alpha channel to the dest texture 1363 * (it should be 1.0). 1364 */ 1365 const GLenum srcFormat = _mesa_base_fbo_format(ctx, src->InternalFormat); 1366 const GLenum dstFormat = _mesa_base_tex_format(ctx, dst->InternalFormat); 1367 1368 /** 1369 * XXX when we have red-only and red/green renderbuffers we'll need 1370 * to add more cases here (or implement a general-purpose routine that 1371 * queries the existance of the R,G,B,A channels in the src and dest). 1372 */ 1373 if (srcFormat == dstFormat) { 1374 /* This is the same as matching_base_formats, which should 1375 * always pass, as it did previously. 1376 */ 1377 return TGSI_WRITEMASK_XYZW; 1378 } 1379 else if (srcFormat == GL_RGB && dstFormat == GL_RGBA) { 1380 /* Make sure that A in the dest is 1. The actual src format 1381 * may be RGBA and have undefined A values. 1382 */ 1383 return TGSI_WRITEMASK_XYZ; 1384 } 1385 else if (srcFormat == GL_RGBA && dstFormat == GL_RGB) { 1386 /* Make sure that A in the dest is 1. The actual dst format 1387 * may be RGBA and will need A=1 to provide proper alpha values 1388 * when sampled later. 1389 */ 1390 return TGSI_WRITEMASK_XYZ; 1391 } 1392 else { 1393 if (ST_DEBUG & DEBUG_FALLBACK) 1394 debug_printf("%s failed for src %s, dst %s\n", 1395 __FUNCTION__, 1396 _mesa_lookup_enum_by_nr(srcFormat), 1397 _mesa_lookup_enum_by_nr(dstFormat)); 1398 1399 /* Otherwise fail. 1400 */ 1401 return 0; 1402 } 1403} 1404 1405 1406 1407/** 1408 * Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible. 1409 * Note that the region to copy has already been clipped so we know we 1410 * won't read from outside the source renderbuffer's bounds. 1411 * 1412 * Note: srcY=0=Bottom of renderbuffer (GL convention) 1413 */ 1414static void 1415st_copy_texsubimage(struct gl_context *ctx, 1416 GLenum target, GLint level, 1417 GLint destX, GLint destY, GLint destZ, 1418 GLint srcX, GLint srcY, 1419 GLsizei width, GLsizei height) 1420{ 1421 struct gl_texture_unit *texUnit = 1422 &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1423 struct gl_texture_object *texObj = 1424 _mesa_select_tex_object(ctx, texUnit, target); 1425 struct gl_texture_image *texImage = 1426 _mesa_select_tex_image(ctx, texObj, target, level); 1427 struct st_texture_image *stImage = st_texture_image(texImage); 1428 const GLenum texBaseFormat = texImage->_BaseFormat; 1429 struct gl_framebuffer *fb = ctx->ReadBuffer; 1430 struct st_renderbuffer *strb; 1431 struct st_context *st = st_context(ctx); 1432 struct pipe_context *pipe = st->pipe; 1433 struct pipe_screen *screen = pipe->screen; 1434 enum pipe_format dest_format, src_format; 1435 GLboolean use_fallback = GL_TRUE; 1436 GLboolean matching_base_formats; 1437 GLuint format_writemask, sample_count; 1438 struct pipe_surface *dest_surface = NULL; 1439 GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP); 1440 1441 /* make sure finalize_textures has been called? 1442 */ 1443 if (0) st_validate_state(st); 1444 1445 /* determine if copying depth or color data */ 1446 if (texBaseFormat == GL_DEPTH_COMPONENT || 1447 texBaseFormat == GL_DEPTH_STENCIL) { 1448 strb = st_renderbuffer(fb->_DepthBuffer); 1449 if (strb->Base.Wrapped) { 1450 strb = st_renderbuffer(strb->Base.Wrapped); 1451 } 1452 } 1453 else { 1454 /* texBaseFormat == GL_RGB, GL_RGBA, GL_ALPHA, etc */ 1455 strb = st_renderbuffer(fb->_ColorReadBuffer); 1456 } 1457 1458 if (!strb || !strb->surface || !stImage->pt) { 1459 debug_printf("%s: null strb or stImage\n", __FUNCTION__); 1460 return; 1461 } 1462 1463 sample_count = strb->surface->texture->nr_samples; 1464 /* I believe this would be legal, presumably would need to do a resolve 1465 for color, and for depth/stencil spec says to just use one of the 1466 depth/stencil samples per pixel? Need some transfer clarifications. */ 1467 assert(sample_count < 2); 1468 1469 if (srcX < 0) { 1470 width -= -srcX; 1471 destX += -srcX; 1472 srcX = 0; 1473 } 1474 1475 if (srcY < 0) { 1476 height -= -srcY; 1477 destY += -srcY; 1478 srcY = 0; 1479 } 1480 1481 if (destX < 0) { 1482 width -= -destX; 1483 srcX += -destX; 1484 destX = 0; 1485 } 1486 1487 if (destY < 0) { 1488 height -= -destY; 1489 srcY += -destY; 1490 destY = 0; 1491 } 1492 1493 if (width < 0 || height < 0) 1494 return; 1495 1496 1497 assert(strb); 1498 assert(strb->surface); 1499 assert(stImage->pt); 1500 1501 src_format = strb->surface->format; 1502 dest_format = stImage->pt->format; 1503 1504 /* 1505 * Determine if the src framebuffer and dest texture have the same 1506 * base format. We need this to detect a case such as the framebuffer 1507 * being GL_RGBA but the texture being GL_RGB. If the actual hardware 1508 * texture format stores RGBA we need to set A=1 (overriding the 1509 * framebuffer's alpha values). We can't do that with the blit or 1510 * textured-quad paths. 1511 */ 1512 matching_base_formats = 1513 (_mesa_get_format_base_format(strb->Base.Format) == 1514 _mesa_get_format_base_format(texImage->TexFormat)); 1515 format_writemask = compatible_src_dst_formats(ctx, &strb->Base, texImage); 1516 1517 if (ctx->_ImageTransferState == 0x0) { 1518 1519 if (matching_base_formats && 1520 src_format == dest_format && 1521 !do_flip) 1522 { 1523 /* use surface_copy() / blit */ 1524 struct pipe_box src_box; 1525 u_box_2d_zslice(srcX, srcY, strb->surface->u.tex.first_layer, 1526 width, height, &src_box); 1527 1528 /* for resource_copy_region(), y=0=top, always */ 1529 pipe->resource_copy_region(pipe, 1530 /* dest */ 1531 stImage->pt, 1532 stImage->level, 1533 destX, destY, destZ + stImage->face, 1534 /* src */ 1535 strb->texture, 1536 strb->surface->u.tex.level, 1537 &src_box); 1538 use_fallback = GL_FALSE; 1539 } 1540 else if (format_writemask && 1541 texBaseFormat != GL_DEPTH_COMPONENT && 1542 texBaseFormat != GL_DEPTH_STENCIL && 1543 screen->is_format_supported(screen, src_format, 1544 PIPE_TEXTURE_2D, sample_count, 1545 PIPE_BIND_SAMPLER_VIEW) && 1546 screen->is_format_supported(screen, dest_format, 1547 PIPE_TEXTURE_2D, 0, 1548 PIPE_BIND_RENDER_TARGET)) { 1549 /* draw textured quad to do the copy */ 1550 GLint srcY0, srcY1; 1551 struct pipe_surface surf_tmpl; 1552 memset(&surf_tmpl, 0, sizeof(surf_tmpl)); 1553 surf_tmpl.format = util_format_linear(stImage->pt->format); 1554 surf_tmpl.usage = PIPE_BIND_RENDER_TARGET; 1555 surf_tmpl.u.tex.level = stImage->level; 1556 surf_tmpl.u.tex.first_layer = stImage->face + destZ; 1557 surf_tmpl.u.tex.last_layer = stImage->face + destZ; 1558 1559 dest_surface = pipe->create_surface(pipe, stImage->pt, 1560 &surf_tmpl); 1561 1562 if (do_flip) { 1563 srcY1 = strb->Base.Height - srcY - height; 1564 srcY0 = srcY1 + height; 1565 } 1566 else { 1567 srcY0 = srcY; 1568 srcY1 = srcY0 + height; 1569 } 1570 1571 /* Disable conditional rendering. */ 1572 if (st->render_condition) { 1573 pipe->render_condition(pipe, NULL, 0); 1574 } 1575 1576 util_blit_pixels_writemask(st->blit, 1577 strb->texture, 1578 strb->surface->u.tex.level, 1579 srcX, srcY0, 1580 srcX + width, srcY1, 1581 strb->surface->u.tex.first_layer, 1582 dest_surface, 1583 destX, destY, 1584 destX + width, destY + height, 1585 0.0, PIPE_TEX_MIPFILTER_NEAREST, 1586 format_writemask); 1587 1588 /* Restore conditional rendering state. */ 1589 if (st->render_condition) { 1590 pipe->render_condition(pipe, st->render_condition, 1591 st->condition_mode); 1592 } 1593 1594 use_fallback = GL_FALSE; 1595 } 1596 1597 if (dest_surface) 1598 pipe_surface_reference(&dest_surface, NULL); 1599 } 1600 1601 if (use_fallback) { 1602 /* software fallback */ 1603 fallback_copy_texsubimage(ctx, target, level, 1604 strb, stImage, texBaseFormat, 1605 destX, destY, destZ, 1606 srcX, srcY, width, height); 1607 } 1608} 1609 1610 1611 1612static void 1613st_CopyTexSubImage1D(struct gl_context * ctx, GLenum target, GLint level, 1614 GLint xoffset, GLint x, GLint y, GLsizei width) 1615{ 1616 const GLint yoffset = 0, zoffset = 0; 1617 const GLsizei height = 1; 1618 st_copy_texsubimage(ctx, target, level, 1619 xoffset, yoffset, zoffset, /* destX,Y,Z */ 1620 x, y, width, height); /* src X, Y, size */ 1621} 1622 1623 1624static void 1625st_CopyTexSubImage2D(struct gl_context * ctx, GLenum target, GLint level, 1626 GLint xoffset, GLint yoffset, 1627 GLint x, GLint y, GLsizei width, GLsizei height) 1628{ 1629 const GLint zoffset = 0; 1630 st_copy_texsubimage(ctx, target, level, 1631 xoffset, yoffset, zoffset, /* destX,Y,Z */ 1632 x, y, width, height); /* src X, Y, size */ 1633} 1634 1635 1636static void 1637st_CopyTexSubImage3D(struct gl_context * ctx, GLenum target, GLint level, 1638 GLint xoffset, GLint yoffset, GLint zoffset, 1639 GLint x, GLint y, GLsizei width, GLsizei height) 1640{ 1641 st_copy_texsubimage(ctx, target, level, 1642 xoffset, yoffset, zoffset, /* destX,Y,Z */ 1643 x, y, width, height); /* src X, Y, size */ 1644} 1645 1646 1647/** 1648 * Copy image data from stImage into the texture object 'stObj' at level 1649 * 'dstLevel'. 1650 */ 1651static void 1652copy_image_data_to_texture(struct st_context *st, 1653 struct st_texture_object *stObj, 1654 GLuint dstLevel, 1655 struct st_texture_image *stImage) 1656{ 1657 /* debug checks */ 1658 { 1659 const struct gl_texture_image *dstImage = 1660 stObj->base.Image[stImage->face][dstLevel]; 1661 assert(dstImage); 1662 assert(dstImage->Width == stImage->base.Width); 1663 assert(dstImage->Height == stImage->base.Height); 1664 assert(dstImage->Depth == stImage->base.Depth); 1665 } 1666 1667 if (stImage->pt) { 1668 /* Copy potentially with the blitter: 1669 */ 1670 st_texture_image_copy(st->pipe, 1671 stObj->pt, dstLevel, /* dest texture, level */ 1672 stImage->pt, stImage->level, /* src texture, level */ 1673 stImage->face); 1674 1675 pipe_resource_reference(&stImage->pt, NULL); 1676 } 1677 else if (stImage->base.Data) { 1678 st_texture_image_data(st, 1679 stObj->pt, 1680 stImage->face, 1681 dstLevel, 1682 stImage->base.Data, 1683 stImage->base.RowStride * 1684 util_format_get_blocksize(stObj->pt->format), 1685 stImage->base.RowStride * 1686 stImage->base.Height * 1687 util_format_get_blocksize(stObj->pt->format)); 1688 _mesa_align_free(stImage->base.Data); 1689 stImage->base.Data = NULL; 1690 } 1691 1692 pipe_resource_reference(&stImage->pt, stObj->pt); 1693} 1694 1695 1696/** 1697 * Called during state validation. When this function is finished, 1698 * the texture object should be ready for rendering. 1699 * \return GL_TRUE for success, GL_FALSE for failure (out of mem) 1700 */ 1701GLboolean 1702st_finalize_texture(struct gl_context *ctx, 1703 struct pipe_context *pipe, 1704 struct gl_texture_object *tObj) 1705{ 1706 struct st_context *st = st_context(ctx); 1707 struct st_texture_object *stObj = st_texture_object(tObj); 1708 const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 1709 GLuint face; 1710 struct st_texture_image *firstImage; 1711 enum pipe_format firstImageFormat; 1712 GLuint ptWidth, ptHeight, ptDepth, ptLayers; 1713 1714 if (stObj->base._Complete) { 1715 /* The texture is complete and we know exactly how many mipmap levels 1716 * are present/needed. This is conditional because we may be called 1717 * from the st_generate_mipmap() function when the texture object is 1718 * incomplete. In that case, we'll have set stObj->lastLevel before 1719 * we get here. 1720 */ 1721 if (stObj->base.Sampler.MinFilter == GL_LINEAR || 1722 stObj->base.Sampler.MinFilter == GL_NEAREST) 1723 stObj->lastLevel = stObj->base.BaseLevel; 1724 else 1725 stObj->lastLevel = stObj->base._MaxLevel; 1726 } 1727 1728 firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]); 1729 assert(firstImage); 1730 1731 /* If both firstImage and stObj point to a texture which can contain 1732 * all active images, favour firstImage. Note that because of the 1733 * completeness requirement, we know that the image dimensions 1734 * will match. 1735 */ 1736 if (firstImage->pt && 1737 firstImage->pt != stObj->pt && 1738 (!stObj->pt || firstImage->pt->last_level >= stObj->pt->last_level)) { 1739 pipe_resource_reference(&stObj->pt, firstImage->pt); 1740 pipe_sampler_view_reference(&stObj->sampler_view, NULL); 1741 } 1742 1743 /* Find gallium format for the Mesa texture */ 1744 firstImageFormat = st_mesa_format_to_pipe_format(firstImage->base.TexFormat); 1745 1746 /* Find size of level=0 Gallium mipmap image, plus number of texture layers */ 1747 { 1748 GLuint width, height, depth; 1749 if (!guess_base_level_size(stObj->base.Target, 1750 firstImage->base.Width2, 1751 firstImage->base.Height2, 1752 firstImage->base.Depth2, 1753 stObj->base.BaseLevel, 1754 &width, &height, &depth)) { 1755 width = stObj->width0; 1756 height = stObj->height0; 1757 depth = stObj->depth0; 1758 } 1759 /* convert GL dims to Gallium dims */ 1760 st_gl_texture_dims_to_pipe_dims(stObj->base.Target, width, height, depth, 1761 &ptWidth, &ptHeight, &ptDepth, &ptLayers); 1762 } 1763 1764 /* If we already have a gallium texture, check that it matches the texture 1765 * object's format, target, size, num_levels, etc. 1766 */ 1767 if (stObj->pt) { 1768 if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) || 1769 !st_sampler_compat_formats(stObj->pt->format, firstImageFormat) || 1770 stObj->pt->last_level < stObj->lastLevel || 1771 stObj->pt->width0 != ptWidth || 1772 stObj->pt->height0 != ptHeight || 1773 stObj->pt->depth0 != ptDepth || 1774 stObj->pt->array_size != ptLayers) 1775 { 1776 /* The gallium texture does not match the Mesa texture so delete the 1777 * gallium texture now. We'll make a new one below. 1778 */ 1779 pipe_resource_reference(&stObj->pt, NULL); 1780 pipe_sampler_view_reference(&stObj->sampler_view, NULL); 1781 st->dirty.st |= ST_NEW_FRAMEBUFFER; 1782 } 1783 } 1784 1785 /* May need to create a new gallium texture: 1786 */ 1787 if (!stObj->pt) { 1788 GLuint bindings = default_bindings(st, firstImageFormat); 1789 1790 stObj->pt = st_texture_create(st, 1791 gl_target_to_pipe(stObj->base.Target), 1792 firstImageFormat, 1793 stObj->lastLevel, 1794 ptWidth, 1795 ptHeight, 1796 ptDepth, 1797 ptLayers, 1798 bindings); 1799 1800 if (!stObj->pt) { 1801 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 1802 return GL_FALSE; 1803 } 1804 } 1805 1806 /* Pull in any images not in the object's texture: 1807 */ 1808 for (face = 0; face < nr_faces; face++) { 1809 GLuint level; 1810 for (level = stObj->base.BaseLevel; level <= stObj->lastLevel; level++) { 1811 struct st_texture_image *stImage = 1812 st_texture_image(stObj->base.Image[face][level]); 1813 1814 /* Need to import images in main memory or held in other textures. 1815 */ 1816 if (stImage && stObj->pt != stImage->pt) { 1817 if (level == 0 || (stImage->base.Width == u_minify(stObj->width0, level) && 1818 stImage->base.Height == u_minify(stObj->height0, level) && 1819 stImage->base.Depth == u_minify(stObj->depth0, level))) { 1820 /* src image fits expected dest mipmap level size */ 1821 copy_image_data_to_texture(st, stObj, level, stImage); 1822 } 1823 } 1824 } 1825 } 1826 1827 return GL_TRUE; 1828} 1829 1830 1831/** 1832 * Returns pointer to a default/dummy texture. 1833 * This is typically used when the current shader has tex/sample instructions 1834 * but the user has not provided a (any) texture(s). 1835 */ 1836struct gl_texture_object * 1837st_get_default_texture(struct st_context *st) 1838{ 1839 if (!st->default_texture) { 1840 static const GLenum target = GL_TEXTURE_2D; 1841 GLubyte pixels[16][16][4]; 1842 struct gl_texture_object *texObj; 1843 struct gl_texture_image *texImg; 1844 GLuint i, j; 1845 1846 /* The ARB_fragment_program spec says (0,0,0,1) should be returned 1847 * when attempting to sample incomplete textures. 1848 */ 1849 for (i = 0; i < 16; i++) { 1850 for (j = 0; j < 16; j++) { 1851 pixels[i][j][0] = 0; 1852 pixels[i][j][1] = 0; 1853 pixels[i][j][2] = 0; 1854 pixels[i][j][3] = 255; 1855 } 1856 } 1857 1858 texObj = st->ctx->Driver.NewTextureObject(st->ctx, 0, target); 1859 1860 texImg = _mesa_get_tex_image(st->ctx, texObj, target, 0); 1861 1862 _mesa_init_teximage_fields(st->ctx, target, texImg, 1863 16, 16, 1, 0, /* w, h, d, border */ 1864 GL_RGBA, MESA_FORMAT_RGBA8888); 1865 1866 st_TexImage(st->ctx, 2, target, 1867 0, GL_RGBA, /* level, intformat */ 1868 16, 16, 1, 0, /* w, h, d, border */ 1869 GL_RGBA, GL_UNSIGNED_BYTE, pixels, 1870 &st->ctx->DefaultPacking, 1871 texObj, texImg, 1872 0, 0); 1873 1874 texObj->Sampler.MinFilter = GL_NEAREST; 1875 texObj->Sampler.MagFilter = GL_NEAREST; 1876 texObj->_Complete = GL_TRUE; 1877 1878 st->default_texture = texObj; 1879 } 1880 return st->default_texture; 1881} 1882 1883 1884void 1885st_init_texture_functions(struct dd_function_table *functions) 1886{ 1887 functions->ChooseTextureFormat = st_ChooseTextureFormat; 1888 functions->TexImage1D = st_TexImage1D; 1889 functions->TexImage2D = st_TexImage2D; 1890 functions->TexImage3D = st_TexImage3D; 1891 functions->TexSubImage1D = st_TexSubImage1D; 1892 functions->TexSubImage2D = st_TexSubImage2D; 1893 functions->TexSubImage3D = st_TexSubImage3D; 1894 functions->CompressedTexSubImage1D = st_CompressedTexSubImage1D; 1895 functions->CompressedTexSubImage2D = st_CompressedTexSubImage2D; 1896 functions->CompressedTexSubImage3D = st_CompressedTexSubImage3D; 1897 functions->CopyTexSubImage1D = st_CopyTexSubImage1D; 1898 functions->CopyTexSubImage2D = st_CopyTexSubImage2D; 1899 functions->CopyTexSubImage3D = st_CopyTexSubImage3D; 1900 functions->GenerateMipmap = st_generate_mipmap; 1901 1902 functions->GetTexImage = st_GetTexImage; 1903 1904 /* compressed texture functions */ 1905 functions->CompressedTexImage2D = st_CompressedTexImage2D; 1906 functions->GetCompressedTexImage = st_GetCompressedTexImage; 1907 1908 functions->NewTextureObject = st_NewTextureObject; 1909 functions->NewTextureImage = st_NewTextureImage; 1910 functions->DeleteTexture = st_DeleteTextureObject; 1911 functions->FreeTexImageData = st_FreeTextureImageData; 1912 1913 functions->TextureMemCpy = do_memcpy; 1914 1915 /* XXX Temporary until we can query pipe's texture sizes */ 1916 functions->TestProxyTexImage = _mesa_test_proxy_teximage; 1917} 1918