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