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