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