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