intel_tex_image.c revision dcb4716802878690908a101b1c196737851d4151
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/image.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 lastLevel = firstLevel; 119 } 120 else { 121 l2width = logbase2(width); 122 l2height = logbase2(height); 123 l2depth = logbase2(depth); 124 lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth); 125 } 126 127 assert(!intelObj->mt); 128 if (_mesa_is_format_compressed(intelImage->base.TexFormat)) 129 comp_byte = intel_compressed_num_bytes(intelImage->base.TexFormat); 130 131 texelBytes = _mesa_get_format_bytes(intelImage->base.TexFormat); 132 133 intelObj->mt = intel_miptree_create(intel, 134 intelObj->base.Target, 135 intelImage->base._BaseFormat, 136 intelImage->base.InternalFormat, 137 firstLevel, 138 lastLevel, 139 width, 140 height, 141 depth, 142 texelBytes, 143 comp_byte, 144 expect_accelerated_upload); 145 146 DBG("%s - success\n", __FUNCTION__); 147} 148 149 150 151 152static GLuint 153target_to_face(GLenum target) 154{ 155 switch (target) { 156 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 157 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 158 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 159 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 160 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 161 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 162 return ((GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X); 163 default: 164 return 0; 165 } 166} 167 168/* There are actually quite a few combinations this will work for, 169 * more than what I've listed here. 170 */ 171static GLboolean 172check_pbo_format(GLint internalFormat, 173 GLenum format, GLenum type, 174 gl_format mesa_format) 175{ 176 switch (internalFormat) { 177 case 4: 178 case GL_RGBA: 179 return (format == GL_BGRA && 180 (type == GL_UNSIGNED_BYTE || 181 type == GL_UNSIGNED_INT_8_8_8_8_REV) && 182 mesa_format == MESA_FORMAT_ARGB8888); 183 case 3: 184 case GL_RGB: 185 return (format == GL_RGB && 186 type == GL_UNSIGNED_SHORT_5_6_5 && 187 mesa_format == MESA_FORMAT_RGB565); 188 case GL_YCBCR_MESA: 189 return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE); 190 default: 191 return GL_FALSE; 192 } 193} 194 195 196/* XXX: Do this for TexSubImage also: 197 */ 198static GLboolean 199try_pbo_upload(struct intel_context *intel, 200 struct intel_texture_image *intelImage, 201 const struct gl_pixelstore_attrib *unpack, 202 GLint internalFormat, 203 GLint width, GLint height, 204 GLenum format, GLenum type, const void *pixels) 205{ 206 struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); 207 GLuint src_offset, src_stride; 208 GLuint dst_x, dst_y, dst_stride; 209 dri_bo *dst_buffer = intel_region_buffer(intel, 210 intelImage->mt->region, 211 INTEL_WRITE_FULL); 212 213 if (!_mesa_is_bufferobj(unpack->BufferObj) || 214 intel->ctx._ImageTransferState || 215 unpack->SkipPixels || unpack->SkipRows) { 216 DBG("%s: failure 1\n", __FUNCTION__); 217 return GL_FALSE; 218 } 219 220 /* note: potential 64-bit ptr to 32-bit int cast */ 221 src_offset = (GLuint) (unsigned long) pixels; 222 223 if (unpack->RowLength > 0) 224 src_stride = unpack->RowLength; 225 else 226 src_stride = width; 227 228 intel_miptree_get_image_offset(intelImage->mt, intelImage->level, 229 intelImage->face, 0, 230 &dst_x, &dst_y); 231 232 dst_stride = intelImage->mt->pitch; 233 234 if (drm_intel_bo_references(intel->batch->buf, dst_buffer)) 235 intelFlush(&intel->ctx); 236 LOCK_HARDWARE(intel); 237 { 238 dri_bo *src_buffer = intel_bufferobj_buffer(intel, pbo, INTEL_READ); 239 240 if (!intelEmitCopyBlit(intel, 241 intelImage->mt->cpp, 242 src_stride, src_buffer, src_offset, GL_FALSE, 243 dst_stride, dst_buffer, 0, GL_FALSE, 244 0, 0, dst_x, dst_y, width, height, 245 GL_COPY)) { 246 UNLOCK_HARDWARE(intel); 247 return GL_FALSE; 248 } 249 } 250 UNLOCK_HARDWARE(intel); 251 252 return GL_TRUE; 253} 254 255 256static GLboolean 257try_pbo_zcopy(struct intel_context *intel, 258 struct intel_texture_image *intelImage, 259 const struct gl_pixelstore_attrib *unpack, 260 GLint internalFormat, 261 GLint width, GLint height, 262 GLenum format, GLenum type, const void *pixels) 263{ 264 struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj); 265 GLuint src_offset, src_stride; 266 GLuint dst_x, dst_y, dst_stride; 267 268 if (!_mesa_is_bufferobj(unpack->BufferObj) || 269 intel->ctx._ImageTransferState || 270 unpack->SkipPixels || unpack->SkipRows) { 271 DBG("%s: failure 1\n", __FUNCTION__); 272 return GL_FALSE; 273 } 274 275 /* note: potential 64-bit ptr to 32-bit int cast */ 276 src_offset = (GLuint) (unsigned long) pixels; 277 278 if (unpack->RowLength > 0) 279 src_stride = unpack->RowLength; 280 else 281 src_stride = width; 282 283 intel_miptree_get_image_offset(intelImage->mt, intelImage->level, 284 intelImage->face, 0, 285 &dst_x, &dst_y); 286 287 dst_stride = intelImage->mt->pitch; 288 289 if (src_stride != dst_stride || dst_x != 0 || dst_y != 0 || 290 src_offset != 0) { 291 DBG("%s: failure 2\n", __FUNCTION__); 292 return GL_FALSE; 293 } 294 295 intel_region_attach_pbo(intel, intelImage->mt->region, pbo); 296 297 return GL_TRUE; 298} 299 300 301static void 302intelTexImage(GLcontext * ctx, 303 GLint dims, 304 GLenum target, GLint level, 305 GLint internalFormat, 306 GLint width, GLint height, GLint depth, 307 GLint border, 308 GLenum format, GLenum type, const void *pixels, 309 const struct gl_pixelstore_attrib *unpack, 310 struct gl_texture_object *texObj, 311 struct gl_texture_image *texImage, GLsizei imageSize, 312 GLboolean compressed) 313{ 314 struct intel_context *intel = intel_context(ctx); 315 struct intel_texture_object *intelObj = intel_texture_object(texObj); 316 struct intel_texture_image *intelImage = intel_texture_image(texImage); 317 GLint postConvWidth = width; 318 GLint postConvHeight = height; 319 GLint texelBytes, sizeInBytes; 320 GLuint dstRowStride = 0, srcRowStride = texImage->RowStride; 321 322 DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__, 323 _mesa_lookup_enum_by_nr(target), level, width, height, depth, border); 324 325 intelImage->face = target_to_face(target); 326 intelImage->level = level; 327 328 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { 329 _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth, 330 &postConvHeight); 331 } 332 333 if (_mesa_is_format_compressed(texImage->TexFormat)) { 334 texelBytes = 0; 335 } 336 else { 337 texelBytes = _mesa_get_format_bytes(texImage->TexFormat); 338 339 /* Minimum pitch of 32 bytes */ 340 if (postConvWidth * texelBytes < 32) { 341 postConvWidth = 32 / texelBytes; 342 texImage->RowStride = postConvWidth; 343 } 344 345 if (!intelImage->mt) { 346 assert(texImage->RowStride == postConvWidth); 347 } 348 } 349 350 /* Release the reference to a potentially orphaned buffer. 351 * Release any old malloced memory. 352 */ 353 if (intelImage->mt) { 354 intel_miptree_release(intel, &intelImage->mt); 355 assert(!texImage->Data); 356 } 357 else if (texImage->Data) { 358 _mesa_free_texmemory(texImage->Data); 359 texImage->Data = NULL; 360 } 361 362 /* If this is the only texture image in the tree, could call 363 * bmBufferData with NULL data to free the old block and avoid 364 * waiting on any outstanding fences. 365 */ 366 if (intelObj->mt && 367 intelObj->mt->first_level == level && 368 intelObj->mt->last_level == level && 369 intelObj->mt->target != GL_TEXTURE_CUBE_MAP_ARB && 370 !intel_miptree_match_image(intelObj->mt, &intelImage->base, 371 intelImage->face, intelImage->level)) { 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 intelImage->face, intelImage->level)) { 390 391 intel_miptree_reference(&intelImage->mt, intelObj->mt); 392 assert(intelImage->mt); 393 } else if (intelImage->base.Border == 0) { 394 int comp_byte = 0; 395 GLuint texelBytes = _mesa_get_format_bytes(intelImage->base.TexFormat); 396 GLenum baseFormat = _mesa_get_format_base_format(intelImage->base.TexFormat); 397 if (_mesa_is_format_compressed(intelImage->base.TexFormat)) { 398 comp_byte = 399 intel_compressed_num_bytes(intelImage->base.TexFormat); 400 } 401 402 /* Didn't fit in the object miptree, but it's suitable for inclusion in 403 * a miptree, so create one just for our level and store it in the image. 404 * It'll get moved into the object miptree at validate time. 405 */ 406 intelImage->mt = intel_miptree_create(intel, target, 407 baseFormat, 408 internalFormat, 409 level, level, 410 width, height, depth, 411 texelBytes, 412 comp_byte, pixels == NULL); 413 414 } 415 416 /* PBO fastpaths: 417 */ 418 if (dims <= 2 && 419 intelImage->mt && 420 _mesa_is_bufferobj(unpack->BufferObj) && 421 check_pbo_format(internalFormat, format, 422 type, intelImage->base.TexFormat)) { 423 424 DBG("trying pbo upload\n"); 425 426 /* Attempt to texture directly from PBO data (zero copy upload). 427 * 428 * Currently disable as it can lead to worse as well as better 429 * performance (in particular when intel_region_cow() is 430 * required). 431 */ 432 if (intelObj->mt == intelImage->mt && 433 intelObj->mt->first_level == level && 434 intelObj->mt->last_level == level) { 435 436 if (try_pbo_zcopy(intel, intelImage, unpack, 437 internalFormat, 438 width, height, format, type, pixels)) { 439 440 DBG("pbo zcopy upload succeeded\n"); 441 return; 442 } 443 } 444 445 446 /* Otherwise, attempt to use the blitter for PBO image uploads. 447 */ 448 if (try_pbo_upload(intel, intelImage, unpack, 449 internalFormat, 450 width, height, format, type, pixels)) { 451 DBG("pbo upload succeeded\n"); 452 return; 453 } 454 455 DBG("pbo upload failed\n"); 456 } 457 458 /* intelCopyTexImage calls this function with pixels == NULL, with 459 * the expectation that the mipmap tree will be set up but nothing 460 * more will be done. This is where those calls return: 461 */ 462 if (compressed) { 463 pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels, 464 unpack, 465 "glCompressedTexImage"); 466 } else { 467 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, 468 format, type, 469 pixels, unpack, "glTexImage"); 470 } 471 472 LOCK_HARDWARE(intel); 473 474 if (intelImage->mt) { 475 if (pixels != NULL) { 476 /* Flush any queued rendering with the texture before mapping. */ 477 if (drm_intel_bo_references(intel->batch->buf, 478 intelImage->mt->region->buffer)) { 479 intelFlush(ctx); 480 } 481 texImage->Data = intel_miptree_image_map(intel, 482 intelImage->mt, 483 intelImage->face, 484 intelImage->level, 485 &dstRowStride, 486 intelImage->base.ImageOffsets); 487 } 488 489 texImage->RowStride = dstRowStride / intelImage->mt->cpp; 490 } 491 else { 492 /* Allocate regular memory and store the image there temporarily. */ 493 if (_mesa_is_format_compressed(texImage->TexFormat)) { 494 sizeInBytes = _mesa_format_image_size(texImage->TexFormat, 495 texImage->Width, 496 texImage->Height, 497 texImage->Depth); 498 dstRowStride = 499 _mesa_format_row_stride(texImage->TexFormat, width); 500 assert(dims != 3); 501 } 502 else { 503 dstRowStride = postConvWidth * texelBytes; 504 sizeInBytes = depth * dstRowStride * postConvHeight; 505 } 506 507 texImage->Data = _mesa_alloc_texmemory(sizeInBytes); 508 } 509 510 DBG("Upload image %dx%dx%d row_len %d " 511 "pitch %d pixels %d compressed %d\n", 512 width, height, depth, width * texelBytes, dstRowStride, 513 pixels ? 1 : 0, compressed); 514 515 /* Copy data. Would like to know when it's ok for us to eg. use 516 * the blitter to copy. Or, use the hardware to do the format 517 * conversion and copy: 518 */ 519 if (pixels) { 520 if (compressed) { 521 if (intelImage->mt) { 522 struct intel_region *dst = intelImage->mt->region; 523 _mesa_copy_rect(texImage->Data, dst->cpp, dst->pitch, 524 0, 0, 525 intelImage->mt->level[level].width, 526 (intelImage->mt->level[level].height+3)/4, 527 pixels, 528 srcRowStride, 529 0, 0); 530 } 531 else { 532 memcpy(texImage->Data, pixels, imageSize); 533 } 534 } 535 else if (!_mesa_texstore(ctx, dims, 536 texImage->_BaseFormat, 537 texImage->TexFormat, 538 texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ 539 dstRowStride, 540 texImage->ImageOffsets, 541 width, height, depth, 542 format, type, pixels, unpack)) { 543 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); 544 } 545 } 546 547 _mesa_unmap_teximage_pbo(ctx, unpack); 548 549 if (intelImage->mt) { 550 if (pixels != NULL) 551 intel_miptree_image_unmap(intel, intelImage->mt); 552 texImage->Data = NULL; 553 } 554 555 UNLOCK_HARDWARE(intel); 556} 557 558 559static void 560intelTexImage3D(GLcontext * ctx, 561 GLenum target, GLint level, 562 GLint internalFormat, 563 GLint width, GLint height, GLint depth, 564 GLint border, 565 GLenum format, GLenum type, const void *pixels, 566 const struct gl_pixelstore_attrib *unpack, 567 struct gl_texture_object *texObj, 568 struct gl_texture_image *texImage) 569{ 570 intelTexImage(ctx, 3, target, level, 571 internalFormat, width, height, depth, border, 572 format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE); 573} 574 575 576static void 577intelTexImage2D(GLcontext * ctx, 578 GLenum target, GLint level, 579 GLint internalFormat, 580 GLint width, GLint height, GLint border, 581 GLenum format, GLenum type, const void *pixels, 582 const struct gl_pixelstore_attrib *unpack, 583 struct gl_texture_object *texObj, 584 struct gl_texture_image *texImage) 585{ 586 intelTexImage(ctx, 2, target, level, 587 internalFormat, width, height, 1, border, 588 format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE); 589} 590 591 592static void 593intelTexImage1D(GLcontext * ctx, 594 GLenum target, GLint level, 595 GLint internalFormat, 596 GLint width, GLint border, 597 GLenum format, GLenum type, const void *pixels, 598 const struct gl_pixelstore_attrib *unpack, 599 struct gl_texture_object *texObj, 600 struct gl_texture_image *texImage) 601{ 602 intelTexImage(ctx, 1, target, level, 603 internalFormat, width, 1, 1, border, 604 format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE); 605} 606 607 608static void 609intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, 610 GLint internalFormat, 611 GLint width, GLint height, GLint border, 612 GLsizei imageSize, const GLvoid *data, 613 struct gl_texture_object *texObj, 614 struct gl_texture_image *texImage ) 615{ 616 intelTexImage(ctx, 2, target, level, 617 internalFormat, width, height, 1, border, 618 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, GL_TRUE); 619} 620 621 622/** 623 * Try to use memcpy() to do a glGetTexImage(). 624 * \return GL_TRUE if done, GL_FALSE otherwise 625 */ 626static GLboolean 627memcpy_get_tex_image(GLcontext *ctx, GLenum target, GLint level, 628 GLenum format, GLenum type, GLvoid * pixels, 629 struct gl_texture_object *texObj, 630 struct gl_texture_image *texImage) 631{ 632 GLboolean memCopy = GL_FALSE; 633 634 /* Texture image should have been mapped already */ 635 assert(texImage->Data); 636 637 /* 638 * Check if the src/dst formats are compatible. 639 * Also note that GL's pixel transfer ops don't apply to glGetTexImage() 640 * so we don't have to worry about those. 641 */ 642 if ((texObj->Target == GL_TEXTURE_1D || 643 texObj->Target == GL_TEXTURE_2D || 644 texObj->Target == GL_TEXTURE_RECTANGLE || 645 (texObj->Target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && 646 texObj->Target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))) { 647 if (texImage->TexFormat == MESA_FORMAT_ARGB8888 && 648 format == GL_BGRA && 649 type == GL_UNSIGNED_BYTE && 650 _mesa_little_endian()) { 651 memCopy = GL_TRUE; 652 } 653 else if (texImage->TexFormat == MESA_FORMAT_AL88 && 654 format == GL_LUMINANCE_ALPHA && 655 type == GL_UNSIGNED_BYTE && 656 _mesa_little_endian()) { 657 memCopy = GL_TRUE; 658 } 659 else if (texImage->TexFormat == MESA_FORMAT_L8 && 660 format == GL_LUMINANCE && 661 type == GL_UNSIGNED_BYTE) { 662 memCopy = GL_TRUE; 663 } 664 else if (texImage->TexFormat == MESA_FORMAT_A8 && 665 format == GL_ALPHA && 666 type == GL_UNSIGNED_BYTE) { 667 memCopy = GL_TRUE; 668 } 669 } 670 671 if (memCopy) { 672 struct gl_pixelstore_attrib *pack = &ctx->Pack; 673 674 if (_mesa_is_bufferobj(pack->BufferObj)) { 675 /* Packing texture image into a PBO */ 676 GLubyte *buf = (GLubyte *) 677 ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 678 GL_WRITE_ONLY_ARB, pack->BufferObj); 679 if (!buf) { 680 /* out of memory or other unexpected error */ 681 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage(map PBO failed)"); 682 return GL_TRUE; /* failed, but done */ 683 } 684 pixels = ADD_POINTERS(buf, pixels); 685 } 686 687 { 688 const GLuint bpp = _mesa_get_format_bytes(texImage->TexFormat); 689 const GLuint bytesPerRow = texImage->Width * bpp; 690 GLubyte *dst = 691 _mesa_image_address2d(&ctx->Pack, pixels, texImage->Width, 692 texImage->Height, format, type, 0, 0); 693 const GLint dstRowStride = 694 _mesa_image_row_stride(&ctx->Pack, texImage->Width, format, type); 695 const GLubyte *src = texImage->Data; 696 const GLint srcRowStride = texImage->RowStride * bpp; 697 GLuint row; 698 699 printf("Fast getteximage!\n"); 700 for (row = 0; row < texImage->Height; row++) { 701 memcpy(dst, src, bytesPerRow); 702 dst += dstRowStride; 703 src += srcRowStride; 704 } 705 } 706 707 if (_mesa_is_bufferobj(pack->BufferObj)) { 708 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, pack->BufferObj); 709 } 710 } 711 712 return memCopy; 713} 714 715 716/** 717 * Need to map texture image into memory before copying image data, 718 * then unmap it. 719 */ 720static void 721intel_get_tex_image(GLcontext * ctx, GLenum target, GLint level, 722 GLenum format, GLenum type, GLvoid * pixels, 723 struct gl_texture_object *texObj, 724 struct gl_texture_image *texImage, GLboolean compressed) 725{ 726 struct intel_context *intel = intel_context(ctx); 727 struct intel_texture_image *intelImage = intel_texture_image(texImage); 728 729 /* If we're reading from a texture that has been rendered to, need to 730 * make sure rendering is complete. 731 * We could probably predicate this on texObj->_RenderToTexture 732 */ 733 intelFlush(ctx); 734 735 /* Map */ 736 if (intelImage->mt) { 737 /* Image is stored in hardware format in a buffer managed by the 738 * kernel. Need to explicitly map and unmap it. 739 */ 740 intelImage->base.Data = 741 intel_miptree_image_map(intel, 742 intelImage->mt, 743 intelImage->face, 744 intelImage->level, 745 &intelImage->base.RowStride, 746 intelImage->base.ImageOffsets); 747 intelImage->base.RowStride /= intelImage->mt->cpp; 748 } 749 else { 750 /* Otherwise, the image should actually be stored in 751 * intelImage->base.Data. This is pretty confusing for 752 * everybody, I'd much prefer to separate the two functions of 753 * texImage->Data - storage for texture images in main memory 754 * and access (ie mappings) of images. In other words, we'd 755 * create a new texImage->Map field and leave Data simply for 756 * storage. 757 */ 758 assert(intelImage->base.Data); 759 } 760 761 762 if (compressed) { 763 _mesa_get_compressed_teximage(ctx, target, level, pixels, 764 texObj, texImage); 765 } 766 else { 767 if (!memcpy_get_tex_image(ctx, target, level, format, type, pixels, 768 texObj, texImage)) { 769 _mesa_get_teximage(ctx, target, level, format, type, pixels, 770 texObj, texImage); 771 } 772 } 773 774 775 /* Unmap */ 776 if (intelImage->mt) { 777 intel_miptree_image_unmap(intel, intelImage->mt); 778 intelImage->base.Data = NULL; 779 } 780} 781 782 783static void 784intelGetTexImage(GLcontext * ctx, GLenum target, GLint level, 785 GLenum format, GLenum type, GLvoid * pixels, 786 struct gl_texture_object *texObj, 787 struct gl_texture_image *texImage) 788{ 789 intel_get_tex_image(ctx, target, level, format, type, pixels, 790 texObj, texImage, GL_FALSE); 791} 792 793 794static void 795intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, 796 GLvoid *pixels, 797 struct gl_texture_object *texObj, 798 struct gl_texture_image *texImage) 799{ 800 intel_get_tex_image(ctx, target, level, 0, 0, pixels, 801 texObj, texImage, GL_TRUE); 802} 803 804 805void 806intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname, 807 unsigned long long offset, GLint depth, GLuint pitch) 808{ 809 struct intel_context *intel = pDRICtx->driverPrivate; 810 struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); 811 struct intel_texture_object *intelObj = intel_texture_object(tObj); 812 813 if (!intelObj) 814 return; 815 816 if (intelObj->mt) 817 intel_miptree_release(intel, &intelObj->mt); 818 819 intelObj->imageOverride = GL_TRUE; 820 intelObj->depthOverride = depth; 821 intelObj->pitchOverride = pitch; 822 823 if (offset) 824 intelObj->textureOffset = offset; 825} 826 827void 828intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, 829 GLint glx_texture_format, 830 __DRIdrawable *dPriv) 831{ 832 struct intel_framebuffer *intel_fb = dPriv->driverPrivate; 833 struct intel_context *intel = pDRICtx->driverPrivate; 834 struct intel_texture_object *intelObj; 835 struct intel_texture_image *intelImage; 836 struct intel_mipmap_tree *mt; 837 struct intel_renderbuffer *rb; 838 struct gl_texture_unit *texUnit; 839 struct gl_texture_object *texObj; 840 struct gl_texture_image *texImage; 841 int level = 0, type, format, internalFormat; 842 843 texUnit = &intel->ctx.Texture.Unit[intel->ctx.Texture.CurrentUnit]; 844 texObj = _mesa_select_tex_object(&intel->ctx, texUnit, target); 845 intelObj = intel_texture_object(texObj); 846 847 if (!intelObj) 848 return; 849 850 intel_update_renderbuffers(pDRICtx, dPriv); 851 852 rb = intel_fb->color_rb[0]; 853 /* If the region isn't set, then intel_update_renderbuffers was unable 854 * to get the buffers for the drawable. 855 */ 856 if (rb->region == NULL) 857 return; 858 859 type = GL_BGRA; 860 format = GL_UNSIGNED_BYTE; 861 if (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT) 862 internalFormat = GL_RGB; 863 else 864 internalFormat = GL_RGBA; 865 866 mt = intel_miptree_create_for_region(intel, target, 867 internalFormat, 868 0, 0, rb->region, 1, 0); 869 if (mt == NULL) 870 return; 871 872 _mesa_lock_texture(&intel->ctx, texObj); 873 874 texImage = _mesa_get_tex_image(&intel->ctx, texObj, target, level); 875 intelImage = intel_texture_image(texImage); 876 877 if (intelImage->mt) { 878 intel_miptree_release(intel, &intelImage->mt); 879 assert(!texImage->Data); 880 } 881 if (intelObj->mt) 882 intel_miptree_release(intel, &intelObj->mt); 883 884 intelObj->mt = mt; 885 _mesa_init_teximage_fields(&intel->ctx, target, texImage, 886 rb->region->width, rb->region->height, 1, 887 0, internalFormat); 888 889 intelImage->face = target_to_face(target); 890 intelImage->level = level; 891 texImage->RowStride = rb->region->pitch; 892 intel_miptree_reference(&intelImage->mt, intelObj->mt); 893 894 if (!intel_miptree_match_image(intelObj->mt, &intelImage->base, 895 intelImage->face, intelImage->level)) { 896 fprintf(stderr, "miptree doesn't match image\n"); 897 } 898 899 _mesa_unlock_texture(&intel->ctx, texObj); 900} 901 902void 903intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) 904{ 905 /* The old interface didn't have the format argument, so copy our 906 * implementation's behavior at the time. 907 */ 908 intelSetTexBuffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv); 909} 910 911 912void 913intelInitTextureImageFuncs(struct dd_function_table *functions) 914{ 915 functions->TexImage1D = intelTexImage1D; 916 functions->TexImage2D = intelTexImage2D; 917 functions->TexImage3D = intelTexImage3D; 918 functions->GetTexImage = intelGetTexImage; 919 920 functions->CompressedTexImage2D = intelCompressedTexImage2D; 921 functions->GetCompressedTexImage = intelGetCompressedTexImage; 922} 923