intel_tex_image.c revision 1f196b786d6bd0c6a5dbdc638574ff716cc3d4de
1 2#include "main/glheader.h" 3#include "main/macros.h" 4#include "main/mtypes.h" 5#include "main/enums.h" 6#include "main/bufferobj.h" 7#include "main/convolve.h" 8#include "main/context.h" 9#include "main/texcompress.h" 10#include "main/texstore.h" 11#include "main/texgetimage.h" 12#include "main/texobj.h" 13#include "main/texstore.h" 14#include "main/teximage.h" 15 16#include "intel_context.h" 17#include "intel_mipmap_tree.h" 18#include "intel_buffer_objects.h" 19#include "intel_batchbuffer.h" 20#include "intel_tex.h" 21#include "intel_blit.h" 22#include "intel_fbo.h" 23 24#define FILE_DEBUG_FLAG DEBUG_TEXTURE 25 26/* Functions to store texture images. Where possible, mipmap_tree's 27 * will be created or further instantiated with image data, otherwise 28 * images will be stored in malloc'd memory. A validation step is 29 * required to pull those images into a mipmap tree, or otherwise 30 * decide a fallback is required. 31 */ 32 33 34static int 35logbase2(int n) 36{ 37 GLint i = 1; 38 GLint log2 = 0; 39 40 while (n > i) { 41 i *= 2; 42 log2++; 43 } 44 45 return log2; 46} 47 48 49/* Otherwise, store it in memory if (Border != 0) or (any dimension == 50 * 1). 51 * 52 * Otherwise, if max_level >= level >= min_level, create tree with 53 * space for textures from min_level down to max_level. 54 * 55 * Otherwise, create tree with space for textures from (level 56 * 0)..(1x1). Consider pruning this tree at a validation if the 57 * saving is worth it. 58 */ 59static void 60guess_and_alloc_mipmap_tree(struct intel_context *intel, 61 struct intel_texture_object *intelObj, 62 struct intel_texture_image *intelImage, 63 GLboolean expect_accelerated_upload) 64{ 65 GLuint firstLevel; 66 GLuint lastLevel; 67 GLuint width = intelImage->base.Width; 68 GLuint height = intelImage->base.Height; 69 GLuint depth = intelImage->base.Depth; 70 GLuint l2width, l2height, l2depth; 71 GLuint i, comp_byte = 0; 72 GLuint texelBytes; 73 74 DBG("%s\n", __FUNCTION__); 75 76 if (intelImage->base.Border || 77 ((intelImage->base._BaseFormat == GL_DEPTH_COMPONENT) && 78 ((intelObj->base.WrapS == GL_CLAMP_TO_BORDER) || 79 (intelObj->base.WrapT == GL_CLAMP_TO_BORDER)))) 80 return; 81 82 if (intelImage->level > intelObj->base.BaseLevel && 83 (intelImage->base.Width == 1 || 84 (intelObj->base.Target != GL_TEXTURE_1D && 85 intelImage->base.Height == 1) || 86 (intelObj->base.Target == GL_TEXTURE_3D && 87 intelImage->base.Depth == 1))) 88 return; 89 90 /* If this image disrespects BaseLevel, allocate from level zero. 91 * Usually BaseLevel == 0, so it's unlikely to happen. 92 */ 93 if (intelImage->level < intelObj->base.BaseLevel) 94 firstLevel = 0; 95 else 96 firstLevel = intelObj->base.BaseLevel; 97 98 99 /* Figure out image dimensions at start level. 100 */ 101 for (i = intelImage->level; i > firstLevel; i--) { 102 width <<= 1; 103 if (height != 1) 104 height <<= 1; 105 if (depth != 1) 106 depth <<= 1; 107 } 108 109 /* Guess a reasonable value for lastLevel. This is probably going 110 * to be wrong fairly often and might mean that we have to look at 111 * resizable buffers, or require that buffers implement lazy 112 * pagetable arrangements. 113 */ 114 if ((intelObj->base.MinFilter == GL_NEAREST || 115 intelObj->base.MinFilter == GL_LINEAR) && 116 intelImage->level == firstLevel) { 117 lastLevel = firstLevel; 118 } 119 else { 120 l2width = logbase2(width); 121 l2height = logbase2(height); 122 l2depth = logbase2(depth); 123 lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth); 124 } 125 126 assert(!intelObj->mt); 127 if (_mesa_is_format_compressed(intelImage->base.TexFormat)) 128 comp_byte = intel_compressed_num_bytes(intelImage->base.TexFormat); 129 130 texelBytes = _mesa_get_format_bytes(intelImage->base.TexFormat); 131 132 intelObj->mt = intel_miptree_create(intel, 133 intelObj->base.Target, 134 intelImage->base._BaseFormat, 135 intelImage->base.InternalFormat, 136 firstLevel, 137 lastLevel, 138 width, 139 height, 140 depth, 141 texelBytes, 142 comp_byte, 143 expect_accelerated_upload); 144 145 DBG("%s - success\n", __FUNCTION__); 146} 147 148 149 150 151static GLuint 152target_to_face(GLenum target) 153{ 154 switch (target) { 155 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 156 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 157 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 158 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 159 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 160 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 161 return ((GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X); 162 default: 163 return 0; 164 } 165} 166 167/* There are actually quite a few combinations this will work for, 168 * more than what I've listed here. 169 */ 170static GLboolean 171check_pbo_format(GLint internalFormat, 172 GLenum format, GLenum type, 173 gl_format mesa_format) 174{ 175 switch (internalFormat) { 176 case 4: 177 case GL_RGBA: 178 return (format == GL_BGRA && 179 (type == GL_UNSIGNED_BYTE || 180 type == GL_UNSIGNED_INT_8_8_8_8_REV) && 181 mesa_format == MESA_FORMAT_ARGB8888); 182 case 3: 183 case GL_RGB: 184 return (format == GL_RGB && 185 type == GL_UNSIGNED_SHORT_5_6_5 && 186 mesa_format == MESA_FORMAT_RGB565); 187 case GL_YCBCR_MESA: 188 return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE); 189 default: 190 return GL_FALSE; 191 } 192} 193 194 195/* XXX: Do this for TexSubImage also: 196 */ 197static GLboolean 198try_pbo_upload(struct intel_context *intel, 199 struct intel_texture_image *intelImage, 200 const struct gl_pixelstore_attrib *unpack, 201 GLint internalFormat, 202 GLint width, GLint height, 203 GLenum format, GLenum type, const void *pixels) 204{ 205 struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); 206 GLuint src_offset, src_stride; 207 GLuint dst_x, dst_y, dst_stride; 208 dri_bo *dst_buffer = intel_region_buffer(intel, 209 intelImage->mt->region, 210 INTEL_WRITE_FULL); 211 212 if (!_mesa_is_bufferobj(unpack->BufferObj) || 213 intel->ctx._ImageTransferState || 214 unpack->SkipPixels || unpack->SkipRows) { 215 DBG("%s: failure 1\n", __FUNCTION__); 216 return GL_FALSE; 217 } 218 219 /* note: potential 64-bit ptr to 32-bit int cast */ 220 src_offset = (GLuint) (unsigned long) pixels; 221 222 if (unpack->RowLength > 0) 223 src_stride = unpack->RowLength; 224 else 225 src_stride = width; 226 227 intel_miptree_get_image_offset(intelImage->mt, intelImage->level, 228 intelImage->face, 0, 229 &dst_x, &dst_y); 230 231 dst_stride = intelImage->mt->pitch; 232 233 if (drm_intel_bo_references(intel->batch->buf, dst_buffer)) 234 intelFlush(&intel->ctx); 235 LOCK_HARDWARE(intel); 236 { 237 dri_bo *src_buffer = intel_bufferobj_buffer(intel, pbo, INTEL_READ); 238 239 if (!intelEmitCopyBlit(intel, 240 intelImage->mt->cpp, 241 src_stride, src_buffer, src_offset, GL_FALSE, 242 dst_stride, dst_buffer, 0, GL_FALSE, 243 0, 0, dst_x, dst_y, width, height, 244 GL_COPY)) { 245 UNLOCK_HARDWARE(intel); 246 return GL_FALSE; 247 } 248 } 249 UNLOCK_HARDWARE(intel); 250 251 return GL_TRUE; 252} 253 254 255static GLboolean 256try_pbo_zcopy(struct intel_context *intel, 257 struct intel_texture_image *intelImage, 258 const struct gl_pixelstore_attrib *unpack, 259 GLint internalFormat, 260 GLint width, GLint height, 261 GLenum format, GLenum type, const void *pixels) 262{ 263 struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); 264 GLuint src_offset, src_stride; 265 GLuint dst_x, dst_y, dst_stride; 266 267 if (!_mesa_is_bufferobj(unpack->BufferObj) || 268 intel->ctx._ImageTransferState || 269 unpack->SkipPixels || unpack->SkipRows) { 270 DBG("%s: failure 1\n", __FUNCTION__); 271 return GL_FALSE; 272 } 273 274 /* note: potential 64-bit ptr to 32-bit int cast */ 275 src_offset = (GLuint) (unsigned long) pixels; 276 277 if (unpack->RowLength > 0) 278 src_stride = unpack->RowLength; 279 else 280 src_stride = width; 281 282 intel_miptree_get_image_offset(intelImage->mt, intelImage->level, 283 intelImage->face, 0, 284 &dst_x, &dst_y); 285 286 dst_stride = intelImage->mt->pitch; 287 288 if (src_stride != dst_stride || dst_x != 0 || dst_y != 0 || 289 src_offset != 0) { 290 DBG("%s: failure 2\n", __FUNCTION__); 291 return GL_FALSE; 292 } 293 294 intel_region_attach_pbo(intel, intelImage->mt->region, pbo); 295 296 return GL_TRUE; 297} 298 299 300static void 301intelTexImage(GLcontext * ctx, 302 GLint dims, 303 GLenum target, GLint level, 304 GLint internalFormat, 305 GLint width, GLint height, GLint depth, 306 GLint border, 307 GLenum format, GLenum type, const void *pixels, 308 const struct gl_pixelstore_attrib *unpack, 309 struct gl_texture_object *texObj, 310 struct gl_texture_image *texImage, GLsizei imageSize, 311 GLboolean compressed) 312{ 313 struct intel_context *intel = intel_context(ctx); 314 struct intel_texture_object *intelObj = intel_texture_object(texObj); 315 struct intel_texture_image *intelImage = intel_texture_image(texImage); 316 GLint postConvWidth = width; 317 GLint postConvHeight = height; 318 GLint texelBytes, sizeInBytes; 319 GLuint dstRowStride = 0, srcRowStride = texImage->RowStride; 320 321 DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, 322 _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); 323 324 intelImage->face = target_to_face(target); 325 intelImage->level = level; 326 327 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 328 _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth, 329 &postConvHeight); 330 } 331 332 if (_mesa_is_format_compressed(texImage->TexFormat)) { 333 texelBytes = 0; 334 } 335 else { 336 texelBytes = _mesa_get_format_bytes(texImage->TexFormat); 337 338 /* Minimum pitch of 32 bytes */ 339 if (postConvWidth * texelBytes < 32) { 340 postConvWidth = 32 / texelBytes; 341 texImage->RowStride = postConvWidth; 342 } 343 344 if (!intelImage->mt) { 345 assert(texImage->RowStride == postConvWidth); 346 } 347 } 348 349 /* Release the reference to a potentially orphaned buffer. 350 * Release any old malloced memory. 351 */ 352 if (intelImage->mt) { 353 intel_miptree_release(intel, &intelImage->mt); 354 assert(!texImage->Data); 355 } 356 else if (texImage->Data) { 357 _mesa_free_texmemory(texImage->Data); 358 texImage->Data = NULL; 359 } 360 361 /* If this is the only texture image in the tree, could call 362 * bmBufferData with NULL data to free the old block and avoid 363 * waiting on any outstanding fences. 364 */ 365 if (intelObj->mt && 366 intelObj->mt->first_level == level && 367 intelObj->mt->last_level == level && 368 intelObj->mt->target != GL_TEXTURE_CUBE_MAP_ARB && 369 !intel_miptree_match_image(intelObj->mt, &intelImage->base, 370 intelImage->face, intelImage->level)) { 371 372 DBG("release it\n"); 373 intel_miptree_release(intel, &intelObj->mt); 374 assert(!intelObj->mt); 375 } 376 377 if (!intelObj->mt) { 378 guess_and_alloc_mipmap_tree(intel, intelObj, intelImage, pixels == NULL); 379 if (!intelObj->mt) { 380 DBG("guess_and_alloc_mipmap_tree: failed\n"); 381 } 382 } 383 384 assert(!intelImage->mt); 385 386 if (intelObj->mt && 387 intel_miptree_match_image(intelObj->mt, &intelImage->base, 388 intelImage->face, intelImage->level)) { 389 390 intel_miptree_reference(&intelImage->mt, intelObj->mt); 391 assert(intelImage->mt); 392 } else if (intelImage->base.Border == 0) { 393 int comp_byte = 0; 394 GLuint texelBytes = _mesa_get_format_bytes(intelImage->base.TexFormat); 395 GLenum baseFormat = _mesa_get_format_base_format(intelImage->base.TexFormat); 396 if (_mesa_is_format_compressed(intelImage->base.TexFormat)) { 397 comp_byte = 398 intel_compressed_num_bytes(intelImage->base.TexFormat); 399 } 400 401 /* Didn't fit in the object miptree, but it's suitable for inclusion in 402 * a miptree, so create one just for our level and store it in the image. 403 * It'll get moved into the object miptree at validate time. 404 */ 405 intelImage->mt = intel_miptree_create(intel, target, 406 baseFormat, 407 internalFormat, 408 level, level, 409 width, height, depth, 410 texelBytes, 411 comp_byte, pixels == NULL); 412 413 } 414 415 /* PBO fastpaths: 416 */ 417 if (dims <= 2 && 418 intelImage->mt && 419 _mesa_is_bufferobj(unpack->BufferObj) && 420 check_pbo_format(internalFormat, format, 421 type, intelImage->base.TexFormat)) { 422 423 DBG("trying pbo upload\n"); 424 425 /* Attempt to texture directly from PBO data (zero copy upload). 426 * 427 * Currently disable as it can lead to worse as well as better 428 * performance (in particular when intel_region_cow() is 429 * required). 430 */ 431 if (intelObj->mt == intelImage->mt && 432 intelObj->mt->first_level == level && 433 intelObj->mt->last_level == level) { 434 435 if (try_pbo_zcopy(intel, intelImage, unpack, 436 internalFormat, 437 width, height, format, type, pixels)) { 438 439 DBG("pbo zcopy upload succeeded\n"); 440 return; 441 } 442 } 443 444 445 /* Otherwise, attempt to use the blitter for PBO image uploads. 446 */ 447 if (try_pbo_upload(intel, intelImage, unpack, 448 internalFormat, 449 width, height, format, type, pixels)) { 450 DBG("pbo upload succeeded\n"); 451 return; 452 } 453 454 DBG("pbo upload failed\n"); 455 } 456 457 /* intelCopyTexImage calls this function with pixels == NULL, with 458 * the expectation that the mipmap tree will be set up but nothing 459 * more will be done. This is where those calls return: 460 */ 461 if (compressed) { 462 pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels, 463 unpack, 464 "glCompressedTexImage"); 465 } else { 466 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, 467 format, type, 468 pixels, unpack, "glTexImage"); 469 } 470 471 LOCK_HARDWARE(intel); 472 473 if (intelImage->mt) { 474 if (pixels != NULL) { 475 /* Flush any queued rendering with the texture before mapping. */ 476 if (drm_intel_bo_references(intel->batch->buf, 477 intelImage->mt->region->buffer)) { 478 intelFlush(ctx); 479 } 480 texImage->Data = intel_miptree_image_map(intel, 481 intelImage->mt, 482 intelImage->face, 483 intelImage->level, 484 &dstRowStride, 485 intelImage->base.ImageOffsets); 486 } 487 488 texImage->RowStride = dstRowStride / intelImage->mt->cpp; 489 } 490 else { 491 /* Allocate regular memory and store the image there temporarily. */ 492 if (_mesa_is_format_compressed(texImage->TexFormat)) { 493 sizeInBytes = _mesa_format_image_size(texImage->TexFormat, 494 texImage->Width, 495 texImage->Height, 496 texImage->Depth); 497 dstRowStride = 498 _mesa_format_row_stride(texImage->TexFormat, width); 499 assert(dims != 3); 500 } 501 else { 502 dstRowStride = postConvWidth * texelBytes; 503 sizeInBytes = depth * dstRowStride * postConvHeight; 504 } 505 506 texImage->Data = _mesa_alloc_texmemory(sizeInBytes); 507 } 508 509 DBG("Upload image %dx%dx%d row_len %d " 510 "pitch %d pixels %d compressed %d\n", 511 width, height, depth, width * texelBytes, dstRowStride, 512 pixels ? 1 : 0, compressed); 513 514 /* Copy data. Would like to know when it's ok for us to eg. use 515 * the blitter to copy. Or, use the hardware to do the format 516 * conversion and copy: 517 */ 518 if (pixels) { 519 if (compressed) { 520 if (intelImage->mt) { 521 struct intel_region *dst = intelImage->mt->region; 522 _mesa_copy_rect(texImage->Data, dst->cpp, dst->pitch, 523 0, 0, 524 intelImage->mt->level[level].width, 525 (intelImage->mt->level[level].height+3)/4, 526 pixels, 527 srcRowStride, 528 0, 0); 529 } 530 else { 531 memcpy(texImage->Data, pixels, imageSize); 532 } 533 } 534 else if (!_mesa_texstore(ctx, dims, 535 texImage->_BaseFormat, 536 texImage->TexFormat, 537 texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ 538 dstRowStride, 539 texImage->ImageOffsets, 540 width, height, depth, 541 format, type, pixels, unpack)) { 542 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 543 } 544 } 545 546 _mesa_unmap_teximage_pbo(ctx, unpack); 547 548 if (intelImage->mt) { 549 if (pixels != NULL) 550 intel_miptree_image_unmap(intel, intelImage->mt); 551 texImage->Data = NULL; 552 } 553 554 UNLOCK_HARDWARE(intel); 555} 556 557 558static void 559intelTexImage3D(GLcontext * ctx, 560 GLenum target, GLint level, 561 GLint internalFormat, 562 GLint width, GLint height, GLint depth, 563 GLint border, 564 GLenum format, GLenum type, const void *pixels, 565 const struct gl_pixelstore_attrib *unpack, 566 struct gl_texture_object *texObj, 567 struct gl_texture_image *texImage) 568{ 569 intelTexImage(ctx, 3, target, level, 570 internalFormat, width, height, depth, border, 571 format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE); 572} 573 574 575static void 576intelTexImage2D(GLcontext * ctx, 577 GLenum target, GLint level, 578 GLint internalFormat, 579 GLint width, GLint height, GLint border, 580 GLenum format, GLenum type, const void *pixels, 581 const struct gl_pixelstore_attrib *unpack, 582 struct gl_texture_object *texObj, 583 struct gl_texture_image *texImage) 584{ 585 intelTexImage(ctx, 2, target, level, 586 internalFormat, width, height, 1, border, 587 format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE); 588} 589 590 591static void 592intelTexImage1D(GLcontext * ctx, 593 GLenum target, GLint level, 594 GLint internalFormat, 595 GLint width, GLint border, 596 GLenum format, GLenum type, const void *pixels, 597 const struct gl_pixelstore_attrib *unpack, 598 struct gl_texture_object *texObj, 599 struct gl_texture_image *texImage) 600{ 601 intelTexImage(ctx, 1, target, level, 602 internalFormat, width, 1, 1, border, 603 format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE); 604} 605 606 607static void 608intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, 609 GLint internalFormat, 610 GLint width, GLint height, GLint border, 611 GLsizei imageSize, const GLvoid *data, 612 struct gl_texture_object *texObj, 613 struct gl_texture_image *texImage ) 614{ 615 intelTexImage(ctx, 2, target, level, 616 internalFormat, width, height, 1, border, 617 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, GL_TRUE); 618} 619 620 621/** 622 * Need to map texture image into memory before copying image data, 623 * then unmap it. 624 */ 625static void 626intel_get_tex_image(GLcontext * ctx, GLenum target, GLint level, 627 GLenum format, GLenum type, GLvoid * pixels, 628 struct gl_texture_object *texObj, 629 struct gl_texture_image *texImage, GLboolean compressed) 630{ 631 struct intel_context *intel = intel_context(ctx); 632 struct intel_texture_image *intelImage = intel_texture_image(texImage); 633 634 /* If we're reading from a texture that has been rendered to, need to 635 * make sure rendering is complete. 636 * We could probably predicate this on texObj->_RenderToTexture 637 */ 638 intelFlush(ctx); 639 640 /* Map */ 641 if (intelImage->mt) { 642 /* Image is stored in hardware format in a buffer managed by the 643 * kernel. Need to explicitly map and unmap it. 644 */ 645 intelImage->base.Data = 646 intel_miptree_image_map(intel, 647 intelImage->mt, 648 intelImage->face, 649 intelImage->level, 650 &intelImage->base.RowStride, 651 intelImage->base.ImageOffsets); 652 intelImage->base.RowStride /= intelImage->mt->cpp; 653 } 654 else { 655 /* Otherwise, the image should actually be stored in 656 * intelImage->base.Data. This is pretty confusing for 657 * everybody, I'd much prefer to separate the two functions of 658 * texImage->Data - storage for texture images in main memory 659 * and access (ie mappings) of images. In other words, we'd 660 * create a new texImage->Map field and leave Data simply for 661 * storage. 662 */ 663 assert(intelImage->base.Data); 664 } 665 666 667 if (compressed) { 668 _mesa_get_compressed_teximage(ctx, target, level, pixels, 669 texObj, texImage); 670 } else { 671 _mesa_get_teximage(ctx, target, level, format, type, pixels, 672 texObj, texImage); 673 } 674 675 676 /* Unmap */ 677 if (intelImage->mt) { 678 intel_miptree_image_unmap(intel, intelImage->mt); 679 intelImage->base.Data = NULL; 680 } 681} 682 683 684static void 685intelGetTexImage(GLcontext * ctx, GLenum target, GLint level, 686 GLenum format, GLenum type, GLvoid * pixels, 687 struct gl_texture_object *texObj, 688 struct gl_texture_image *texImage) 689{ 690 intel_get_tex_image(ctx, target, level, format, type, pixels, 691 texObj, texImage, GL_FALSE); 692} 693 694 695static void 696intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, 697 GLvoid *pixels, 698 struct gl_texture_object *texObj, 699 struct gl_texture_image *texImage) 700{ 701 intel_get_tex_image(ctx, target, level, 0, 0, pixels, 702 texObj, texImage, GL_TRUE); 703} 704 705 706void 707intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname, 708 unsigned long long offset, GLint depth, GLuint pitch) 709{ 710 struct intel_context *intel = pDRICtx->driverPrivate; 711 struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); 712 struct intel_texture_object *intelObj = intel_texture_object(tObj); 713 714 if (!intelObj) 715 return; 716 717 if (intelObj->mt) 718 intel_miptree_release(intel, &intelObj->mt); 719 720 intelObj->imageOverride = GL_TRUE; 721 intelObj->depthOverride = depth; 722 intelObj->pitchOverride = pitch; 723 724 if (offset) 725 intelObj->textureOffset = offset; 726} 727 728void 729intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, 730 GLint glx_texture_format, 731 __DRIdrawable *dPriv) 732{ 733 struct intel_framebuffer *intel_fb = dPriv->driverPrivate; 734 struct intel_context *intel = pDRICtx->driverPrivate; 735 struct intel_texture_object *intelObj; 736 struct intel_texture_image *intelImage; 737 struct intel_mipmap_tree *mt; 738 struct intel_renderbuffer *rb; 739 struct gl_texture_unit *texUnit; 740 struct gl_texture_object *texObj; 741 struct gl_texture_image *texImage; 742 int level = 0, type, format, internalFormat; 743 744 texUnit = &intel->ctx.Texture.Unit[intel->ctx.Texture.CurrentUnit]; 745 texObj = _mesa_select_tex_object(&intel->ctx, texUnit, target); 746 intelObj = intel_texture_object(texObj); 747 748 if (!intelObj) 749 return; 750 751 intel_update_renderbuffers(pDRICtx, dPriv); 752 753 rb = intel_fb->color_rb[0]; 754 /* If the region isn't set, then intel_update_renderbuffers was unable 755 * to get the buffers for the drawable. 756 */ 757 if (rb->region == NULL) 758 return; 759 760 type = GL_BGRA; 761 format = GL_UNSIGNED_BYTE; 762 if (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT) 763 internalFormat = GL_RGB; 764 else 765 internalFormat = GL_RGBA; 766 767 mt = intel_miptree_create_for_region(intel, target, 768 internalFormat, 769 0, 0, rb->region, 1, 0); 770 if (mt == NULL) 771 return; 772 773 _mesa_lock_texture(&intel->ctx, texObj); 774 775 texImage = _mesa_get_tex_image(&intel->ctx, texObj, target, level); 776 intelImage = intel_texture_image(texImage); 777 778 if (intelImage->mt) { 779 intel_miptree_release(intel, &intelImage->mt); 780 assert(!texImage->Data); 781 } 782 if (intelObj->mt) 783 intel_miptree_release(intel, &intelObj->mt); 784 785 intelObj->mt = mt; 786 _mesa_init_teximage_fields(&intel->ctx, target, texImage, 787 rb->region->width, rb->region->height, 1, 788 0, internalFormat); 789 790 intelImage->face = target_to_face(target); 791 intelImage->level = level; 792 texImage->RowStride = rb->region->pitch; 793 intel_miptree_reference(&intelImage->mt, intelObj->mt); 794 795 if (!intel_miptree_match_image(intelObj->mt, &intelImage->base, 796 intelImage->face, intelImage->level)) { 797 fprintf(stderr, "miptree doesn't match image\n"); 798 } 799 800 _mesa_unlock_texture(&intel->ctx, texObj); 801} 802 803void 804intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) 805{ 806 /* The old interface didn't have the format argument, so copy our 807 * implementation's behavior at the time. 808 */ 809 intelSetTexBuffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv); 810} 811 812 813void 814intelInitTextureImageFuncs(struct dd_function_table *functions) 815{ 816 functions->TexImage1D = intelTexImage1D; 817 functions->TexImage2D = intelTexImage2D; 818 functions->TexImage3D = intelTexImage3D; 819 functions->GetTexImage = intelGetTexImage; 820 821 functions->CompressedTexImage2D = intelCompressedTexImage2D; 822 functions->GetCompressedTexImage = intelGetCompressedTexImage; 823} 824