st_cb_texture.c revision f0cc59d68a9f5231e8e2111393a1834858820735
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/bufferobj.h" 29#include "main/enums.h" 30#include "main/fbobject.h" 31#include "main/formats.h" 32#include "main/image.h" 33#include "main/imports.h" 34#include "main/macros.h" 35#include "main/mipmap.h" 36#include "main/pack.h" 37#include "main/pbo.h" 38#include "main/pixeltransfer.h" 39#include "main/texcompress.h" 40#include "main/texgetimage.h" 41#include "main/teximage.h" 42#include "main/texobj.h" 43#include "main/texstore.h" 44 45#include "state_tracker/st_debug.h" 46#include "state_tracker/st_context.h" 47#include "state_tracker/st_cb_fbo.h" 48#include "state_tracker/st_cb_flush.h" 49#include "state_tracker/st_cb_texture.h" 50#include "state_tracker/st_cb_bufferobjects.h" 51#include "state_tracker/st_format.h" 52#include "state_tracker/st_texture.h" 53#include "state_tracker/st_gen_mipmap.h" 54#include "state_tracker/st_atom.h" 55 56#include "pipe/p_context.h" 57#include "pipe/p_defines.h" 58#include "util/u_inlines.h" 59#include "pipe/p_shader_tokens.h" 60#include "util/u_tile.h" 61#include "util/u_format.h" 62#include "util/u_surface.h" 63#include "util/u_sampler.h" 64#include "util/u_math.h" 65#include "util/u_box.h" 66 67#define DBG if (0) printf 68 69 70enum pipe_texture_target 71gl_target_to_pipe(GLenum target) 72{ 73 switch (target) { 74 case GL_TEXTURE_1D: 75 case GL_PROXY_TEXTURE_1D: 76 return PIPE_TEXTURE_1D; 77 case GL_TEXTURE_2D: 78 case GL_PROXY_TEXTURE_2D: 79 case GL_TEXTURE_EXTERNAL_OES: 80 case GL_TEXTURE_2D_MULTISAMPLE: 81 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 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 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 104 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 105 return PIPE_TEXTURE_2D_ARRAY; 106 case GL_TEXTURE_BUFFER: 107 return PIPE_BUFFER; 108 case GL_TEXTURE_CUBE_MAP_ARRAY: 109 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 110 return PIPE_TEXTURE_CUBE_ARRAY; 111 default: 112 assert(0); 113 return 0; 114 } 115} 116 117 118/** called via ctx->Driver.NewTextureImage() */ 119static struct gl_texture_image * 120st_NewTextureImage(struct gl_context * ctx) 121{ 122 DBG("%s\n", __FUNCTION__); 123 (void) ctx; 124 return (struct gl_texture_image *) ST_CALLOC_STRUCT(st_texture_image); 125} 126 127 128/** called via ctx->Driver.DeleteTextureImage() */ 129static void 130st_DeleteTextureImage(struct gl_context * ctx, struct gl_texture_image *img) 131{ 132 /* nothing special (yet) for st_texture_image */ 133 _mesa_delete_texture_image(ctx, img); 134} 135 136 137/** called via ctx->Driver.NewTextureObject() */ 138static struct gl_texture_object * 139st_NewTextureObject(struct gl_context * ctx, GLuint name, GLenum target) 140{ 141 struct st_texture_object *obj = ST_CALLOC_STRUCT(st_texture_object); 142 143 DBG("%s\n", __FUNCTION__); 144 _mesa_initialize_texture_object(ctx, &obj->base, name, target); 145 146 return &obj->base; 147} 148 149/** called via ctx->Driver.DeleteTextureObject() */ 150static void 151st_DeleteTextureObject(struct gl_context *ctx, 152 struct gl_texture_object *texObj) 153{ 154 struct st_context *st = st_context(ctx); 155 struct st_texture_object *stObj = st_texture_object(texObj); 156 if (stObj->pt) 157 pipe_resource_reference(&stObj->pt, NULL); 158 if (stObj->sampler_view) { 159 pipe_sampler_view_release(st->pipe, &stObj->sampler_view); 160 } 161 _mesa_delete_texture_object(ctx, texObj); 162} 163 164 165/** called via ctx->Driver.FreeTextureImageBuffer() */ 166static void 167st_FreeTextureImageBuffer(struct gl_context *ctx, 168 struct gl_texture_image *texImage) 169{ 170 struct st_texture_image *stImage = st_texture_image(texImage); 171 172 DBG("%s\n", __FUNCTION__); 173 174 if (stImage->pt) { 175 pipe_resource_reference(&stImage->pt, NULL); 176 } 177 178 _mesa_align_free(stImage->TexData); 179 stImage->TexData = NULL; 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, 0, 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, 0, 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 */ 546unsigned 547st_get_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_TexSubImage(struct gl_context *ctx, GLuint dims, 590 struct gl_texture_image *texImage, 591 GLint xoffset, GLint yoffset, GLint zoffset, 592 GLint width, GLint height, GLint depth, 593 GLenum format, GLenum type, const void *pixels, 594 const struct gl_pixelstore_attrib *unpack) 595{ 596 struct st_context *st = st_context(ctx); 597 struct st_texture_image *stImage = st_texture_image(texImage); 598 struct st_texture_object *stObj = st_texture_object(texImage->TexObject); 599 struct pipe_context *pipe = st->pipe; 600 struct pipe_screen *screen = pipe->screen; 601 struct pipe_resource *dst = stImage->pt; 602 struct pipe_resource *src = NULL; 603 struct pipe_resource src_templ; 604 struct pipe_transfer *transfer; 605 struct pipe_blit_info blit; 606 enum pipe_format src_format, dst_format; 607 gl_format mesa_src_format; 608 GLenum gl_target = texImage->TexObject->Target; 609 unsigned bind; 610 GLubyte *map; 611 612 if (!st->prefer_blit_based_texture_transfer) { 613 goto fallback; 614 } 615 616 if (!dst) { 617 goto fallback; 618 } 619 620 /* XXX Fallback for depth-stencil formats due to an incomplete stencil 621 * blit implementation in some drivers. */ 622 if (format == GL_DEPTH_STENCIL) { 623 goto fallback; 624 } 625 626 /* If the base internal format and the texture format don't match, 627 * we can't use blit-based TexSubImage. */ 628 if (texImage->_BaseFormat != 629 _mesa_get_format_base_format(texImage->TexFormat)) { 630 goto fallback; 631 } 632 633 /* See if the texture format already matches the format and type, 634 * in which case the memcpy-based fast path will likely be used and 635 * we don't have to blit. */ 636 if (_mesa_format_matches_format_and_type(texImage->TexFormat, format, 637 type, unpack->SwapBytes)) { 638 goto fallback; 639 } 640 641 if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL) 642 bind = PIPE_BIND_DEPTH_STENCIL; 643 else 644 bind = PIPE_BIND_RENDER_TARGET; 645 646 /* See if the destination format is supported. 647 * For luminance and intensity, only the red channel is stored there. */ 648 dst_format = util_format_linear(dst->format); 649 dst_format = util_format_luminance_to_red(dst_format); 650 dst_format = util_format_intensity_to_red(dst_format); 651 652 if (!dst_format || 653 !screen->is_format_supported(screen, dst_format, dst->target, 654 dst->nr_samples, bind)) { 655 goto fallback; 656 } 657 658 /* Choose the source format. */ 659 src_format = st_choose_matching_format(screen, PIPE_BIND_SAMPLER_VIEW, 660 format, type, unpack->SwapBytes); 661 if (!src_format) { 662 goto fallback; 663 } 664 665 mesa_src_format = st_pipe_format_to_mesa_format(src_format); 666 667 /* There is no reason to do this if we cannot use memcpy for the temporary 668 * source texture at least. This also takes transfer ops into account, 669 * etc. */ 670 if (!_mesa_texstore_can_use_memcpy(ctx, 671 _mesa_get_format_base_format(mesa_src_format), 672 mesa_src_format, format, type, unpack)) { 673 goto fallback; 674 } 675 676 /* TexSubImage only sets a single cubemap face. */ 677 if (gl_target == GL_TEXTURE_CUBE_MAP) { 678 gl_target = GL_TEXTURE_2D; 679 } 680 681 /* Initialize the source texture description. */ 682 memset(&src_templ, 0, sizeof(src_templ)); 683 src_templ.target = gl_target_to_pipe(gl_target); 684 src_templ.format = src_format; 685 src_templ.bind = PIPE_BIND_SAMPLER_VIEW; 686 src_templ.usage = PIPE_USAGE_STAGING; 687 688 st_gl_texture_dims_to_pipe_dims(gl_target, width, height, depth, 689 &src_templ.width0, &src_templ.height0, 690 &src_templ.depth0, &src_templ.array_size); 691 692 /* Check for NPOT texture support. */ 693 if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES) && 694 (!util_is_power_of_two(src_templ.width0) || 695 !util_is_power_of_two(src_templ.height0) || 696 !util_is_power_of_two(src_templ.depth0))) { 697 goto fallback; 698 } 699 700 /* Create the source texture. */ 701 src = screen->resource_create(screen, &src_templ); 702 if (!src) { 703 goto fallback; 704 } 705 706 /* Map source pixels. */ 707 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, 708 format, type, pixels, unpack, 709 "glTexSubImage"); 710 if (!pixels) { 711 /* This is a GL error. */ 712 pipe_resource_reference(&src, NULL); 713 return; 714 } 715 716 /* From now on, we need the gallium representation of dimensions. */ 717 if (gl_target == GL_TEXTURE_1D_ARRAY) { 718 depth = height; 719 height = 1; 720 } 721 722 map = pipe_transfer_map_3d(pipe, src, 0, PIPE_TRANSFER_WRITE, 0, 0, 0, 723 width, height, depth, &transfer); 724 if (!map) { 725 _mesa_unmap_teximage_pbo(ctx, unpack); 726 pipe_resource_reference(&src, NULL); 727 goto fallback; 728 } 729 730 /* Upload pixels (just memcpy). */ 731 { 732 const uint bytesPerRow = width * util_format_get_blocksize(src_format); 733 GLuint row, slice; 734 735 for (slice = 0; slice < (unsigned) depth; slice++) { 736 if (gl_target == GL_TEXTURE_1D_ARRAY) { 737 /* 1D array textures. 738 * We need to convert gallium coords to GL coords. 739 */ 740 GLvoid *src = _mesa_image_address3d(unpack, pixels, 741 width, depth, format, 742 type, 0, slice, 0); 743 memcpy(map, src, bytesPerRow); 744 } 745 else { 746 ubyte *slice_map = map; 747 748 for (row = 0; row < (unsigned) height; row++) { 749 GLvoid *src = _mesa_image_address3d(unpack, pixels, 750 width, height, format, 751 type, slice, row, 0); 752 memcpy(slice_map, src, bytesPerRow); 753 slice_map += transfer->stride; 754 } 755 } 756 map += transfer->layer_stride; 757 } 758 } 759 760 pipe_transfer_unmap(pipe, transfer); 761 _mesa_unmap_teximage_pbo(ctx, unpack); 762 763 /* Blit. */ 764 blit.src.resource = src; 765 blit.src.level = 0; 766 blit.src.format = src_format; 767 blit.dst.resource = dst; 768 blit.dst.level = stObj->pt != stImage->pt ? 0 : texImage->Level; 769 blit.dst.format = dst_format; 770 blit.src.box.x = blit.src.box.y = blit.src.box.z = 0; 771 blit.dst.box.x = xoffset; 772 blit.dst.box.y = yoffset; 773 blit.dst.box.z = zoffset + texImage->Face; 774 blit.src.box.width = blit.dst.box.width = width; 775 blit.src.box.height = blit.dst.box.height = height; 776 blit.src.box.depth = blit.dst.box.depth = depth; 777 blit.mask = st_get_blit_mask(format, texImage->_BaseFormat); 778 blit.filter = PIPE_TEX_FILTER_NEAREST; 779 blit.scissor_enable = FALSE; 780 781 st->pipe->blit(st->pipe, &blit); 782 783 pipe_resource_reference(&src, NULL); 784 return; 785 786fallback: 787 _mesa_store_texsubimage(ctx, dims, texImage, xoffset, yoffset, zoffset, 788 width, height, depth, format, type, pixels, 789 unpack); 790} 791 792static void 793st_TexImage(struct gl_context * ctx, GLuint dims, 794 struct gl_texture_image *texImage, 795 GLenum format, GLenum type, const void *pixels, 796 const struct gl_pixelstore_attrib *unpack) 797{ 798 assert(dims == 1 || dims == 2 || dims == 3); 799 800 prep_teximage(ctx, texImage, format, type); 801 802 if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0) 803 return; 804 805 /* allocate storage for texture data */ 806 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) { 807 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims); 808 return; 809 } 810 811 st_TexSubImage(ctx, dims, texImage, 0, 0, 0, 812 texImage->Width, texImage->Height, texImage->Depth, 813 format, type, pixels, unpack); 814} 815 816 817static void 818st_CompressedTexImage(struct gl_context *ctx, GLuint dims, 819 struct gl_texture_image *texImage, 820 GLsizei imageSize, const GLvoid *data) 821{ 822 prep_teximage(ctx, texImage, GL_NONE, GL_NONE); 823 _mesa_store_compressed_teximage(ctx, dims, texImage, imageSize, data); 824} 825 826 827 828 829/** 830 * Called via ctx->Driver.GetTexImage() 831 * 832 * This uses a blit to copy the texture to a texture format which matches 833 * the format and type combo and then a fast read-back is done using memcpy. 834 * We can do arbitrary X/Y/Z/W/0/1 swizzling here as long as there is 835 * a format which matches the swizzling. 836 * 837 * If such a format isn't available, it falls back to _mesa_get_teximage. 838 * 839 * NOTE: Drivers usually do a blit to convert between tiled and linear 840 * texture layouts during texture uploads/downloads, so the blit 841 * we do here should be free in such cases. 842 */ 843static void 844st_GetTexImage(struct gl_context * ctx, 845 GLenum format, GLenum type, GLvoid * pixels, 846 struct gl_texture_image *texImage) 847{ 848 struct st_context *st = st_context(ctx); 849 struct pipe_context *pipe = st->pipe; 850 struct pipe_screen *screen = pipe->screen; 851 GLuint width = texImage->Width; 852 GLuint height = texImage->Height; 853 GLuint depth = texImage->Depth; 854 struct st_texture_image *stImage = st_texture_image(texImage); 855 struct pipe_resource *src = st_texture_object(texImage->TexObject)->pt; 856 struct pipe_resource *dst = NULL; 857 struct pipe_resource dst_templ; 858 enum pipe_format dst_format, src_format; 859 gl_format mesa_format; 860 GLenum gl_target = texImage->TexObject->Target; 861 enum pipe_texture_target pipe_target; 862 struct pipe_blit_info blit; 863 unsigned bind = PIPE_BIND_TRANSFER_READ; 864 struct pipe_transfer *tex_xfer; 865 ubyte *map = NULL; 866 boolean done = FALSE; 867 868 if (!st->prefer_blit_based_texture_transfer) { 869 goto fallback; 870 } 871 872 if (!stImage->pt || !src) { 873 goto fallback; 874 } 875 876 /* XXX Fallback to _mesa_get_teximage for depth-stencil formats 877 * due to an incomplete stencil blit implementation in some drivers. */ 878 if (format == GL_DEPTH_STENCIL) { 879 goto fallback; 880 } 881 882 /* If the base internal format and the texture format don't match, we have 883 * to fall back to _mesa_get_teximage. */ 884 if (texImage->_BaseFormat != 885 _mesa_get_format_base_format(texImage->TexFormat)) { 886 goto fallback; 887 } 888 889 /* See if the texture format already matches the format and type, 890 * in which case the memcpy-based fast path will be used. */ 891 if (_mesa_format_matches_format_and_type(texImage->TexFormat, format, 892 type, ctx->Pack.SwapBytes)) { 893 goto fallback; 894 } 895 896 /* Convert the source format to what is expected by GetTexImage 897 * and see if it's supported. 898 * 899 * This only applies to glGetTexImage: 900 * - Luminance must be returned as (L,0,0,1). 901 * - Luminance alpha must be returned as (L,0,0,A). 902 * - Intensity must be returned as (I,0,0,1) 903 */ 904 src_format = util_format_linear(src->format); 905 src_format = util_format_luminance_to_red(src_format); 906 src_format = util_format_intensity_to_red(src_format); 907 908 if (!src_format || 909 !screen->is_format_supported(screen, src_format, src->target, 910 src->nr_samples, 911 PIPE_BIND_SAMPLER_VIEW)) { 912 goto fallback; 913 } 914 915 if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL) 916 bind |= PIPE_BIND_DEPTH_STENCIL; 917 else 918 bind |= PIPE_BIND_RENDER_TARGET; 919 920 /* GetTexImage only returns a single face for cubemaps. */ 921 if (gl_target == GL_TEXTURE_CUBE_MAP) { 922 gl_target = GL_TEXTURE_2D; 923 } 924 pipe_target = gl_target_to_pipe(gl_target); 925 926 /* Choose the destination format by finding the best match 927 * for the format+type combo. */ 928 dst_format = st_choose_matching_format(screen, bind, format, type, 929 ctx->Pack.SwapBytes); 930 931 if (dst_format == PIPE_FORMAT_NONE) { 932 GLenum dst_glformat; 933 934 /* Fall back to _mesa_get_teximage except for compressed formats, 935 * where decompression with a blit is always preferred. */ 936 if (!util_format_is_compressed(src->format)) { 937 goto fallback; 938 } 939 940 /* Set the appropriate format for the decompressed texture. 941 * Luminance and sRGB formats shouldn't appear here.*/ 942 switch (src_format) { 943 case PIPE_FORMAT_DXT1_RGB: 944 case PIPE_FORMAT_DXT1_RGBA: 945 case PIPE_FORMAT_DXT3_RGBA: 946 case PIPE_FORMAT_DXT5_RGBA: 947 case PIPE_FORMAT_RGTC1_UNORM: 948 case PIPE_FORMAT_RGTC2_UNORM: 949 case PIPE_FORMAT_ETC1_RGB8: 950 dst_glformat = GL_RGBA8; 951 break; 952 case PIPE_FORMAT_RGTC1_SNORM: 953 case PIPE_FORMAT_RGTC2_SNORM: 954 if (!ctx->Extensions.EXT_texture_snorm) 955 goto fallback; 956 dst_glformat = GL_RGBA8_SNORM; 957 break; 958 /* TODO: for BPTC_*FLOAT, set RGBA32F and check for ARB_texture_float */ 959 default: 960 assert(0); 961 goto fallback; 962 } 963 964 dst_format = st_choose_format(st, dst_glformat, format, type, 965 pipe_target, 0, bind, FALSE); 966 967 if (dst_format == PIPE_FORMAT_NONE) { 968 /* unable to get an rgba format!?! */ 969 goto fallback; 970 } 971 } 972 973 /* create the destination texture */ 974 memset(&dst_templ, 0, sizeof(dst_templ)); 975 dst_templ.target = pipe_target; 976 dst_templ.format = dst_format; 977 dst_templ.bind = bind; 978 dst_templ.usage = PIPE_USAGE_STAGING; 979 980 st_gl_texture_dims_to_pipe_dims(gl_target, width, height, depth, 981 &dst_templ.width0, &dst_templ.height0, 982 &dst_templ.depth0, &dst_templ.array_size); 983 984 dst = screen->resource_create(screen, &dst_templ); 985 if (!dst) { 986 goto fallback; 987 } 988 989 /* From now on, we need the gallium representation of dimensions. */ 990 if (gl_target == GL_TEXTURE_1D_ARRAY) { 991 depth = height; 992 height = 1; 993 } 994 995 blit.src.resource = src; 996 blit.src.level = texImage->Level; 997 blit.src.format = src_format; 998 blit.dst.resource = dst; 999 blit.dst.level = 0; 1000 blit.dst.format = dst->format; 1001 blit.src.box.x = blit.dst.box.x = 0; 1002 blit.src.box.y = blit.dst.box.y = 0; 1003 blit.src.box.z = texImage->Face; 1004 blit.dst.box.z = 0; 1005 blit.src.box.width = blit.dst.box.width = width; 1006 blit.src.box.height = blit.dst.box.height = height; 1007 blit.src.box.depth = blit.dst.box.depth = depth; 1008 blit.mask = st_get_blit_mask(texImage->_BaseFormat, format); 1009 blit.filter = PIPE_TEX_FILTER_NEAREST; 1010 blit.scissor_enable = FALSE; 1011 1012 /* blit/render/decompress */ 1013 st->pipe->blit(st->pipe, &blit); 1014 1015 pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels); 1016 1017 map = pipe_transfer_map_3d(pipe, dst, 0, PIPE_TRANSFER_READ, 1018 0, 0, 0, width, height, depth, &tex_xfer); 1019 if (!map) { 1020 goto end; 1021 } 1022 1023 mesa_format = st_pipe_format_to_mesa_format(dst_format); 1024 1025 /* copy/pack data into user buffer */ 1026 if (_mesa_format_matches_format_and_type(mesa_format, format, type, 1027 ctx->Pack.SwapBytes)) { 1028 /* memcpy */ 1029 const uint bytesPerRow = width * util_format_get_blocksize(dst_format); 1030 GLuint row, slice; 1031 1032 for (slice = 0; slice < depth; slice++) { 1033 if (gl_target == GL_TEXTURE_1D_ARRAY) { 1034 /* 1D array textures. 1035 * We need to convert gallium coords to GL coords. 1036 */ 1037 GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels, 1038 width, depth, format, 1039 type, 0, slice, 0); 1040 memcpy(dest, map, bytesPerRow); 1041 } 1042 else { 1043 ubyte *slice_map = map; 1044 1045 for (row = 0; row < height; row++) { 1046 GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels, 1047 width, height, format, 1048 type, slice, row, 0); 1049 memcpy(dest, slice_map, bytesPerRow); 1050 slice_map += tex_xfer->stride; 1051 } 1052 } 1053 map += tex_xfer->layer_stride; 1054 } 1055 } 1056 else { 1057 /* format translation via floats */ 1058 GLuint row, slice; 1059 GLfloat *rgba; 1060 1061 assert(util_format_is_compressed(src->format)); 1062 1063 rgba = malloc(width * 4 * sizeof(GLfloat)); 1064 if (!rgba) { 1065 goto end; 1066 } 1067 1068 if (ST_DEBUG & DEBUG_FALLBACK) 1069 debug_printf("%s: fallback format translation\n", __FUNCTION__); 1070 1071 for (slice = 0; slice < depth; slice++) { 1072 if (gl_target == GL_TEXTURE_1D_ARRAY) { 1073 /* 1D array textures. 1074 * We need to convert gallium coords to GL coords. 1075 */ 1076 GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels, 1077 width, depth, format, 1078 type, 0, slice, 0); 1079 1080 /* get float[4] rgba row from surface */ 1081 pipe_get_tile_rgba_format(tex_xfer, map, 0, 0, width, 1, 1082 dst_format, rgba); 1083 1084 _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, 1085 type, dest, &ctx->Pack, 0); 1086 } 1087 else { 1088 for (row = 0; row < height; row++) { 1089 GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels, 1090 width, height, format, 1091 type, slice, row, 0); 1092 1093 /* get float[4] rgba row from surface */ 1094 pipe_get_tile_rgba_format(tex_xfer, map, 0, row, width, 1, 1095 dst_format, rgba); 1096 1097 _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format, 1098 type, dest, &ctx->Pack, 0); 1099 } 1100 } 1101 map += tex_xfer->layer_stride; 1102 } 1103 1104 free(rgba); 1105 } 1106 done = TRUE; 1107 1108end: 1109 if (map) 1110 pipe_transfer_unmap(pipe, tex_xfer); 1111 1112 _mesa_unmap_pbo_dest(ctx, &ctx->Pack); 1113 pipe_resource_reference(&dst, NULL); 1114 1115fallback: 1116 if (!done) { 1117 _mesa_get_teximage(ctx, format, type, pixels, texImage); 1118 } 1119} 1120 1121 1122/** 1123 * Do a CopyTexSubImage operation using a read transfer from the source, 1124 * a write transfer to the destination and get_tile()/put_tile() to access 1125 * the pixels/texels. 1126 * 1127 * Note: srcY=0=TOP of renderbuffer 1128 */ 1129static void 1130fallback_copy_texsubimage(struct gl_context *ctx, 1131 struct st_renderbuffer *strb, 1132 struct st_texture_image *stImage, 1133 GLenum baseFormat, 1134 GLint destX, GLint destY, GLint slice, 1135 GLint srcX, GLint srcY, 1136 GLsizei width, GLsizei height) 1137{ 1138 struct st_context *st = st_context(ctx); 1139 struct pipe_context *pipe = st->pipe; 1140 struct pipe_transfer *src_trans; 1141 GLubyte *texDest; 1142 enum pipe_transfer_usage transfer_usage; 1143 void *map; 1144 unsigned dst_width = width; 1145 unsigned dst_height = height; 1146 unsigned dst_depth = 1; 1147 1148 if (ST_DEBUG & DEBUG_FALLBACK) 1149 debug_printf("%s: fallback processing\n", __FUNCTION__); 1150 1151 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 1152 srcY = strb->Base.Height - srcY - height; 1153 } 1154 1155 map = pipe_transfer_map(pipe, 1156 strb->texture, 1157 strb->surface->u.tex.level, 1158 strb->surface->u.tex.first_layer, 1159 PIPE_TRANSFER_READ, 1160 srcX, srcY, 1161 width, height, &src_trans); 1162 1163 if ((baseFormat == GL_DEPTH_COMPONENT || 1164 baseFormat == GL_DEPTH_STENCIL) && 1165 util_format_is_depth_and_stencil(stImage->pt->format)) 1166 transfer_usage = PIPE_TRANSFER_READ_WRITE; 1167 else 1168 transfer_usage = PIPE_TRANSFER_WRITE; 1169 1170 texDest = st_texture_image_map(st, stImage, transfer_usage, 1171 destX, destY, slice, 1172 dst_width, dst_height, dst_depth); 1173 1174 if (baseFormat == GL_DEPTH_COMPONENT || 1175 baseFormat == GL_DEPTH_STENCIL) { 1176 const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F || 1177 ctx->Pixel.DepthBias != 0.0F); 1178 GLint row, yStep; 1179 uint *data; 1180 1181 /* determine bottom-to-top vs. top-to-bottom order for src buffer */ 1182 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 1183 srcY = height - 1; 1184 yStep = -1; 1185 } 1186 else { 1187 srcY = 0; 1188 yStep = 1; 1189 } 1190 1191 data = malloc(width * sizeof(uint)); 1192 1193 if (data) { 1194 /* To avoid a large temp memory allocation, do copy row by row */ 1195 for (row = 0; row < height; row++, srcY += yStep) { 1196 pipe_get_tile_z(src_trans, map, 0, srcY, width, 1, data); 1197 if (scaleOrBias) { 1198 _mesa_scale_and_bias_depth_uint(ctx, width, data); 1199 } 1200 1201 if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) { 1202 pipe_put_tile_z(stImage->transfer, 1203 texDest + row*stImage->transfer->layer_stride, 1204 0, 0, width, 1, data); 1205 } 1206 else { 1207 pipe_put_tile_z(stImage->transfer, texDest, 0, row, width, 1, 1208 data); 1209 } 1210 } 1211 } 1212 else { 1213 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage()"); 1214 } 1215 1216 free(data); 1217 } 1218 else { 1219 /* RGBA format */ 1220 GLfloat *tempSrc = 1221 malloc(width * height * 4 * sizeof(GLfloat)); 1222 1223 if (tempSrc && texDest) { 1224 const GLint dims = 2; 1225 GLint dstRowStride; 1226 struct gl_texture_image *texImage = &stImage->base; 1227 struct gl_pixelstore_attrib unpack = ctx->DefaultPacking; 1228 1229 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 1230 unpack.Invert = GL_TRUE; 1231 } 1232 1233 if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) { 1234 dstRowStride = stImage->transfer->layer_stride; 1235 } 1236 else { 1237 dstRowStride = stImage->transfer->stride; 1238 } 1239 1240 /* get float/RGBA image from framebuffer */ 1241 /* XXX this usually involves a lot of int/float conversion. 1242 * try to avoid that someday. 1243 */ 1244 pipe_get_tile_rgba_format(src_trans, map, 0, 0, width, height, 1245 util_format_linear(strb->texture->format), 1246 tempSrc); 1247 1248 /* Store into texture memory. 1249 * Note that this does some special things such as pixel transfer 1250 * ops and format conversion. In particular, if the dest tex format 1251 * is actually RGBA but the user created the texture as GL_RGB we 1252 * need to fill-in/override the alpha channel with 1.0. 1253 */ 1254 _mesa_texstore(ctx, dims, 1255 texImage->_BaseFormat, 1256 texImage->TexFormat, 1257 dstRowStride, 1258 &texDest, 1259 width, height, 1, 1260 GL_RGBA, GL_FLOAT, tempSrc, /* src */ 1261 &unpack); 1262 } 1263 else { 1264 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); 1265 } 1266 1267 free(tempSrc); 1268 } 1269 1270 st_texture_image_unmap(st, stImage); 1271 pipe->transfer_unmap(pipe, src_trans); 1272} 1273 1274 1275/** 1276 * Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible. 1277 * Note that the region to copy has already been clipped so we know we 1278 * won't read from outside the source renderbuffer's bounds. 1279 * 1280 * Note: srcY=0=Bottom of renderbuffer (GL convention) 1281 */ 1282static void 1283st_CopyTexSubImage(struct gl_context *ctx, GLuint dims, 1284 struct gl_texture_image *texImage, 1285 GLint destX, GLint destY, GLint slice, 1286 struct gl_renderbuffer *rb, 1287 GLint srcX, GLint srcY, GLsizei width, GLsizei height) 1288{ 1289 struct st_texture_image *stImage = st_texture_image(texImage); 1290 struct st_texture_object *stObj = st_texture_object(texImage->TexObject); 1291 struct st_renderbuffer *strb = st_renderbuffer(rb); 1292 struct st_context *st = st_context(ctx); 1293 struct pipe_context *pipe = st->pipe; 1294 struct pipe_screen *screen = pipe->screen; 1295 struct pipe_blit_info blit; 1296 enum pipe_format dst_format; 1297 GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP); 1298 unsigned bind; 1299 GLint srcY0, srcY1; 1300 1301 if (!strb || !strb->surface || !stImage->pt) { 1302 debug_printf("%s: null strb or stImage\n", __FUNCTION__); 1303 return; 1304 } 1305 1306 if (_mesa_texstore_needs_transfer_ops(ctx, texImage->_BaseFormat, 1307 texImage->TexFormat)) { 1308 goto fallback; 1309 } 1310 1311 /* The base internal format must match the mesa format, so make sure 1312 * e.g. an RGB internal format is really allocated as RGB and not as RGBA. 1313 */ 1314 if (texImage->_BaseFormat != 1315 _mesa_get_format_base_format(texImage->TexFormat) || 1316 rb->_BaseFormat != _mesa_get_format_base_format(rb->Format)) { 1317 goto fallback; 1318 } 1319 1320 /* Choose the destination format to match the TexImage behavior. */ 1321 dst_format = util_format_linear(stImage->pt->format); 1322 dst_format = util_format_luminance_to_red(dst_format); 1323 dst_format = util_format_intensity_to_red(dst_format); 1324 1325 /* See if the destination format is supported. */ 1326 if (texImage->_BaseFormat == GL_DEPTH_STENCIL || 1327 texImage->_BaseFormat == GL_DEPTH_COMPONENT) { 1328 bind = PIPE_BIND_DEPTH_STENCIL; 1329 } 1330 else { 1331 bind = PIPE_BIND_RENDER_TARGET; 1332 } 1333 1334 if (!dst_format || 1335 !screen->is_format_supported(screen, dst_format, stImage->pt->target, 1336 stImage->pt->nr_samples, bind)) { 1337 goto fallback; 1338 } 1339 1340 /* Y flipping for the main framebuffer. */ 1341 if (do_flip) { 1342 srcY1 = strb->Base.Height - srcY - height; 1343 srcY0 = srcY1 + height; 1344 } 1345 else { 1346 srcY0 = srcY; 1347 srcY1 = srcY0 + height; 1348 } 1349 1350 /* Blit the texture. 1351 * This supports flipping, format conversions, and downsampling. 1352 */ 1353 memset(&blit, 0, sizeof(blit)); 1354 blit.src.resource = strb->texture; 1355 blit.src.format = util_format_linear(strb->surface->format); 1356 blit.src.level = strb->surface->u.tex.level; 1357 blit.src.box.x = srcX; 1358 blit.src.box.y = srcY0; 1359 blit.src.box.z = strb->surface->u.tex.first_layer; 1360 blit.src.box.width = width; 1361 blit.src.box.height = srcY1 - srcY0; 1362 blit.src.box.depth = 1; 1363 blit.dst.resource = stImage->pt; 1364 blit.dst.format = dst_format; 1365 blit.dst.level = stObj->pt != stImage->pt ? 0 : texImage->Level; 1366 blit.dst.box.x = destX; 1367 blit.dst.box.y = destY; 1368 blit.dst.box.z = stImage->base.Face + slice; 1369 blit.dst.box.width = width; 1370 blit.dst.box.height = height; 1371 blit.dst.box.depth = 1; 1372 blit.mask = st_get_blit_mask(rb->_BaseFormat, texImage->_BaseFormat); 1373 blit.filter = PIPE_TEX_FILTER_NEAREST; 1374 pipe->blit(pipe, &blit); 1375 return; 1376 1377fallback: 1378 /* software fallback */ 1379 fallback_copy_texsubimage(ctx, 1380 strb, stImage, texImage->_BaseFormat, 1381 destX, destY, slice, 1382 srcX, srcY, width, height); 1383} 1384 1385 1386/** 1387 * Copy image data from stImage into the texture object 'stObj' at level 1388 * 'dstLevel'. 1389 */ 1390static void 1391copy_image_data_to_texture(struct st_context *st, 1392 struct st_texture_object *stObj, 1393 GLuint dstLevel, 1394 struct st_texture_image *stImage) 1395{ 1396 /* debug checks */ 1397 { 1398 const struct gl_texture_image *dstImage = 1399 stObj->base.Image[stImage->base.Face][dstLevel]; 1400 assert(dstImage); 1401 assert(dstImage->Width == stImage->base.Width); 1402 assert(dstImage->Height == stImage->base.Height); 1403 assert(dstImage->Depth == stImage->base.Depth); 1404 } 1405 1406 if (stImage->pt) { 1407 /* Copy potentially with the blitter: 1408 */ 1409 GLuint src_level; 1410 if (stImage->pt->last_level == 0) 1411 src_level = 0; 1412 else 1413 src_level = stImage->base.Level; 1414 1415 assert(src_level <= stImage->pt->last_level); 1416 assert(u_minify(stImage->pt->width0, src_level) == stImage->base.Width); 1417 assert(stImage->pt->target == PIPE_TEXTURE_1D_ARRAY || 1418 u_minify(stImage->pt->height0, src_level) == stImage->base.Height); 1419 assert(stImage->pt->target == PIPE_TEXTURE_2D_ARRAY || 1420 stImage->pt->target == PIPE_TEXTURE_CUBE_ARRAY || 1421 u_minify(stImage->pt->depth0, src_level) == stImage->base.Depth); 1422 1423 st_texture_image_copy(st->pipe, 1424 stObj->pt, dstLevel, /* dest texture, level */ 1425 stImage->pt, src_level, /* src texture, level */ 1426 stImage->base.Face); 1427 1428 pipe_resource_reference(&stImage->pt, NULL); 1429 } 1430 else if (stImage->TexData) { 1431 /* Copy from malloc'd memory */ 1432 /* XXX this should be re-examined/tested with a compressed format */ 1433 GLuint blockSize = util_format_get_blocksize(stObj->pt->format); 1434 GLuint srcRowStride = stImage->base.Width * blockSize; 1435 GLuint srcSliceStride = stImage->base.Height * srcRowStride; 1436 st_texture_image_data(st, 1437 stObj->pt, 1438 stImage->base.Face, 1439 dstLevel, 1440 stImage->TexData, 1441 srcRowStride, 1442 srcSliceStride); 1443 _mesa_align_free(stImage->TexData); 1444 stImage->TexData = NULL; 1445 } 1446 1447 pipe_resource_reference(&stImage->pt, stObj->pt); 1448} 1449 1450 1451/** 1452 * Called during state validation. When this function is finished, 1453 * the texture object should be ready for rendering. 1454 * \return GL_TRUE for success, GL_FALSE for failure (out of mem) 1455 */ 1456GLboolean 1457st_finalize_texture(struct gl_context *ctx, 1458 struct pipe_context *pipe, 1459 struct gl_texture_object *tObj) 1460{ 1461 struct st_context *st = st_context(ctx); 1462 struct st_texture_object *stObj = st_texture_object(tObj); 1463 const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 1464 GLuint face; 1465 struct st_texture_image *firstImage; 1466 enum pipe_format firstImageFormat; 1467 GLuint ptWidth, ptHeight, ptDepth, ptLayers, ptNumSamples; 1468 1469 if (_mesa_is_texture_complete(tObj, &tObj->Sampler)) { 1470 /* The texture is complete and we know exactly how many mipmap levels 1471 * are present/needed. This is conditional because we may be called 1472 * from the st_generate_mipmap() function when the texture object is 1473 * incomplete. In that case, we'll have set stObj->lastLevel before 1474 * we get here. 1475 */ 1476 if (stObj->base.Sampler.MinFilter == GL_LINEAR || 1477 stObj->base.Sampler.MinFilter == GL_NEAREST) 1478 stObj->lastLevel = stObj->base.BaseLevel; 1479 else 1480 stObj->lastLevel = stObj->base._MaxLevel; 1481 } 1482 1483 if (tObj->Target == GL_TEXTURE_BUFFER) { 1484 struct st_buffer_object *st_obj = st_buffer_object(tObj->BufferObject); 1485 1486 if (st_obj->buffer != stObj->pt) { 1487 pipe_resource_reference(&stObj->pt, st_obj->buffer); 1488 pipe_sampler_view_release(st->pipe, &stObj->sampler_view); 1489 stObj->width0 = stObj->pt->width0 / _mesa_get_format_bytes(tObj->_BufferObjectFormat); 1490 stObj->height0 = 1; 1491 stObj->depth0 = 1; 1492 } 1493 return GL_TRUE; 1494 1495 } 1496 1497 firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]); 1498 assert(firstImage); 1499 1500 /* If both firstImage and stObj point to a texture which can contain 1501 * all active images, favour firstImage. Note that because of the 1502 * completeness requirement, we know that the image dimensions 1503 * will match. 1504 */ 1505 if (firstImage->pt && 1506 firstImage->pt != stObj->pt && 1507 (!stObj->pt || firstImage->pt->last_level >= stObj->pt->last_level)) { 1508 pipe_resource_reference(&stObj->pt, firstImage->pt); 1509 pipe_sampler_view_release(st->pipe, &stObj->sampler_view); 1510 } 1511 1512 /* If this texture comes from a window system, there is nothing else to do. */ 1513 if (stObj->surface_based) { 1514 return GL_TRUE; 1515 } 1516 1517 /* Find gallium format for the Mesa texture */ 1518 firstImageFormat = st_mesa_format_to_pipe_format(firstImage->base.TexFormat); 1519 1520 /* Find size of level=0 Gallium mipmap image, plus number of texture layers */ 1521 { 1522 GLuint width, height, depth; 1523 if (!guess_base_level_size(stObj->base.Target, 1524 firstImage->base.Width2, 1525 firstImage->base.Height2, 1526 firstImage->base.Depth2, 1527 firstImage->base.Level, 1528 &width, &height, &depth)) { 1529 width = stObj->width0; 1530 height = stObj->height0; 1531 depth = stObj->depth0; 1532 } 1533 /* convert GL dims to Gallium dims */ 1534 st_gl_texture_dims_to_pipe_dims(stObj->base.Target, width, height, depth, 1535 &ptWidth, &ptHeight, &ptDepth, &ptLayers); 1536 ptNumSamples = firstImage->base.NumSamples; 1537 } 1538 1539 /* If we already have a gallium texture, check that it matches the texture 1540 * object's format, target, size, num_levels, etc. 1541 */ 1542 if (stObj->pt) { 1543 if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) || 1544 stObj->pt->format != firstImageFormat || 1545 stObj->pt->last_level < stObj->lastLevel || 1546 stObj->pt->width0 != ptWidth || 1547 stObj->pt->height0 != ptHeight || 1548 stObj->pt->depth0 != ptDepth || 1549 stObj->pt->nr_samples != ptNumSamples || 1550 stObj->pt->array_size != ptLayers) 1551 { 1552 /* The gallium texture does not match the Mesa texture so delete the 1553 * gallium texture now. We'll make a new one below. 1554 */ 1555 pipe_resource_reference(&stObj->pt, NULL); 1556 pipe_sampler_view_release(st->pipe, &stObj->sampler_view); 1557 st->dirty.st |= ST_NEW_FRAMEBUFFER; 1558 } 1559 } 1560 1561 /* May need to create a new gallium texture: 1562 */ 1563 if (!stObj->pt) { 1564 GLuint bindings = default_bindings(st, firstImageFormat); 1565 1566 stObj->pt = st_texture_create(st, 1567 gl_target_to_pipe(stObj->base.Target), 1568 firstImageFormat, 1569 stObj->lastLevel, 1570 ptWidth, 1571 ptHeight, 1572 ptDepth, 1573 ptLayers, ptNumSamples, 1574 bindings); 1575 1576 if (!stObj->pt) { 1577 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 1578 return GL_FALSE; 1579 } 1580 } 1581 1582 /* Pull in any images not in the object's texture: 1583 */ 1584 for (face = 0; face < nr_faces; face++) { 1585 GLuint level; 1586 for (level = stObj->base.BaseLevel; level <= stObj->lastLevel; level++) { 1587 struct st_texture_image *stImage = 1588 st_texture_image(stObj->base.Image[face][level]); 1589 1590 /* Need to import images in main memory or held in other textures. 1591 */ 1592 if (stImage && stObj->pt != stImage->pt) { 1593 if (level == 0 || 1594 (stImage->base.Width == u_minify(stObj->width0, level) && 1595 stImage->base.Height == u_minify(stObj->height0, level) && 1596 stImage->base.Depth == u_minify(stObj->depth0, level))) { 1597 /* src image fits expected dest mipmap level size */ 1598 copy_image_data_to_texture(st, stObj, level, stImage); 1599 } 1600 } 1601 } 1602 } 1603 1604 return GL_TRUE; 1605} 1606 1607 1608/** 1609 * Called via ctx->Driver.AllocTextureStorage() to allocate texture memory 1610 * for a whole mipmap stack. 1611 */ 1612static GLboolean 1613st_AllocTextureStorage(struct gl_context *ctx, 1614 struct gl_texture_object *texObj, 1615 GLsizei levels, GLsizei width, 1616 GLsizei height, GLsizei depth) 1617{ 1618 const GLuint numFaces = _mesa_num_tex_faces(texObj->Target); 1619 struct gl_texture_image *texImage = texObj->Image[0][0]; 1620 struct st_context *st = st_context(ctx); 1621 struct st_texture_object *stObj = st_texture_object(texObj); 1622 struct pipe_screen *screen = st->pipe->screen; 1623 GLuint ptWidth, ptHeight, ptDepth, ptLayers, bindings; 1624 enum pipe_format fmt; 1625 GLint level; 1626 GLuint num_samples = texImage->NumSamples; 1627 1628 assert(levels > 0); 1629 1630 /* Save the level=0 dimensions */ 1631 stObj->width0 = width; 1632 stObj->height0 = height; 1633 stObj->depth0 = depth; 1634 stObj->lastLevel = levels - 1; 1635 1636 fmt = st_mesa_format_to_pipe_format(texImage->TexFormat); 1637 1638 bindings = default_bindings(st, fmt); 1639 1640 /* Raise the sample count if the requested one is unsupported. */ 1641 if (num_samples > 1) { 1642 boolean found = FALSE; 1643 1644 for (; num_samples <= ctx->Const.MaxSamples; num_samples++) { 1645 if (screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D, 1646 num_samples, 1647 PIPE_BIND_SAMPLER_VIEW)) { 1648 /* Update the sample count in gl_texture_image as well. */ 1649 texImage->NumSamples = num_samples; 1650 found = TRUE; 1651 break; 1652 } 1653 } 1654 1655 if (!found) { 1656 return GL_FALSE; 1657 } 1658 } 1659 1660 st_gl_texture_dims_to_pipe_dims(texObj->Target, 1661 width, height, depth, 1662 &ptWidth, &ptHeight, &ptDepth, &ptLayers); 1663 1664 stObj->pt = st_texture_create(st, 1665 gl_target_to_pipe(texObj->Target), 1666 fmt, 1667 levels - 1, 1668 ptWidth, 1669 ptHeight, 1670 ptDepth, 1671 ptLayers, num_samples, 1672 bindings); 1673 if (!stObj->pt) 1674 return GL_FALSE; 1675 1676 /* Set image resource pointers */ 1677 for (level = 0; level < levels; level++) { 1678 GLuint face; 1679 for (face = 0; face < numFaces; face++) { 1680 struct st_texture_image *stImage = 1681 st_texture_image(texObj->Image[face][level]); 1682 pipe_resource_reference(&stImage->pt, stObj->pt); 1683 } 1684 } 1685 1686 return GL_TRUE; 1687} 1688 1689 1690static GLboolean 1691st_TestProxyTexImage(struct gl_context *ctx, GLenum target, 1692 GLint level, gl_format format, 1693 GLint width, GLint height, 1694 GLint depth, GLint border) 1695{ 1696 struct st_context *st = st_context(ctx); 1697 struct pipe_context *pipe = st->pipe; 1698 1699 if (width == 0 || height == 0 || depth == 0) { 1700 /* zero-sized images are legal, and always fit! */ 1701 return GL_TRUE; 1702 } 1703 1704 if (pipe->screen->can_create_resource) { 1705 /* Ask the gallium driver if the texture is too large */ 1706 struct gl_texture_object *texObj = 1707 _mesa_get_current_tex_object(ctx, target); 1708 struct pipe_resource pt; 1709 1710 /* Setup the pipe_resource object 1711 */ 1712 memset(&pt, 0, sizeof(pt)); 1713 1714 pt.target = gl_target_to_pipe(target); 1715 pt.format = st_mesa_format_to_pipe_format(format); 1716 1717 st_gl_texture_dims_to_pipe_dims(target, 1718 width, height, depth, 1719 &pt.width0, &pt.height0, 1720 &pt.depth0, &pt.array_size); 1721 1722 if (level == 0 && (texObj->Sampler.MinFilter == GL_LINEAR || 1723 texObj->Sampler.MinFilter == GL_NEAREST)) { 1724 /* assume just one mipmap level */ 1725 pt.last_level = 0; 1726 } 1727 else { 1728 /* assume a full set of mipmaps */ 1729 pt.last_level = _mesa_logbase2(MAX3(width, height, depth)); 1730 } 1731 1732 return pipe->screen->can_create_resource(pipe->screen, &pt); 1733 } 1734 else { 1735 /* Use core Mesa fallback */ 1736 return _mesa_test_proxy_teximage(ctx, target, level, format, 1737 width, height, depth, border); 1738 } 1739} 1740 1741 1742void 1743st_init_texture_functions(struct dd_function_table *functions) 1744{ 1745 functions->ChooseTextureFormat = st_ChooseTextureFormat; 1746 functions->QuerySamplesForFormat = st_QuerySamplesForFormat; 1747 functions->TexImage = st_TexImage; 1748 functions->TexSubImage = st_TexSubImage; 1749 functions->CompressedTexSubImage = _mesa_store_compressed_texsubimage; 1750 functions->CopyTexSubImage = st_CopyTexSubImage; 1751 functions->GenerateMipmap = st_generate_mipmap; 1752 1753 functions->GetTexImage = st_GetTexImage; 1754 1755 /* compressed texture functions */ 1756 functions->CompressedTexImage = st_CompressedTexImage; 1757 functions->GetCompressedTexImage = _mesa_get_compressed_teximage; 1758 1759 functions->NewTextureObject = st_NewTextureObject; 1760 functions->NewTextureImage = st_NewTextureImage; 1761 functions->DeleteTextureImage = st_DeleteTextureImage; 1762 functions->DeleteTexture = st_DeleteTextureObject; 1763 functions->AllocTextureImageBuffer = st_AllocTextureImageBuffer; 1764 functions->FreeTextureImageBuffer = st_FreeTextureImageBuffer; 1765 functions->MapTextureImage = st_MapTextureImage; 1766 functions->UnmapTextureImage = st_UnmapTextureImage; 1767 1768 /* XXX Temporary until we can query pipe's texture sizes */ 1769 functions->TestProxyTexImage = st_TestProxyTexImage; 1770 1771 functions->AllocTextureStorage = st_AllocTextureStorage; 1772} 1773