st_cb_texture.c revision 91acf6225a5e3f08388e6bff8f2c4213769120fe
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/texgetimage.h" 42#include "main/teximage.h" 43#include "main/texobj.h" 44#include "main/texstore.h" 45 46#include "state_tracker/st_debug.h" 47#include "state_tracker/st_context.h" 48#include "state_tracker/st_cb_fbo.h" 49#include "state_tracker/st_cb_flush.h" 50#include "state_tracker/st_cb_texture.h" 51#include "state_tracker/st_cb_bufferobjects.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 case GL_PROXY_TEXTURE_1D: 78 return PIPE_TEXTURE_1D; 79 case GL_TEXTURE_2D: 80 case GL_PROXY_TEXTURE_2D: 81 case GL_TEXTURE_EXTERNAL_OES: 82 return PIPE_TEXTURE_2D; 83 case GL_TEXTURE_RECTANGLE_NV: 84 case GL_PROXY_TEXTURE_RECTANGLE_NV: 85 return PIPE_TEXTURE_RECT; 86 case GL_TEXTURE_3D: 87 case GL_PROXY_TEXTURE_3D: 88 return PIPE_TEXTURE_3D; 89 case GL_TEXTURE_CUBE_MAP_ARB: 90 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 91 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 92 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 93 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 94 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 95 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 96 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 97 return PIPE_TEXTURE_CUBE; 98 case GL_TEXTURE_1D_ARRAY_EXT: 99 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 100 return PIPE_TEXTURE_1D_ARRAY; 101 case GL_TEXTURE_2D_ARRAY_EXT: 102 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 103 return PIPE_TEXTURE_2D_ARRAY; 104 case GL_TEXTURE_BUFFER: 105 return PIPE_BUFFER; 106 case GL_TEXTURE_CUBE_MAP_ARRAY: 107 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 108 return PIPE_TEXTURE_CUBE_ARRAY; 109 default: 110 assert(0); 111 return 0; 112 } 113} 114 115 116/** called via ctx->Driver.NewTextureImage() */ 117static struct gl_texture_image * 118st_NewTextureImage(struct gl_context * ctx) 119{ 120 DBG("%s\n", __FUNCTION__); 121 (void) ctx; 122 return (struct gl_texture_image *) ST_CALLOC_STRUCT(st_texture_image); 123} 124 125 126/** called via ctx->Driver.DeleteTextureImage() */ 127static void 128st_DeleteTextureImage(struct gl_context * ctx, struct gl_texture_image *img) 129{ 130 /* nothing special (yet) for st_texture_image */ 131 _mesa_delete_texture_image(ctx, img); 132} 133 134 135/** called via ctx->Driver.NewTextureObject() */ 136static struct gl_texture_object * 137st_NewTextureObject(struct gl_context * ctx, GLuint name, GLenum target) 138{ 139 struct st_texture_object *obj = ST_CALLOC_STRUCT(st_texture_object); 140 141 DBG("%s\n", __FUNCTION__); 142 _mesa_initialize_texture_object(&obj->base, name, target); 143 144 return &obj->base; 145} 146 147/** called via ctx->Driver.DeleteTextureObject() */ 148static void 149st_DeleteTextureObject(struct gl_context *ctx, 150 struct gl_texture_object *texObj) 151{ 152 struct st_context *st = st_context(ctx); 153 struct st_texture_object *stObj = st_texture_object(texObj); 154 if (stObj->pt) 155 pipe_resource_reference(&stObj->pt, NULL); 156 if (stObj->sampler_view) { 157 pipe_sampler_view_release(st->pipe, &stObj->sampler_view); 158 } 159 _mesa_delete_texture_object(ctx, texObj); 160} 161 162 163/** called via ctx->Driver.FreeTextureImageBuffer() */ 164static void 165st_FreeTextureImageBuffer(struct gl_context *ctx, 166 struct gl_texture_image *texImage) 167{ 168 struct st_texture_image *stImage = st_texture_image(texImage); 169 170 DBG("%s\n", __FUNCTION__); 171 172 if (stImage->pt) { 173 pipe_resource_reference(&stImage->pt, NULL); 174 } 175 176 if (stImage->TexData) { 177 _mesa_align_free(stImage->TexData); 178 stImage->TexData = NULL; 179 } 180} 181 182 183/** called via ctx->Driver.MapTextureImage() */ 184static void 185st_MapTextureImage(struct gl_context *ctx, 186 struct gl_texture_image *texImage, 187 GLuint slice, GLuint x, GLuint y, GLuint w, GLuint h, 188 GLbitfield mode, 189 GLubyte **mapOut, GLint *rowStrideOut) 190{ 191 struct st_context *st = st_context(ctx); 192 struct st_texture_image *stImage = st_texture_image(texImage); 193 unsigned pipeMode; 194 GLubyte *map; 195 196 pipeMode = 0x0; 197 if (mode & GL_MAP_READ_BIT) 198 pipeMode |= PIPE_TRANSFER_READ; 199 if (mode & GL_MAP_WRITE_BIT) 200 pipeMode |= PIPE_TRANSFER_WRITE; 201 if (mode & GL_MAP_INVALIDATE_RANGE_BIT) 202 pipeMode |= PIPE_TRANSFER_DISCARD_RANGE; 203 204 map = st_texture_image_map(st, stImage, pipeMode, x, y, slice, w, h, 1); 205 if (map) { 206 *mapOut = map; 207 *rowStrideOut = stImage->transfer->stride; 208 } 209 else { 210 *mapOut = NULL; 211 *rowStrideOut = 0; 212 } 213} 214 215 216/** called via ctx->Driver.UnmapTextureImage() */ 217static void 218st_UnmapTextureImage(struct gl_context *ctx, 219 struct gl_texture_image *texImage, 220 GLuint slice) 221{ 222 struct st_context *st = st_context(ctx); 223 struct st_texture_image *stImage = st_texture_image(texImage); 224 st_texture_image_unmap(st, stImage); 225} 226 227 228/** 229 * Return default texture resource binding bitmask for the given format. 230 */ 231static GLuint 232default_bindings(struct st_context *st, enum pipe_format format) 233{ 234 struct pipe_screen *screen = st->pipe->screen; 235 const unsigned target = PIPE_TEXTURE_2D; 236 unsigned bindings; 237 238 if (util_format_is_depth_or_stencil(format)) 239 bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_DEPTH_STENCIL; 240 else 241 bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; 242 243 if (screen->is_format_supported(screen, format, target, 0, bindings)) 244 return bindings; 245 else { 246 /* Try non-sRGB. */ 247 format = util_format_linear(format); 248 249 if (screen->is_format_supported(screen, format, target, 0, bindings)) 250 return bindings; 251 else 252 return PIPE_BIND_SAMPLER_VIEW; 253 } 254} 255 256 257/** 258 * Given the size of a mipmap image, try to compute the size of the level=0 259 * mipmap image. 260 * 261 * Note that this isn't always accurate for odd-sized, non-POW textures. 262 * For example, if level=1 and width=40 then the level=0 width may be 80 or 81. 263 * 264 * \return GL_TRUE for success, GL_FALSE for failure 265 */ 266static GLboolean 267guess_base_level_size(GLenum target, 268 GLuint width, GLuint height, GLuint depth, GLuint level, 269 GLuint *width0, GLuint *height0, GLuint *depth0) 270{ 271 assert(width >= 1); 272 assert(height >= 1); 273 assert(depth >= 1); 274 275 if (level > 0) { 276 /* Guess the size of the base level. 277 * Depending on the image's size, we can't always make a guess here. 278 */ 279 switch (target) { 280 case GL_TEXTURE_1D: 281 case GL_TEXTURE_1D_ARRAY: 282 width <<= level; 283 break; 284 285 case GL_TEXTURE_2D: 286 case GL_TEXTURE_2D_ARRAY: 287 /* We can't make a good guess here, because the base level dimensions 288 * can be non-square. 289 */ 290 if (width == 1 || height == 1) { 291 return GL_FALSE; 292 } 293 width <<= level; 294 height <<= level; 295 break; 296 297 case GL_TEXTURE_CUBE_MAP: 298 case GL_TEXTURE_CUBE_MAP_ARRAY: 299 width <<= level; 300 height <<= level; 301 break; 302 303 case GL_TEXTURE_3D: 304 /* We can't make a good guess here, because the base level dimensions 305 * can be non-cube. 306 */ 307 if (width == 1 || height == 1 || depth == 1) { 308 return GL_FALSE; 309 } 310 width <<= level; 311 height <<= level; 312 depth <<= level; 313 break; 314 315 case GL_TEXTURE_RECTANGLE: 316 break; 317 318 default: 319 assert(0); 320 } 321 } 322 323 *width0 = width; 324 *height0 = height; 325 *depth0 = depth; 326 327 return GL_TRUE; 328} 329 330 331/** 332 * Try to allocate a pipe_resource object for the given st_texture_object. 333 * 334 * We use the given st_texture_image as a clue to determine the size of the 335 * mipmap image at level=0. 336 * 337 * \return GL_TRUE for success, GL_FALSE if out of memory. 338 */ 339static GLboolean 340guess_and_alloc_texture(struct st_context *st, 341 struct st_texture_object *stObj, 342 const struct st_texture_image *stImage) 343{ 344 GLuint lastLevel, width, height, depth; 345 GLuint bindings; 346 GLuint ptWidth, ptHeight, ptDepth, ptLayers; 347 enum pipe_format fmt; 348 349 DBG("%s\n", __FUNCTION__); 350 351 assert(!stObj->pt); 352 353 if (!guess_base_level_size(stObj->base.Target, 354 stImage->base.Width2, 355 stImage->base.Height2, 356 stImage->base.Depth2, 357 stImage->base.Level, 358 &width, &height, &depth)) { 359 /* we can't determine the image size at level=0 */ 360 stObj->width0 = stObj->height0 = stObj->depth0 = 0; 361 /* this is not an out of memory error */ 362 return GL_TRUE; 363 } 364 365 /* At this point, (width x height x depth) is the expected size of 366 * the level=0 mipmap image. 367 */ 368 369 /* Guess a reasonable value for lastLevel. With OpenGL we have no 370 * idea how many mipmap levels will be in a texture until we start 371 * to render with it. Make an educated guess here but be prepared 372 * to re-allocating a texture buffer with space for more (or fewer) 373 * mipmap levels later. 374 */ 375 if ((stObj->base.Sampler.MinFilter == GL_NEAREST || 376 stObj->base.Sampler.MinFilter == GL_LINEAR || 377 (stObj->base.BaseLevel == 0 && 378 stObj->base.MaxLevel == 0) || 379 stImage->base._BaseFormat == GL_DEPTH_COMPONENT || 380 stImage->base._BaseFormat == GL_DEPTH_STENCIL_EXT) && 381 !stObj->base.GenerateMipmap && 382 stImage->base.Level == 0) { 383 /* only alloc space for a single mipmap level */ 384 lastLevel = 0; 385 } 386 else { 387 /* alloc space for a full mipmap */ 388 lastLevel = _mesa_get_tex_max_num_levels(stObj->base.Target, 389 width, height, depth) - 1; 390 } 391 392 /* Save the level=0 dimensions */ 393 stObj->width0 = width; 394 stObj->height0 = height; 395 stObj->depth0 = depth; 396 397 fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat); 398 399 bindings = default_bindings(st, fmt); 400 401 st_gl_texture_dims_to_pipe_dims(stObj->base.Target, 402 width, height, depth, 403 &ptWidth, &ptHeight, &ptDepth, &ptLayers); 404 405 stObj->pt = st_texture_create(st, 406 gl_target_to_pipe(stObj->base.Target), 407 fmt, 408 lastLevel, 409 ptWidth, 410 ptHeight, 411 ptDepth, 412 ptLayers, 413 bindings); 414 415 stObj->lastLevel = lastLevel; 416 417 DBG("%s returning %d\n", __FUNCTION__, (stObj->pt != NULL)); 418 419 return stObj->pt != NULL; 420} 421 422 423/** 424 * Called via ctx->Driver.AllocTextureImageBuffer(). 425 * If the texture object/buffer already has space for the indicated image, 426 * we're done. Otherwise, allocate memory for the new texture image. 427 */ 428static GLboolean 429st_AllocTextureImageBuffer(struct gl_context *ctx, 430 struct gl_texture_image *texImage) 431{ 432 struct st_context *st = st_context(ctx); 433 struct st_texture_image *stImage = st_texture_image(texImage); 434 struct st_texture_object *stObj = st_texture_object(texImage->TexObject); 435 const GLuint level = texImage->Level; 436 GLuint width = texImage->Width; 437 GLuint height = texImage->Height; 438 GLuint depth = texImage->Depth; 439 440 DBG("%s\n", __FUNCTION__); 441 442 assert(!stImage->TexData); 443 assert(!stImage->pt); /* xxx this might be wrong */ 444 445 /* Look if the parent texture object has space for this image */ 446 if (stObj->pt && 447 level <= stObj->pt->last_level && 448 st_texture_match_image(stObj->pt, texImage)) { 449 /* this image will fit in the existing texture object's memory */ 450 pipe_resource_reference(&stImage->pt, stObj->pt); 451 return GL_TRUE; 452 } 453 454 /* The parent texture object does not have space for this image */ 455 456 pipe_resource_reference(&stObj->pt, NULL); 457 pipe_sampler_view_release(st->pipe, &stObj->sampler_view); 458 459 if (!guess_and_alloc_texture(st, stObj, stImage)) { 460 /* Probably out of memory. 461 * Try flushing any pending rendering, then retry. 462 */ 463 st_finish(st); 464 if (!guess_and_alloc_texture(st, stObj, stImage)) { 465 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 466 return GL_FALSE; 467 } 468 } 469 470 if (stObj->pt && 471 st_texture_match_image(stObj->pt, texImage)) { 472 /* The image will live in the object's mipmap memory */ 473 pipe_resource_reference(&stImage->pt, stObj->pt); 474 assert(stImage->pt); 475 return GL_TRUE; 476 } 477 else { 478 /* Create a new, temporary texture/resource/buffer to hold this 479 * one texture image. Note that when we later access this image 480 * (either for mapping or copying) we'll want to always specify 481 * mipmap level=0, even if the image represents some other mipmap 482 * level. 483 */ 484 enum pipe_format format = 485 st_mesa_format_to_pipe_format(texImage->TexFormat); 486 GLuint bindings = default_bindings(st, format); 487 GLuint ptWidth, ptHeight, ptDepth, ptLayers; 488 489 st_gl_texture_dims_to_pipe_dims(stObj->base.Target, 490 width, height, depth, 491 &ptWidth, &ptHeight, &ptDepth, &ptLayers); 492 493 stImage->pt = st_texture_create(st, 494 gl_target_to_pipe(stObj->base.Target), 495 format, 496 0, /* lastLevel */ 497 ptWidth, 498 ptHeight, 499 ptDepth, 500 ptLayers, 501 bindings); 502 return stImage->pt != NULL; 503 } 504} 505 506 507/** 508 * Preparation prior to glTexImage. Basically check the 'surface_based' 509 * field and switch to a "normal" tex image if necessary. 510 */ 511static void 512prep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage, 513 GLenum format, GLenum type) 514{ 515 struct gl_texture_object *texObj = texImage->TexObject; 516 struct st_texture_object *stObj = st_texture_object(texObj); 517 518 /* switch to "normal" */ 519 if (stObj->surface_based) { 520 const GLenum target = texObj->Target; 521 const GLuint level = texImage->Level; 522 gl_format texFormat; 523 524 _mesa_clear_texture_object(ctx, texObj); 525 pipe_resource_reference(&stObj->pt, NULL); 526 527 /* oops, need to init this image again */ 528 texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, 529 texImage->InternalFormat, format, 530 type); 531 532 _mesa_init_teximage_fields(ctx, texImage, 533 texImage->Width, texImage->Height, 534 texImage->Depth, texImage->Border, 535 texImage->InternalFormat, texFormat); 536 537 stObj->surface_based = GL_FALSE; 538 } 539} 540 541 542/** 543 * Return a writemask for the gallium blit. The parameters can be base 544 * formats or "format" from glDrawPixels/glTexImage/glGetTexImage. 545 */ 546static unsigned 547get_blit_mask(GLenum srcFormat, GLenum dstFormat) 548{ 549 switch (dstFormat) { 550 case GL_DEPTH_STENCIL: 551 switch (srcFormat) { 552 case GL_DEPTH_STENCIL: 553 return PIPE_MASK_ZS; 554 case GL_DEPTH_COMPONENT: 555 return PIPE_MASK_Z; 556 case GL_STENCIL_INDEX: 557 return PIPE_MASK_S; 558 default: 559 assert(0); 560 return 0; 561 } 562 563 case GL_DEPTH_COMPONENT: 564 switch (srcFormat) { 565 case GL_DEPTH_STENCIL: 566 case GL_DEPTH_COMPONENT: 567 return PIPE_MASK_Z; 568 default: 569 assert(0); 570 return 0; 571 } 572 573 case GL_STENCIL_INDEX: 574 switch (srcFormat) { 575 case GL_STENCIL_INDEX: 576 return PIPE_MASK_S; 577 default: 578 assert(0); 579 return 0; 580 } 581 582 default: 583 return PIPE_MASK_RGBA; 584 } 585} 586 587 588static void 589st_TexImage(struct gl_context * ctx, GLuint dims, 590 struct gl_texture_image *texImage, 591 GLenum format, GLenum type, const void *pixels, 592 const struct gl_pixelstore_attrib *unpack) 593{ 594 prep_teximage(ctx, texImage, format, type); 595 _mesa_store_teximage(ctx, dims, texImage, format, type, pixels, unpack); 596} 597 598 599static void 600st_CompressedTexImage(struct gl_context *ctx, GLuint dims, 601 struct gl_texture_image *texImage, 602 GLsizei imageSize, const GLvoid *data) 603{ 604 prep_teximage(ctx, texImage, GL_NONE, GL_NONE); 605 _mesa_store_compressed_teximage(ctx, dims, texImage, imageSize, data); 606} 607 608 609 610 611/** 612 * Called via ctx->Driver.GetTexImage() 613 * 614 * This uses a blit to copy the texture to a texture format which matches 615 * the format and type combo and then a fast read-back is done using memcpy. 616 * We can do arbitrary X/Y/Z/W/0/1 swizzling here as long as there is 617 * a format which matches the swizzling. 618 * 619 * If such a format isn't available, it falls back to _mesa_get_teximage. 620 * 621 * NOTE: Drivers usually do a blit to convert between tiled and linear 622 * texture layouts during texture uploads/downloads, so the blit 623 * we do here should be free in such cases. 624 */ 625static void 626st_GetTexImage(struct gl_context * ctx, 627 GLenum format, GLenum type, GLvoid * pixels, 628 struct gl_texture_image *texImage) 629{ 630 struct st_context *st = st_context(ctx); 631 struct pipe_context *pipe = st->pipe; 632 struct pipe_screen *screen = pipe->screen; 633 const GLuint width = texImage->Width; 634 const GLuint height = texImage->Height; 635 const GLuint depth = texImage->Depth; 636 struct st_texture_image *stImage = st_texture_image(texImage); 637 struct pipe_resource *src = st_texture_object(texImage->TexObject)->pt; 638 struct pipe_resource *dst = NULL; 639 struct pipe_resource dst_templ; 640 enum pipe_format dst_format, src_format; 641 gl_format mesa_format; 642 GLenum gl_target = texImage->TexObject->Target; 643 enum pipe_texture_target pipe_target; 644 struct pipe_blit_info blit; 645 unsigned bind = PIPE_BIND_TRANSFER_READ; 646 struct pipe_transfer *tex_xfer; 647 ubyte *map = NULL; 648 boolean done = FALSE; 649 650 if (!stImage->pt) { 651 goto fallback; 652 } 653 654 /* XXX Fallback to _mesa_get_teximage for depth-stencil formats 655 * due to an incomplete stencil blit implementation in some drivers. */ 656 if (format == GL_DEPTH_STENCIL) { 657 goto fallback; 658 } 659 660 /* If the base internal format and the texture format don't match, we have 661 * to fall back to _mesa_get_teximage. */ 662 if (texImage->_BaseFormat != 663 _mesa_get_format_base_format(texImage->TexFormat)) { 664 goto fallback; 665 } 666 667 /* See if the texture format already matches the format and type, 668 * in which case the memcpy-based fast path will be used. */ 669 if (_mesa_format_matches_format_and_type(texImage->TexFormat, format, 670 type, ctx->Pack.SwapBytes)) { 671 goto fallback; 672 } 673 674 /* Convert the source format to what is expected by GetTexImage 675 * and see if it's supported. 676 * 677 * This only applies to glGetTexImage: 678 * - Luminance must be returned as (L,0,0,1). 679 * - Luminance alpha must be returned as (L,0,0,A). 680 * - Intensity must be returned as (I,0,0,1) 681 */ 682 src_format = util_format_linear(src->format); 683 src_format = util_format_luminance_to_red(src_format); 684 src_format = util_format_intensity_to_red(src_format); 685 686 if (!src_format || 687 !screen->is_format_supported(screen, src_format, src->target, 688 src->nr_samples, 689 PIPE_BIND_SAMPLER_VIEW)) { 690 goto fallback; 691 } 692 693 if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL) 694 bind |= PIPE_BIND_DEPTH_STENCIL; 695 else 696 bind |= PIPE_BIND_RENDER_TARGET; 697 698 /* GetTexImage only returns a single face for cubemaps. */ 699 if (gl_target == GL_TEXTURE_CUBE_MAP) { 700 gl_target = GL_TEXTURE_2D; 701 } 702 pipe_target = gl_target_to_pipe(gl_target); 703 704 /* Choose the destination format by finding the best match 705 * for the format+type combo. */ 706 dst_format = st_choose_matching_format(screen, bind, format, type, 707 ctx->Pack.SwapBytes); 708 709 if (dst_format == PIPE_FORMAT_NONE) { 710 GLenum dst_glformat; 711 712 /* Fall back to _mesa_get_teximage except for compressed formats, 713 * where decompression with a blit is always preferred. */ 714 if (!util_format_is_compressed(src->format)) { 715 goto fallback; 716 } 717 718 /* Set the appropriate format for the decompressed texture. 719 * Luminance and sRGB formats shouldn't appear here.*/ 720 switch (src_format) { 721 case PIPE_FORMAT_DXT1_RGB: 722 case PIPE_FORMAT_DXT1_RGBA: 723 case PIPE_FORMAT_DXT3_RGBA: 724 case PIPE_FORMAT_DXT5_RGBA: 725 case PIPE_FORMAT_RGTC1_UNORM: 726 case PIPE_FORMAT_RGTC2_UNORM: 727 case PIPE_FORMAT_ETC1_RGB8: 728 dst_glformat = GL_RGBA8; 729 break; 730 case PIPE_FORMAT_RGTC1_SNORM: 731 case PIPE_FORMAT_RGTC2_SNORM: 732 if (!ctx->Extensions.EXT_texture_snorm) 733 goto fallback; 734 dst_glformat = GL_RGBA8_SNORM; 735 break; 736 /* TODO: for BPTC_*FLOAT, set RGBA32F and check for ARB_texture_float */ 737 default: 738 assert(0); 739 goto fallback; 740 } 741 742 dst_format = st_choose_format(st, dst_glformat, format, type, 743 pipe_target, 0, bind, FALSE); 744 745 if (dst_format == PIPE_FORMAT_NONE) { 746 /* unable to get an rgba format!?! */ 747 goto fallback; 748 } 749 } 750 751 /* create the destination texture */ 752 memset(&dst_templ, 0, sizeof(dst_templ)); 753 dst_templ.target = pipe_target; 754 dst_templ.format = dst_format; 755 dst_templ.bind = bind; 756 dst_templ.usage = PIPE_USAGE_STAGING; 757 758 st_gl_texture_dims_to_pipe_dims(gl_target, width, height, depth, 759 &dst_templ.width0, &dst_templ.height0, 760 &dst_templ.depth0, &dst_templ.array_size); 761 762 dst = screen->resource_create(screen, &dst_templ); 763 if (!dst) { 764 goto fallback; 765 } 766 767 blit.src.resource = src; 768 blit.src.level = texImage->Level; 769 blit.src.format = src_format; 770 blit.dst.resource = dst; 771 blit.dst.level = 0; 772 blit.dst.format = dst->format; 773 blit.src.box.x = blit.dst.box.x = 0; 774 blit.src.box.y = blit.dst.box.y = 0; 775 blit.src.box.z = texImage->Face; 776 blit.dst.box.z = 0; 777 blit.src.box.width = blit.dst.box.width = width; 778 blit.src.box.height = blit.dst.box.height = height; 779 blit.src.box.depth = blit.dst.box.depth = depth; 780 blit.mask = get_blit_mask(texImage->_BaseFormat, format); 781 blit.filter = PIPE_TEX_FILTER_NEAREST; 782 blit.scissor_enable = FALSE; 783 784 /* blit/render/decompress */ 785 st->pipe->blit(st->pipe, &blit); 786 787 pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels); 788 789 map = pipe_transfer_map_3d(pipe, dst, 0, PIPE_TRANSFER_READ, 790 0, 0, 0, width, height, depth, &tex_xfer); 791 if (!map) { 792 goto end; 793 } 794 795 mesa_format = st_pipe_format_to_mesa_format(dst_format); 796 797 /* copy/pack data into user buffer */ 798 if (_mesa_format_matches_format_and_type(mesa_format, format, type, 799 ctx->Pack.SwapBytes)) { 800 /* memcpy */ 801 const uint bytesPerRow = width * util_format_get_blocksize(dst_format); 802 GLuint row, slice; 803 804 for (slice = 0; slice < depth; slice++) { 805 ubyte *slice_map = map; 806 807 for (row = 0; row < height; row++) { 808 GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels, 809 width, height, format, 810 type, slice, row, 0); 811 memcpy(dest, slice_map, bytesPerRow); 812 slice_map += tex_xfer->stride; 813 } 814 map += tex_xfer->layer_stride; 815 } 816 } 817 else { 818 /* format translation via floats */ 819 GLuint row, slice; 820 GLfloat *rgba; 821 822 assert(util_format_is_compressed(src->format)); 823 824 rgba = malloc(width * 4 * sizeof(GLfloat)); 825 if (!rgba) { 826 goto end; 827 } 828 829 for (slice = 0; slice < depth; slice++) { 830 for (row = 0; row < height; row++) { 831 const GLbitfield transferOps = 0x0; /* bypassed for glGetTexImage() */ 832 GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels, 833 width, height, format, 834 type, slice, row, 0); 835 836 if (ST_DEBUG & DEBUG_FALLBACK) 837 debug_printf("%s: fallback format translation\n", __FUNCTION__); 838 839 /* get float[4] rgba row from surface */ 840 pipe_get_tile_rgba_format(tex_xfer, map, 0, row, width, 1, 841 dst_format, rgba); 842 843 _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, 844 type, dest, &ctx->Pack, transferOps); 845 } 846 map += tex_xfer->layer_stride; 847 } 848 849 free(rgba); 850 } 851 done = TRUE; 852 853end: 854 if (map) 855 pipe_transfer_unmap(pipe, tex_xfer); 856 857 _mesa_unmap_pbo_dest(ctx, &ctx->Pack); 858 pipe_resource_reference(&dst, NULL); 859 860fallback: 861 if (!done) { 862 _mesa_get_teximage(ctx, format, type, pixels, texImage); 863 } 864} 865 866 867/** 868 * Do a CopyTexSubImage operation using a read transfer from the source, 869 * a write transfer to the destination and get_tile()/put_tile() to access 870 * the pixels/texels. 871 * 872 * Note: srcY=0=TOP of renderbuffer 873 */ 874static void 875fallback_copy_texsubimage(struct gl_context *ctx, 876 struct st_renderbuffer *strb, 877 struct st_texture_image *stImage, 878 GLenum baseFormat, 879 GLint destX, GLint destY, GLint destZ, 880 GLint srcX, GLint srcY, 881 GLsizei width, GLsizei height) 882{ 883 struct st_context *st = st_context(ctx); 884 struct pipe_context *pipe = st->pipe; 885 struct pipe_transfer *src_trans; 886 GLubyte *texDest; 887 enum pipe_transfer_usage transfer_usage; 888 void *map; 889 unsigned dst_width = width; 890 unsigned dst_height = height; 891 unsigned dst_depth = 1; 892 893 if (ST_DEBUG & DEBUG_FALLBACK) 894 debug_printf("%s: fallback processing\n", __FUNCTION__); 895 896 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 897 srcY = strb->Base.Height - srcY - height; 898 } 899 900 if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) { 901 /* Move y/height to z/depth for 1D array textures. */ 902 destZ = destY; 903 destY = 0; 904 dst_depth = dst_height; 905 dst_height = 1; 906 } 907 908 map = pipe_transfer_map(pipe, 909 strb->texture, 910 strb->rtt_level, 911 strb->rtt_face + strb->rtt_slice, 912 PIPE_TRANSFER_READ, 913 srcX, srcY, 914 width, height, &src_trans); 915 916 if ((baseFormat == GL_DEPTH_COMPONENT || 917 baseFormat == GL_DEPTH_STENCIL) && 918 util_format_is_depth_and_stencil(stImage->pt->format)) 919 transfer_usage = PIPE_TRANSFER_READ_WRITE; 920 else 921 transfer_usage = PIPE_TRANSFER_WRITE; 922 923 texDest = st_texture_image_map(st, stImage, transfer_usage, 924 destX, destY, destZ, 925 dst_width, dst_height, dst_depth); 926 927 if (baseFormat == GL_DEPTH_COMPONENT || 928 baseFormat == GL_DEPTH_STENCIL) { 929 const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F || 930 ctx->Pixel.DepthBias != 0.0F); 931 GLint row, yStep; 932 uint *data; 933 934 /* determine bottom-to-top vs. top-to-bottom order for src buffer */ 935 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 936 srcY = height - 1; 937 yStep = -1; 938 } 939 else { 940 srcY = 0; 941 yStep = 1; 942 } 943 944 data = malloc(width * sizeof(uint)); 945 946 if (data) { 947 /* To avoid a large temp memory allocation, do copy row by row */ 948 for (row = 0; row < height; row++, srcY += yStep) { 949 pipe_get_tile_z(src_trans, map, 0, srcY, width, 1, data); 950 if (scaleOrBias) { 951 _mesa_scale_and_bias_depth_uint(ctx, width, data); 952 } 953 954 if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) { 955 pipe_put_tile_z(stImage->transfer, 956 texDest + row*stImage->transfer->layer_stride, 957 0, 0, width, 1, data); 958 } 959 else { 960 pipe_put_tile_z(stImage->transfer, texDest, 0, row, width, 1, 961 data); 962 } 963 } 964 } 965 else { 966 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage()"); 967 } 968 969 free(data); 970 } 971 else { 972 /* RGBA format */ 973 GLfloat *tempSrc = 974 malloc(width * height * 4 * sizeof(GLfloat)); 975 976 if (tempSrc && texDest) { 977 const GLint dims = 2; 978 GLint dstRowStride; 979 struct gl_texture_image *texImage = &stImage->base; 980 struct gl_pixelstore_attrib unpack = ctx->DefaultPacking; 981 982 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 983 unpack.Invert = GL_TRUE; 984 } 985 986 if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) { 987 dstRowStride = stImage->transfer->layer_stride; 988 } 989 else { 990 dstRowStride = stImage->transfer->stride; 991 } 992 993 /* get float/RGBA image from framebuffer */ 994 /* XXX this usually involves a lot of int/float conversion. 995 * try to avoid that someday. 996 */ 997 pipe_get_tile_rgba_format(src_trans, map, 0, 0, width, height, 998 util_format_linear(strb->texture->format), 999 tempSrc); 1000 1001 /* Store into texture memory. 1002 * Note that this does some special things such as pixel transfer 1003 * ops and format conversion. In particular, if the dest tex format 1004 * is actually RGBA but the user created the texture as GL_RGB we 1005 * need to fill-in/override the alpha channel with 1.0. 1006 */ 1007 _mesa_texstore(ctx, dims, 1008 texImage->_BaseFormat, 1009 texImage->TexFormat, 1010 dstRowStride, 1011 &texDest, 1012 width, height, 1, 1013 GL_RGBA, GL_FLOAT, tempSrc, /* src */ 1014 &unpack); 1015 } 1016 else { 1017 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 1018 } 1019 1020 free(tempSrc); 1021 } 1022 1023 st_texture_image_unmap(st, stImage); 1024 pipe->transfer_unmap(pipe, src_trans); 1025} 1026 1027 1028 1029/** 1030 * If the format of the src renderbuffer and the format of the dest 1031 * texture are compatible (in terms of blitting), return a TGSI writemask 1032 * to be used during the blit. 1033 * If the src/dest are incompatible, return 0. 1034 */ 1035static unsigned 1036compatible_src_dst_formats(struct gl_context *ctx, 1037 const struct gl_renderbuffer *src, 1038 const struct gl_texture_image *dst) 1039{ 1040 /* Get logical base formats for the src and dest. 1041 * That is, use the user-requested formats and not the actual, device- 1042 * chosen formats. 1043 * For example, the user may have requested an A8 texture but the 1044 * driver may actually be using an RGBA texture format. When we 1045 * copy/blit to that texture, we only want to copy the Alpha channel 1046 * and not the RGB channels. 1047 * 1048 * Similarly, when the src FBO was created an RGB format may have been 1049 * requested but the driver actually chose an RGBA format. In that case, 1050 * we don't want to copy the undefined Alpha channel to the dest texture 1051 * (it should be 1.0). 1052 */ 1053 const GLenum srcFormat = _mesa_base_fbo_format(ctx, src->InternalFormat); 1054 const GLenum dstFormat = _mesa_base_tex_format(ctx, dst->InternalFormat); 1055 1056 /** 1057 * XXX when we have red-only and red/green renderbuffers we'll need 1058 * to add more cases here (or implement a general-purpose routine that 1059 * queries the existance of the R,G,B,A channels in the src and dest). 1060 */ 1061 if (srcFormat == dstFormat) { 1062 /* This is the same as matching_base_formats, which should 1063 * always pass, as it did previously. 1064 */ 1065 return TGSI_WRITEMASK_XYZW; 1066 } 1067 else if (srcFormat == GL_RGB && dstFormat == GL_RGBA) { 1068 /* Make sure that A in the dest is 1. The actual src format 1069 * may be RGBA and have undefined A values. 1070 */ 1071 return TGSI_WRITEMASK_XYZ; 1072 } 1073 else if (srcFormat == GL_RGBA && dstFormat == GL_RGB) { 1074 /* Make sure that A in the dest is 1. The actual dst format 1075 * may be RGBA and will need A=1 to provide proper alpha values 1076 * when sampled later. 1077 */ 1078 return TGSI_WRITEMASK_XYZ; 1079 } 1080 else { 1081 if (ST_DEBUG & DEBUG_FALLBACK) 1082 debug_printf("%s failed for src %s, dst %s\n", 1083 __FUNCTION__, 1084 _mesa_lookup_enum_by_nr(srcFormat), 1085 _mesa_lookup_enum_by_nr(dstFormat)); 1086 1087 /* Otherwise fail. 1088 */ 1089 return 0; 1090 } 1091} 1092 1093 1094/** 1095 * Do pipe->blit. Return FALSE if the blitting is unsupported 1096 * for the given formats. 1097 */ 1098static GLboolean 1099st_pipe_blit(struct pipe_context *pipe, struct pipe_blit_info *blit) 1100{ 1101 struct pipe_screen *screen = pipe->screen; 1102 unsigned dst_usage; 1103 1104 if (util_format_is_depth_or_stencil(blit->dst.format)) { 1105 dst_usage = PIPE_BIND_DEPTH_STENCIL; 1106 } 1107 else { 1108 dst_usage = PIPE_BIND_RENDER_TARGET; 1109 } 1110 1111 /* try resource_copy_region in case the format is not supported 1112 * for rendering */ 1113 if (util_try_blit_via_copy_region(pipe, blit)) { 1114 return GL_TRUE; /* done */ 1115 } 1116 1117 /* check the format support */ 1118 if (!screen->is_format_supported(screen, blit->src.format, 1119 PIPE_TEXTURE_2D, 0, 1120 PIPE_BIND_SAMPLER_VIEW) || 1121 !screen->is_format_supported(screen, blit->dst.format, 1122 PIPE_TEXTURE_2D, 0, 1123 dst_usage)) { 1124 return GL_FALSE; 1125 } 1126 1127 pipe->blit(pipe, blit); 1128 return GL_TRUE; 1129} 1130 1131 1132/** 1133 * Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible. 1134 * Note that the region to copy has already been clipped so we know we 1135 * won't read from outside the source renderbuffer's bounds. 1136 * 1137 * Note: srcY=0=Bottom of renderbuffer (GL convention) 1138 */ 1139static void 1140st_CopyTexSubImage(struct gl_context *ctx, GLuint dims, 1141 struct gl_texture_image *texImage, 1142 GLint destX, GLint destY, GLint destZ, 1143 struct gl_renderbuffer *rb, 1144 GLint srcX, GLint srcY, GLsizei width, GLsizei height) 1145{ 1146 struct st_texture_image *stImage = st_texture_image(texImage); 1147 const GLenum texBaseFormat = texImage->_BaseFormat; 1148 struct st_renderbuffer *strb = st_renderbuffer(rb); 1149 struct st_context *st = st_context(ctx); 1150 struct pipe_context *pipe = st->pipe; 1151 struct pipe_screen *screen = pipe->screen; 1152 enum pipe_format dest_format, src_format; 1153 GLuint color_writemask; 1154 struct pipe_surface *dest_surface = NULL; 1155 GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP); 1156 struct pipe_surface surf_tmpl; 1157 unsigned dst_usage; 1158 unsigned blit_mask; 1159 GLint srcY0, srcY1, yStep; 1160 1161 /* make sure finalize_textures has been called? 1162 */ 1163 if (0) st_validate_state(st); 1164 1165 if (!strb || !strb->surface || !stImage->pt) { 1166 debug_printf("%s: null strb or stImage\n", __FUNCTION__); 1167 return; 1168 } 1169 1170 assert(strb); 1171 assert(strb->surface); 1172 assert(stImage->pt); 1173 1174 src_format = strb->surface->format; 1175 dest_format = stImage->pt->format; 1176 1177 if (do_flip) { 1178 srcY1 = strb->Base.Height - srcY - height; 1179 srcY0 = srcY1 + height; 1180 yStep = -1; 1181 } 1182 else { 1183 srcY0 = srcY; 1184 srcY1 = srcY0 + height; 1185 yStep = 1; 1186 } 1187 1188 if (ctx->_ImageTransferState) { 1189 goto fallback; 1190 } 1191 1192 /* Compressed and subsampled textures aren't supported for blitting. */ 1193 if (!util_format_is_plain(dest_format)) { 1194 goto fallback; 1195 } 1196 1197 if (texBaseFormat == GL_DEPTH_STENCIL || 1198 texBaseFormat == GL_DEPTH_COMPONENT) { 1199 dst_usage = PIPE_BIND_DEPTH_STENCIL; 1200 } 1201 else { 1202 dst_usage = PIPE_BIND_RENDER_TARGET; 1203 } 1204 1205 blit_mask = get_blit_mask(rb->_BaseFormat, texImage->_BaseFormat); 1206 1207 /* Determine if the src framebuffer and dest texture have the same 1208 * base format. We need this to detect a case such as the framebuffer 1209 * being GL_RGBA but the texture being GL_RGB. If the actual hardware 1210 * texture format stores RGBA we need to set A=1 (overriding the 1211 * framebuffer's alpha values). 1212 * 1213 * XXX util_blit_pixels doesn't support MSAA resolve, so always use 1214 * pipe->blit for MSAA textures 1215 */ 1216 if ((blit_mask & PIPE_MASK_RGBA) && 1217 texBaseFormat != strb->Base._BaseFormat && 1218 strb->texture->nr_samples <= 1) { 1219 blit_mask = 0; 1220 } 1221 1222 /* Blit the texture. 1223 * This supports flipping, format conversions, and downsampling. 1224 */ 1225 if (blit_mask) { 1226 /* If stImage->pt is an independent image (not a pointer into a full 1227 * mipmap) stImage->pt.last_level will be zero and we need to use that 1228 * as the dest level. 1229 */ 1230 unsigned dstLevel = MIN2(stImage->base.Level, stImage->pt->last_level); 1231 struct pipe_blit_info blit; 1232 1233 memset(&blit, 0, sizeof(blit)); 1234 blit.src.resource = strb->texture; 1235 blit.src.format = src_format; 1236 blit.src.level = strb->surface->u.tex.level; 1237 blit.src.box.x = srcX; 1238 blit.src.box.y = srcY0; 1239 blit.src.box.z = strb->surface->u.tex.first_layer; 1240 blit.src.box.width = width; 1241 blit.src.box.height = srcY1 - srcY0; 1242 blit.src.box.depth = 1; 1243 blit.dst.resource = stImage->pt; 1244 blit.dst.format = dest_format; 1245 blit.dst.level = dstLevel; 1246 blit.dst.box.x = destX; 1247 blit.dst.box.y = destY; 1248 blit.dst.box.z = stImage->base.Face + destZ; 1249 blit.dst.box.width = width; 1250 blit.dst.box.height = height; 1251 blit.dst.box.depth = 1; 1252 blit.mask = blit_mask; 1253 blit.filter = PIPE_TEX_FILTER_NEAREST; 1254 1255 /* 1D array textures need special treatment. 1256 * Blit rows from the source to layers in the destination. */ 1257 if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) { 1258 int y, layer; 1259 1260 for (y = srcY0, layer = 0; layer < height; y += yStep, layer++) { 1261 blit.src.box.y = y; 1262 blit.src.box.height = 1; 1263 blit.dst.box.y = 0; 1264 blit.dst.box.height = 1; 1265 blit.dst.box.z = destY + layer; 1266 1267 if (!st_pipe_blit(pipe, &blit)) { 1268 goto fallback; 1269 } 1270 } 1271 } 1272 else { 1273 /* All the other texture targets. */ 1274 if (!st_pipe_blit(pipe, &blit)) { 1275 goto fallback; 1276 } 1277 } 1278 return; 1279 } 1280 1281 /* try u_blit */ 1282 if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) { 1283 /* u_blit cannot copy 1D array textures as required by CopyTexSubImage */ 1284 goto fallback; 1285 } 1286 1287 color_writemask = compatible_src_dst_formats(ctx, &strb->Base, texImage); 1288 1289 if (!color_writemask || 1290 !screen->is_format_supported(screen, src_format, 1291 PIPE_TEXTURE_2D, 0, 1292 PIPE_BIND_SAMPLER_VIEW) || 1293 !screen->is_format_supported(screen, dest_format, 1294 PIPE_TEXTURE_2D, 0, 1295 dst_usage)) { 1296 goto fallback; 1297 } 1298 1299 memset(&surf_tmpl, 0, sizeof(surf_tmpl)); 1300 surf_tmpl.format = util_format_linear(stImage->pt->format); 1301 surf_tmpl.u.tex.level = stImage->base.Level; 1302 surf_tmpl.u.tex.first_layer = stImage->base.Face + destZ; 1303 surf_tmpl.u.tex.last_layer = stImage->base.Face + destZ; 1304 1305 dest_surface = pipe->create_surface(pipe, stImage->pt, 1306 &surf_tmpl); 1307 util_blit_pixels(st->blit, 1308 strb->texture, 1309 strb->surface->u.tex.level, 1310 srcX, srcY0, 1311 srcX + width, srcY1, 1312 strb->surface->u.tex.first_layer, 1313 dest_surface, 1314 destX, destY, 1315 destX + width, destY + height, 1316 0.0, PIPE_TEX_MIPFILTER_NEAREST, 1317 color_writemask, 0); 1318 pipe_surface_reference(&dest_surface, NULL); 1319 return; 1320 1321fallback: 1322 /* software fallback */ 1323 fallback_copy_texsubimage(ctx, 1324 strb, stImage, texBaseFormat, 1325 destX, destY, destZ, 1326 srcX, srcY, width, height); 1327} 1328 1329 1330/** 1331 * Copy image data from stImage into the texture object 'stObj' at level 1332 * 'dstLevel'. 1333 */ 1334static void 1335copy_image_data_to_texture(struct st_context *st, 1336 struct st_texture_object *stObj, 1337 GLuint dstLevel, 1338 struct st_texture_image *stImage) 1339{ 1340 /* debug checks */ 1341 { 1342 const struct gl_texture_image *dstImage = 1343 stObj->base.Image[stImage->base.Face][dstLevel]; 1344 assert(dstImage); 1345 assert(dstImage->Width == stImage->base.Width); 1346 assert(dstImage->Height == stImage->base.Height); 1347 assert(dstImage->Depth == stImage->base.Depth); 1348 } 1349 1350 if (stImage->pt) { 1351 /* Copy potentially with the blitter: 1352 */ 1353 GLuint src_level; 1354 if (stImage->pt->last_level == 0) 1355 src_level = 0; 1356 else 1357 src_level = stImage->base.Level; 1358 1359 assert(src_level <= stImage->pt->last_level); 1360 assert(u_minify(stImage->pt->width0, src_level) == stImage->base.Width); 1361 assert(stImage->pt->target == PIPE_TEXTURE_1D_ARRAY || 1362 u_minify(stImage->pt->height0, src_level) == stImage->base.Height); 1363 assert(stImage->pt->target == PIPE_TEXTURE_2D_ARRAY || 1364 stImage->pt->target == PIPE_TEXTURE_CUBE_ARRAY || 1365 u_minify(stImage->pt->depth0, src_level) == stImage->base.Depth); 1366 1367 st_texture_image_copy(st->pipe, 1368 stObj->pt, dstLevel, /* dest texture, level */ 1369 stImage->pt, src_level, /* src texture, level */ 1370 stImage->base.Face); 1371 1372 pipe_resource_reference(&stImage->pt, NULL); 1373 } 1374 else if (stImage->TexData) { 1375 /* Copy from malloc'd memory */ 1376 /* XXX this should be re-examined/tested with a compressed format */ 1377 GLuint blockSize = util_format_get_blocksize(stObj->pt->format); 1378 GLuint srcRowStride = stImage->base.Width * blockSize; 1379 GLuint srcSliceStride = stImage->base.Height * srcRowStride; 1380 st_texture_image_data(st, 1381 stObj->pt, 1382 stImage->base.Face, 1383 dstLevel, 1384 stImage->TexData, 1385 srcRowStride, 1386 srcSliceStride); 1387 _mesa_align_free(stImage->TexData); 1388 stImage->TexData = NULL; 1389 } 1390 1391 pipe_resource_reference(&stImage->pt, stObj->pt); 1392} 1393 1394 1395/** 1396 * Called during state validation. When this function is finished, 1397 * the texture object should be ready for rendering. 1398 * \return GL_TRUE for success, GL_FALSE for failure (out of mem) 1399 */ 1400GLboolean 1401st_finalize_texture(struct gl_context *ctx, 1402 struct pipe_context *pipe, 1403 struct gl_texture_object *tObj) 1404{ 1405 struct st_context *st = st_context(ctx); 1406 struct st_texture_object *stObj = st_texture_object(tObj); 1407 const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 1408 GLuint face; 1409 struct st_texture_image *firstImage; 1410 enum pipe_format firstImageFormat; 1411 GLuint ptWidth, ptHeight, ptDepth, ptLayers; 1412 1413 if (_mesa_is_texture_complete(tObj, &tObj->Sampler)) { 1414 /* The texture is complete and we know exactly how many mipmap levels 1415 * are present/needed. This is conditional because we may be called 1416 * from the st_generate_mipmap() function when the texture object is 1417 * incomplete. In that case, we'll have set stObj->lastLevel before 1418 * we get here. 1419 */ 1420 if (stObj->base.Sampler.MinFilter == GL_LINEAR || 1421 stObj->base.Sampler.MinFilter == GL_NEAREST) 1422 stObj->lastLevel = stObj->base.BaseLevel; 1423 else 1424 stObj->lastLevel = stObj->base._MaxLevel; 1425 } 1426 1427 if (tObj->Target == GL_TEXTURE_BUFFER) { 1428 struct st_buffer_object *st_obj = st_buffer_object(tObj->BufferObject); 1429 1430 if (st_obj->buffer != stObj->pt) { 1431 pipe_resource_reference(&stObj->pt, st_obj->buffer); 1432 pipe_sampler_view_release(st->pipe, &stObj->sampler_view); 1433 stObj->width0 = stObj->pt->width0 / _mesa_get_format_bytes(tObj->_BufferObjectFormat); 1434 stObj->height0 = 1; 1435 stObj->depth0 = 1; 1436 } 1437 return GL_TRUE; 1438 1439 } 1440 1441 firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]); 1442 assert(firstImage); 1443 1444 /* If both firstImage and stObj point to a texture which can contain 1445 * all active images, favour firstImage. Note that because of the 1446 * completeness requirement, we know that the image dimensions 1447 * will match. 1448 */ 1449 if (firstImage->pt && 1450 firstImage->pt != stObj->pt && 1451 (!stObj->pt || firstImage->pt->last_level >= stObj->pt->last_level)) { 1452 pipe_resource_reference(&stObj->pt, firstImage->pt); 1453 pipe_sampler_view_release(st->pipe, &stObj->sampler_view); 1454 } 1455 1456 /* Find gallium format for the Mesa texture */ 1457 firstImageFormat = st_mesa_format_to_pipe_format(firstImage->base.TexFormat); 1458 1459 /* Find size of level=0 Gallium mipmap image, plus number of texture layers */ 1460 { 1461 GLuint width, height, depth; 1462 if (!guess_base_level_size(stObj->base.Target, 1463 firstImage->base.Width2, 1464 firstImage->base.Height2, 1465 firstImage->base.Depth2, 1466 firstImage->base.Level, 1467 &width, &height, &depth)) { 1468 width = stObj->width0; 1469 height = stObj->height0; 1470 depth = stObj->depth0; 1471 } 1472 /* convert GL dims to Gallium dims */ 1473 st_gl_texture_dims_to_pipe_dims(stObj->base.Target, width, height, depth, 1474 &ptWidth, &ptHeight, &ptDepth, &ptLayers); 1475 } 1476 1477 /* If we already have a gallium texture, check that it matches the texture 1478 * object's format, target, size, num_levels, etc. 1479 */ 1480 if (stObj->pt) { 1481 if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) || 1482 !st_sampler_compat_formats(stObj->pt->format, firstImageFormat) || 1483 stObj->pt->last_level < stObj->lastLevel || 1484 stObj->pt->width0 != ptWidth || 1485 stObj->pt->height0 != ptHeight || 1486 stObj->pt->depth0 != ptDepth || 1487 stObj->pt->array_size != ptLayers) 1488 { 1489 /* The gallium texture does not match the Mesa texture so delete the 1490 * gallium texture now. We'll make a new one below. 1491 */ 1492 pipe_resource_reference(&stObj->pt, NULL); 1493 pipe_sampler_view_release(st->pipe, &stObj->sampler_view); 1494 st->dirty.st |= ST_NEW_FRAMEBUFFER; 1495 } 1496 } 1497 1498 /* May need to create a new gallium texture: 1499 */ 1500 if (!stObj->pt) { 1501 GLuint bindings = default_bindings(st, firstImageFormat); 1502 1503 stObj->pt = st_texture_create(st, 1504 gl_target_to_pipe(stObj->base.Target), 1505 firstImageFormat, 1506 stObj->lastLevel, 1507 ptWidth, 1508 ptHeight, 1509 ptDepth, 1510 ptLayers, 1511 bindings); 1512 1513 if (!stObj->pt) { 1514 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 1515 return GL_FALSE; 1516 } 1517 } 1518 1519 /* Pull in any images not in the object's texture: 1520 */ 1521 for (face = 0; face < nr_faces; face++) { 1522 GLuint level; 1523 for (level = stObj->base.BaseLevel; level <= stObj->lastLevel; level++) { 1524 struct st_texture_image *stImage = 1525 st_texture_image(stObj->base.Image[face][level]); 1526 1527 /* Need to import images in main memory or held in other textures. 1528 */ 1529 if (stImage && stObj->pt != stImage->pt) { 1530 if (level == 0 || 1531 (stImage->base.Width == u_minify(stObj->width0, level) && 1532 stImage->base.Height == u_minify(stObj->height0, level) && 1533 stImage->base.Depth == u_minify(stObj->depth0, level))) { 1534 /* src image fits expected dest mipmap level size */ 1535 copy_image_data_to_texture(st, stObj, level, stImage); 1536 } 1537 } 1538 } 1539 } 1540 1541 return GL_TRUE; 1542} 1543 1544 1545/** 1546 * Called via ctx->Driver.AllocTextureStorage() to allocate texture memory 1547 * for a whole mipmap stack. 1548 */ 1549static GLboolean 1550st_AllocTextureStorage(struct gl_context *ctx, 1551 struct gl_texture_object *texObj, 1552 GLsizei levels, GLsizei width, 1553 GLsizei height, GLsizei depth) 1554{ 1555 const GLuint numFaces = _mesa_num_tex_faces(texObj->Target); 1556 struct st_context *st = st_context(ctx); 1557 struct st_texture_object *stObj = st_texture_object(texObj); 1558 GLuint ptWidth, ptHeight, ptDepth, ptLayers, bindings; 1559 enum pipe_format fmt; 1560 GLint level; 1561 1562 assert(levels > 0); 1563 1564 /* Save the level=0 dimensions */ 1565 stObj->width0 = width; 1566 stObj->height0 = height; 1567 stObj->depth0 = depth; 1568 stObj->lastLevel = levels - 1; 1569 1570 fmt = st_mesa_format_to_pipe_format(texObj->Image[0][0]->TexFormat); 1571 1572 bindings = default_bindings(st, fmt); 1573 1574 st_gl_texture_dims_to_pipe_dims(texObj->Target, 1575 width, height, depth, 1576 &ptWidth, &ptHeight, &ptDepth, &ptLayers); 1577 1578 stObj->pt = st_texture_create(st, 1579 gl_target_to_pipe(texObj->Target), 1580 fmt, 1581 levels, 1582 ptWidth, 1583 ptHeight, 1584 ptDepth, 1585 ptLayers, 1586 bindings); 1587 if (!stObj->pt) 1588 return GL_FALSE; 1589 1590 /* Set image resource pointers */ 1591 for (level = 0; level < levels; level++) { 1592 GLuint face; 1593 for (face = 0; face < numFaces; face++) { 1594 struct st_texture_image *stImage = 1595 st_texture_image(texObj->Image[face][level]); 1596 pipe_resource_reference(&stImage->pt, stObj->pt); 1597 } 1598 } 1599 1600 return GL_TRUE; 1601} 1602 1603 1604static GLboolean 1605st_TestProxyTexImage(struct gl_context *ctx, GLenum target, 1606 GLint level, gl_format format, 1607 GLint width, GLint height, 1608 GLint depth, GLint border) 1609{ 1610 struct st_context *st = st_context(ctx); 1611 struct pipe_context *pipe = st->pipe; 1612 1613 if (width == 0 || height == 0 || depth == 0) { 1614 /* zero-sized images are legal, and always fit! */ 1615 return GL_TRUE; 1616 } 1617 1618 if (pipe->screen->can_create_resource) { 1619 /* Ask the gallium driver if the texture is too large */ 1620 struct gl_texture_object *texObj = 1621 _mesa_get_current_tex_object(ctx, target); 1622 struct pipe_resource pt; 1623 1624 /* Setup the pipe_resource object 1625 */ 1626 memset(&pt, 0, sizeof(pt)); 1627 1628 pt.target = gl_target_to_pipe(target); 1629 pt.format = st_mesa_format_to_pipe_format(format); 1630 1631 st_gl_texture_dims_to_pipe_dims(target, 1632 width, height, depth, 1633 &pt.width0, &pt.height0, 1634 &pt.depth0, &pt.array_size); 1635 1636 if (level == 0 && (texObj->Sampler.MinFilter == GL_LINEAR || 1637 texObj->Sampler.MinFilter == GL_NEAREST)) { 1638 /* assume just one mipmap level */ 1639 pt.last_level = 0; 1640 } 1641 else { 1642 /* assume a full set of mipmaps */ 1643 pt.last_level = _mesa_logbase2(MAX3(width, height, depth)); 1644 } 1645 1646 return pipe->screen->can_create_resource(pipe->screen, &pt); 1647 } 1648 else { 1649 /* Use core Mesa fallback */ 1650 return _mesa_test_proxy_teximage(ctx, target, level, format, 1651 width, height, depth, border); 1652 } 1653} 1654 1655 1656void 1657st_init_texture_functions(struct dd_function_table *functions) 1658{ 1659 functions->ChooseTextureFormat = st_ChooseTextureFormat; 1660 functions->QuerySamplesForFormat = st_QuerySamplesForFormat; 1661 functions->TexImage = st_TexImage; 1662 functions->TexSubImage = _mesa_store_texsubimage; 1663 functions->CompressedTexSubImage = _mesa_store_compressed_texsubimage; 1664 functions->CopyTexSubImage = st_CopyTexSubImage; 1665 functions->GenerateMipmap = st_generate_mipmap; 1666 1667 functions->GetTexImage = st_GetTexImage; 1668 1669 /* compressed texture functions */ 1670 functions->CompressedTexImage = st_CompressedTexImage; 1671 functions->GetCompressedTexImage = _mesa_get_compressed_teximage; 1672 1673 functions->NewTextureObject = st_NewTextureObject; 1674 functions->NewTextureImage = st_NewTextureImage; 1675 functions->DeleteTextureImage = st_DeleteTextureImage; 1676 functions->DeleteTexture = st_DeleteTextureObject; 1677 functions->AllocTextureImageBuffer = st_AllocTextureImageBuffer; 1678 functions->FreeTextureImageBuffer = st_FreeTextureImageBuffer; 1679 functions->MapTextureImage = st_MapTextureImage; 1680 functions->UnmapTextureImage = st_UnmapTextureImage; 1681 1682 /* XXX Temporary until we can query pipe's texture sizes */ 1683 functions->TestProxyTexImage = st_TestProxyTexImage; 1684 1685 functions->AllocTextureStorage = st_AllocTextureStorage; 1686} 1687