intel_tex_image.c revision 8f30ceaaefc33401b08739a16ce1c5638d6432fa
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/formats.h" 10#include "main/image.h" 11#include "main/texcompress.h" 12#include "main/texstore.h" 13#include "main/texgetimage.h" 14#include "main/texobj.h" 15#include "main/texstore.h" 16#include "main/teximage.h" 17 18#include "intel_context.h" 19#include "intel_mipmap_tree.h" 20#include "intel_buffer_objects.h" 21#include "intel_batchbuffer.h" 22#include "intel_tex.h" 23#include "intel_blit.h" 24#include "intel_fbo.h" 25 26#define FILE_DEBUG_FLAG DEBUG_TEXTURE 27 28/* Functions to store texture images. Where possible, mipmap_tree's 29 * will be created or further instantiated with image data, otherwise 30 * images will be stored in malloc'd memory. A validation step is 31 * required to pull those images into a mipmap tree, or otherwise 32 * decide a fallback is required. 33 */ 34 35 36static int 37logbase2(int n) 38{ 39 GLint i = 1; 40 GLint log2 = 0; 41 42 while (n > i) { 43 i *= 2; 44 log2++; 45 } 46 47 return log2; 48} 49 50 51/* Otherwise, store it in memory if (Border != 0) or (any dimension == 52 * 1). 53 * 54 * Otherwise, if max_level >= level >= min_level, create tree with 55 * space for textures from min_level down to max_level. 56 * 57 * Otherwise, create tree with space for textures from (level 58 * 0)..(1x1). Consider pruning this tree at a validation if the 59 * saving is worth it. 60 */ 61static void 62guess_and_alloc_mipmap_tree(struct intel_context *intel, 63 struct intel_texture_object *intelObj, 64 struct intel_texture_image *intelImage, 65 GLboolean expect_accelerated_upload) 66{ 67 GLuint firstLevel; 68 GLuint lastLevel; 69 GLuint width = intelImage->base.Width; 70 GLuint height = intelImage->base.Height; 71 GLuint depth = intelImage->base.Depth; 72 GLuint l2width, l2height, l2depth; 73 GLuint i, comp_byte = 0; 74 GLuint texelBytes; 75 76 DBG("%s\n", __FUNCTION__); 77 78 if (intelImage->base.Border || 79 ((intelImage->base._BaseFormat == GL_DEPTH_COMPONENT) && 80 ((intelObj->base.WrapS == GL_CLAMP_TO_BORDER) || 81 (intelObj->base.WrapT == GL_CLAMP_TO_BORDER)))) 82 return; 83 84 if (intelImage->level > intelObj->base.BaseLevel && 85 (intelImage->base.Width == 1 || 86 (intelObj->base.Target != GL_TEXTURE_1D && 87 intelImage->base.Height == 1) || 88 (intelObj->base.Target == GL_TEXTURE_3D && 89 intelImage->base.Depth == 1))) 90 return; 91 92 /* If this image disrespects BaseLevel, allocate from level zero. 93 * Usually BaseLevel == 0, so it's unlikely to happen. 94 */ 95 if (intelImage->level < intelObj->base.BaseLevel) 96 firstLevel = 0; 97 else 98 firstLevel = intelObj->base.BaseLevel; 99 100 101 /* Figure out image dimensions at start level. 102 */ 103 for (i = intelImage->level; i > firstLevel; i--) { 104 width <<= 1; 105 if (height != 1) 106 height <<= 1; 107 if (depth != 1) 108 depth <<= 1; 109 } 110 111 /* Guess a reasonable value for lastLevel. This is probably going 112 * to be wrong fairly often and might mean that we have to look at 113 * resizable buffers, or require that buffers implement lazy 114 * pagetable arrangements. 115 */ 116 if ((intelObj->base.MinFilter == GL_NEAREST || 117 intelObj->base.MinFilter == GL_LINEAR) && 118 intelImage->level == firstLevel) { 119 lastLevel = firstLevel; 120 } 121 else { 122 l2width = logbase2(width); 123 l2height = logbase2(height); 124 l2depth = logbase2(depth); 125 lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth); 126 } 127 128 assert(!intelObj->mt); 129 if (_mesa_is_format_compressed(intelImage->base.TexFormat)) 130 comp_byte = intel_compressed_num_bytes(intelImage->base.TexFormat); 131 132 texelBytes = _mesa_get_format_bytes(intelImage->base.TexFormat); 133 134 intelObj->mt = intel_miptree_create(intel, 135 intelObj->base.Target, 136 intelImage->base._BaseFormat, 137 intelImage->base.InternalFormat, 138 firstLevel, 139 lastLevel, 140 width, 141 height, 142 depth, 143 texelBytes, 144 comp_byte, 145 expect_accelerated_upload); 146 147 DBG("%s - success\n", __FUNCTION__); 148} 149 150 151 152 153static GLuint 154target_to_face(GLenum target) 155{ 156 switch (target) { 157 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 158 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 159 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 160 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 161 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 162 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 163 return ((GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X); 164 default: 165 return 0; 166 } 167} 168 169/* There are actually quite a few combinations this will work for, 170 * more than what I've listed here. 171 */ 172static GLboolean 173check_pbo_format(GLint internalFormat, 174 GLenum format, GLenum type, 175 gl_format mesa_format) 176{ 177 switch (internalFormat) { 178 case 4: 179 case GL_RGBA: 180 return (format == GL_BGRA && 181 (type == GL_UNSIGNED_BYTE || 182 type == GL_UNSIGNED_INT_8_8_8_8_REV) && 183 mesa_format == MESA_FORMAT_ARGB8888); 184 case 3: 185 case GL_RGB: 186 return (format == GL_RGB && 187 type == GL_UNSIGNED_SHORT_5_6_5 && 188 mesa_format == MESA_FORMAT_RGB565); 189 case GL_YCBCR_MESA: 190 return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE); 191 default: 192 return GL_FALSE; 193 } 194} 195 196 197/* XXX: Do this for TexSubImage also: 198 */ 199static GLboolean 200try_pbo_upload(struct intel_context *intel, 201 struct intel_texture_image *intelImage, 202 const struct gl_pixelstore_attrib *unpack, 203 GLint internalFormat, 204 GLint width, GLint height, 205 GLenum format, GLenum type, const void *pixels) 206{ 207 struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); 208 GLuint src_offset, src_stride; 209 GLuint dst_x, dst_y, dst_stride; 210 dri_bo *dst_buffer = intel_region_buffer(intel, 211 intelImage->mt->region, 212 INTEL_WRITE_FULL); 213 214 if (!_mesa_is_bufferobj(unpack->BufferObj) || 215 intel->ctx._ImageTransferState || 216 unpack->SkipPixels || unpack->SkipRows) { 217 DBG("%s: failure 1\n", __FUNCTION__); 218 return GL_FALSE; 219 } 220 221 /* note: potential 64-bit ptr to 32-bit int cast */ 222 src_offset = (GLuint) (unsigned long) pixels; 223 224 if (unpack->RowLength > 0) 225 src_stride = unpack->RowLength; 226 else 227 src_stride = width; 228 229 intel_miptree_get_image_offset(intelImage->mt, intelImage->level, 230 intelImage->face, 0, 231 &dst_x, &dst_y); 232 233 dst_stride = intelImage->mt->pitch; 234 235 if (drm_intel_bo_references(intel->batch->buf, dst_buffer)) 236 intelFlush(&intel->ctx); 237 LOCK_HARDWARE(intel); 238 { 239 dri_bo *src_buffer = intel_bufferobj_buffer(intel, pbo, INTEL_READ); 240 241 if (!intelEmitCopyBlit(intel, 242 intelImage->mt->cpp, 243 src_stride, src_buffer, src_offset, GL_FALSE, 244 dst_stride, dst_buffer, 0, GL_FALSE, 245 0, 0, dst_x, dst_y, width, height, 246 GL_COPY)) { 247 UNLOCK_HARDWARE(intel); 248 return GL_FALSE; 249 } 250 } 251 UNLOCK_HARDWARE(intel); 252 253 return GL_TRUE; 254} 255 256 257static GLboolean 258try_pbo_zcopy(struct intel_context *intel, 259 struct intel_texture_image *intelImage, 260 const struct gl_pixelstore_attrib *unpack, 261 GLint internalFormat, 262 GLint width, GLint height, 263 GLenum format, GLenum type, const void *pixels) 264{ 265 struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); 266 GLuint src_offset, src_stride; 267 GLuint dst_x, dst_y, dst_stride; 268 269 if (!_mesa_is_bufferobj(unpack->BufferObj) || 270 intel->ctx._ImageTransferState || 271 unpack->SkipPixels || unpack->SkipRows) { 272 DBG("%s: failure 1\n", __FUNCTION__); 273 return GL_FALSE; 274 } 275 276 /* note: potential 64-bit ptr to 32-bit int cast */ 277 src_offset = (GLuint) (unsigned long) pixels; 278 279 if (unpack->RowLength > 0) 280 src_stride = unpack->RowLength; 281 else 282 src_stride = width; 283 284 intel_miptree_get_image_offset(intelImage->mt, intelImage->level, 285 intelImage->face, 0, 286 &dst_x, &dst_y); 287 288 dst_stride = intelImage->mt->pitch; 289 290 if (src_stride != dst_stride || dst_x != 0 || dst_y != 0 || 291 src_offset != 0) { 292 DBG("%s: failure 2\n", __FUNCTION__); 293 return GL_FALSE; 294 } 295 296 intel_region_attach_pbo(intel, intelImage->mt->region, pbo); 297 298 return GL_TRUE; 299} 300 301 302static void 303intelTexImage(GLcontext * ctx, 304 GLint dims, 305 GLenum target, GLint level, 306 GLint internalFormat, 307 GLint width, GLint height, GLint depth, 308 GLint border, 309 GLenum format, GLenum type, const void *pixels, 310 const struct gl_pixelstore_attrib *unpack, 311 struct gl_texture_object *texObj, 312 struct gl_texture_image *texImage, GLsizei imageSize, 313 GLboolean compressed) 314{ 315 struct intel_context *intel = intel_context(ctx); 316 struct intel_texture_object *intelObj = intel_texture_object(texObj); 317 struct intel_texture_image *intelImage = intel_texture_image(texImage); 318 GLint postConvWidth = width; 319 GLint postConvHeight = height; 320 GLint texelBytes, sizeInBytes; 321 GLuint dstRowStride = 0, srcRowStride = texImage->RowStride; 322 323 DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, 324 _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); 325 326 intelImage->face = target_to_face(target); 327 intelImage->level = level; 328 329 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 330 _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth, 331 &postConvHeight); 332 } 333 334 if (_mesa_is_format_compressed(texImage->TexFormat)) { 335 texelBytes = 0; 336 } 337 else { 338 texelBytes = _mesa_get_format_bytes(texImage->TexFormat); 339 340 /* Minimum pitch of 32 bytes */ 341 if (postConvWidth * texelBytes < 32) { 342 postConvWidth = 32 / texelBytes; 343 texImage->RowStride = postConvWidth; 344 } 345 346 if (!intelImage->mt) { 347 assert(texImage->RowStride == postConvWidth); 348 } 349 } 350 351 /* Release the reference to a potentially orphaned buffer. 352 * Release any old malloced memory. 353 */ 354 if (intelImage->mt) { 355 intel_miptree_release(intel, &intelImage->mt); 356 assert(!texImage->Data); 357 } 358 else if (texImage->Data) { 359 _mesa_free_texmemory(texImage->Data); 360 texImage->Data = NULL; 361 } 362 363 /* If this is the only texture image in the tree, could call 364 * bmBufferData with NULL data to free the old block and avoid 365 * waiting on any outstanding fences. 366 */ 367 if (intelObj->mt && 368 intelObj->mt->first_level == level && 369 intelObj->mt->last_level == level && 370 intelObj->mt->target != GL_TEXTURE_CUBE_MAP_ARB && 371 !intel_miptree_match_image(intelObj->mt, &intelImage->base)) { 372 373 DBG("release it\n"); 374 intel_miptree_release(intel, &intelObj->mt); 375 assert(!intelObj->mt); 376 } 377 378 if (!intelObj->mt) { 379 guess_and_alloc_mipmap_tree(intel, intelObj, intelImage, pixels == NULL); 380 if (!intelObj->mt) { 381 DBG("guess_and_alloc_mipmap_tree: failed\n"); 382 } 383 } 384 385 assert(!intelImage->mt); 386 387 if (intelObj->mt && 388 intel_miptree_match_image(intelObj->mt, &intelImage->base)) { 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 } 671 else { 672 _mesa_get_teximage(ctx, target, level, format, type, pixels, 673 texObj, texImage); 674 } 675 676 677 /* Unmap */ 678 if (intelImage->mt) { 679 intel_miptree_image_unmap(intel, intelImage->mt); 680 intelImage->base.Data = NULL; 681 } 682} 683 684 685static void 686intelGetTexImage(GLcontext * ctx, GLenum target, GLint level, 687 GLenum format, GLenum type, GLvoid * pixels, 688 struct gl_texture_object *texObj, 689 struct gl_texture_image *texImage) 690{ 691 intel_get_tex_image(ctx, target, level, format, type, pixels, 692 texObj, texImage, GL_FALSE); 693} 694 695 696static void 697intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, 698 GLvoid *pixels, 699 struct gl_texture_object *texObj, 700 struct gl_texture_image *texImage) 701{ 702 intel_get_tex_image(ctx, target, level, 0, 0, pixels, 703 texObj, texImage, GL_TRUE); 704} 705 706 707void 708intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname, 709 unsigned long long offset, GLint depth, GLuint pitch) 710{ 711 struct intel_context *intel = pDRICtx->driverPrivate; 712 struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); 713 struct intel_texture_object *intelObj = intel_texture_object(tObj); 714 715 if (!intelObj) 716 return; 717 718 if (intelObj->mt) 719 intel_miptree_release(intel, &intelObj->mt); 720 721 intelObj->imageOverride = GL_TRUE; 722 intelObj->depthOverride = depth; 723 intelObj->pitchOverride = pitch; 724 725 if (offset) 726 intelObj->textureOffset = offset; 727} 728 729void 730intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, 731 GLint glx_texture_format, 732 __DRIdrawable *dPriv) 733{ 734 struct intel_framebuffer *intel_fb = dPriv->driverPrivate; 735 struct intel_context *intel = pDRICtx->driverPrivate; 736 struct intel_texture_object *intelObj; 737 struct intel_texture_image *intelImage; 738 struct intel_mipmap_tree *mt; 739 struct intel_renderbuffer *rb; 740 struct gl_texture_unit *texUnit; 741 struct gl_texture_object *texObj; 742 struct gl_texture_image *texImage; 743 int level = 0, internalFormat; 744 745 texUnit = &intel->ctx.Texture.Unit[intel->ctx.Texture.CurrentUnit]; 746 texObj = _mesa_select_tex_object(&intel->ctx, texUnit, target); 747 intelObj = intel_texture_object(texObj); 748 749 if (!intelObj) 750 return; 751 752 intel_update_renderbuffers(pDRICtx, dPriv); 753 754 rb = intel_fb->color_rb[0]; 755 /* If the region isn't set, then intel_update_renderbuffers was unable 756 * to get the buffers for the drawable. 757 */ 758 if (rb->region == NULL) 759 return; 760 761 if (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT) 762 internalFormat = GL_RGB; 763 else 764 internalFormat = GL_RGBA; 765 766 mt = intel_miptree_create_for_region(intel, target, 767 internalFormat, 768 0, 0, rb->region, 1, 0); 769 if (mt == NULL) 770 return; 771 772 _mesa_lock_texture(&intel->ctx, texObj); 773 774 texImage = _mesa_get_tex_image(&intel->ctx, texObj, target, level); 775 intelImage = intel_texture_image(texImage); 776 777 if (intelImage->mt) { 778 intel_miptree_release(intel, &intelImage->mt); 779 assert(!texImage->Data); 780 } 781 if (intelObj->mt) 782 intel_miptree_release(intel, &intelObj->mt); 783 784 intelObj->mt = mt; 785 _mesa_init_teximage_fields(&intel->ctx, target, texImage, 786 rb->region->width, rb->region->height, 1, 787 0, internalFormat); 788 789 intelImage->face = target_to_face(target); 790 intelImage->level = level; 791 if (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT) 792 texImage->TexFormat = MESA_FORMAT_XRGB8888; 793 else 794 texImage->TexFormat = MESA_FORMAT_ARGB8888; 795 texImage->RowStride = rb->region->pitch; 796 intel_miptree_reference(&intelImage->mt, intelObj->mt); 797 798 if (!intel_miptree_match_image(intelObj->mt, &intelImage->base)) { 799 fprintf(stderr, "miptree doesn't match image\n"); 800 } 801 802 _mesa_unlock_texture(&intel->ctx, texObj); 803} 804 805void 806intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) 807{ 808 /* The old interface didn't have the format argument, so copy our 809 * implementation's behavior at the time. 810 */ 811 intelSetTexBuffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv); 812} 813 814 815void 816intelInitTextureImageFuncs(struct dd_function_table *functions) 817{ 818 functions->TexImage1D = intelTexImage1D; 819 functions->TexImage2D = intelTexImage2D; 820 functions->TexImage3D = intelTexImage3D; 821 functions->GetTexImage = intelGetTexImage; 822 823 functions->CompressedTexImage2D = intelCompressedTexImage2D; 824 functions->GetCompressedTexImage = intelGetCompressedTexImage; 825} 826