intel_tex_image.c revision debf00e5fc3828f63e0f99d72c7fa6cd6ce012c5
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/texcompress.h" 11#include "main/texstore.h" 12#include "main/texgetimage.h" 13#include "main/texobj.h" 14#include "main/texstore.h" 15#include "main/teximage.h" 16 17#include "intel_context.h" 18#include "intel_mipmap_tree.h" 19#include "intel_buffer_objects.h" 20#include "intel_batchbuffer.h" 21#include "intel_tex.h" 22#include "intel_blit.h" 23#include "intel_fbo.h" 24 25#define FILE_DEBUG_FLAG DEBUG_TEXTURE 26 27/* Functions to store texture images. Where possible, mipmap_tree's 28 * will be created or further instantiated with image data, otherwise 29 * images will be stored in malloc'd memory. A validation step is 30 * required to pull those images into a mipmap tree, or otherwise 31 * decide a fallback is required. 32 */ 33 34 35static int 36logbase2(int n) 37{ 38 GLint i = 1; 39 GLint log2 = 0; 40 41 while (n > i) { 42 i *= 2; 43 log2++; 44 } 45 46 return log2; 47} 48 49 50/* Otherwise, store it in memory if (Border != 0) or (any dimension == 51 * 1). 52 * 53 * Otherwise, if max_level >= level >= min_level, create tree with 54 * space for textures from min_level down to max_level. 55 * 56 * Otherwise, create tree with space for textures from (level 57 * 0)..(1x1). Consider pruning this tree at a validation if the 58 * saving is worth it. 59 */ 60static void 61guess_and_alloc_mipmap_tree(struct intel_context *intel, 62 struct intel_texture_object *intelObj, 63 struct intel_texture_image *intelImage, 64 GLboolean expect_accelerated_upload) 65{ 66 GLuint firstLevel; 67 GLuint lastLevel; 68 GLuint width = intelImage->base.Width; 69 GLuint height = intelImage->base.Height; 70 GLuint depth = intelImage->base.Depth; 71 GLuint l2width, l2height, l2depth; 72 GLuint i, comp_byte = 0; 73 GLuint texelBytes; 74 75 DBG("%s\n", __FUNCTION__); 76 77 if (intelImage->base.Border || 78 ((intelImage->base._BaseFormat == GL_DEPTH_COMPONENT) && 79 ((intelObj->base.WrapS == GL_CLAMP_TO_BORDER) || 80 (intelObj->base.WrapT == GL_CLAMP_TO_BORDER)))) 81 return; 82 83 if (intelImage->level > intelObj->base.BaseLevel && 84 (intelImage->base.Width == 1 || 85 (intelObj->base.Target != GL_TEXTURE_1D && 86 intelImage->base.Height == 1) || 87 (intelObj->base.Target == GL_TEXTURE_3D && 88 intelImage->base.Depth == 1))) 89 return; 90 91 /* If this image disrespects BaseLevel, allocate from level zero. 92 * Usually BaseLevel == 0, so it's unlikely to happen. 93 */ 94 if (intelImage->level < intelObj->base.BaseLevel) 95 firstLevel = 0; 96 else 97 firstLevel = intelObj->base.BaseLevel; 98 99 100 /* Figure out image dimensions at start level. 101 */ 102 for (i = intelImage->level; i > firstLevel; i--) { 103 width <<= 1; 104 if (height != 1) 105 height <<= 1; 106 if (depth != 1) 107 depth <<= 1; 108 } 109 110 /* Guess a reasonable value for lastLevel. This is probably going 111 * to be wrong fairly often and might mean that we have to look at 112 * resizable buffers, or require that buffers implement lazy 113 * pagetable arrangements. 114 */ 115 if ((intelObj->base.MinFilter == GL_NEAREST || 116 intelObj->base.MinFilter == GL_LINEAR) && 117 intelImage->level == firstLevel && 118 (intel->gen < 4 || firstLevel == 0)) { 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 case GL_RGBA8: 181 return (format == GL_BGRA && 182 (type == GL_UNSIGNED_BYTE || 183 type == GL_UNSIGNED_INT_8_8_8_8_REV) && 184 mesa_format == MESA_FORMAT_ARGB8888); 185 case 3: 186 case GL_RGB: 187 return (format == GL_RGB && 188 type == GL_UNSIGNED_SHORT_5_6_5 && 189 mesa_format == MESA_FORMAT_RGB565); 190 case 1: 191 case GL_LUMINANCE: 192 return (format == GL_LUMINANCE && 193 type == GL_UNSIGNED_BYTE && 194 mesa_format == MESA_FORMAT_L8); 195 case GL_YCBCR_MESA: 196 return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE); 197 default: 198 return GL_FALSE; 199 } 200} 201 202 203/* XXX: Do this for TexSubImage also: 204 */ 205static GLboolean 206try_pbo_upload(struct intel_context *intel, 207 struct intel_texture_image *intelImage, 208 const struct gl_pixelstore_attrib *unpack, 209 GLint internalFormat, 210 GLint width, GLint height, 211 GLenum format, GLenum type, const void *pixels) 212{ 213 struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); 214 GLuint src_offset, src_stride; 215 GLuint dst_x, dst_y, dst_stride; 216 dri_bo *dst_buffer = intel_region_buffer(intel, 217 intelImage->mt->region, 218 INTEL_WRITE_FULL); 219 220 if (!_mesa_is_bufferobj(unpack->BufferObj) || 221 intel->ctx._ImageTransferState || 222 unpack->SkipPixels || unpack->SkipRows) { 223 DBG("%s: failure 1\n", __FUNCTION__); 224 return GL_FALSE; 225 } 226 227 /* note: potential 64-bit ptr to 32-bit int cast */ 228 src_offset = (GLuint) (unsigned long) pixels; 229 230 if (unpack->RowLength > 0) 231 src_stride = unpack->RowLength; 232 else 233 src_stride = width; 234 235 intel_miptree_get_image_offset(intelImage->mt, intelImage->level, 236 intelImage->face, 0, 237 &dst_x, &dst_y); 238 239 dst_stride = intelImage->mt->pitch; 240 241 if (drm_intel_bo_references(intel->batch->buf, dst_buffer)) 242 intelFlush(&intel->ctx); 243 { 244 dri_bo *src_buffer = intel_bufferobj_buffer(intel, pbo, INTEL_READ); 245 246 if (!intelEmitCopyBlit(intel, 247 intelImage->mt->cpp, 248 src_stride, src_buffer, src_offset, GL_FALSE, 249 dst_stride, dst_buffer, 0, 250 intelImage->mt->region->tiling, 251 0, 0, dst_x, dst_y, width, height, 252 GL_COPY)) { 253 return GL_FALSE; 254 } 255 } 256 257 return GL_TRUE; 258} 259 260 261static GLboolean 262try_pbo_zcopy(struct intel_context *intel, 263 struct intel_texture_image *intelImage, 264 const struct gl_pixelstore_attrib *unpack, 265 GLint internalFormat, 266 GLint width, GLint height, 267 GLenum format, GLenum type, const void *pixels) 268{ 269 struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); 270 GLuint src_offset, src_stride; 271 GLuint dst_x, dst_y, dst_stride; 272 273 if (!_mesa_is_bufferobj(unpack->BufferObj) || 274 intel->ctx._ImageTransferState || 275 unpack->SkipPixels || unpack->SkipRows) { 276 DBG("%s: failure 1\n", __FUNCTION__); 277 return GL_FALSE; 278 } 279 280 /* note: potential 64-bit ptr to 32-bit int cast */ 281 src_offset = (GLuint) (unsigned long) pixels; 282 283 if (unpack->RowLength > 0) 284 src_stride = unpack->RowLength; 285 else 286 src_stride = width; 287 288 intel_miptree_get_image_offset(intelImage->mt, intelImage->level, 289 intelImage->face, 0, 290 &dst_x, &dst_y); 291 292 dst_stride = intelImage->mt->pitch; 293 294 if (src_stride != dst_stride || dst_x != 0 || dst_y != 0 || 295 src_offset != 0) { 296 DBG("%s: failure 2\n", __FUNCTION__); 297 return GL_FALSE; 298 } 299 300 intel_region_attach_pbo(intel, intelImage->mt->region, pbo); 301 302 return GL_TRUE; 303} 304 305 306static void 307intelTexImage(GLcontext * ctx, 308 GLint dims, 309 GLenum target, GLint level, 310 GLint internalFormat, 311 GLint width, GLint height, GLint depth, 312 GLint border, 313 GLenum format, GLenum type, const void *pixels, 314 const struct gl_pixelstore_attrib *unpack, 315 struct gl_texture_object *texObj, 316 struct gl_texture_image *texImage, GLsizei imageSize, 317 GLboolean compressed) 318{ 319 struct intel_context *intel = intel_context(ctx); 320 struct intel_texture_object *intelObj = intel_texture_object(texObj); 321 struct intel_texture_image *intelImage = intel_texture_image(texImage); 322 GLint postConvWidth = width; 323 GLint postConvHeight = height; 324 GLint texelBytes, sizeInBytes; 325 GLuint dstRowStride = 0, srcRowStride = texImage->RowStride; 326 327 DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, 328 _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); 329 330 intelImage->face = target_to_face(target); 331 intelImage->level = level; 332 333 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 334 _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth, 335 &postConvHeight); 336 } 337 338 if (_mesa_is_format_compressed(texImage->TexFormat)) { 339 texelBytes = 0; 340 } 341 else { 342 texelBytes = _mesa_get_format_bytes(texImage->TexFormat); 343 344 /* Minimum pitch of 32 bytes */ 345 if (postConvWidth * texelBytes < 32) { 346 postConvWidth = 32 / texelBytes; 347 texImage->RowStride = postConvWidth; 348 } 349 350 if (!intelImage->mt) { 351 assert(texImage->RowStride == postConvWidth); 352 } 353 } 354 355 /* Release the reference to a potentially orphaned buffer. 356 * Release any old malloced memory. 357 */ 358 if (intelImage->mt) { 359 intel_miptree_release(intel, &intelImage->mt); 360 assert(!texImage->Data); 361 } 362 else if (texImage->Data) { 363 _mesa_free_texmemory(texImage->Data); 364 texImage->Data = NULL; 365 } 366 367 /* If this is the only texture image in the tree, could call 368 * bmBufferData with NULL data to free the old block and avoid 369 * waiting on any outstanding fences. 370 */ 371 if (intelObj->mt && 372 intelObj->mt->first_level == level && 373 intelObj->mt->last_level == level && 374 intelObj->mt->target != GL_TEXTURE_CUBE_MAP_ARB && 375 !intel_miptree_match_image(intelObj->mt, &intelImage->base)) { 376 377 DBG("release it\n"); 378 intel_miptree_release(intel, &intelObj->mt); 379 assert(!intelObj->mt); 380 } 381 382 if (!intelObj->mt) { 383 guess_and_alloc_mipmap_tree(intel, intelObj, intelImage, pixels == NULL); 384 if (!intelObj->mt) { 385 DBG("guess_and_alloc_mipmap_tree: failed\n"); 386 } 387 } 388 389 assert(!intelImage->mt); 390 391 if (intelObj->mt && 392 intel_miptree_match_image(intelObj->mt, &intelImage->base)) { 393 394 intel_miptree_reference(&intelImage->mt, intelObj->mt); 395 assert(intelImage->mt); 396 } else if (intelImage->base.Border == 0) { 397 int comp_byte = 0; 398 GLuint texelBytes = _mesa_get_format_bytes(intelImage->base.TexFormat); 399 GLenum baseFormat = _mesa_get_format_base_format(intelImage->base.TexFormat); 400 if (_mesa_is_format_compressed(intelImage->base.TexFormat)) { 401 comp_byte = 402 intel_compressed_num_bytes(intelImage->base.TexFormat); 403 } 404 405 /* Didn't fit in the object miptree, but it's suitable for inclusion in 406 * a miptree, so create one just for our level and store it in the image. 407 * It'll get moved into the object miptree at validate time. 408 */ 409 intelImage->mt = intel_miptree_create(intel, target, 410 baseFormat, 411 internalFormat, 412 level, level, 413 width, height, depth, 414 texelBytes, 415 comp_byte, pixels == NULL); 416 417 } 418 419 /* PBO fastpaths: 420 */ 421 if (dims <= 2 && 422 intelImage->mt && 423 _mesa_is_bufferobj(unpack->BufferObj) && 424 check_pbo_format(internalFormat, format, 425 type, intelImage->base.TexFormat)) { 426 427 DBG("trying pbo upload\n"); 428 429 /* Attempt to texture directly from PBO data (zero copy upload). 430 * 431 * Currently disable as it can lead to worse as well as better 432 * performance (in particular when intel_region_cow() is 433 * required). 434 */ 435 if (intelObj->mt == intelImage->mt && 436 intelObj->mt->first_level == level && 437 intelObj->mt->last_level == level) { 438 439 if (try_pbo_zcopy(intel, intelImage, unpack, 440 internalFormat, 441 width, height, format, type, pixels)) { 442 443 DBG("pbo zcopy upload succeeded\n"); 444 return; 445 } 446 } 447 448 449 /* Otherwise, attempt to use the blitter for PBO image uploads. 450 */ 451 if (try_pbo_upload(intel, intelImage, unpack, 452 internalFormat, 453 width, height, format, type, pixels)) { 454 DBG("pbo upload succeeded\n"); 455 return; 456 } 457 458 DBG("pbo upload failed\n"); 459 } 460 461 /* intelCopyTexImage calls this function with pixels == NULL, with 462 * the expectation that the mipmap tree will be set up but nothing 463 * more will be done. This is where those calls return: 464 */ 465 if (compressed) { 466 pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels, 467 unpack, 468 "glCompressedTexImage"); 469 } else { 470 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, 471 format, type, 472 pixels, unpack, "glTexImage"); 473 } 474 475 if (intelImage->mt) { 476 if (pixels != NULL) { 477 /* Flush any queued rendering with the texture before mapping. */ 478 if (drm_intel_bo_references(intel->batch->buf, 479 intelImage->mt->region->buffer)) { 480 intelFlush(ctx); 481 } 482 texImage->Data = intel_miptree_image_map(intel, 483 intelImage->mt, 484 intelImage->face, 485 intelImage->level, 486 &dstRowStride, 487 intelImage->base.ImageOffsets); 488 } 489 490 texImage->RowStride = dstRowStride / intelImage->mt->cpp; 491 } 492 else { 493 /* Allocate regular memory and store the image there temporarily. */ 494 if (_mesa_is_format_compressed(texImage->TexFormat)) { 495 sizeInBytes = _mesa_format_image_size(texImage->TexFormat, 496 texImage->Width, 497 texImage->Height, 498 texImage->Depth); 499 dstRowStride = 500 _mesa_format_row_stride(texImage->TexFormat, width); 501 assert(dims != 3); 502 } 503 else { 504 dstRowStride = postConvWidth * texelBytes; 505 sizeInBytes = depth * dstRowStride * postConvHeight; 506 } 507 508 texImage->Data = _mesa_alloc_texmemory(sizeInBytes); 509 } 510 511 DBG("Upload image %dx%dx%d row_len %d " 512 "pitch %d pixels %d compressed %d\n", 513 width, height, depth, width * texelBytes, dstRowStride, 514 pixels ? 1 : 0, compressed); 515 516 /* Copy data. Would like to know when it's ok for us to eg. use 517 * the blitter to copy. Or, use the hardware to do the format 518 * conversion and copy: 519 */ 520 if (pixels) { 521 if (compressed) { 522 if (intelImage->mt) { 523 struct intel_region *dst = intelImage->mt->region; 524 _mesa_copy_rect(texImage->Data, dst->cpp, dst->pitch, 525 0, 0, 526 intelImage->mt->level[level].width, 527 (intelImage->mt->level[level].height+3)/4, 528 pixels, 529 srcRowStride, 530 0, 0); 531 } 532 else { 533 memcpy(texImage->Data, pixels, imageSize); 534 } 535 } 536 else if (!_mesa_texstore(ctx, dims, 537 texImage->_BaseFormat, 538 texImage->TexFormat, 539 texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ 540 dstRowStride, 541 texImage->ImageOffsets, 542 width, height, depth, 543 format, type, pixels, unpack)) { 544 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 545 } 546 } 547 548 _mesa_unmap_teximage_pbo(ctx, unpack); 549 550 if (intelImage->mt) { 551 if (pixels != NULL) 552 intel_miptree_image_unmap(intel, intelImage->mt); 553 texImage->Data = NULL; 554 } 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 texture_format, 732 __DRIdrawable *dPriv) 733{ 734 struct gl_framebuffer *fb = dPriv->driverPrivate; 735 struct intel_context *intel = pDRICtx->driverPrivate; 736 GLcontext *ctx = &intel->ctx; 737 struct intel_texture_object *intelObj; 738 struct intel_texture_image *intelImage; 739 struct intel_mipmap_tree *mt; 740 struct intel_renderbuffer *rb; 741 struct gl_texture_object *texObj; 742 struct gl_texture_image *texImage; 743 int level = 0, internalFormat; 744 745 texObj = _mesa_get_current_tex_object(ctx, target); 746 intelObj = intel_texture_object(texObj); 747 748 if (!intelObj) 749 return; 750 751 if (!dPriv->validBuffers) 752 intel_update_renderbuffers(pDRICtx, dPriv); 753 754 rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); 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 (texture_format == __DRI_TEXTURE_FORMAT_RGB) 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 (texture_format == __DRI_TEXTURE_FORMAT_RGB) 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, __DRI_TEXTURE_FORMAT_RGBA, 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