1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5 * Copyright (c) 2008-2009 VMware, Inc. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 * OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26/* 27 * Authors: 28 * Brian Paul 29 */ 30 31/** 32 * The GL texture image functions in teximage.c basically just do 33 * error checking and data structure allocation. They in turn call 34 * device driver functions which actually copy/convert/store the user's 35 * texture image data. 36 * 37 * However, most device drivers will be able to use the fallback functions 38 * in this file. That is, most drivers will have the following bit of 39 * code: 40 * ctx->Driver.TexImage = _mesa_store_teximage; 41 * ctx->Driver.TexSubImage = _mesa_store_texsubimage; 42 * etc... 43 * 44 * Texture image processing is actually kind of complicated. We have to do: 45 * Format/type conversions 46 * pixel unpacking 47 * pixel transfer (scale, bais, lookup, etc) 48 * 49 * These functions can handle most everything, including processing full 50 * images and sub-images. 51 */ 52 53 54#include "errors.h" 55#include "glheader.h" 56#include "bufferobj.h" 57#include "format_pack.h" 58#include "format_utils.h" 59#include "image.h" 60#include "macros.h" 61#include "mipmap.h" 62#include "mtypes.h" 63#include "pack.h" 64#include "pbo.h" 65#include "imports.h" 66#include "texcompress.h" 67#include "texcompress_fxt1.h" 68#include "texcompress_rgtc.h" 69#include "texcompress_s3tc.h" 70#include "texcompress_etc.h" 71#include "texcompress_bptc.h" 72#include "teximage.h" 73#include "texstore.h" 74#include "enums.h" 75#include "glformats.h" 76#include "pixeltransfer.h" 77#include "util/format_rgb9e5.h" 78#include "util/format_r11g11b10f.h" 79 80 81enum { 82 ZERO = 4, 83 ONE = 5 84}; 85 86 87/** 88 * Texture image storage function. 89 */ 90typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS); 91 92 93/** 94 * Teximage storage routine for when a simple memcpy will do. 95 * No pixel transfer operations or special texel encodings allowed. 96 * 1D, 2D and 3D images supported. 97 */ 98void 99_mesa_memcpy_texture(struct gl_context *ctx, 100 GLuint dimensions, 101 mesa_format dstFormat, 102 GLint dstRowStride, 103 GLubyte **dstSlices, 104 GLint srcWidth, GLint srcHeight, GLint srcDepth, 105 GLenum srcFormat, GLenum srcType, 106 const GLvoid *srcAddr, 107 const struct gl_pixelstore_attrib *srcPacking) 108{ 109 const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, 110 srcFormat, srcType); 111 const GLint srcImageStride = _mesa_image_image_stride(srcPacking, 112 srcWidth, srcHeight, srcFormat, srcType); 113 const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions, 114 srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0); 115 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); 116 const GLint bytesPerRow = srcWidth * texelBytes; 117 118 if (dstRowStride == srcRowStride && 119 dstRowStride == bytesPerRow) { 120 /* memcpy image by image */ 121 GLint img; 122 for (img = 0; img < srcDepth; img++) { 123 GLubyte *dstImage = dstSlices[img]; 124 memcpy(dstImage, srcImage, bytesPerRow * srcHeight); 125 srcImage += srcImageStride; 126 } 127 } 128 else { 129 /* memcpy row by row */ 130 GLint img, row; 131 for (img = 0; img < srcDepth; img++) { 132 const GLubyte *srcRow = srcImage; 133 GLubyte *dstRow = dstSlices[img]; 134 for (row = 0; row < srcHeight; row++) { 135 memcpy(dstRow, srcRow, bytesPerRow); 136 dstRow += dstRowStride; 137 srcRow += srcRowStride; 138 } 139 srcImage += srcImageStride; 140 } 141 } 142} 143 144 145/** 146 * Store a 32-bit integer or float depth component texture image. 147 */ 148static GLboolean 149_mesa_texstore_z32(TEXSTORE_PARAMS) 150{ 151 const GLuint depthScale = 0xffffffff; 152 GLenum dstType; 153 (void) dims; 154 assert(dstFormat == MESA_FORMAT_Z_UNORM32 || 155 dstFormat == MESA_FORMAT_Z_FLOAT32); 156 assert(_mesa_get_format_bytes(dstFormat) == sizeof(GLuint)); 157 158 if (dstFormat == MESA_FORMAT_Z_UNORM32) 159 dstType = GL_UNSIGNED_INT; 160 else 161 dstType = GL_FLOAT; 162 163 { 164 /* general path */ 165 GLint img, row; 166 for (img = 0; img < srcDepth; img++) { 167 GLubyte *dstRow = dstSlices[img]; 168 for (row = 0; row < srcHeight; row++) { 169 const GLvoid *src = _mesa_image_address(dims, srcPacking, 170 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); 171 _mesa_unpack_depth_span(ctx, srcWidth, 172 dstType, dstRow, 173 depthScale, srcType, src, srcPacking); 174 dstRow += dstRowStride; 175 } 176 } 177 } 178 return GL_TRUE; 179} 180 181 182/** 183 * Store a 24-bit integer depth component texture image. 184 */ 185static GLboolean 186_mesa_texstore_x8_z24(TEXSTORE_PARAMS) 187{ 188 const GLuint depthScale = 0xffffff; 189 190 (void) dims; 191 assert(dstFormat == MESA_FORMAT_Z24_UNORM_X8_UINT); 192 193 { 194 /* general path */ 195 GLint img, row; 196 for (img = 0; img < srcDepth; img++) { 197 GLubyte *dstRow = dstSlices[img]; 198 for (row = 0; row < srcHeight; row++) { 199 const GLvoid *src = _mesa_image_address(dims, srcPacking, 200 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); 201 _mesa_unpack_depth_span(ctx, srcWidth, 202 GL_UNSIGNED_INT, (GLuint *) dstRow, 203 depthScale, srcType, src, srcPacking); 204 dstRow += dstRowStride; 205 } 206 } 207 } 208 return GL_TRUE; 209} 210 211 212/** 213 * Store a 24-bit integer depth component texture image. 214 */ 215static GLboolean 216_mesa_texstore_z24_x8(TEXSTORE_PARAMS) 217{ 218 const GLuint depthScale = 0xffffff; 219 220 (void) dims; 221 assert(dstFormat == MESA_FORMAT_X8_UINT_Z24_UNORM); 222 223 { 224 /* general path */ 225 GLint img, row; 226 for (img = 0; img < srcDepth; img++) { 227 GLubyte *dstRow = dstSlices[img]; 228 for (row = 0; row < srcHeight; row++) { 229 const GLvoid *src = _mesa_image_address(dims, srcPacking, 230 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); 231 GLuint *dst = (GLuint *) dstRow; 232 GLint i; 233 _mesa_unpack_depth_span(ctx, srcWidth, 234 GL_UNSIGNED_INT, dst, 235 depthScale, srcType, src, srcPacking); 236 for (i = 0; i < srcWidth; i++) 237 dst[i] <<= 8; 238 dstRow += dstRowStride; 239 } 240 } 241 } 242 return GL_TRUE; 243} 244 245 246/** 247 * Store a 16-bit integer depth component texture image. 248 */ 249static GLboolean 250_mesa_texstore_z16(TEXSTORE_PARAMS) 251{ 252 const GLuint depthScale = 0xffff; 253 (void) dims; 254 assert(dstFormat == MESA_FORMAT_Z_UNORM16); 255 assert(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort)); 256 257 { 258 /* general path */ 259 GLint img, row; 260 for (img = 0; img < srcDepth; img++) { 261 GLubyte *dstRow = dstSlices[img]; 262 for (row = 0; row < srcHeight; row++) { 263 const GLvoid *src = _mesa_image_address(dims, srcPacking, 264 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); 265 GLushort *dst16 = (GLushort *) dstRow; 266 _mesa_unpack_depth_span(ctx, srcWidth, 267 GL_UNSIGNED_SHORT, dst16, depthScale, 268 srcType, src, srcPacking); 269 dstRow += dstRowStride; 270 } 271 } 272 } 273 return GL_TRUE; 274} 275 276 277/** 278 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV. 279 */ 280static GLboolean 281_mesa_texstore_ycbcr(TEXSTORE_PARAMS) 282{ 283 const GLboolean littleEndian = _mesa_little_endian(); 284 285 (void) ctx; (void) dims; (void) baseInternalFormat; 286 287 assert((dstFormat == MESA_FORMAT_YCBCR) || 288 (dstFormat == MESA_FORMAT_YCBCR_REV)); 289 assert(_mesa_get_format_bytes(dstFormat) == 2); 290 assert(ctx->Extensions.MESA_ycbcr_texture); 291 assert(srcFormat == GL_YCBCR_MESA); 292 assert((srcType == GL_UNSIGNED_SHORT_8_8_MESA) || 293 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA)); 294 assert(baseInternalFormat == GL_YCBCR_MESA); 295 296 /* always just memcpy since no pixel transfer ops apply */ 297 _mesa_memcpy_texture(ctx, dims, 298 dstFormat, 299 dstRowStride, dstSlices, 300 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 301 srcAddr, srcPacking); 302 303 /* Check if we need byte swapping */ 304 /* XXX the logic here _might_ be wrong */ 305 if (srcPacking->SwapBytes ^ 306 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^ 307 (dstFormat == MESA_FORMAT_YCBCR_REV) ^ 308 !littleEndian) { 309 GLint img, row; 310 for (img = 0; img < srcDepth; img++) { 311 GLubyte *dstRow = dstSlices[img]; 312 for (row = 0; row < srcHeight; row++) { 313 _mesa_swap2((GLushort *) dstRow, srcWidth); 314 dstRow += dstRowStride; 315 } 316 } 317 } 318 return GL_TRUE; 319} 320 321 322/** 323 * Store a combined depth/stencil texture image. 324 */ 325static GLboolean 326_mesa_texstore_z24_s8(TEXSTORE_PARAMS) 327{ 328 const GLuint depthScale = 0xffffff; 329 const GLint srcRowStride 330 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); 331 GLint img, row; 332 GLuint *depth = malloc(srcWidth * sizeof(GLuint)); 333 GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte)); 334 335 assert(dstFormat == MESA_FORMAT_S8_UINT_Z24_UNORM); 336 assert(srcFormat == GL_DEPTH_STENCIL_EXT || 337 srcFormat == GL_DEPTH_COMPONENT || 338 srcFormat == GL_STENCIL_INDEX); 339 assert(srcFormat != GL_DEPTH_STENCIL_EXT || 340 srcType == GL_UNSIGNED_INT_24_8_EXT || 341 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); 342 343 if (!depth || !stencil) { 344 free(depth); 345 free(stencil); 346 return GL_FALSE; 347 } 348 349 /* In case we only upload depth we need to preserve the stencil */ 350 for (img = 0; img < srcDepth; img++) { 351 GLuint *dstRow = (GLuint *) dstSlices[img]; 352 const GLubyte *src 353 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, 354 srcWidth, srcHeight, 355 srcFormat, srcType, 356 img, 0, 0); 357 for (row = 0; row < srcHeight; row++) { 358 GLint i; 359 GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE; 360 361 if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */ 362 keepstencil = GL_TRUE; 363 } 364 else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */ 365 keepdepth = GL_TRUE; 366 } 367 368 if (keepdepth == GL_FALSE) 369 /* the 24 depth bits will be in the low position: */ 370 _mesa_unpack_depth_span(ctx, srcWidth, 371 GL_UNSIGNED_INT, /* dst type */ 372 keepstencil ? depth : dstRow, /* dst addr */ 373 depthScale, 374 srcType, src, srcPacking); 375 376 if (keepstencil == GL_FALSE) 377 /* get the 8-bit stencil values */ 378 _mesa_unpack_stencil_span(ctx, srcWidth, 379 GL_UNSIGNED_BYTE, /* dst type */ 380 stencil, /* dst addr */ 381 srcType, src, srcPacking, 382 ctx->_ImageTransferState); 383 384 for (i = 0; i < srcWidth; i++) { 385 if (keepstencil) 386 dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF); 387 else 388 dstRow[i] = (dstRow[i] & 0xFFFFFF00) | (stencil[i] & 0xFF); 389 } 390 src += srcRowStride; 391 dstRow += dstRowStride / sizeof(GLuint); 392 } 393 } 394 395 free(depth); 396 free(stencil); 397 return GL_TRUE; 398} 399 400 401/** 402 * Store a combined depth/stencil texture image. 403 */ 404static GLboolean 405_mesa_texstore_s8_z24(TEXSTORE_PARAMS) 406{ 407 const GLuint depthScale = 0xffffff; 408 const GLint srcRowStride 409 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); 410 GLint img, row; 411 GLuint *depth; 412 GLubyte *stencil; 413 414 assert(dstFormat == MESA_FORMAT_Z24_UNORM_S8_UINT); 415 assert(srcFormat == GL_DEPTH_STENCIL_EXT || 416 srcFormat == GL_DEPTH_COMPONENT || 417 srcFormat == GL_STENCIL_INDEX); 418 assert(srcFormat != GL_DEPTH_STENCIL_EXT || 419 srcType == GL_UNSIGNED_INT_24_8_EXT || 420 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); 421 422 depth = malloc(srcWidth * sizeof(GLuint)); 423 stencil = malloc(srcWidth * sizeof(GLubyte)); 424 425 if (!depth || !stencil) { 426 free(depth); 427 free(stencil); 428 return GL_FALSE; 429 } 430 431 for (img = 0; img < srcDepth; img++) { 432 GLuint *dstRow = (GLuint *) dstSlices[img]; 433 const GLubyte *src 434 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, 435 srcWidth, srcHeight, 436 srcFormat, srcType, 437 img, 0, 0); 438 for (row = 0; row < srcHeight; row++) { 439 GLint i; 440 GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE; 441 442 if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */ 443 keepstencil = GL_TRUE; 444 } 445 else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */ 446 keepdepth = GL_TRUE; 447 } 448 449 if (keepdepth == GL_FALSE) 450 /* the 24 depth bits will be in the low position: */ 451 _mesa_unpack_depth_span(ctx, srcWidth, 452 GL_UNSIGNED_INT, /* dst type */ 453 keepstencil ? depth : dstRow, /* dst addr */ 454 depthScale, 455 srcType, src, srcPacking); 456 457 if (keepstencil == GL_FALSE) 458 /* get the 8-bit stencil values */ 459 _mesa_unpack_stencil_span(ctx, srcWidth, 460 GL_UNSIGNED_BYTE, /* dst type */ 461 stencil, /* dst addr */ 462 srcType, src, srcPacking, 463 ctx->_ImageTransferState); 464 465 /* merge stencil values into depth values */ 466 for (i = 0; i < srcWidth; i++) { 467 if (keepstencil) 468 dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000); 469 else 470 dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24); 471 472 } 473 src += srcRowStride; 474 dstRow += dstRowStride / sizeof(GLuint); 475 } 476 } 477 478 free(depth); 479 free(stencil); 480 481 return GL_TRUE; 482} 483 484 485/** 486 * Store simple 8-bit/value stencil texture data. 487 */ 488static GLboolean 489_mesa_texstore_s8(TEXSTORE_PARAMS) 490{ 491 assert(dstFormat == MESA_FORMAT_S_UINT8); 492 assert(srcFormat == GL_STENCIL_INDEX); 493 494 { 495 const GLint srcRowStride 496 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); 497 GLint img, row; 498 GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte)); 499 500 if (!stencil) 501 return GL_FALSE; 502 503 for (img = 0; img < srcDepth; img++) { 504 GLubyte *dstRow = dstSlices[img]; 505 const GLubyte *src 506 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, 507 srcWidth, srcHeight, 508 srcFormat, srcType, 509 img, 0, 0); 510 for (row = 0; row < srcHeight; row++) { 511 GLint i; 512 513 /* get the 8-bit stencil values */ 514 _mesa_unpack_stencil_span(ctx, srcWidth, 515 GL_UNSIGNED_BYTE, /* dst type */ 516 stencil, /* dst addr */ 517 srcType, src, srcPacking, 518 ctx->_ImageTransferState); 519 /* merge stencil values into depth values */ 520 for (i = 0; i < srcWidth; i++) 521 dstRow[i] = stencil[i]; 522 523 src += srcRowStride; 524 dstRow += dstRowStride / sizeof(GLubyte); 525 } 526 } 527 528 free(stencil); 529 } 530 531 return GL_TRUE; 532} 533 534 535static GLboolean 536_mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS) 537{ 538 GLint img, row; 539 const GLint srcRowStride 540 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) 541 / sizeof(uint64_t); 542 543 assert(dstFormat == MESA_FORMAT_Z32_FLOAT_S8X24_UINT); 544 assert(srcFormat == GL_DEPTH_STENCIL || 545 srcFormat == GL_DEPTH_COMPONENT || 546 srcFormat == GL_STENCIL_INDEX); 547 assert(srcFormat != GL_DEPTH_STENCIL || 548 srcType == GL_UNSIGNED_INT_24_8 || 549 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); 550 551 /* In case we only upload depth we need to preserve the stencil */ 552 for (img = 0; img < srcDepth; img++) { 553 uint64_t *dstRow = (uint64_t *) dstSlices[img]; 554 const uint64_t *src 555 = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr, 556 srcWidth, srcHeight, 557 srcFormat, srcType, 558 img, 0, 0); 559 for (row = 0; row < srcHeight; row++) { 560 /* The unpack functions with: 561 * dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV 562 * only write their own dword, so the other dword (stencil 563 * or depth) is preserved. */ 564 if (srcFormat != GL_STENCIL_INDEX) 565 _mesa_unpack_depth_span(ctx, srcWidth, 566 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */ 567 dstRow, /* dst addr */ 568 ~0U, srcType, src, srcPacking); 569 570 if (srcFormat != GL_DEPTH_COMPONENT) 571 _mesa_unpack_stencil_span(ctx, srcWidth, 572 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */ 573 dstRow, /* dst addr */ 574 srcType, src, srcPacking, 575 ctx->_ImageTransferState); 576 577 src += srcRowStride; 578 dstRow += dstRowStride / sizeof(uint64_t); 579 } 580 } 581 return GL_TRUE; 582} 583 584static GLboolean 585texstore_depth_stencil(TEXSTORE_PARAMS) 586{ 587 static StoreTexImageFunc table[MESA_FORMAT_COUNT]; 588 static GLboolean initialized = GL_FALSE; 589 590 if (!initialized) { 591 memset(table, 0, sizeof table); 592 593 table[MESA_FORMAT_S8_UINT_Z24_UNORM] = _mesa_texstore_z24_s8; 594 table[MESA_FORMAT_Z24_UNORM_S8_UINT] = _mesa_texstore_s8_z24; 595 table[MESA_FORMAT_Z_UNORM16] = _mesa_texstore_z16; 596 table[MESA_FORMAT_Z24_UNORM_X8_UINT] = _mesa_texstore_x8_z24; 597 table[MESA_FORMAT_X8_UINT_Z24_UNORM] = _mesa_texstore_z24_x8; 598 table[MESA_FORMAT_Z_UNORM32] = _mesa_texstore_z32; 599 table[MESA_FORMAT_S_UINT8] = _mesa_texstore_s8; 600 table[MESA_FORMAT_Z_FLOAT32] = _mesa_texstore_z32; 601 table[MESA_FORMAT_Z32_FLOAT_S8X24_UINT] = _mesa_texstore_z32f_x24s8; 602 603 initialized = GL_TRUE; 604 } 605 606 assert(table[dstFormat]); 607 return table[dstFormat](ctx, dims, baseInternalFormat, 608 dstFormat, dstRowStride, dstSlices, 609 srcWidth, srcHeight, srcDepth, 610 srcFormat, srcType, srcAddr, srcPacking); 611} 612 613static GLboolean 614texstore_compressed(TEXSTORE_PARAMS) 615{ 616 static StoreTexImageFunc table[MESA_FORMAT_COUNT]; 617 static GLboolean initialized = GL_FALSE; 618 619 if (!initialized) { 620 memset(table, 0, sizeof table); 621 622 table[MESA_FORMAT_SRGB_DXT1] = _mesa_texstore_rgb_dxt1; 623 table[MESA_FORMAT_SRGBA_DXT1] = _mesa_texstore_rgba_dxt1; 624 table[MESA_FORMAT_SRGBA_DXT3] = _mesa_texstore_rgba_dxt3; 625 table[MESA_FORMAT_SRGBA_DXT5] = _mesa_texstore_rgba_dxt5; 626 table[MESA_FORMAT_RGB_FXT1] = _mesa_texstore_rgb_fxt1; 627 table[MESA_FORMAT_RGBA_FXT1] = _mesa_texstore_rgba_fxt1; 628 table[MESA_FORMAT_RGB_DXT1] = _mesa_texstore_rgb_dxt1; 629 table[MESA_FORMAT_RGBA_DXT1] = _mesa_texstore_rgba_dxt1; 630 table[MESA_FORMAT_RGBA_DXT3] = _mesa_texstore_rgba_dxt3; 631 table[MESA_FORMAT_RGBA_DXT5] = _mesa_texstore_rgba_dxt5; 632 table[MESA_FORMAT_R_RGTC1_UNORM] = _mesa_texstore_red_rgtc1; 633 table[MESA_FORMAT_R_RGTC1_SNORM] = _mesa_texstore_signed_red_rgtc1; 634 table[MESA_FORMAT_RG_RGTC2_UNORM] = _mesa_texstore_rg_rgtc2; 635 table[MESA_FORMAT_RG_RGTC2_SNORM] = _mesa_texstore_signed_rg_rgtc2; 636 table[MESA_FORMAT_L_LATC1_UNORM] = _mesa_texstore_red_rgtc1; 637 table[MESA_FORMAT_L_LATC1_SNORM] = _mesa_texstore_signed_red_rgtc1; 638 table[MESA_FORMAT_LA_LATC2_UNORM] = _mesa_texstore_rg_rgtc2; 639 table[MESA_FORMAT_LA_LATC2_SNORM] = _mesa_texstore_signed_rg_rgtc2; 640 table[MESA_FORMAT_ETC1_RGB8] = _mesa_texstore_etc1_rgb8; 641 table[MESA_FORMAT_ETC2_RGB8] = _mesa_texstore_etc2_rgb8; 642 table[MESA_FORMAT_ETC2_SRGB8] = _mesa_texstore_etc2_srgb8; 643 table[MESA_FORMAT_ETC2_RGBA8_EAC] = _mesa_texstore_etc2_rgba8_eac; 644 table[MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC] = _mesa_texstore_etc2_srgb8_alpha8_eac; 645 table[MESA_FORMAT_ETC2_R11_EAC] = _mesa_texstore_etc2_r11_eac; 646 table[MESA_FORMAT_ETC2_RG11_EAC] = _mesa_texstore_etc2_rg11_eac; 647 table[MESA_FORMAT_ETC2_SIGNED_R11_EAC] = _mesa_texstore_etc2_signed_r11_eac; 648 table[MESA_FORMAT_ETC2_SIGNED_RG11_EAC] = _mesa_texstore_etc2_signed_rg11_eac; 649 table[MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1] = 650 _mesa_texstore_etc2_rgb8_punchthrough_alpha1; 651 table[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1] = 652 _mesa_texstore_etc2_srgb8_punchthrough_alpha1; 653 654 table[MESA_FORMAT_BPTC_RGBA_UNORM] = 655 _mesa_texstore_bptc_rgba_unorm; 656 table[MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM] = 657 _mesa_texstore_bptc_rgba_unorm; 658 table[MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT] = 659 _mesa_texstore_bptc_rgb_signed_float; 660 table[MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT] = 661 _mesa_texstore_bptc_rgb_unsigned_float; 662 663 initialized = GL_TRUE; 664 } 665 666 assert(table[dstFormat]); 667 return table[dstFormat](ctx, dims, baseInternalFormat, 668 dstFormat, dstRowStride, dstSlices, 669 srcWidth, srcHeight, srcDepth, 670 srcFormat, srcType, srcAddr, srcPacking); 671} 672 673static GLboolean 674texstore_rgba(TEXSTORE_PARAMS) 675{ 676 void *tempImage = NULL; 677 int img; 678 GLubyte *src, *dst; 679 uint8_t rebaseSwizzle[4]; 680 bool transferOpsDone = false; 681 682 /* We have to handle MESA_FORMAT_YCBCR manually because it is a special case 683 * and _mesa_format_convert does not support it. In this case the we only 684 * allow conversions between YCBCR formats and it is mostly a memcpy. 685 */ 686 if (dstFormat == MESA_FORMAT_YCBCR || dstFormat == MESA_FORMAT_YCBCR_REV) { 687 return _mesa_texstore_ycbcr(ctx, dims, baseInternalFormat, 688 dstFormat, dstRowStride, dstSlices, 689 srcWidth, srcHeight, srcDepth, 690 srcFormat, srcType, srcAddr, 691 srcPacking); 692 } 693 694 /* We have to deal with GL_COLOR_INDEX manually because 695 * _mesa_format_convert does not handle this format. So what we do here is 696 * convert it to RGBA ubyte first and then convert from that to dst as usual. 697 */ 698 if (srcFormat == GL_COLOR_INDEX) { 699 /* Notice that this will already handle byte swapping if necessary */ 700 tempImage = 701 _mesa_unpack_color_index_to_rgba_ubyte(ctx, dims, 702 srcAddr, srcFormat, srcType, 703 srcWidth, srcHeight, srcDepth, 704 srcPacking, 705 ctx->_ImageTransferState); 706 if (!tempImage) 707 return GL_FALSE; 708 709 /* _mesa_unpack_color_index_to_rgba_ubyte has handled transferops 710 * if needed. 711 */ 712 transferOpsDone = true; 713 714 /* Now we only have to adjust our src info for a conversion from 715 * the RGBA ubyte and then we continue as usual. 716 */ 717 srcAddr = tempImage; 718 srcFormat = GL_RGBA; 719 srcType = GL_UNSIGNED_BYTE; 720 } else if (srcPacking->SwapBytes) { 721 /* We have to handle byte-swapping scenarios before calling 722 * _mesa_format_convert 723 */ 724 GLint swapSize = _mesa_sizeof_packed_type(srcType); 725 if (swapSize == 2 || swapSize == 4) { 726 int imageStride = _mesa_image_image_stride(srcPacking, srcWidth, 727 srcHeight, srcFormat, 728 srcType); 729 int bufferSize = imageStride * srcDepth; 730 int layer; 731 const uint8_t *src; 732 uint8_t *dst; 733 734 tempImage = malloc(bufferSize); 735 if (!tempImage) 736 return GL_FALSE; 737 src = srcAddr; 738 dst = tempImage; 739 for (layer = 0; layer < srcDepth; layer++) { 740 _mesa_swap_bytes_2d_image(srcFormat, srcType, 741 srcPacking, 742 srcWidth, srcHeight, 743 dst, src); 744 src += imageStride; 745 dst += imageStride; 746 } 747 srcAddr = tempImage; 748 } 749 } 750 751 int srcRowStride = 752 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); 753 754 uint32_t srcMesaFormat = 755 _mesa_format_from_format_and_type(srcFormat, srcType); 756 757 dstFormat = _mesa_get_srgb_format_linear(dstFormat); 758 759 /* If we have transferOps then we need to convert to RGBA float first, 760 then apply transferOps, then do the conversion to dst 761 */ 762 void *tempRGBA = NULL; 763 if (!transferOpsDone && 764 _mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) { 765 /* Allocate RGBA float image */ 766 int elementCount = srcWidth * srcHeight * srcDepth; 767 tempRGBA = malloc(4 * elementCount * sizeof(float)); 768 if (!tempRGBA) { 769 free(tempImage); 770 return GL_FALSE; 771 } 772 773 /* Convert from src to RGBA float */ 774 src = (GLubyte *) srcAddr; 775 dst = (GLubyte *) tempRGBA; 776 for (img = 0; img < srcDepth; img++) { 777 _mesa_format_convert(dst, RGBA32_FLOAT, 4 * srcWidth * sizeof(float), 778 src, srcMesaFormat, srcRowStride, 779 srcWidth, srcHeight, NULL); 780 src += srcHeight * srcRowStride; 781 dst += srcHeight * 4 * srcWidth * sizeof(float); 782 } 783 784 /* Apply transferOps */ 785 _mesa_apply_rgba_transfer_ops(ctx, ctx->_ImageTransferState, elementCount, 786 (float(*)[4]) tempRGBA); 787 788 /* Now we have to adjust our src info for a conversion from 789 * the RGBA float image and then we continue as usual. 790 */ 791 srcAddr = tempRGBA; 792 srcFormat = GL_RGBA; 793 srcType = GL_FLOAT; 794 srcRowStride = srcWidth * 4 * sizeof(float); 795 srcMesaFormat = RGBA32_FLOAT; 796 srcPacking = &ctx->DefaultPacking; 797 } 798 799 src = (GLubyte *) 800 _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, 801 srcFormat, srcType, 0, 0, 0); 802 803 bool needRebase; 804 if (_mesa_get_format_base_format(dstFormat) != baseInternalFormat) { 805 needRebase = 806 _mesa_compute_rgba2base2rgba_component_mapping(baseInternalFormat, 807 rebaseSwizzle); 808 } else { 809 needRebase = false; 810 } 811 812 for (img = 0; img < srcDepth; img++) { 813 _mesa_format_convert(dstSlices[img], dstFormat, dstRowStride, 814 src, srcMesaFormat, srcRowStride, 815 srcWidth, srcHeight, 816 needRebase ? rebaseSwizzle : NULL); 817 src += srcHeight * srcRowStride; 818 } 819 820 free(tempImage); 821 free(tempRGBA); 822 823 return GL_TRUE; 824} 825 826GLboolean 827_mesa_texstore_needs_transfer_ops(struct gl_context *ctx, 828 GLenum baseInternalFormat, 829 mesa_format dstFormat) 830{ 831 GLenum dstType; 832 833 /* There are different rules depending on the base format. */ 834 switch (baseInternalFormat) { 835 case GL_DEPTH_COMPONENT: 836 case GL_DEPTH_STENCIL: 837 return ctx->Pixel.DepthScale != 1.0f || 838 ctx->Pixel.DepthBias != 0.0f; 839 840 case GL_STENCIL_INDEX: 841 return GL_FALSE; 842 843 default: 844 /* Color formats. 845 * Pixel transfer ops (scale, bias, table lookup) do not apply 846 * to integer formats. 847 */ 848 dstType = _mesa_get_format_datatype(dstFormat); 849 850 return dstType != GL_INT && dstType != GL_UNSIGNED_INT && 851 ctx->_ImageTransferState; 852 } 853} 854 855 856GLboolean 857_mesa_texstore_can_use_memcpy(struct gl_context *ctx, 858 GLenum baseInternalFormat, mesa_format dstFormat, 859 GLenum srcFormat, GLenum srcType, 860 const struct gl_pixelstore_attrib *srcPacking) 861{ 862 if (_mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) { 863 return GL_FALSE; 864 } 865 866 /* The base internal format and the base Mesa format must match. */ 867 if (baseInternalFormat != _mesa_get_format_base_format(dstFormat)) { 868 return GL_FALSE; 869 } 870 871 /* The Mesa format must match the input format and type. */ 872 if (!_mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 873 srcPacking->SwapBytes, NULL)) { 874 return GL_FALSE; 875 } 876 877 /* Depth texture data needs clamping in following cases: 878 * - Floating point dstFormat with signed srcType: clamp to [0.0, 1.0]. 879 * - Fixed point dstFormat with signed srcType: clamp to [0, 2^n -1]. 880 * 881 * All the cases except one (float dstFormat with float srcType) are ruled 882 * out by _mesa_format_matches_format_and_type() check above. Handle the 883 * remaining case here. 884 */ 885 if ((baseInternalFormat == GL_DEPTH_COMPONENT || 886 baseInternalFormat == GL_DEPTH_STENCIL) && 887 (srcType == GL_FLOAT || 888 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV)) { 889 return GL_FALSE; 890 } 891 892 return GL_TRUE; 893} 894 895static GLboolean 896_mesa_texstore_memcpy(TEXSTORE_PARAMS) 897{ 898 if (!_mesa_texstore_can_use_memcpy(ctx, baseInternalFormat, dstFormat, 899 srcFormat, srcType, srcPacking)) { 900 return GL_FALSE; 901 } 902 903 _mesa_memcpy_texture(ctx, dims, 904 dstFormat, 905 dstRowStride, dstSlices, 906 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 907 srcAddr, srcPacking); 908 return GL_TRUE; 909} 910 911 912/** 913 * Store user data into texture memory. 914 * Called via glTex[Sub]Image1/2/3D() 915 * \return GL_TRUE for success, GL_FALSE for failure (out of memory). 916 */ 917GLboolean 918_mesa_texstore(TEXSTORE_PARAMS) 919{ 920 if (_mesa_texstore_memcpy(ctx, dims, baseInternalFormat, 921 dstFormat, 922 dstRowStride, dstSlices, 923 srcWidth, srcHeight, srcDepth, 924 srcFormat, srcType, srcAddr, srcPacking)) { 925 return GL_TRUE; 926 } 927 928 if (_mesa_is_depth_or_stencil_format(baseInternalFormat)) { 929 return texstore_depth_stencil(ctx, dims, baseInternalFormat, 930 dstFormat, dstRowStride, dstSlices, 931 srcWidth, srcHeight, srcDepth, 932 srcFormat, srcType, srcAddr, srcPacking); 933 } else if (_mesa_is_format_compressed(dstFormat)) { 934 return texstore_compressed(ctx, dims, baseInternalFormat, 935 dstFormat, dstRowStride, dstSlices, 936 srcWidth, srcHeight, srcDepth, 937 srcFormat, srcType, srcAddr, srcPacking); 938 } else { 939 return texstore_rgba(ctx, dims, baseInternalFormat, 940 dstFormat, dstRowStride, dstSlices, 941 srcWidth, srcHeight, srcDepth, 942 srcFormat, srcType, srcAddr, srcPacking); 943 } 944} 945 946 947/** 948 * Normally, we'll only _write_ texel data to a texture when we map it. 949 * But if the user is providing depth or stencil values and the texture 950 * image is a combined depth/stencil format, we'll actually read from 951 * the texture buffer too (in order to insert the depth or stencil values. 952 * \param userFormat the user-provided image format 953 * \param texFormat the destination texture format 954 */ 955static GLbitfield 956get_read_write_mode(GLenum userFormat, mesa_format texFormat) 957{ 958 if ((userFormat == GL_STENCIL_INDEX || userFormat == GL_DEPTH_COMPONENT) 959 && _mesa_get_format_base_format(texFormat) == GL_DEPTH_STENCIL) 960 return GL_MAP_READ_BIT | GL_MAP_WRITE_BIT; 961 else 962 return GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT; 963} 964 965 966/** 967 * Helper function for storing 1D, 2D, 3D whole and subimages into texture 968 * memory. 969 * The source of the image data may be user memory or a PBO. In the later 970 * case, we'll map the PBO, copy from it, then unmap it. 971 */ 972static void 973store_texsubimage(struct gl_context *ctx, 974 struct gl_texture_image *texImage, 975 GLint xoffset, GLint yoffset, GLint zoffset, 976 GLint width, GLint height, GLint depth, 977 GLenum format, GLenum type, const GLvoid *pixels, 978 const struct gl_pixelstore_attrib *packing, 979 const char *caller) 980 981{ 982 const GLbitfield mapMode = get_read_write_mode(format, texImage->TexFormat); 983 const GLenum target = texImage->TexObject->Target; 984 GLboolean success = GL_FALSE; 985 GLuint dims, slice, numSlices = 1, sliceOffset = 0; 986 GLint srcImageStride = 0; 987 const GLubyte *src; 988 989 assert(xoffset + width <= texImage->Width); 990 assert(yoffset + height <= texImage->Height); 991 assert(zoffset + depth <= texImage->Depth); 992 993 switch (target) { 994 case GL_TEXTURE_1D: 995 dims = 1; 996 break; 997 case GL_TEXTURE_2D_ARRAY: 998 case GL_TEXTURE_CUBE_MAP_ARRAY: 999 case GL_TEXTURE_3D: 1000 dims = 3; 1001 break; 1002 default: 1003 dims = 2; 1004 } 1005 1006 /* get pointer to src pixels (may be in a pbo which we'll map here) */ 1007 src = (const GLubyte *) 1008 _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, 1009 format, type, pixels, packing, caller); 1010 if (!src) 1011 return; 1012 1013 /* compute slice info (and do some sanity checks) */ 1014 switch (target) { 1015 case GL_TEXTURE_2D: 1016 case GL_TEXTURE_2D_MULTISAMPLE: 1017 case GL_TEXTURE_RECTANGLE: 1018 case GL_TEXTURE_CUBE_MAP: 1019 case GL_TEXTURE_EXTERNAL_OES: 1020 /* one image slice, nothing special needs to be done */ 1021 break; 1022 case GL_TEXTURE_1D: 1023 assert(height == 1); 1024 assert(depth == 1); 1025 assert(yoffset == 0); 1026 assert(zoffset == 0); 1027 break; 1028 case GL_TEXTURE_1D_ARRAY: 1029 assert(depth == 1); 1030 assert(zoffset == 0); 1031 numSlices = height; 1032 sliceOffset = yoffset; 1033 height = 1; 1034 yoffset = 0; 1035 srcImageStride = _mesa_image_row_stride(packing, width, format, type); 1036 break; 1037 case GL_TEXTURE_2D_ARRAY: 1038 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1039 numSlices = depth; 1040 sliceOffset = zoffset; 1041 depth = 1; 1042 zoffset = 0; 1043 srcImageStride = _mesa_image_image_stride(packing, width, height, 1044 format, type); 1045 break; 1046 case GL_TEXTURE_3D: 1047 /* we'll store 3D images as a series of slices */ 1048 numSlices = depth; 1049 sliceOffset = zoffset; 1050 srcImageStride = _mesa_image_image_stride(packing, width, height, 1051 format, type); 1052 break; 1053 case GL_TEXTURE_CUBE_MAP_ARRAY: 1054 numSlices = depth; 1055 sliceOffset = zoffset; 1056 srcImageStride = _mesa_image_image_stride(packing, width, height, 1057 format, type); 1058 break; 1059 default: 1060 _mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()", 1061 target); 1062 return; 1063 } 1064 1065 assert(numSlices == 1 || srcImageStride != 0); 1066 1067 for (slice = 0; slice < numSlices; slice++) { 1068 GLubyte *dstMap; 1069 GLint dstRowStride; 1070 1071 ctx->Driver.MapTextureImage(ctx, texImage, 1072 slice + sliceOffset, 1073 xoffset, yoffset, width, height, 1074 mapMode, &dstMap, &dstRowStride); 1075 if (dstMap) { 1076 /* Note: we're only storing a 2D (or 1D) slice at a time but we need 1077 * to pass the right 'dims' value so that GL_UNPACK_SKIP_IMAGES is 1078 * used for 3D images. 1079 */ 1080 success = _mesa_texstore(ctx, dims, texImage->_BaseFormat, 1081 texImage->TexFormat, 1082 dstRowStride, 1083 &dstMap, 1084 width, height, 1, /* w, h, d */ 1085 format, type, src, packing); 1086 1087 ctx->Driver.UnmapTextureImage(ctx, texImage, slice + sliceOffset); 1088 } 1089 1090 src += srcImageStride; 1091 1092 if (!success) 1093 break; 1094 } 1095 1096 if (!success) 1097 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); 1098 1099 _mesa_unmap_teximage_pbo(ctx, packing); 1100} 1101 1102 1103 1104/** 1105 * Fallback code for ctx->Driver.TexImage(). 1106 * Basically, allocate storage for the texture image, then copy the 1107 * user's image into it. 1108 */ 1109void 1110_mesa_store_teximage(struct gl_context *ctx, 1111 GLuint dims, 1112 struct gl_texture_image *texImage, 1113 GLenum format, GLenum type, const GLvoid *pixels, 1114 const struct gl_pixelstore_attrib *packing) 1115{ 1116 assert(dims == 1 || dims == 2 || dims == 3); 1117 1118 if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0) 1119 return; 1120 1121 /* allocate storage for texture data */ 1122 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) { 1123 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims); 1124 return; 1125 } 1126 1127 store_texsubimage(ctx, texImage, 1128 0, 0, 0, texImage->Width, texImage->Height, texImage->Depth, 1129 format, type, pixels, packing, "glTexImage"); 1130} 1131 1132 1133/* 1134 * Fallback for Driver.TexSubImage(). 1135 */ 1136void 1137_mesa_store_texsubimage(struct gl_context *ctx, GLuint dims, 1138 struct gl_texture_image *texImage, 1139 GLint xoffset, GLint yoffset, GLint zoffset, 1140 GLint width, GLint height, GLint depth, 1141 GLenum format, GLenum type, const void *pixels, 1142 const struct gl_pixelstore_attrib *packing) 1143{ 1144 store_texsubimage(ctx, texImage, 1145 xoffset, yoffset, zoffset, width, height, depth, 1146 format, type, pixels, packing, "glTexSubImage"); 1147} 1148 1149static void 1150clear_image_to_zero(GLubyte *dstMap, GLint dstRowStride, 1151 GLsizei width, GLsizei height, 1152 GLsizei clearValueSize) 1153{ 1154 GLsizei y; 1155 1156 for (y = 0; y < height; y++) { 1157 memset(dstMap, 0, clearValueSize * width); 1158 dstMap += dstRowStride; 1159 } 1160} 1161 1162static void 1163clear_image_to_value(GLubyte *dstMap, GLint dstRowStride, 1164 GLsizei width, GLsizei height, 1165 const GLvoid *clearValue, 1166 GLsizei clearValueSize) 1167{ 1168 GLsizei y, x; 1169 1170 for (y = 0; y < height; y++) { 1171 for (x = 0; x < width; x++) { 1172 memcpy(dstMap, clearValue, clearValueSize); 1173 dstMap += clearValueSize; 1174 } 1175 dstMap += dstRowStride - clearValueSize * width; 1176 } 1177} 1178 1179/* 1180 * Fallback for Driver.ClearTexSubImage(). 1181 */ 1182void 1183_mesa_store_cleartexsubimage(struct gl_context *ctx, 1184 struct gl_texture_image *texImage, 1185 GLint xoffset, GLint yoffset, GLint zoffset, 1186 GLsizei width, GLsizei height, GLsizei depth, 1187 const GLvoid *clearValue) 1188{ 1189 GLubyte *dstMap; 1190 GLint dstRowStride; 1191 GLsizeiptr clearValueSize; 1192 GLsizei z; 1193 1194 clearValueSize = _mesa_get_format_bytes(texImage->TexFormat); 1195 1196 for (z = 0; z < depth; z++) { 1197 ctx->Driver.MapTextureImage(ctx, texImage, 1198 z + zoffset, xoffset, yoffset, 1199 width, height, 1200 GL_MAP_WRITE_BIT, 1201 &dstMap, &dstRowStride); 1202 if (dstMap == NULL) { 1203 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClearTex*Image"); 1204 return; 1205 } 1206 1207 if (clearValue) { 1208 clear_image_to_value(dstMap, dstRowStride, 1209 width, height, 1210 clearValue, 1211 clearValueSize); 1212 } else { 1213 clear_image_to_zero(dstMap, dstRowStride, 1214 width, height, 1215 clearValueSize); 1216 } 1217 1218 ctx->Driver.UnmapTextureImage(ctx, texImage, z + zoffset); 1219 } 1220} 1221 1222/** 1223 * Fallback for Driver.CompressedTexImage() 1224 */ 1225void 1226_mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims, 1227 struct gl_texture_image *texImage, 1228 GLsizei imageSize, const GLvoid *data) 1229{ 1230 /* only 2D and 3D compressed images are supported at this time */ 1231 if (dims == 1) { 1232 _mesa_problem(ctx, "Unexpected glCompressedTexImage1D call"); 1233 return; 1234 } 1235 1236 /* This is pretty simple, because unlike the general texstore path we don't 1237 * have to worry about the usual image unpacking or image transfer 1238 * operations. 1239 */ 1240 assert(texImage); 1241 assert(texImage->Width > 0); 1242 assert(texImage->Height > 0); 1243 assert(texImage->Depth > 0); 1244 1245 /* allocate storage for texture data */ 1246 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) { 1247 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage%uD", dims); 1248 return; 1249 } 1250 1251 ctx->Driver.CompressedTexSubImage(ctx, dims, texImage, 1252 0, 0, 0, 1253 texImage->Width, texImage->Height, texImage->Depth, 1254 texImage->TexFormat, 1255 imageSize, data); 1256} 1257 1258 1259/** 1260 * Compute compressed_pixelstore parameters for copying compressed 1261 * texture data. 1262 * \param dims number of texture image dimensions: 1, 2 or 3 1263 * \param texFormat the compressed texture format 1264 * \param width, height, depth size of image to copy 1265 * \param packing pixelstore parameters describing user-space image packing 1266 * \param store returns the compressed_pixelstore parameters 1267 */ 1268void 1269_mesa_compute_compressed_pixelstore(GLuint dims, mesa_format texFormat, 1270 GLsizei width, GLsizei height, 1271 GLsizei depth, 1272 const struct gl_pixelstore_attrib *packing, 1273 struct compressed_pixelstore *store) 1274{ 1275 GLuint bw, bh, bd; 1276 1277 _mesa_get_format_block_size_3d(texFormat, &bw, &bh, &bd); 1278 1279 store->SkipBytes = 0; 1280 store->TotalBytesPerRow = store->CopyBytesPerRow = 1281 _mesa_format_row_stride(texFormat, width); 1282 store->TotalRowsPerSlice = store->CopyRowsPerSlice = 1283 (height + bh - 1) / bh; 1284 store->CopySlices = (depth + bd - 1) / bd; 1285 1286 if (packing->CompressedBlockWidth && 1287 packing->CompressedBlockSize) { 1288 1289 bw = packing->CompressedBlockWidth; 1290 1291 if (packing->RowLength) { 1292 store->TotalBytesPerRow = packing->CompressedBlockSize * 1293 ((packing->RowLength + bw - 1) / bw); 1294 } 1295 1296 store->SkipBytes += 1297 packing->SkipPixels * packing->CompressedBlockSize / bw; 1298 } 1299 1300 if (dims > 1 && packing->CompressedBlockHeight && 1301 packing->CompressedBlockSize) { 1302 1303 bh = packing->CompressedBlockHeight; 1304 1305 store->SkipBytes += packing->SkipRows * store->TotalBytesPerRow / bh; 1306 store->CopyRowsPerSlice = (height + bh - 1) / bh; /* rows in blocks */ 1307 1308 if (packing->ImageHeight) { 1309 store->TotalRowsPerSlice = (packing->ImageHeight + bh - 1) / bh; 1310 } 1311 } 1312 1313 if (dims > 2 && packing->CompressedBlockDepth && 1314 packing->CompressedBlockSize) { 1315 1316 int bd = packing->CompressedBlockDepth; 1317 1318 store->SkipBytes += packing->SkipImages * store->TotalBytesPerRow * 1319 store->TotalRowsPerSlice / bd; 1320 } 1321} 1322 1323 1324/** 1325 * Fallback for Driver.CompressedTexSubImage() 1326 */ 1327void 1328_mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims, 1329 struct gl_texture_image *texImage, 1330 GLint xoffset, GLint yoffset, GLint zoffset, 1331 GLsizei width, GLsizei height, GLsizei depth, 1332 GLenum format, 1333 GLsizei imageSize, const GLvoid *data) 1334{ 1335 struct compressed_pixelstore store; 1336 GLint dstRowStride; 1337 GLint i, slice; 1338 GLubyte *dstMap; 1339 const GLubyte *src; 1340 1341 if (dims == 1) { 1342 _mesa_problem(ctx, "Unexpected 1D compressed texsubimage call"); 1343 return; 1344 } 1345 1346 _mesa_compute_compressed_pixelstore(dims, texImage->TexFormat, 1347 width, height, depth, 1348 &ctx->Unpack, &store); 1349 1350 /* get pointer to src pixels (may be in a pbo which we'll map here) */ 1351 data = _mesa_validate_pbo_compressed_teximage(ctx, dims, imageSize, data, 1352 &ctx->Unpack, 1353 "glCompressedTexSubImage"); 1354 if (!data) 1355 return; 1356 1357 src = (const GLubyte *) data + store.SkipBytes; 1358 1359 for (slice = 0; slice < store.CopySlices; slice++) { 1360 /* Map dest texture buffer */ 1361 ctx->Driver.MapTextureImage(ctx, texImage, slice + zoffset, 1362 xoffset, yoffset, width, height, 1363 GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT, 1364 &dstMap, &dstRowStride); 1365 1366 if (dstMap) { 1367 1368 /* copy rows of blocks */ 1369 if (dstRowStride == store.TotalBytesPerRow && 1370 dstRowStride == store.CopyBytesPerRow) { 1371 memcpy(dstMap, src, store.CopyBytesPerRow * store.CopyRowsPerSlice); 1372 src += store.CopyBytesPerRow * store.CopyRowsPerSlice; 1373 } 1374 else { 1375 for (i = 0; i < store.CopyRowsPerSlice; i++) { 1376 memcpy(dstMap, src, store.CopyBytesPerRow); 1377 dstMap += dstRowStride; 1378 src += store.TotalBytesPerRow; 1379 } 1380 } 1381 1382 ctx->Driver.UnmapTextureImage(ctx, texImage, slice + zoffset); 1383 1384 /* advance to next slice */ 1385 src += store.TotalBytesPerRow * (store.TotalRowsPerSlice 1386 - store.CopyRowsPerSlice); 1387 } 1388 else { 1389 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage%uD", 1390 dims); 1391 } 1392 } 1393 1394 _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack); 1395} 1396