14a49301eSmrg/* 24a49301eSmrg * Mesa 3-D graphics library 34a49301eSmrg * 44a49301eSmrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 54a49301eSmrg * Copyright (c) 2008-2009 VMware, Inc. 64a49301eSmrg * 74a49301eSmrg * Permission is hereby granted, free of charge, to any person obtaining a 84a49301eSmrg * copy of this software and associated documentation files (the "Software"), 94a49301eSmrg * to deal in the Software without restriction, including without limitation 104a49301eSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 114a49301eSmrg * and/or sell copies of the Software, and to permit persons to whom the 124a49301eSmrg * Software is furnished to do so, subject to the following conditions: 134a49301eSmrg * 144a49301eSmrg * The above copyright notice and this permission notice shall be included 154a49301eSmrg * in all copies or substantial portions of the Software. 164a49301eSmrg * 174a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 184a49301eSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 194a49301eSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE. 244a49301eSmrg */ 254a49301eSmrg 264a49301eSmrg 2701e04c3fSmrg#include "errors.h" 287ec681f3Smrg 294a49301eSmrg#include "formats.h" 30af69d88dSmrg#include "macros.h" 31af69d88dSmrg#include "glformats.h" 3201e04c3fSmrg#include "c11/threads.h" 3301e04c3fSmrg#include "util/hash_table.h" 344a49301eSmrg 354a49301eSmrg/** 364a49301eSmrg * Information about texture formats. 374a49301eSmrg */ 387ec681f3Smrgstruct mesa_format_info 394a49301eSmrg{ 40af69d88dSmrg mesa_format Name; 414a49301eSmrg 424a49301eSmrg /** text name for debugging */ 434a49301eSmrg const char *StrName; 444a49301eSmrg 45af69d88dSmrg enum mesa_format_layout Layout; 46af69d88dSmrg 474a49301eSmrg /** 483464ebd5Sriastradh * Base format is one of GL_RED, GL_RG, GL_RGB, GL_RGBA, GL_ALPHA, 493464ebd5Sriastradh * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_INTENSITY, GL_YCBCR_MESA, 50af69d88dSmrg * GL_DEPTH_COMPONENT, GL_STENCIL_INDEX, GL_DEPTH_STENCIL. 514a49301eSmrg */ 524a49301eSmrg GLenum BaseFormat; 534a49301eSmrg 544a49301eSmrg /** 55af69d88dSmrg * Logical data type: one of GL_UNSIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, 563464ebd5Sriastradh * GL_UNSIGNED_INT, GL_INT, GL_FLOAT. 574a49301eSmrg */ 584a49301eSmrg GLenum DataType; 594a49301eSmrg 607ec681f3Smrg uint8_t RedBits; 617ec681f3Smrg uint8_t GreenBits; 627ec681f3Smrg uint8_t BlueBits; 637ec681f3Smrg uint8_t AlphaBits; 647ec681f3Smrg uint8_t LuminanceBits; 657ec681f3Smrg uint8_t IntensityBits; 667ec681f3Smrg uint8_t DepthBits; 677ec681f3Smrg uint8_t StencilBits; 684a49301eSmrg 6901e04c3fSmrg bool IsSRGBFormat; 7001e04c3fSmrg 714a49301eSmrg /** 7201e04c3fSmrg * To describe compressed formats. If not compressed, Width=Height=Depth=1. 734a49301eSmrg */ 747ec681f3Smrg uint8_t BlockWidth, BlockHeight, BlockDepth; 757ec681f3Smrg uint8_t BytesPerBlock; 764a49301eSmrg 77af69d88dSmrg uint8_t Swizzle[4]; 7801e04c3fSmrg mesa_array_format ArrayFormat; 794a49301eSmrg}; 804a49301eSmrg 8101e04c3fSmrg#include "format_info.h" 824a49301eSmrg 837ec681f3Smrgstatic const struct mesa_format_info * 84af69d88dSmrg_mesa_get_format_info(mesa_format format) 854a49301eSmrg{ 867ec681f3Smrg const struct mesa_format_info *info = &format_info[format]; 8701e04c3fSmrg STATIC_ASSERT(ARRAY_SIZE(format_info) == MESA_FORMAT_COUNT); 887ec681f3Smrg 897ec681f3Smrg /* The MESA_FORMAT_* enums are sparse, don't return a format info 907ec681f3Smrg * for empty entries. 917ec681f3Smrg */ 927ec681f3Smrg if (info->Name == MESA_FORMAT_NONE && format != MESA_FORMAT_NONE) 937ec681f3Smrg return NULL; 947ec681f3Smrg 954a49301eSmrg assert(info->Name == format); 964a49301eSmrg return info; 974a49301eSmrg} 984a49301eSmrg 994a49301eSmrg 1004a49301eSmrg/** Return string name of format (for debugging) */ 1014a49301eSmrgconst char * 102af69d88dSmrg_mesa_get_format_name(mesa_format format) 1034a49301eSmrg{ 1047ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 1057ec681f3Smrg if (!info) 1067ec681f3Smrg return NULL; 1074a49301eSmrg return info->StrName; 1084a49301eSmrg} 1094a49301eSmrg 1104a49301eSmrg 1114a49301eSmrg 1124a49301eSmrg/** 1134a49301eSmrg * Return bytes needed to store a block of pixels in the given format. 1144a49301eSmrg * Normally, a block is 1x1 (a single pixel). But for compressed formats 1154a49301eSmrg * a block may be 4x4 or 8x4, etc. 1163464ebd5Sriastradh * 1177ec681f3Smrg * Note: return is signed, so as not to coerce math to unsigned. cf. fdo #37351 1184a49301eSmrg */ 1197ec681f3Smrgint 120af69d88dSmrg_mesa_get_format_bytes(mesa_format format) 1214a49301eSmrg{ 12201e04c3fSmrg if (_mesa_format_is_mesa_array_format(format)) { 12301e04c3fSmrg return _mesa_array_format_get_type_size(format) * 12401e04c3fSmrg _mesa_array_format_get_num_channels(format); 12501e04c3fSmrg } 12601e04c3fSmrg 1277ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 12801e04c3fSmrg assert(info->BytesPerBlock); 12901e04c3fSmrg assert(info->BytesPerBlock <= MAX_PIXEL_BYTES || 130af69d88dSmrg _mesa_is_format_compressed(format)); 1314a49301eSmrg return info->BytesPerBlock; 1324a49301eSmrg} 1334a49301eSmrg 1344a49301eSmrg 1354a49301eSmrg/** 1364a49301eSmrg * Return bits per component for the given format. 1374a49301eSmrg * \param format one of MESA_FORMAT_x 1384a49301eSmrg * \param pname the component, such as GL_RED_BITS, GL_TEXTURE_BLUE_BITS, etc. 1394a49301eSmrg */ 1404a49301eSmrgGLint 141af69d88dSmrg_mesa_get_format_bits(mesa_format format, GLenum pname) 1424a49301eSmrg{ 1437ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 1444a49301eSmrg 1454a49301eSmrg switch (pname) { 1464a49301eSmrg case GL_RED_BITS: 1474a49301eSmrg case GL_TEXTURE_RED_SIZE: 1484a49301eSmrg case GL_RENDERBUFFER_RED_SIZE_EXT: 1494a49301eSmrg case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: 15001e04c3fSmrg case GL_INTERNALFORMAT_RED_SIZE: 1514a49301eSmrg return info->RedBits; 1524a49301eSmrg case GL_GREEN_BITS: 1534a49301eSmrg case GL_TEXTURE_GREEN_SIZE: 1544a49301eSmrg case GL_RENDERBUFFER_GREEN_SIZE_EXT: 1554a49301eSmrg case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: 15601e04c3fSmrg case GL_INTERNALFORMAT_GREEN_SIZE: 1574a49301eSmrg return info->GreenBits; 1584a49301eSmrg case GL_BLUE_BITS: 1594a49301eSmrg case GL_TEXTURE_BLUE_SIZE: 1604a49301eSmrg case GL_RENDERBUFFER_BLUE_SIZE_EXT: 1614a49301eSmrg case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: 16201e04c3fSmrg case GL_INTERNALFORMAT_BLUE_SIZE: 1634a49301eSmrg return info->BlueBits; 1644a49301eSmrg case GL_ALPHA_BITS: 1654a49301eSmrg case GL_TEXTURE_ALPHA_SIZE: 1664a49301eSmrg case GL_RENDERBUFFER_ALPHA_SIZE_EXT: 1674a49301eSmrg case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: 16801e04c3fSmrg case GL_INTERNALFORMAT_ALPHA_SIZE: 1694a49301eSmrg return info->AlphaBits; 1704a49301eSmrg case GL_TEXTURE_INTENSITY_SIZE: 1714a49301eSmrg return info->IntensityBits; 1724a49301eSmrg case GL_TEXTURE_LUMINANCE_SIZE: 1734a49301eSmrg return info->LuminanceBits; 1744a49301eSmrg case GL_INDEX_BITS: 175af69d88dSmrg return 0; 1764a49301eSmrg case GL_DEPTH_BITS: 1774a49301eSmrg case GL_TEXTURE_DEPTH_SIZE_ARB: 1784a49301eSmrg case GL_RENDERBUFFER_DEPTH_SIZE_EXT: 1794a49301eSmrg case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: 18001e04c3fSmrg case GL_INTERNALFORMAT_DEPTH_SIZE: 1814a49301eSmrg return info->DepthBits; 1824a49301eSmrg case GL_STENCIL_BITS: 1834a49301eSmrg case GL_TEXTURE_STENCIL_SIZE_EXT: 1844a49301eSmrg case GL_RENDERBUFFER_STENCIL_SIZE_EXT: 1854a49301eSmrg case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: 18601e04c3fSmrg case GL_INTERNALFORMAT_STENCIL_SIZE: 1874a49301eSmrg return info->StencilBits; 1884a49301eSmrg default: 1894a49301eSmrg _mesa_problem(NULL, "bad pname in _mesa_get_format_bits()"); 1904a49301eSmrg return 0; 1914a49301eSmrg } 1924a49301eSmrg} 1934a49301eSmrg 1944a49301eSmrg 1957ec681f3Smrgunsigned int 196af69d88dSmrg_mesa_get_format_max_bits(mesa_format format) 197af69d88dSmrg{ 1987ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 1997ec681f3Smrg unsigned int max = MAX2(info->RedBits, info->GreenBits); 200af69d88dSmrg max = MAX2(max, info->BlueBits); 201af69d88dSmrg max = MAX2(max, info->AlphaBits); 202af69d88dSmrg max = MAX2(max, info->LuminanceBits); 203af69d88dSmrg max = MAX2(max, info->IntensityBits); 204af69d88dSmrg max = MAX2(max, info->DepthBits); 205af69d88dSmrg max = MAX2(max, info->StencilBits); 206af69d88dSmrg return max; 207af69d88dSmrg} 208af69d88dSmrg 209af69d88dSmrg 210af69d88dSmrg/** 211af69d88dSmrg * Return the layout type of the given format. 212af69d88dSmrg */ 213af69d88dSmrgextern enum mesa_format_layout 214af69d88dSmrg_mesa_get_format_layout(mesa_format format) 215af69d88dSmrg{ 2167ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 217af69d88dSmrg return info->Layout; 218af69d88dSmrg} 219af69d88dSmrg 220af69d88dSmrg 2214a49301eSmrg/** 2224a49301eSmrg * Return the data type (or more specifically, the data representation) 2234a49301eSmrg * for the given format. 2244a49301eSmrg * The return value will be one of: 2254a49301eSmrg * GL_UNSIGNED_NORMALIZED = unsigned int representing [0,1] 2264a49301eSmrg * GL_SIGNED_NORMALIZED = signed int representing [-1, 1] 2274a49301eSmrg * GL_UNSIGNED_INT = an ordinary unsigned integer 2283464ebd5Sriastradh * GL_INT = an ordinary signed integer 2294a49301eSmrg * GL_FLOAT = an ordinary float 2304a49301eSmrg */ 2314a49301eSmrgGLenum 232af69d88dSmrg_mesa_get_format_datatype(mesa_format format) 2334a49301eSmrg{ 2347ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 2354a49301eSmrg return info->DataType; 2364a49301eSmrg} 2374a49301eSmrg 23801e04c3fSmrgstatic GLenum 23901e04c3fSmrgget_base_format_for_array_format(mesa_array_format format) 24001e04c3fSmrg{ 24101e04c3fSmrg uint8_t swizzle[4]; 24201e04c3fSmrg int num_channels; 24301e04c3fSmrg 2447ec681f3Smrg switch (_mesa_array_format_get_base_format(format)) { 2457ec681f3Smrg case MESA_ARRAY_FORMAT_BASE_FORMAT_DEPTH: 2467ec681f3Smrg return GL_DEPTH_COMPONENT; 2477ec681f3Smrg case MESA_ARRAY_FORMAT_BASE_FORMAT_STENCIL: 2487ec681f3Smrg return GL_STENCIL_INDEX; 2497ec681f3Smrg case MESA_ARRAY_FORMAT_BASE_FORMAT_RGBA_VARIANTS: 2507ec681f3Smrg break; 2517ec681f3Smrg } 2527ec681f3Smrg 25301e04c3fSmrg _mesa_array_format_get_swizzle(format, swizzle); 25401e04c3fSmrg num_channels = _mesa_array_format_get_num_channels(format); 25501e04c3fSmrg 25601e04c3fSmrg switch (num_channels) { 25701e04c3fSmrg case 4: 25801e04c3fSmrg /* FIXME: RGBX formats have 4 channels, but their base format is GL_RGB. 25901e04c3fSmrg * This is not really a problem for now because we only create array 26001e04c3fSmrg * formats from GL format/type combinations, and these cannot specify 26101e04c3fSmrg * RGBX formats. 26201e04c3fSmrg */ 26301e04c3fSmrg return GL_RGBA; 26401e04c3fSmrg case 3: 26501e04c3fSmrg return GL_RGB; 26601e04c3fSmrg case 2: 26701e04c3fSmrg if (swizzle[0] == 0 && 26801e04c3fSmrg swizzle[1] == 0 && 26901e04c3fSmrg swizzle[2] == 0 && 27001e04c3fSmrg swizzle[3] == 1) 27101e04c3fSmrg return GL_LUMINANCE_ALPHA; 27201e04c3fSmrg if (swizzle[0] == 1 && 27301e04c3fSmrg swizzle[1] == 1 && 27401e04c3fSmrg swizzle[2] == 1 && 27501e04c3fSmrg swizzle[3] == 0) 27601e04c3fSmrg return GL_LUMINANCE_ALPHA; 27701e04c3fSmrg if (swizzle[0] == 0 && 27801e04c3fSmrg swizzle[1] == 1 && 27901e04c3fSmrg swizzle[2] == 4 && 28001e04c3fSmrg swizzle[3] == 5) 28101e04c3fSmrg return GL_RG; 28201e04c3fSmrg if (swizzle[0] == 1 && 28301e04c3fSmrg swizzle[1] == 0 && 28401e04c3fSmrg swizzle[2] == 4 && 28501e04c3fSmrg swizzle[3] == 5) 28601e04c3fSmrg return GL_RG; 28701e04c3fSmrg break; 28801e04c3fSmrg case 1: 28901e04c3fSmrg if (swizzle[0] == 0 && 29001e04c3fSmrg swizzle[1] == 0 && 29101e04c3fSmrg swizzle[2] == 0 && 29201e04c3fSmrg swizzle[3] == 5) 29301e04c3fSmrg return GL_LUMINANCE; 29401e04c3fSmrg if (swizzle[0] == 0 && 29501e04c3fSmrg swizzle[1] == 0 && 29601e04c3fSmrg swizzle[2] == 0 && 29701e04c3fSmrg swizzle[3] == 0) 29801e04c3fSmrg return GL_INTENSITY; 29901e04c3fSmrg if (swizzle[0] <= MESA_FORMAT_SWIZZLE_W) 30001e04c3fSmrg return GL_RED; 30101e04c3fSmrg if (swizzle[1] <= MESA_FORMAT_SWIZZLE_W) 30201e04c3fSmrg return GL_GREEN; 30301e04c3fSmrg if (swizzle[2] <= MESA_FORMAT_SWIZZLE_W) 30401e04c3fSmrg return GL_BLUE; 30501e04c3fSmrg if (swizzle[3] <= MESA_FORMAT_SWIZZLE_W) 30601e04c3fSmrg return GL_ALPHA; 30701e04c3fSmrg break; 30801e04c3fSmrg } 30901e04c3fSmrg 31001e04c3fSmrg unreachable("Unsupported format"); 31101e04c3fSmrg} 3124a49301eSmrg 3134a49301eSmrg/** 314af69d88dSmrg * Return the basic format for the given type. The result will be one of 315af69d88dSmrg * GL_RGB, GL_RGBA, GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_INTENSITY, 316af69d88dSmrg * GL_YCBCR_MESA, GL_DEPTH_COMPONENT, GL_STENCIL_INDEX, GL_DEPTH_STENCIL. 31701e04c3fSmrg * This functions accepts a mesa_format or a mesa_array_format. 3184a49301eSmrg */ 3194a49301eSmrgGLenum 32001e04c3fSmrg_mesa_get_format_base_format(uint32_t format) 3214a49301eSmrg{ 32201e04c3fSmrg if (!_mesa_format_is_mesa_array_format(format)) { 3237ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 32401e04c3fSmrg return info->BaseFormat; 32501e04c3fSmrg } else { 32601e04c3fSmrg return get_base_format_for_array_format(format); 32701e04c3fSmrg } 3284a49301eSmrg} 3294a49301eSmrg 3304a49301eSmrg 3314a49301eSmrg/** 3324a49301eSmrg * Return the block size (in pixels) for the given format. Normally 3334a49301eSmrg * the block size is 1x1. But compressed formats will have block sizes 3344a49301eSmrg * of 4x4 or 8x4 pixels, etc. 3354a49301eSmrg * \param bw returns block width in pixels 3364a49301eSmrg * \param bh returns block height in pixels 3374a49301eSmrg */ 3384a49301eSmrgvoid 3397ec681f3Smrg_mesa_get_format_block_size(mesa_format format, 3407ec681f3Smrg unsigned int *bw, unsigned int *bh) 34101e04c3fSmrg{ 3427ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 34301e04c3fSmrg /* Use _mesa_get_format_block_size_3d() for 3D blocks. */ 34401e04c3fSmrg assert(info->BlockDepth == 1); 34501e04c3fSmrg 34601e04c3fSmrg *bw = info->BlockWidth; 34701e04c3fSmrg *bh = info->BlockHeight; 34801e04c3fSmrg} 34901e04c3fSmrg 35001e04c3fSmrg 35101e04c3fSmrg/** 35201e04c3fSmrg * Return the block size (in pixels) for the given format. Normally 35301e04c3fSmrg * the block size is 1x1x1. But compressed formats will have block 35401e04c3fSmrg * sizes of 4x4x4, 3x3x3 pixels, etc. 35501e04c3fSmrg * \param bw returns block width in pixels 35601e04c3fSmrg * \param bh returns block height in pixels 35701e04c3fSmrg * \param bd returns block depth in pixels 35801e04c3fSmrg */ 35901e04c3fSmrgvoid 36001e04c3fSmrg_mesa_get_format_block_size_3d(mesa_format format, 3617ec681f3Smrg unsigned int *bw, 3627ec681f3Smrg unsigned int *bh, 3637ec681f3Smrg unsigned int *bd) 3644a49301eSmrg{ 3657ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 3664a49301eSmrg *bw = info->BlockWidth; 3674a49301eSmrg *bh = info->BlockHeight; 36801e04c3fSmrg *bd = info->BlockDepth; 3694a49301eSmrg} 3704a49301eSmrg 3714a49301eSmrg 372af69d88dSmrg/** 373af69d88dSmrg * Returns the an array of four numbers representing the transformation 374af69d88dSmrg * from the RGBA or SZ colorspace to the given format. For array formats, 375af69d88dSmrg * the i'th RGBA component is given by: 376af69d88dSmrg * 377af69d88dSmrg * if (swizzle[i] <= MESA_FORMAT_SWIZZLE_W) 378af69d88dSmrg * comp = data[swizzle[i]]; 379af69d88dSmrg * else if (swizzle[i] == MESA_FORMAT_SWIZZLE_ZERO) 380af69d88dSmrg * comp = 0; 381af69d88dSmrg * else if (swizzle[i] == MESA_FORMAT_SWIZZLE_ONE) 382af69d88dSmrg * comp = 1; 383af69d88dSmrg * else if (swizzle[i] == MESA_FORMAT_SWIZZLE_NONE) 384af69d88dSmrg * // data does not contain a channel of this format 385af69d88dSmrg * 386af69d88dSmrg * For packed formats, the swizzle gives the number of components left of 387af69d88dSmrg * the least significant bit. 388af69d88dSmrg * 389af69d88dSmrg * Compressed formats have no swizzle. 390af69d88dSmrg */ 391af69d88dSmrgvoid 392af69d88dSmrg_mesa_get_format_swizzle(mesa_format format, uint8_t swizzle_out[4]) 393af69d88dSmrg{ 3947ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 395af69d88dSmrg memcpy(swizzle_out, info->Swizzle, sizeof(info->Swizzle)); 396af69d88dSmrg} 397af69d88dSmrg 39801e04c3fSmrgmesa_array_format 39901e04c3fSmrg_mesa_array_format_flip_channels(mesa_array_format format) 40001e04c3fSmrg{ 40101e04c3fSmrg int num_channels; 40201e04c3fSmrg uint8_t swizzle[4]; 40301e04c3fSmrg 40401e04c3fSmrg num_channels = _mesa_array_format_get_num_channels(format); 40501e04c3fSmrg _mesa_array_format_get_swizzle(format, swizzle); 40601e04c3fSmrg 4077ec681f3Smrg if (num_channels == 1 || num_channels == 3) 40801e04c3fSmrg return format; 40901e04c3fSmrg 41001e04c3fSmrg if (num_channels == 2) { 41101e04c3fSmrg /* Assert that the swizzle makes sense for 2 channels */ 41201e04c3fSmrg for (unsigned i = 0; i < 4; i++) 41301e04c3fSmrg assert(swizzle[i] != 2 && swizzle[i] != 3); 41401e04c3fSmrg 41501e04c3fSmrg static const uint8_t flip_xy[6] = { 1, 0, 2, 3, 4, 5 }; 41601e04c3fSmrg _mesa_array_format_set_swizzle(&format, 41701e04c3fSmrg flip_xy[swizzle[0]], flip_xy[swizzle[1]], 41801e04c3fSmrg flip_xy[swizzle[2]], flip_xy[swizzle[3]]); 41901e04c3fSmrg return format; 42001e04c3fSmrg } 42101e04c3fSmrg 42201e04c3fSmrg if (num_channels == 4) { 42301e04c3fSmrg static const uint8_t flip[6] = { 3, 2, 1, 0, 4, 5 }; 42401e04c3fSmrg _mesa_array_format_set_swizzle(&format, 42501e04c3fSmrg flip[swizzle[0]], flip[swizzle[1]], 42601e04c3fSmrg flip[swizzle[2]], flip[swizzle[3]]); 42701e04c3fSmrg return format; 42801e04c3fSmrg } 42901e04c3fSmrg 43001e04c3fSmrg unreachable("Invalid array format"); 43101e04c3fSmrg} 43201e04c3fSmrg 4337ec681f3Smrgstatic uint32_t 4347ec681f3Smrg_mesa_format_info_to_array_format(const struct mesa_format_info *info) 43501e04c3fSmrg{ 4367ec681f3Smrg#if UTIL_ARCH_BIG_ENDIAN 4377ec681f3Smrg if (info->ArrayFormat && info->Layout == MESA_FORMAT_LAYOUT_PACKED) 43801e04c3fSmrg return _mesa_array_format_flip_channels(info->ArrayFormat); 43901e04c3fSmrg else 4407ec681f3Smrg#endif 44101e04c3fSmrg return info->ArrayFormat; 44201e04c3fSmrg} 44301e04c3fSmrg 4447ec681f3Smrguint32_t 4457ec681f3Smrg_mesa_format_to_array_format(mesa_format format) 4467ec681f3Smrg{ 4477ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 4487ec681f3Smrg return _mesa_format_info_to_array_format(info); 4497ec681f3Smrg} 4507ec681f3Smrg 45101e04c3fSmrgstatic struct hash_table *format_array_format_table; 45201e04c3fSmrgstatic once_flag format_array_format_table_exists = ONCE_FLAG_INIT; 45301e04c3fSmrg 4547ec681f3Smrgstatic void 4557ec681f3Smrgformat_array_format_table_destroy(void) 4567ec681f3Smrg{ 4577ec681f3Smrg _mesa_hash_table_destroy(format_array_format_table, NULL); 4587ec681f3Smrg} 4597ec681f3Smrg 46001e04c3fSmrgstatic bool 46101e04c3fSmrgarray_formats_equal(const void *a, const void *b) 46201e04c3fSmrg{ 46301e04c3fSmrg return (intptr_t)a == (intptr_t)b; 46401e04c3fSmrg} 46501e04c3fSmrg 46601e04c3fSmrgstatic void 46701e04c3fSmrgformat_array_format_table_init(void) 46801e04c3fSmrg{ 4697ec681f3Smrg const struct mesa_format_info *info; 47001e04c3fSmrg mesa_array_format array_format; 47101e04c3fSmrg unsigned f; 47201e04c3fSmrg 47301e04c3fSmrg format_array_format_table = _mesa_hash_table_create(NULL, NULL, 47401e04c3fSmrg array_formats_equal); 47501e04c3fSmrg 47601e04c3fSmrg if (!format_array_format_table) { 47701e04c3fSmrg _mesa_error_no_memory(__func__); 47801e04c3fSmrg return; 47901e04c3fSmrg } 48001e04c3fSmrg 48101e04c3fSmrg for (f = 1; f < MESA_FORMAT_COUNT; ++f) { 48201e04c3fSmrg info = _mesa_get_format_info(f); 4837ec681f3Smrg if (!info || !info->ArrayFormat) 48401e04c3fSmrg continue; 48501e04c3fSmrg 4867ec681f3Smrg /* All sRGB formats should have an equivalent UNORM format, and that's 4877ec681f3Smrg * the one we want in the table. 48801e04c3fSmrg */ 4897ec681f3Smrg if (_mesa_is_format_srgb(f)) 49001e04c3fSmrg continue; 49101e04c3fSmrg 4927ec681f3Smrg array_format = _mesa_format_info_to_array_format(info); 49301e04c3fSmrg _mesa_hash_table_insert_pre_hashed(format_array_format_table, 49401e04c3fSmrg array_format, 49501e04c3fSmrg (void *)(intptr_t)array_format, 49601e04c3fSmrg (void *)(intptr_t)f); 49701e04c3fSmrg } 4987ec681f3Smrg 4997ec681f3Smrg atexit(format_array_format_table_destroy); 50001e04c3fSmrg} 50101e04c3fSmrg 50201e04c3fSmrgmesa_format 50301e04c3fSmrg_mesa_format_from_array_format(uint32_t array_format) 50401e04c3fSmrg{ 50501e04c3fSmrg struct hash_entry *entry; 50601e04c3fSmrg 50701e04c3fSmrg assert(_mesa_format_is_mesa_array_format(array_format)); 50801e04c3fSmrg 50901e04c3fSmrg call_once(&format_array_format_table_exists, format_array_format_table_init); 51001e04c3fSmrg 51101e04c3fSmrg if (!format_array_format_table) { 51201e04c3fSmrg static const once_flag once_flag_init = ONCE_FLAG_INIT; 51301e04c3fSmrg format_array_format_table_exists = once_flag_init; 51401e04c3fSmrg return MESA_FORMAT_NONE; 51501e04c3fSmrg } 51601e04c3fSmrg 51701e04c3fSmrg entry = _mesa_hash_table_search_pre_hashed(format_array_format_table, 51801e04c3fSmrg array_format, 51901e04c3fSmrg (void *)(intptr_t)array_format); 52001e04c3fSmrg if (entry) 52101e04c3fSmrg return (intptr_t)entry->data; 52201e04c3fSmrg else 52301e04c3fSmrg return MESA_FORMAT_NONE; 52401e04c3fSmrg} 525af69d88dSmrg 5264a49301eSmrg/** Is the given format a compressed format? */ 5277ec681f3Smrgbool 528af69d88dSmrg_mesa_is_format_compressed(mesa_format format) 5294a49301eSmrg{ 5307ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 5314a49301eSmrg return info->BlockWidth > 1 || info->BlockHeight > 1; 5324a49301eSmrg} 5334a49301eSmrg 5344a49301eSmrg 5353464ebd5Sriastradh/** 5363464ebd5Sriastradh * Determine if the given format represents a packed depth/stencil buffer. 5373464ebd5Sriastradh */ 5387ec681f3Smrgbool 539af69d88dSmrg_mesa_is_format_packed_depth_stencil(mesa_format format) 5403464ebd5Sriastradh{ 5417ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 5423464ebd5Sriastradh 5433464ebd5Sriastradh return info->BaseFormat == GL_DEPTH_STENCIL; 5443464ebd5Sriastradh} 5453464ebd5Sriastradh 5463464ebd5Sriastradh 5473464ebd5Sriastradh/** 5483464ebd5Sriastradh * Is the given format a signed/unsigned integer color format? 5493464ebd5Sriastradh */ 5507ec681f3Smrgbool 551af69d88dSmrg_mesa_is_format_integer_color(mesa_format format) 5523464ebd5Sriastradh{ 5537ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 5543464ebd5Sriastradh return (info->DataType == GL_INT || info->DataType == GL_UNSIGNED_INT) && 5553464ebd5Sriastradh info->BaseFormat != GL_DEPTH_COMPONENT && 5563464ebd5Sriastradh info->BaseFormat != GL_DEPTH_STENCIL && 5573464ebd5Sriastradh info->BaseFormat != GL_STENCIL_INDEX; 5583464ebd5Sriastradh} 5593464ebd5Sriastradh 5603464ebd5Sriastradh 561af69d88dSmrg/** 562af69d88dSmrg * Is the given format an unsigned integer format? 563af69d88dSmrg */ 5647ec681f3Smrgbool 565af69d88dSmrg_mesa_is_format_unsigned(mesa_format format) 566af69d88dSmrg{ 5677ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 568af69d88dSmrg return _mesa_is_type_unsigned(info->DataType); 569af69d88dSmrg} 570af69d88dSmrg 571af69d88dSmrg 572af69d88dSmrg/** 573af69d88dSmrg * Does the given format store signed values? 574af69d88dSmrg */ 5757ec681f3Smrgbool 576af69d88dSmrg_mesa_is_format_signed(mesa_format format) 577af69d88dSmrg{ 5787ec681f3Smrg if (format == MESA_FORMAT_R11G11B10_FLOAT || 579af69d88dSmrg format == MESA_FORMAT_R9G9B9E5_FLOAT) { 580af69d88dSmrg /* these packed float formats only store unsigned values */ 5817ec681f3Smrg return false; 582af69d88dSmrg } 583af69d88dSmrg else { 5847ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 585af69d88dSmrg return (info->DataType == GL_SIGNED_NORMALIZED || 586af69d88dSmrg info->DataType == GL_INT || 587af69d88dSmrg info->DataType == GL_FLOAT); 588af69d88dSmrg } 589af69d88dSmrg} 590af69d88dSmrg 591af69d88dSmrg/** 592af69d88dSmrg * Is the given format an integer format? 593af69d88dSmrg */ 5947ec681f3Smrgbool 595af69d88dSmrg_mesa_is_format_integer(mesa_format format) 596af69d88dSmrg{ 5977ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 598af69d88dSmrg return (info->DataType == GL_INT || info->DataType == GL_UNSIGNED_INT); 599af69d88dSmrg} 600af69d88dSmrg 60101e04c3fSmrg 60201e04c3fSmrg/** 60301e04c3fSmrg * Return true if the given format is a color format. 60401e04c3fSmrg */ 6057ec681f3Smrgbool 60601e04c3fSmrg_mesa_is_format_color_format(mesa_format format) 60701e04c3fSmrg{ 6087ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 60901e04c3fSmrg switch (info->BaseFormat) { 61001e04c3fSmrg case GL_DEPTH_COMPONENT: 61101e04c3fSmrg case GL_STENCIL_INDEX: 61201e04c3fSmrg case GL_DEPTH_STENCIL: 61301e04c3fSmrg return false; 61401e04c3fSmrg default: 61501e04c3fSmrg return true; 61601e04c3fSmrg } 61701e04c3fSmrg} 61801e04c3fSmrg 6197ec681f3Smrgbool 6207ec681f3Smrg_mesa_is_format_srgb(mesa_format format) 6214a49301eSmrg{ 6227ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 6237ec681f3Smrg return info->IsSRGBFormat; 6244a49301eSmrg} 6254a49301eSmrg 626af69d88dSmrg/** 627af69d88dSmrg * Return TRUE if format is an ETC2 compressed format specified 628af69d88dSmrg * by GL_ARB_ES3_compatibility. 629af69d88dSmrg */ 630af69d88dSmrgbool 631af69d88dSmrg_mesa_is_format_etc2(mesa_format format) 632af69d88dSmrg{ 633af69d88dSmrg switch (format) { 634af69d88dSmrg case MESA_FORMAT_ETC2_RGB8: 635af69d88dSmrg case MESA_FORMAT_ETC2_SRGB8: 636af69d88dSmrg case MESA_FORMAT_ETC2_RGBA8_EAC: 637af69d88dSmrg case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC: 638af69d88dSmrg case MESA_FORMAT_ETC2_R11_EAC: 639af69d88dSmrg case MESA_FORMAT_ETC2_RG11_EAC: 640af69d88dSmrg case MESA_FORMAT_ETC2_SIGNED_R11_EAC: 641af69d88dSmrg case MESA_FORMAT_ETC2_SIGNED_RG11_EAC: 642af69d88dSmrg case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: 643af69d88dSmrg case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: 6447ec681f3Smrg return true; 645af69d88dSmrg default: 6467ec681f3Smrg return false; 647af69d88dSmrg } 648af69d88dSmrg} 649af69d88dSmrg 650af69d88dSmrg 6513464ebd5Sriastradh/** 65201e04c3fSmrg * Return TRUE if format is an ASTC 2D compressed format. 6533464ebd5Sriastradh */ 65401e04c3fSmrgbool 65501e04c3fSmrg_mesa_is_format_astc_2d(mesa_format format) 6563464ebd5Sriastradh{ 6573464ebd5Sriastradh switch (format) { 65801e04c3fSmrg case MESA_FORMAT_RGBA_ASTC_4x4: 65901e04c3fSmrg case MESA_FORMAT_RGBA_ASTC_5x4: 66001e04c3fSmrg case MESA_FORMAT_RGBA_ASTC_5x5: 66101e04c3fSmrg case MESA_FORMAT_RGBA_ASTC_6x5: 66201e04c3fSmrg case MESA_FORMAT_RGBA_ASTC_6x6: 66301e04c3fSmrg case MESA_FORMAT_RGBA_ASTC_8x5: 66401e04c3fSmrg case MESA_FORMAT_RGBA_ASTC_8x6: 66501e04c3fSmrg case MESA_FORMAT_RGBA_ASTC_8x8: 66601e04c3fSmrg case MESA_FORMAT_RGBA_ASTC_10x5: 66701e04c3fSmrg case MESA_FORMAT_RGBA_ASTC_10x6: 66801e04c3fSmrg case MESA_FORMAT_RGBA_ASTC_10x8: 66901e04c3fSmrg case MESA_FORMAT_RGBA_ASTC_10x10: 67001e04c3fSmrg case MESA_FORMAT_RGBA_ASTC_12x10: 67101e04c3fSmrg case MESA_FORMAT_RGBA_ASTC_12x12: 67201e04c3fSmrg case MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4: 67301e04c3fSmrg case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x4: 67401e04c3fSmrg case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5: 67501e04c3fSmrg case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x5: 67601e04c3fSmrg case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6: 67701e04c3fSmrg case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x5: 67801e04c3fSmrg case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x6: 67901e04c3fSmrg case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x8: 68001e04c3fSmrg case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x5: 68101e04c3fSmrg case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x6: 68201e04c3fSmrg case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x8: 68301e04c3fSmrg case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x10: 68401e04c3fSmrg case MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x10: 68501e04c3fSmrg case MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x12: 68601e04c3fSmrg return true; 6873464ebd5Sriastradh default: 68801e04c3fSmrg return false; 6893464ebd5Sriastradh } 6903464ebd5Sriastradh} 6913464ebd5Sriastradh 6923464ebd5Sriastradh 693af69d88dSmrg/** 694af69d88dSmrg * If the given format is a compressed format, return a corresponding 695af69d88dSmrg * uncompressed format. 696af69d88dSmrg */ 697af69d88dSmrgmesa_format 698af69d88dSmrg_mesa_get_uncompressed_format(mesa_format format) 699af69d88dSmrg{ 700af69d88dSmrg switch (format) { 701af69d88dSmrg case MESA_FORMAT_RGB_FXT1: 702af69d88dSmrg return MESA_FORMAT_BGR_UNORM8; 703af69d88dSmrg case MESA_FORMAT_RGBA_FXT1: 704af69d88dSmrg return MESA_FORMAT_A8B8G8R8_UNORM; 705af69d88dSmrg case MESA_FORMAT_RGB_DXT1: 706af69d88dSmrg case MESA_FORMAT_SRGB_DXT1: 707af69d88dSmrg return MESA_FORMAT_BGR_UNORM8; 708af69d88dSmrg case MESA_FORMAT_RGBA_DXT1: 709af69d88dSmrg case MESA_FORMAT_SRGBA_DXT1: 710af69d88dSmrg return MESA_FORMAT_A8B8G8R8_UNORM; 711af69d88dSmrg case MESA_FORMAT_RGBA_DXT3: 712af69d88dSmrg case MESA_FORMAT_SRGBA_DXT3: 713af69d88dSmrg return MESA_FORMAT_A8B8G8R8_UNORM; 714af69d88dSmrg case MESA_FORMAT_RGBA_DXT5: 715af69d88dSmrg case MESA_FORMAT_SRGBA_DXT5: 716af69d88dSmrg return MESA_FORMAT_A8B8G8R8_UNORM; 717af69d88dSmrg case MESA_FORMAT_R_RGTC1_UNORM: 718af69d88dSmrg return MESA_FORMAT_R_UNORM8; 719af69d88dSmrg case MESA_FORMAT_R_RGTC1_SNORM: 720af69d88dSmrg return MESA_FORMAT_R_SNORM8; 721af69d88dSmrg case MESA_FORMAT_RG_RGTC2_UNORM: 7227ec681f3Smrg return MESA_FORMAT_RG_UNORM8; 723af69d88dSmrg case MESA_FORMAT_RG_RGTC2_SNORM: 7247ec681f3Smrg return MESA_FORMAT_RG_SNORM8; 725af69d88dSmrg case MESA_FORMAT_L_LATC1_UNORM: 726af69d88dSmrg return MESA_FORMAT_L_UNORM8; 727af69d88dSmrg case MESA_FORMAT_L_LATC1_SNORM: 728af69d88dSmrg return MESA_FORMAT_L_SNORM8; 729af69d88dSmrg case MESA_FORMAT_LA_LATC2_UNORM: 7307ec681f3Smrg return MESA_FORMAT_LA_UNORM8; 731af69d88dSmrg case MESA_FORMAT_LA_LATC2_SNORM: 7327ec681f3Smrg return MESA_FORMAT_LA_SNORM8; 733af69d88dSmrg case MESA_FORMAT_ETC1_RGB8: 734af69d88dSmrg case MESA_FORMAT_ETC2_RGB8: 735af69d88dSmrg case MESA_FORMAT_ETC2_SRGB8: 736b9abf16eSmaya case MESA_FORMAT_ATC_RGB: 737af69d88dSmrg return MESA_FORMAT_BGR_UNORM8; 738af69d88dSmrg case MESA_FORMAT_ETC2_RGBA8_EAC: 739af69d88dSmrg case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC: 740af69d88dSmrg case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: 741af69d88dSmrg case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: 742b9abf16eSmaya case MESA_FORMAT_ATC_RGBA_EXPLICIT: 743b9abf16eSmaya case MESA_FORMAT_ATC_RGBA_INTERPOLATED: 744af69d88dSmrg return MESA_FORMAT_A8B8G8R8_UNORM; 745af69d88dSmrg case MESA_FORMAT_ETC2_R11_EAC: 746af69d88dSmrg case MESA_FORMAT_ETC2_SIGNED_R11_EAC: 747af69d88dSmrg return MESA_FORMAT_R_UNORM16; 748af69d88dSmrg case MESA_FORMAT_ETC2_RG11_EAC: 749af69d88dSmrg case MESA_FORMAT_ETC2_SIGNED_RG11_EAC: 7507ec681f3Smrg return MESA_FORMAT_RG_UNORM16; 751af69d88dSmrg case MESA_FORMAT_BPTC_RGBA_UNORM: 752af69d88dSmrg case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM: 753af69d88dSmrg return MESA_FORMAT_A8B8G8R8_UNORM; 754af69d88dSmrg case MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT: 755af69d88dSmrg case MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT: 756af69d88dSmrg return MESA_FORMAT_RGB_FLOAT32; 757af69d88dSmrg default: 758af69d88dSmrg assert(!_mesa_is_format_compressed(format)); 759af69d88dSmrg return format; 760af69d88dSmrg } 761af69d88dSmrg} 762af69d88dSmrg 763af69d88dSmrg 7647ec681f3Smrgunsigned int 765af69d88dSmrg_mesa_format_num_components(mesa_format format) 766af69d88dSmrg{ 7677ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 768af69d88dSmrg return ((info->RedBits > 0) + 769af69d88dSmrg (info->GreenBits > 0) + 770af69d88dSmrg (info->BlueBits > 0) + 771af69d88dSmrg (info->AlphaBits > 0) + 772af69d88dSmrg (info->LuminanceBits > 0) + 773af69d88dSmrg (info->IntensityBits > 0) + 774af69d88dSmrg (info->DepthBits > 0) + 775af69d88dSmrg (info->StencilBits > 0)); 776af69d88dSmrg} 777af69d88dSmrg 778af69d88dSmrg 779af69d88dSmrg/** 780af69d88dSmrg * Returns true if a color format has data stored in the R/G/B/A channels, 781af69d88dSmrg * given an index from 0 to 3. 782af69d88dSmrg */ 783af69d88dSmrgbool 784af69d88dSmrg_mesa_format_has_color_component(mesa_format format, int component) 785af69d88dSmrg{ 7867ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 787af69d88dSmrg 788af69d88dSmrg assert(info->BaseFormat != GL_DEPTH_COMPONENT && 789af69d88dSmrg info->BaseFormat != GL_DEPTH_STENCIL && 790af69d88dSmrg info->BaseFormat != GL_STENCIL_INDEX); 791af69d88dSmrg 792af69d88dSmrg switch (component) { 793af69d88dSmrg case 0: 794af69d88dSmrg return (info->RedBits + info->IntensityBits + info->LuminanceBits) > 0; 795af69d88dSmrg case 1: 796af69d88dSmrg return (info->GreenBits + info->IntensityBits + info->LuminanceBits) > 0; 797af69d88dSmrg case 2: 798af69d88dSmrg return (info->BlueBits + info->IntensityBits + info->LuminanceBits) > 0; 799af69d88dSmrg case 3: 800af69d88dSmrg return (info->AlphaBits + info->IntensityBits) > 0; 801af69d88dSmrg default: 802af69d88dSmrg assert(!"Invalid color component: must be 0..3"); 803af69d88dSmrg return false; 804af69d88dSmrg } 805af69d88dSmrg} 806af69d88dSmrg 807af69d88dSmrg 8084a49301eSmrg/** 8094a49301eSmrg * Return number of bytes needed to store an image of the given size 8104a49301eSmrg * in the given format. 8114a49301eSmrg */ 8127ec681f3Smrguint32_t 8137ec681f3Smrg_mesa_format_image_size(mesa_format format, int width, 8147ec681f3Smrg int height, int depth) 8154a49301eSmrg{ 8167ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 8177ec681f3Smrg uint32_t sz; 8184a49301eSmrg /* Strictly speaking, a conditional isn't needed here */ 81901e04c3fSmrg if (info->BlockWidth > 1 || info->BlockHeight > 1 || info->BlockDepth > 1) { 8203464ebd5Sriastradh /* compressed format (2D only for now) */ 8217ec681f3Smrg const uint32_t bw = info->BlockWidth; 8227ec681f3Smrg const uint32_t bh = info->BlockHeight; 8237ec681f3Smrg const uint32_t bd = info->BlockDepth; 8247ec681f3Smrg const uint32_t wblocks = (width + bw - 1) / bw; 8257ec681f3Smrg const uint32_t hblocks = (height + bh - 1) / bh; 8267ec681f3Smrg const uint32_t dblocks = (depth + bd - 1) / bd; 82701e04c3fSmrg sz = wblocks * hblocks * dblocks * info->BytesPerBlock; 82801e04c3fSmrg } else 8294a49301eSmrg /* non-compressed */ 83001e04c3fSmrg sz = width * height * depth * info->BytesPerBlock; 83101e04c3fSmrg 83201e04c3fSmrg return sz; 8334a49301eSmrg} 8344a49301eSmrg 8354a49301eSmrg 8363464ebd5Sriastradh/** 8373464ebd5Sriastradh * Same as _mesa_format_image_size() but returns a 64-bit value to 83801e04c3fSmrg * accommodate very large textures. 8393464ebd5Sriastradh */ 8403464ebd5Sriastradhuint64_t 8417ec681f3Smrg_mesa_format_image_size64(mesa_format format, int width, 8427ec681f3Smrg int height, int depth) 8433464ebd5Sriastradh{ 8447ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 84501e04c3fSmrg uint64_t sz; 8463464ebd5Sriastradh /* Strictly speaking, a conditional isn't needed here */ 84701e04c3fSmrg if (info->BlockWidth > 1 || info->BlockHeight > 1 || info->BlockDepth > 1) { 8483464ebd5Sriastradh /* compressed format (2D only for now) */ 84901e04c3fSmrg const uint64_t bw = info->BlockWidth; 85001e04c3fSmrg const uint64_t bh = info->BlockHeight; 85101e04c3fSmrg const uint64_t bd = info->BlockDepth; 8523464ebd5Sriastradh const uint64_t wblocks = (width + bw - 1) / bw; 8533464ebd5Sriastradh const uint64_t hblocks = (height + bh - 1) / bh; 85401e04c3fSmrg const uint64_t dblocks = (depth + bd - 1) / bd; 85501e04c3fSmrg sz = wblocks * hblocks * dblocks * info->BytesPerBlock; 85601e04c3fSmrg } else 8573464ebd5Sriastradh /* non-compressed */ 85801e04c3fSmrg sz = ((uint64_t) width * (uint64_t) height * 85901e04c3fSmrg (uint64_t) depth * info->BytesPerBlock); 86001e04c3fSmrg 86101e04c3fSmrg return sz; 8623464ebd5Sriastradh} 8633464ebd5Sriastradh 8643464ebd5Sriastradh 8654a49301eSmrg 8667ec681f3Smrgint32_t 8677ec681f3Smrg_mesa_format_row_stride(mesa_format format, int width) 8684a49301eSmrg{ 8697ec681f3Smrg const struct mesa_format_info *info = _mesa_get_format_info(format); 8704a49301eSmrg /* Strictly speaking, a conditional isn't needed here */ 8714a49301eSmrg if (info->BlockWidth > 1 || info->BlockHeight > 1) { 8724a49301eSmrg /* compressed format */ 8737ec681f3Smrg const uint32_t bw = info->BlockWidth; 8747ec681f3Smrg const uint32_t wblocks = (width + bw - 1) / bw; 8757ec681f3Smrg const int32_t stride = wblocks * info->BytesPerBlock; 8764a49301eSmrg return stride; 8774a49301eSmrg } 8784a49301eSmrg else { 8797ec681f3Smrg const int32_t stride = width * info->BytesPerBlock; 8804a49301eSmrg return stride; 8814a49301eSmrg } 8824a49301eSmrg} 8834a49301eSmrg 8844a49301eSmrg 8854a49301eSmrg 8864a49301eSmrg/** 88701e04c3fSmrg * Return datatype and number of components per texel for the given 88801e04c3fSmrg * uncompressed mesa_format. Only used for mipmap generation code. 8894a49301eSmrg */ 8904a49301eSmrgvoid 89101e04c3fSmrg_mesa_uncompressed_format_to_type_and_comps(mesa_format format, 8924a49301eSmrg GLenum *datatype, GLuint *comps) 8934a49301eSmrg{ 8944a49301eSmrg switch (format) { 895af69d88dSmrg case MESA_FORMAT_A8B8G8R8_UNORM: 896af69d88dSmrg case MESA_FORMAT_R8G8B8A8_UNORM: 897af69d88dSmrg case MESA_FORMAT_B8G8R8A8_UNORM: 898af69d88dSmrg case MESA_FORMAT_A8R8G8B8_UNORM: 899af69d88dSmrg case MESA_FORMAT_X8B8G8R8_UNORM: 900af69d88dSmrg case MESA_FORMAT_R8G8B8X8_UNORM: 901af69d88dSmrg case MESA_FORMAT_B8G8R8X8_UNORM: 902af69d88dSmrg case MESA_FORMAT_X8R8G8B8_UNORM: 90301e04c3fSmrg case MESA_FORMAT_A8B8G8R8_UINT: 90401e04c3fSmrg case MESA_FORMAT_R8G8B8A8_UINT: 90501e04c3fSmrg case MESA_FORMAT_B8G8R8A8_UINT: 90601e04c3fSmrg case MESA_FORMAT_A8R8G8B8_UINT: 9074a49301eSmrg *datatype = GL_UNSIGNED_BYTE; 9084a49301eSmrg *comps = 4; 9094a49301eSmrg return; 910af69d88dSmrg case MESA_FORMAT_BGR_UNORM8: 911af69d88dSmrg case MESA_FORMAT_RGB_UNORM8: 9124a49301eSmrg *datatype = GL_UNSIGNED_BYTE; 9134a49301eSmrg *comps = 3; 9144a49301eSmrg return; 915af69d88dSmrg case MESA_FORMAT_B5G6R5_UNORM: 916af69d88dSmrg case MESA_FORMAT_R5G6B5_UNORM: 91701e04c3fSmrg case MESA_FORMAT_B5G6R5_UINT: 91801e04c3fSmrg case MESA_FORMAT_R5G6B5_UINT: 9194a49301eSmrg *datatype = GL_UNSIGNED_SHORT_5_6_5; 9204a49301eSmrg *comps = 3; 9214a49301eSmrg return; 9224a49301eSmrg 923af69d88dSmrg case MESA_FORMAT_B4G4R4A4_UNORM: 924af69d88dSmrg case MESA_FORMAT_A4R4G4B4_UNORM: 925af69d88dSmrg case MESA_FORMAT_B4G4R4X4_UNORM: 92601e04c3fSmrg case MESA_FORMAT_B4G4R4A4_UINT: 92701e04c3fSmrg case MESA_FORMAT_A4R4G4B4_UINT: 9284a49301eSmrg *datatype = GL_UNSIGNED_SHORT_4_4_4_4; 9294a49301eSmrg *comps = 4; 9304a49301eSmrg return; 9314a49301eSmrg 932af69d88dSmrg case MESA_FORMAT_B5G5R5A1_UNORM: 933af69d88dSmrg case MESA_FORMAT_A1R5G5B5_UNORM: 934af69d88dSmrg case MESA_FORMAT_B5G5R5X1_UNORM: 93501e04c3fSmrg case MESA_FORMAT_B5G5R5A1_UINT: 93601e04c3fSmrg case MESA_FORMAT_A1R5G5B5_UINT: 9374a49301eSmrg *datatype = GL_UNSIGNED_SHORT_1_5_5_5_REV; 9384a49301eSmrg *comps = 4; 9394a49301eSmrg return; 9404a49301eSmrg 941af69d88dSmrg case MESA_FORMAT_B10G10R10A2_UNORM: 9423464ebd5Sriastradh *datatype = GL_UNSIGNED_INT_2_10_10_10_REV; 9433464ebd5Sriastradh *comps = 4; 9443464ebd5Sriastradh return; 9453464ebd5Sriastradh 946af69d88dSmrg case MESA_FORMAT_A1B5G5R5_UNORM: 94701e04c3fSmrg case MESA_FORMAT_A1B5G5R5_UINT: 94801e04c3fSmrg case MESA_FORMAT_X1B5G5R5_UNORM: 9493464ebd5Sriastradh *datatype = GL_UNSIGNED_SHORT_5_5_5_1; 9503464ebd5Sriastradh *comps = 4; 9513464ebd5Sriastradh return; 9523464ebd5Sriastradh 953af69d88dSmrg case MESA_FORMAT_L4A4_UNORM: 9543464ebd5Sriastradh *datatype = MESA_UNSIGNED_BYTE_4_4; 9553464ebd5Sriastradh *comps = 2; 9563464ebd5Sriastradh return; 9573464ebd5Sriastradh 9587ec681f3Smrg case MESA_FORMAT_LA_UNORM8: 9597ec681f3Smrg case MESA_FORMAT_RG_UNORM8: 9604a49301eSmrg *datatype = GL_UNSIGNED_BYTE; 9614a49301eSmrg *comps = 2; 9624a49301eSmrg return; 9634a49301eSmrg 9647ec681f3Smrg case MESA_FORMAT_LA_UNORM16: 9657ec681f3Smrg case MESA_FORMAT_RG_UNORM16: 9664a49301eSmrg *datatype = GL_UNSIGNED_SHORT; 9674a49301eSmrg *comps = 2; 9684a49301eSmrg return; 9694a49301eSmrg 970af69d88dSmrg case MESA_FORMAT_R_UNORM16: 971af69d88dSmrg case MESA_FORMAT_A_UNORM16: 972af69d88dSmrg case MESA_FORMAT_L_UNORM16: 973af69d88dSmrg case MESA_FORMAT_I_UNORM16: 9743464ebd5Sriastradh *datatype = GL_UNSIGNED_SHORT; 9753464ebd5Sriastradh *comps = 1; 9763464ebd5Sriastradh return; 9773464ebd5Sriastradh 97801e04c3fSmrg case MESA_FORMAT_R3G3B2_UNORM: 97901e04c3fSmrg case MESA_FORMAT_R3G3B2_UINT: 98001e04c3fSmrg *datatype = GL_UNSIGNED_BYTE_2_3_3_REV; 98101e04c3fSmrg *comps = 3; 98201e04c3fSmrg return; 98301e04c3fSmrg case MESA_FORMAT_A4B4G4R4_UNORM: 98401e04c3fSmrg case MESA_FORMAT_A4B4G4R4_UINT: 98501e04c3fSmrg *datatype = GL_UNSIGNED_SHORT_4_4_4_4; 98601e04c3fSmrg *comps = 4; 98701e04c3fSmrg return; 98801e04c3fSmrg 98901e04c3fSmrg case MESA_FORMAT_R4G4B4A4_UNORM: 99001e04c3fSmrg case MESA_FORMAT_R4G4B4A4_UINT: 99101e04c3fSmrg *datatype = GL_UNSIGNED_SHORT_4_4_4_4; 99201e04c3fSmrg *comps = 4; 99301e04c3fSmrg return; 99401e04c3fSmrg case MESA_FORMAT_R5G5B5A1_UNORM: 99501e04c3fSmrg case MESA_FORMAT_R5G5B5A1_UINT: 99601e04c3fSmrg *datatype = GL_UNSIGNED_SHORT_1_5_5_5_REV; 99701e04c3fSmrg *comps = 4; 99801e04c3fSmrg return; 99901e04c3fSmrg case MESA_FORMAT_A2B10G10R10_UNORM: 100001e04c3fSmrg case MESA_FORMAT_A2B10G10R10_UINT: 100101e04c3fSmrg *datatype = GL_UNSIGNED_INT_10_10_10_2; 100201e04c3fSmrg *comps = 4; 100301e04c3fSmrg return; 100401e04c3fSmrg case MESA_FORMAT_A2R10G10B10_UNORM: 100501e04c3fSmrg case MESA_FORMAT_A2R10G10B10_UINT: 100601e04c3fSmrg *datatype = GL_UNSIGNED_INT_10_10_10_2; 100701e04c3fSmrg *comps = 4; 100801e04c3fSmrg return; 100901e04c3fSmrg 1010af69d88dSmrg case MESA_FORMAT_B2G3R3_UNORM: 101101e04c3fSmrg case MESA_FORMAT_B2G3R3_UINT: 10124a49301eSmrg *datatype = GL_UNSIGNED_BYTE_3_3_2; 10134a49301eSmrg *comps = 3; 10144a49301eSmrg return; 10154a49301eSmrg 1016af69d88dSmrg case MESA_FORMAT_A_UNORM8: 1017af69d88dSmrg case MESA_FORMAT_L_UNORM8: 1018af69d88dSmrg case MESA_FORMAT_I_UNORM8: 1019af69d88dSmrg case MESA_FORMAT_R_UNORM8: 1020af69d88dSmrg case MESA_FORMAT_S_UINT8: 10214a49301eSmrg *datatype = GL_UNSIGNED_BYTE; 10224a49301eSmrg *comps = 1; 10234a49301eSmrg return; 10244a49301eSmrg 10254a49301eSmrg case MESA_FORMAT_YCBCR: 10264a49301eSmrg case MESA_FORMAT_YCBCR_REV: 10277ec681f3Smrg case MESA_FORMAT_RG_RB_UNORM8: 10287ec681f3Smrg case MESA_FORMAT_GR_BR_UNORM8: 10294a49301eSmrg *datatype = GL_UNSIGNED_SHORT; 10304a49301eSmrg *comps = 2; 10314a49301eSmrg return; 10324a49301eSmrg 1033af69d88dSmrg case MESA_FORMAT_S8_UINT_Z24_UNORM: 1034af69d88dSmrg *datatype = GL_UNSIGNED_INT_24_8_MESA; 1035af69d88dSmrg *comps = 2; 10364a49301eSmrg return; 10374a49301eSmrg 1038af69d88dSmrg case MESA_FORMAT_Z24_UNORM_S8_UINT: 1039af69d88dSmrg *datatype = GL_UNSIGNED_INT_8_24_REV_MESA; 1040af69d88dSmrg *comps = 2; 10414a49301eSmrg return; 10424a49301eSmrg 1043af69d88dSmrg case MESA_FORMAT_Z_UNORM16: 10444a49301eSmrg *datatype = GL_UNSIGNED_SHORT; 10454a49301eSmrg *comps = 1; 10464a49301eSmrg return; 10474a49301eSmrg 1048af69d88dSmrg case MESA_FORMAT_Z24_UNORM_X8_UINT: 10494a49301eSmrg *datatype = GL_UNSIGNED_INT; 10504a49301eSmrg *comps = 1; 10514a49301eSmrg return; 10524a49301eSmrg 1053af69d88dSmrg case MESA_FORMAT_X8_UINT_Z24_UNORM: 10544a49301eSmrg *datatype = GL_UNSIGNED_INT; 10554a49301eSmrg *comps = 1; 10564a49301eSmrg return; 10574a49301eSmrg 1058af69d88dSmrg case MESA_FORMAT_Z_UNORM32: 10594a49301eSmrg *datatype = GL_UNSIGNED_INT; 10604a49301eSmrg *comps = 1; 10614a49301eSmrg return; 10624a49301eSmrg 1063af69d88dSmrg case MESA_FORMAT_Z_FLOAT32: 1064af69d88dSmrg *datatype = GL_FLOAT; 1065af69d88dSmrg *comps = 1; 1066af69d88dSmrg return; 1067af69d88dSmrg 1068af69d88dSmrg case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: 1069af69d88dSmrg *datatype = GL_FLOAT_32_UNSIGNED_INT_24_8_REV; 1070af69d88dSmrg *comps = 1; 10714a49301eSmrg return; 10724a49301eSmrg 1073af69d88dSmrg case MESA_FORMAT_R_SNORM8: 1074af69d88dSmrg case MESA_FORMAT_A_SNORM8: 1075af69d88dSmrg case MESA_FORMAT_L_SNORM8: 1076af69d88dSmrg case MESA_FORMAT_I_SNORM8: 10773464ebd5Sriastradh *datatype = GL_BYTE; 10783464ebd5Sriastradh *comps = 1; 10793464ebd5Sriastradh return; 10807ec681f3Smrg case MESA_FORMAT_RG_SNORM8: 10817ec681f3Smrg case MESA_FORMAT_LA_SNORM8: 10823464ebd5Sriastradh *datatype = GL_BYTE; 10833464ebd5Sriastradh *comps = 2; 10843464ebd5Sriastradh return; 1085af69d88dSmrg case MESA_FORMAT_A8B8G8R8_SNORM: 1086af69d88dSmrg case MESA_FORMAT_R8G8B8A8_SNORM: 1087af69d88dSmrg case MESA_FORMAT_X8B8G8R8_SNORM: 10884a49301eSmrg *datatype = GL_BYTE; 10894a49301eSmrg *comps = 4; 10904a49301eSmrg return; 10913464ebd5Sriastradh 1092af69d88dSmrg case MESA_FORMAT_RGBA_UNORM16: 10933464ebd5Sriastradh *datatype = GL_UNSIGNED_SHORT; 10943464ebd5Sriastradh *comps = 4; 10953464ebd5Sriastradh return; 10963464ebd5Sriastradh 1097af69d88dSmrg case MESA_FORMAT_R_SNORM16: 1098af69d88dSmrg case MESA_FORMAT_A_SNORM16: 1099af69d88dSmrg case MESA_FORMAT_L_SNORM16: 1100af69d88dSmrg case MESA_FORMAT_I_SNORM16: 11013464ebd5Sriastradh *datatype = GL_SHORT; 11023464ebd5Sriastradh *comps = 1; 11033464ebd5Sriastradh return; 11047ec681f3Smrg case MESA_FORMAT_RG_SNORM16: 1105af69d88dSmrg case MESA_FORMAT_LA_SNORM16: 11063464ebd5Sriastradh *datatype = GL_SHORT; 11073464ebd5Sriastradh *comps = 2; 11083464ebd5Sriastradh return; 1109af69d88dSmrg case MESA_FORMAT_RGB_SNORM16: 11103464ebd5Sriastradh *datatype = GL_SHORT; 11113464ebd5Sriastradh *comps = 3; 11123464ebd5Sriastradh return; 1113af69d88dSmrg case MESA_FORMAT_RGBA_SNORM16: 11144a49301eSmrg *datatype = GL_SHORT; 11154a49301eSmrg *comps = 4; 11164a49301eSmrg return; 11174a49301eSmrg 1118af69d88dSmrg case MESA_FORMAT_BGR_SRGB8: 11194a49301eSmrg *datatype = GL_UNSIGNED_BYTE; 11204a49301eSmrg *comps = 3; 11214a49301eSmrg return; 1122af69d88dSmrg case MESA_FORMAT_A8B8G8R8_SRGB: 1123af69d88dSmrg case MESA_FORMAT_B8G8R8A8_SRGB: 112401e04c3fSmrg case MESA_FORMAT_A8R8G8B8_SRGB: 1125af69d88dSmrg case MESA_FORMAT_R8G8B8A8_SRGB: 11264a49301eSmrg *datatype = GL_UNSIGNED_BYTE; 11274a49301eSmrg *comps = 4; 11284a49301eSmrg return; 1129af69d88dSmrg case MESA_FORMAT_L_SRGB8: 1130b9abf16eSmaya case MESA_FORMAT_R_SRGB8: 11314a49301eSmrg *datatype = GL_UNSIGNED_BYTE; 11324a49301eSmrg *comps = 1; 11334a49301eSmrg return; 11347ec681f3Smrg case MESA_FORMAT_LA_SRGB8: 11357ec681f3Smrg case MESA_FORMAT_RG_SRGB8: 11364a49301eSmrg *datatype = GL_UNSIGNED_BYTE; 11374a49301eSmrg *comps = 2; 11384a49301eSmrg return; 11394a49301eSmrg 11404a49301eSmrg case MESA_FORMAT_RGBA_FLOAT32: 11414a49301eSmrg *datatype = GL_FLOAT; 11424a49301eSmrg *comps = 4; 11434a49301eSmrg return; 11444a49301eSmrg case MESA_FORMAT_RGBA_FLOAT16: 11454a49301eSmrg *datatype = GL_HALF_FLOAT_ARB; 11464a49301eSmrg *comps = 4; 11474a49301eSmrg return; 11484a49301eSmrg case MESA_FORMAT_RGB_FLOAT32: 11494a49301eSmrg *datatype = GL_FLOAT; 11504a49301eSmrg *comps = 3; 11514a49301eSmrg return; 11524a49301eSmrg case MESA_FORMAT_RGB_FLOAT16: 11534a49301eSmrg *datatype = GL_HALF_FLOAT_ARB; 11544a49301eSmrg *comps = 3; 11554a49301eSmrg return; 1156af69d88dSmrg case MESA_FORMAT_LA_FLOAT32: 11573464ebd5Sriastradh case MESA_FORMAT_RG_FLOAT32: 11584a49301eSmrg *datatype = GL_FLOAT; 11594a49301eSmrg *comps = 2; 11604a49301eSmrg return; 1161af69d88dSmrg case MESA_FORMAT_LA_FLOAT16: 11623464ebd5Sriastradh case MESA_FORMAT_RG_FLOAT16: 11634a49301eSmrg *datatype = GL_HALF_FLOAT_ARB; 11644a49301eSmrg *comps = 2; 11654a49301eSmrg return; 1166af69d88dSmrg case MESA_FORMAT_A_FLOAT32: 1167af69d88dSmrg case MESA_FORMAT_L_FLOAT32: 1168af69d88dSmrg case MESA_FORMAT_I_FLOAT32: 11693464ebd5Sriastradh case MESA_FORMAT_R_FLOAT32: 11704a49301eSmrg *datatype = GL_FLOAT; 11714a49301eSmrg *comps = 1; 11724a49301eSmrg return; 1173af69d88dSmrg case MESA_FORMAT_A_FLOAT16: 1174af69d88dSmrg case MESA_FORMAT_L_FLOAT16: 1175af69d88dSmrg case MESA_FORMAT_I_FLOAT16: 11763464ebd5Sriastradh case MESA_FORMAT_R_FLOAT16: 11774a49301eSmrg *datatype = GL_HALF_FLOAT_ARB; 11784a49301eSmrg *comps = 1; 11794a49301eSmrg return; 11804a49301eSmrg 1181af69d88dSmrg case MESA_FORMAT_A_UINT8: 1182af69d88dSmrg case MESA_FORMAT_L_UINT8: 1183af69d88dSmrg case MESA_FORMAT_I_UINT8: 1184af69d88dSmrg *datatype = GL_UNSIGNED_BYTE; 1185af69d88dSmrg *comps = 1; 1186af69d88dSmrg return; 1187af69d88dSmrg case MESA_FORMAT_LA_UINT8: 1188af69d88dSmrg *datatype = GL_UNSIGNED_BYTE; 1189af69d88dSmrg *comps = 2; 1190af69d88dSmrg return; 1191af69d88dSmrg 1192af69d88dSmrg case MESA_FORMAT_A_UINT16: 1193af69d88dSmrg case MESA_FORMAT_L_UINT16: 1194af69d88dSmrg case MESA_FORMAT_I_UINT16: 1195af69d88dSmrg *datatype = GL_UNSIGNED_SHORT; 1196af69d88dSmrg *comps = 1; 1197af69d88dSmrg return; 1198af69d88dSmrg case MESA_FORMAT_LA_UINT16: 1199af69d88dSmrg *datatype = GL_UNSIGNED_SHORT; 1200af69d88dSmrg *comps = 2; 1201af69d88dSmrg return; 1202af69d88dSmrg case MESA_FORMAT_A_UINT32: 1203af69d88dSmrg case MESA_FORMAT_L_UINT32: 1204af69d88dSmrg case MESA_FORMAT_I_UINT32: 1205af69d88dSmrg *datatype = GL_UNSIGNED_INT; 1206af69d88dSmrg *comps = 1; 1207af69d88dSmrg return; 1208af69d88dSmrg case MESA_FORMAT_LA_UINT32: 1209af69d88dSmrg *datatype = GL_UNSIGNED_INT; 1210af69d88dSmrg *comps = 2; 1211af69d88dSmrg return; 1212af69d88dSmrg case MESA_FORMAT_A_SINT8: 1213af69d88dSmrg case MESA_FORMAT_L_SINT8: 1214af69d88dSmrg case MESA_FORMAT_I_SINT8: 1215af69d88dSmrg *datatype = GL_BYTE; 1216af69d88dSmrg *comps = 1; 1217af69d88dSmrg return; 1218af69d88dSmrg case MESA_FORMAT_LA_SINT8: 1219af69d88dSmrg *datatype = GL_BYTE; 1220af69d88dSmrg *comps = 2; 1221af69d88dSmrg return; 1222af69d88dSmrg 1223af69d88dSmrg case MESA_FORMAT_A_SINT16: 1224af69d88dSmrg case MESA_FORMAT_L_SINT16: 1225af69d88dSmrg case MESA_FORMAT_I_SINT16: 1226af69d88dSmrg *datatype = GL_SHORT; 1227af69d88dSmrg *comps = 1; 1228af69d88dSmrg return; 1229af69d88dSmrg case MESA_FORMAT_LA_SINT16: 1230af69d88dSmrg *datatype = GL_SHORT; 1231af69d88dSmrg *comps = 2; 1232af69d88dSmrg return; 1233af69d88dSmrg 1234af69d88dSmrg case MESA_FORMAT_A_SINT32: 1235af69d88dSmrg case MESA_FORMAT_L_SINT32: 1236af69d88dSmrg case MESA_FORMAT_I_SINT32: 1237af69d88dSmrg *datatype = GL_INT; 1238af69d88dSmrg *comps = 1; 1239af69d88dSmrg return; 1240af69d88dSmrg case MESA_FORMAT_LA_SINT32: 1241af69d88dSmrg *datatype = GL_INT; 1242af69d88dSmrg *comps = 2; 1243af69d88dSmrg return; 1244af69d88dSmrg 1245af69d88dSmrg case MESA_FORMAT_R_SINT8: 1246af69d88dSmrg *datatype = GL_BYTE; 1247af69d88dSmrg *comps = 1; 1248af69d88dSmrg return; 1249af69d88dSmrg case MESA_FORMAT_RG_SINT8: 1250af69d88dSmrg *datatype = GL_BYTE; 1251af69d88dSmrg *comps = 2; 1252af69d88dSmrg return; 1253af69d88dSmrg case MESA_FORMAT_RGB_SINT8: 1254af69d88dSmrg *datatype = GL_BYTE; 1255af69d88dSmrg *comps = 3; 1256af69d88dSmrg return; 1257af69d88dSmrg case MESA_FORMAT_RGBA_SINT8: 12583464ebd5Sriastradh *datatype = GL_BYTE; 12593464ebd5Sriastradh *comps = 4; 12603464ebd5Sriastradh return; 1261af69d88dSmrg case MESA_FORMAT_R_SINT16: 1262af69d88dSmrg *datatype = GL_SHORT; 1263af69d88dSmrg *comps = 1; 1264af69d88dSmrg return; 1265af69d88dSmrg case MESA_FORMAT_RG_SINT16: 1266af69d88dSmrg *datatype = GL_SHORT; 1267af69d88dSmrg *comps = 2; 1268af69d88dSmrg return; 1269af69d88dSmrg case MESA_FORMAT_RGB_SINT16: 1270af69d88dSmrg *datatype = GL_SHORT; 1271af69d88dSmrg *comps = 3; 1272af69d88dSmrg return; 1273af69d88dSmrg case MESA_FORMAT_RGBA_SINT16: 12743464ebd5Sriastradh *datatype = GL_SHORT; 12753464ebd5Sriastradh *comps = 4; 12763464ebd5Sriastradh return; 1277af69d88dSmrg case MESA_FORMAT_R_SINT32: 1278af69d88dSmrg *datatype = GL_INT; 1279af69d88dSmrg *comps = 1; 1280af69d88dSmrg return; 1281af69d88dSmrg case MESA_FORMAT_RG_SINT32: 1282af69d88dSmrg *datatype = GL_INT; 1283af69d88dSmrg *comps = 2; 1284af69d88dSmrg return; 1285af69d88dSmrg case MESA_FORMAT_RGB_SINT32: 1286af69d88dSmrg *datatype = GL_INT; 1287af69d88dSmrg *comps = 3; 1288af69d88dSmrg return; 1289af69d88dSmrg case MESA_FORMAT_RGBA_SINT32: 12903464ebd5Sriastradh *datatype = GL_INT; 12913464ebd5Sriastradh *comps = 4; 12923464ebd5Sriastradh return; 12933464ebd5Sriastradh 12943464ebd5Sriastradh /** 12953464ebd5Sriastradh * \name Non-normalized unsigned integer formats. 12963464ebd5Sriastradh */ 1297af69d88dSmrg case MESA_FORMAT_R_UINT8: 1298af69d88dSmrg *datatype = GL_UNSIGNED_BYTE; 1299af69d88dSmrg *comps = 1; 1300af69d88dSmrg return; 1301af69d88dSmrg case MESA_FORMAT_RG_UINT8: 1302af69d88dSmrg *datatype = GL_UNSIGNED_BYTE; 1303af69d88dSmrg *comps = 2; 1304af69d88dSmrg return; 1305af69d88dSmrg case MESA_FORMAT_RGB_UINT8: 1306af69d88dSmrg *datatype = GL_UNSIGNED_BYTE; 1307af69d88dSmrg *comps = 3; 1308af69d88dSmrg return; 1309af69d88dSmrg case MESA_FORMAT_R_UINT16: 1310af69d88dSmrg *datatype = GL_UNSIGNED_SHORT; 1311af69d88dSmrg *comps = 1; 1312af69d88dSmrg return; 1313af69d88dSmrg case MESA_FORMAT_RG_UINT16: 1314af69d88dSmrg *datatype = GL_UNSIGNED_SHORT; 1315af69d88dSmrg *comps = 2; 1316af69d88dSmrg return; 1317af69d88dSmrg case MESA_FORMAT_RGB_UINT16: 1318af69d88dSmrg *datatype = GL_UNSIGNED_SHORT; 1319af69d88dSmrg *comps = 3; 1320af69d88dSmrg return; 13213464ebd5Sriastradh case MESA_FORMAT_RGBA_UINT16: 13223464ebd5Sriastradh *datatype = GL_UNSIGNED_SHORT; 13233464ebd5Sriastradh *comps = 4; 13243464ebd5Sriastradh return; 1325af69d88dSmrg case MESA_FORMAT_R_UINT32: 1326af69d88dSmrg *datatype = GL_UNSIGNED_INT; 1327af69d88dSmrg *comps = 1; 1328af69d88dSmrg return; 1329af69d88dSmrg case MESA_FORMAT_RG_UINT32: 1330af69d88dSmrg *datatype = GL_UNSIGNED_INT; 1331af69d88dSmrg *comps = 2; 1332af69d88dSmrg return; 1333af69d88dSmrg case MESA_FORMAT_RGB_UINT32: 1334af69d88dSmrg *datatype = GL_UNSIGNED_INT; 1335af69d88dSmrg *comps = 3; 1336af69d88dSmrg return; 13373464ebd5Sriastradh case MESA_FORMAT_RGBA_UINT32: 13383464ebd5Sriastradh *datatype = GL_UNSIGNED_INT; 13393464ebd5Sriastradh *comps = 4; 13403464ebd5Sriastradh return; 13413464ebd5Sriastradh 1342af69d88dSmrg case MESA_FORMAT_R9G9B9E5_FLOAT: 13433464ebd5Sriastradh *datatype = GL_UNSIGNED_INT_5_9_9_9_REV; 13443464ebd5Sriastradh *comps = 3; 13453464ebd5Sriastradh return; 13463464ebd5Sriastradh 1347af69d88dSmrg case MESA_FORMAT_R11G11B10_FLOAT: 13483464ebd5Sriastradh *datatype = GL_UNSIGNED_INT_10F_11F_11F_REV; 13493464ebd5Sriastradh *comps = 3; 13503464ebd5Sriastradh return; 13513464ebd5Sriastradh 1352af69d88dSmrg case MESA_FORMAT_B10G10R10A2_UINT: 1353af69d88dSmrg case MESA_FORMAT_R10G10B10A2_UINT: 1354af69d88dSmrg *datatype = GL_UNSIGNED_INT_2_10_10_10_REV; 1355af69d88dSmrg *comps = 4; 1356af69d88dSmrg return; 1357af69d88dSmrg 1358af69d88dSmrg case MESA_FORMAT_R8G8B8X8_SRGB: 135901e04c3fSmrg case MESA_FORMAT_X8B8G8R8_SRGB: 1360af69d88dSmrg case MESA_FORMAT_RGBX_UINT8: 1361af69d88dSmrg *datatype = GL_UNSIGNED_BYTE; 1362af69d88dSmrg *comps = 4; 1363af69d88dSmrg return; 1364af69d88dSmrg 1365af69d88dSmrg case MESA_FORMAT_R8G8B8X8_SNORM: 1366af69d88dSmrg case MESA_FORMAT_RGBX_SINT8: 1367af69d88dSmrg *datatype = GL_BYTE; 1368af69d88dSmrg *comps = 4; 1369af69d88dSmrg return; 1370af69d88dSmrg 1371af69d88dSmrg case MESA_FORMAT_B10G10R10X2_UNORM: 137201e04c3fSmrg case MESA_FORMAT_R10G10B10X2_UNORM: 1373af69d88dSmrg *datatype = GL_UNSIGNED_INT_2_10_10_10_REV; 1374af69d88dSmrg *comps = 4; 1375af69d88dSmrg return; 1376af69d88dSmrg 1377af69d88dSmrg case MESA_FORMAT_RGBX_UNORM16: 1378af69d88dSmrg case MESA_FORMAT_RGBX_UINT16: 1379af69d88dSmrg *datatype = GL_UNSIGNED_SHORT; 1380af69d88dSmrg *comps = 4; 1381af69d88dSmrg return; 1382af69d88dSmrg 1383af69d88dSmrg case MESA_FORMAT_RGBX_SNORM16: 1384af69d88dSmrg case MESA_FORMAT_RGBX_SINT16: 1385af69d88dSmrg *datatype = GL_SHORT; 1386af69d88dSmrg *comps = 4; 1387af69d88dSmrg return; 1388af69d88dSmrg 1389af69d88dSmrg case MESA_FORMAT_RGBX_FLOAT16: 1390af69d88dSmrg *datatype = GL_HALF_FLOAT; 1391af69d88dSmrg *comps = 4; 1392af69d88dSmrg return; 1393af69d88dSmrg 1394af69d88dSmrg case MESA_FORMAT_RGBX_FLOAT32: 1395af69d88dSmrg *datatype = GL_FLOAT; 1396af69d88dSmrg *comps = 4; 1397af69d88dSmrg return; 1398af69d88dSmrg 1399af69d88dSmrg case MESA_FORMAT_RGBX_UINT32: 1400af69d88dSmrg *datatype = GL_UNSIGNED_INT; 1401af69d88dSmrg *comps = 4; 1402af69d88dSmrg return; 1403af69d88dSmrg 1404af69d88dSmrg case MESA_FORMAT_RGBX_SINT32: 1405af69d88dSmrg *datatype = GL_INT; 1406af69d88dSmrg *comps = 4; 1407af69d88dSmrg return; 1408af69d88dSmrg 1409af69d88dSmrg case MESA_FORMAT_R10G10B10A2_UNORM: 1410af69d88dSmrg *datatype = GL_UNSIGNED_INT_2_10_10_10_REV; 1411af69d88dSmrg *comps = 4; 1412af69d88dSmrg return; 1413af69d88dSmrg 1414af69d88dSmrg case MESA_FORMAT_B8G8R8X8_SRGB: 141501e04c3fSmrg case MESA_FORMAT_X8R8G8B8_SRGB: 1416af69d88dSmrg *datatype = GL_UNSIGNED_BYTE; 1417af69d88dSmrg *comps = 4; 1418af69d88dSmrg return; 1419af69d88dSmrg 14203464ebd5Sriastradh case MESA_FORMAT_COUNT: 14213464ebd5Sriastradh assert(0); 14223464ebd5Sriastradh return; 14237ec681f3Smrg default: { 14247ec681f3Smrg const char *name = _mesa_get_format_name(format); 142501e04c3fSmrg /* Warn if any formats are not handled */ 142601e04c3fSmrg _mesa_problem(NULL, "bad format %s in _mesa_uncompressed_format_to_type_and_comps", 14277ec681f3Smrg name ? name : "???"); 142801e04c3fSmrg assert(format == MESA_FORMAT_NONE || 142901e04c3fSmrg _mesa_is_format_compressed(format)); 14304a49301eSmrg *datatype = 0; 14314a49301eSmrg *comps = 1; 14324a49301eSmrg } 14337ec681f3Smrg } 14344a49301eSmrg} 1435af69d88dSmrg 1436af69d88dSmrg/** 1437af69d88dSmrg * Check if a mesa_format exactly matches a GL format/type combination 1438af69d88dSmrg * such that we can use memcpy() from one to the other. 1439af69d88dSmrg * \param mesa_format a MESA_FORMAT_x value 1440af69d88dSmrg * \param format the user-specified image format 1441af69d88dSmrg * \param type the user-specified image datatype 1442af69d88dSmrg * \param swapBytes typically the current pixel pack/unpack byteswap state 144301e04c3fSmrg * \param[out] error GL_NO_ERROR if format is an expected input. 144401e04c3fSmrg * GL_INVALID_ENUM if format is an unexpected input. 14457ec681f3Smrg * \return true if the formats match, false otherwise. 1446af69d88dSmrg */ 14477ec681f3Smrgbool 14487ec681f3Smrg_mesa_format_matches_format_and_type(mesa_format mformat, 1449af69d88dSmrg GLenum format, GLenum type, 14507ec681f3Smrg bool swapBytes, GLenum *error) 1451af69d88dSmrg{ 145201e04c3fSmrg if (error) 145301e04c3fSmrg *error = GL_NO_ERROR; 1454af69d88dSmrg 14557ec681f3Smrg if (_mesa_is_format_compressed(mformat)) { 14567ec681f3Smrg if (error) 14577ec681f3Smrg *error = GL_INVALID_ENUM; 14587ec681f3Smrg return false; 14597ec681f3Smrg } 1460af69d88dSmrg 14617ec681f3Smrg if (swapBytes && !_mesa_swap_bytes_in_type_enum(&type)) 14627ec681f3Smrg return false; 1463af69d88dSmrg 14647ec681f3Smrg /* format/type don't include srgb and should match regardless of it. */ 14657ec681f3Smrg mformat = _mesa_get_srgb_format_linear(mformat); 1466af69d88dSmrg 14677ec681f3Smrg /* intensity formats are uploaded with GL_RED, and we want to find 14687ec681f3Smrg * memcpy matches for them. 14697ec681f3Smrg */ 14707ec681f3Smrg mformat = _mesa_get_intensity_format_red(mformat); 1471af69d88dSmrg 14727ec681f3Smrg if (format == GL_COLOR_INDEX) 14737ec681f3Smrg return false; 1474af69d88dSmrg 14757ec681f3Smrg mesa_format other_format = _mesa_format_from_format_and_type(format, type); 14767ec681f3Smrg if (_mesa_format_is_mesa_array_format(other_format)) 14777ec681f3Smrg other_format = _mesa_format_from_array_format(other_format); 1478af69d88dSmrg 14797ec681f3Smrg return other_format == mformat; 1480af69d88dSmrg} 1481af69d88dSmrg 1482