X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fformats.c;h=f58b1975672371fca606a70033f1c4c119c3c1c8;hb=3941539179b72fe25b6dffd1aacc0722d198a5ca;hp=d0c9c0028b2cea90d3bc0bedbe2410523f092c1d;hpb=a8238bb08a95e7ea4430450c304a6bee210df1a6;p=mesa.git diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c index d0c9c0028b2..d927073b0dc 100644 --- a/src/mesa/main/formats.c +++ b/src/mesa/main/formats.c @@ -1,6 +1,5 @@ /* * Mesa 3-D graphics library - * Version: 7.7 * * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. * Copyright (c) 2008-2009 VMware, Inc. @@ -18,37 +17,42 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ #include "imports.h" #include "formats.h" -#include "config.h" - +#include "macros.h" +#include "glformats.h" +#include "c11/threads.h" +#include "util/hash_table.h" /** * Information about texture formats. */ struct gl_format_info { - gl_format Name; + mesa_format Name; /** text name for debugging */ const char *StrName; + enum mesa_format_layout Layout; + /** - * Base format is one of GL_RGB, GL_RGBA, GL_ALPHA, GL_LUMINANCE, - * GL_LUMINANCE_ALPHA, GL_INTENSITY, GL_YCBCR_MESA, GL_COLOR_INDEX, + * Base format is one of GL_RED, GL_RG, GL_RGB, GL_RGBA, GL_ALPHA, + * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_INTENSITY, GL_YCBCR_MESA, * GL_DEPTH_COMPONENT, GL_STENCIL_INDEX, GL_DEPTH_STENCIL. */ GLenum BaseFormat; /** - * Logical data type: one of GL_UNSIGNED_NORMALIZED, GL_SIGNED_NORMALED, - * GL_UNSIGNED_INT, GL_SIGNED_INT, GL_FLOAT. + * Logical data type: one of GL_UNSIGNED_NORMALIZED, GL_SIGNED_NORMALIZED, + * GL_UNSIGNED_INT, GL_INT, GL_FLOAT. */ GLenum DataType; @@ -58,7 +62,6 @@ struct gl_format_info GLubyte AlphaBits; GLubyte LuminanceBits; GLubyte IntensityBits; - GLubyte IndexBits; GLubyte DepthBits; GLubyte StencilBits; @@ -67,609 +70,15 @@ struct gl_format_info */ GLubyte BlockWidth, BlockHeight; GLubyte BytesPerBlock; -}; - -/** - * Info about each format. - * These must be in the same order as the MESA_FORMAT_* enums so that - * we can do lookups without searching. - */ -static struct gl_format_info format_info[MESA_FORMAT_COUNT] = -{ - { - MESA_FORMAT_NONE, /* Name */ - "MESA_FORMAT_NONE", /* StrName */ - GL_NONE, /* BaseFormat */ - GL_NONE, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 0, 0, 0 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_RGBA8888, /* Name */ - "MESA_FORMAT_RGBA8888", /* StrName */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 8, 8, 8, 8, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_RGBA8888_REV, /* Name */ - "MESA_FORMAT_RGBA8888_REV", /* StrName */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 8, 8, 8, 8, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_ARGB8888, /* Name */ - "MESA_FORMAT_ARGB8888", /* StrName */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 8, 8, 8, 8, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_ARGB8888_REV, /* Name */ - "MESA_FORMAT_ARGB8888_REV", /* StrName */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 8, 8, 8, 8, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_XRGB8888, /* Name */ - "MESA_FORMAT_XRGB8888", /* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 8, 8, 8, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_XRGB8888_REV, /* Name */ - "MESA_FORMAT_XRGB8888_REV", /* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 8, 8, 8, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_RGB888, /* Name */ - "MESA_FORMAT_RGB888", /* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 8, 8, 8, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 3 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_BGR888, /* Name */ - "MESA_FORMAT_BGR888", /* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 8, 8, 8, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 3 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_RGB565, /* Name */ - "MESA_FORMAT_RGB565", /* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 5, 6, 5, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_RGB565_REV, /* Name */ - "MESA_FORMAT_RGB565_REV", /* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 5, 6, 5, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_ARGB4444, /* Name */ - "MESA_FORMAT_ARGB4444", /* StrName */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 4, 4, 4, 4, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_ARGB4444_REV, /* Name */ - "MESA_FORMAT_ARGB4444_REV", /* StrName */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 4, 4, 4, 4, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_RGBA5551, /* Name */ - "MESA_FORMAT_RGBA5551", /* StrName */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 5, 5, 5, 1, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_ARGB1555, /* Name */ - "MESA_FORMAT_ARGB1555", /* StrName */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 5, 5, 5, 1, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_ARGB1555_REV, /* Name */ - "MESA_FORMAT_ARGB1555_REV", /* StrName */ - GL_RGBA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 5, 5, 5, 1, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_AL88, /* Name */ - "MESA_FORMAT_AL88", /* StrName */ - GL_LUMINANCE_ALPHA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 8, /* Red/Green/Blue/AlphaBits */ - 8, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_AL88_REV, /* Name */ - "MESA_FORMAT_AL88_REV", /* StrName */ - GL_LUMINANCE_ALPHA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 8, /* Red/Green/Blue/AlphaBits */ - 8, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_AL1616, /* Name */ - "MESA_FORMAT_AL1616", /* StrName */ - GL_LUMINANCE_ALPHA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 16, /* Red/Green/Blue/AlphaBits */ - 16, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_AL1616_REV, /* Name */ - "MESA_FORMAT_AL1616_REV", /* StrName */ - GL_LUMINANCE_ALPHA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 16, /* Red/Green/Blue/AlphaBits */ - 16, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_RGB332, /* Name */ - "MESA_FORMAT_RGB332", /* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 3, 3, 2, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 1 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_A8, /* Name */ - "MESA_FORMAT_A8", /* StrName */ - GL_ALPHA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 8, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 1 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_L8, /* Name */ - "MESA_FORMAT_L8", /* StrName */ - GL_LUMINANCE, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 8, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 1 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_I8, /* Name */ - "MESA_FORMAT_I8", /* StrName */ - GL_INTENSITY, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 8, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 1 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_CI8, /* Name */ - "MESA_FORMAT_CI8", /* StrName */ - GL_COLOR_INDEX, /* BaseFormat */ - GL_UNSIGNED_INT, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 8, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 1 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_YCBCR, /* Name */ - "MESA_FORMAT_YCBCR", /* StrName */ - GL_YCBCR_MESA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_YCBCR_REV, /* Name */ - "MESA_FORMAT_YCBCR_REV", /* StrName */ - GL_YCBCR_MESA, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_Z24_S8, /* Name */ - "MESA_FORMAT_Z24_S8", /* StrName */ - GL_DEPTH_STENCIL, /* BaseFormat */ - GL_UNSIGNED_INT, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 24, 8, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_S8_Z24, /* Name */ - "MESA_FORMAT_S8_Z24", /* StrName */ - GL_DEPTH_STENCIL, /* BaseFormat */ - GL_UNSIGNED_INT, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 24, 8, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_Z16, /* Name */ - "MESA_FORMAT_Z16", /* StrName */ - GL_DEPTH_COMPONENT, /* BaseFormat */ - GL_UNSIGNED_INT, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 16, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 2 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_X8_Z24, /* Name */ - "MESA_FORMAT_X8_Z24", /* StrName */ - GL_DEPTH_COMPONENT, /* BaseFormat */ - GL_UNSIGNED_INT, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 24, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_Z24_X8, /* Name */ - "MESA_FORMAT_Z24_X8", /* StrName */ - GL_DEPTH_COMPONENT, /* BaseFormat */ - GL_UNSIGNED_INT, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 24, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_Z32, /* Name */ - "MESA_FORMAT_Z32", /* StrName */ - GL_DEPTH_COMPONENT, /* BaseFormat */ - GL_UNSIGNED_INT, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 32, 0, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 4 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_S8, /* Name */ - "MESA_FORMAT_S8", /* StrName */ - GL_STENCIL_INDEX, /* BaseFormat */ - GL_UNSIGNED_INT, /* DataType */ - 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 8, /* Lum/Int/Index/Depth/StencilBits */ - 1, 1, 1 /* BlockWidth/Height,Bytes */ - }, - { - MESA_FORMAT_SRGB8, - "MESA_FORMAT_SRGB8", - GL_RGB, - GL_UNSIGNED_NORMALIZED, - 8, 8, 8, 0, - 0, 0, 0, 0, 0, - 1, 1, 3 - }, - { - MESA_FORMAT_SRGBA8, - "MESA_FORMAT_SRGBA8", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 8, 8, 8, 8, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_SARGB8, - "MESA_FORMAT_SARGB8", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 8, 8, 8, 8, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_SL8, - "MESA_FORMAT_SL8", - GL_LUMINANCE, - GL_UNSIGNED_NORMALIZED, - 0, 0, 0, 0, - 8, 0, 0, 0, 0, - 1, 1, 1 - }, - { - MESA_FORMAT_SLA8, - "MESA_FORMAT_SLA8", - GL_LUMINANCE_ALPHA, - GL_UNSIGNED_NORMALIZED, - 0, 0, 0, 8, - 8, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_SRGB_DXT1, /* Name */ - "MESA_FORMAT_SRGB_DXT1", /* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 4, 4, 4, 0, /* approx Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 4, 4, 8 /* 8 bytes per 4x4 block */ - }, - { - MESA_FORMAT_SRGBA_DXT1, - "MESA_FORMAT_SRGBA_DXT1", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 4, 4, 4, 4, - 0, 0, 0, 0, 0, - 4, 4, 8 /* 8 bytes per 4x4 block */ - }, - { - MESA_FORMAT_SRGBA_DXT3, - "MESA_FORMAT_SRGBA_DXT3", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 4, 4, 4, 4, - 0, 0, 0, 0, 0, - 4, 4, 16 /* 16 bytes per 4x4 block */ - }, - { - MESA_FORMAT_SRGBA_DXT5, - "MESA_FORMAT_SRGBA_DXT5", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 4, 4, 4, 4, - 0, 0, 0, 0, 0, - 4, 4, 16 /* 16 bytes per 4x4 block */ - }, - - { - MESA_FORMAT_RGB_FXT1, - "MESA_FORMAT_RGB_FXT1", - GL_RGB, - GL_UNSIGNED_NORMALIZED, - 4, 4, 4, 0, /* approx Red/Green/BlueBits */ - 0, 0, 0, 0, 0, - 8, 4, 16 /* 16 bytes per 8x4 block */ - }, - { - MESA_FORMAT_RGBA_FXT1, - "MESA_FORMAT_RGBA_FXT1", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 4, 4, 4, 1, /* approx Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, - 8, 4, 16 /* 16 bytes per 8x4 block */ - }, - - { - MESA_FORMAT_RGB_DXT1, /* Name */ - "MESA_FORMAT_RGB_DXT1", /* StrName */ - GL_RGB, /* BaseFormat */ - GL_UNSIGNED_NORMALIZED, /* DataType */ - 4, 4, 4, 0, /* approx Red/Green/Blue/AlphaBits */ - 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */ - 4, 4, 8 /* 8 bytes per 4x4 block */ - }, - { - MESA_FORMAT_RGBA_DXT1, - "MESA_FORMAT_RGBA_DXT1", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 4, 4, 4, 4, - 0, 0, 0, 0, 0, - 4, 4, 8 /* 8 bytes per 4x4 block */ - }, - { - MESA_FORMAT_RGBA_DXT3, - "MESA_FORMAT_RGBA_DXT3", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 4, 4, 4, 4, - 0, 0, 0, 0, 0, - 4, 4, 16 /* 16 bytes per 4x4 block */ - }, - { - MESA_FORMAT_RGBA_DXT5, - "MESA_FORMAT_RGBA_DXT5", - GL_RGBA, - GL_UNSIGNED_NORMALIZED, - 4, 4, 4, 4, - 0, 0, 0, 0, 0, - 4, 4, 16 /* 16 bytes per 4x4 block */ - }, - { - MESA_FORMAT_RGBA_FLOAT32, - "MESA_FORMAT_RGBA_FLOAT32", - GL_RGBA, - GL_FLOAT, - 32, 32, 32, 32, - 0, 0, 0, 0, 0, - 1, 1, 16 - }, - { - MESA_FORMAT_RGBA_FLOAT16, - "MESA_FORMAT_RGBA_FLOAT16", - GL_RGBA, - GL_FLOAT, - 16, 16, 16, 16, - 0, 0, 0, 0, 0, - 1, 1, 8 - }, - { - MESA_FORMAT_RGB_FLOAT32, - "MESA_FORMAT_RGB_FLOAT32", - GL_RGB, - GL_FLOAT, - 32, 32, 32, 0, - 0, 0, 0, 0, 0, - 1, 1, 12 - }, - { - MESA_FORMAT_RGB_FLOAT16, - "MESA_FORMAT_RGB_FLOAT16", - GL_RGB, - GL_FLOAT, - 16, 16, 16, 0, - 0, 0, 0, 0, 0, - 1, 1, 6 - }, - { - MESA_FORMAT_ALPHA_FLOAT32, - "MESA_FORMAT_ALPHA_FLOAT32", - GL_ALPHA, - GL_FLOAT, - 0, 0, 0, 32, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_ALPHA_FLOAT16, - "MESA_FORMAT_ALPHA_FLOAT16", - GL_ALPHA, - GL_FLOAT, - 0, 0, 0, 16, - 0, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_LUMINANCE_FLOAT32, - "MESA_FORMAT_LUMINANCE_FLOAT32", - GL_ALPHA, - GL_FLOAT, - 0, 0, 0, 0, - 32, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_LUMINANCE_FLOAT16, - "MESA_FORMAT_LUMINANCE_FLOAT16", - GL_ALPHA, - GL_FLOAT, - 0, 0, 0, 0, - 16, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32, - "MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32", - GL_LUMINANCE_ALPHA, - GL_FLOAT, - 0, 0, 0, 32, - 32, 0, 0, 0, 0, - 1, 1, 8 - }, - { - MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16, - "MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16", - GL_LUMINANCE_ALPHA, - GL_FLOAT, - 0, 0, 0, 16, - 16, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_INTENSITY_FLOAT32, - "MESA_FORMAT_INTENSITY_FLOAT32", - GL_INTENSITY, - GL_FLOAT, - 0, 0, 0, 0, - 0, 32, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_INTENSITY_FLOAT16, - "MESA_FORMAT_INTENSITY_FLOAT16", - GL_INTENSITY, - GL_FLOAT, - 0, 0, 0, 0, - 0, 16, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_DUDV8, - "MESA_FORMAT_DUDV8", - GL_DUDV_ATI, - GL_SIGNED_NORMALIZED, - 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 1, 1, 2 - }, - { - MESA_FORMAT_SIGNED_RGBA8888, - "MESA_FORMAT_SIGNED_RGBA8888", - GL_RGBA, - GL_SIGNED_NORMALIZED, - 8, 8, 8, 8, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_SIGNED_RGBA8888_REV, - "MESA_FORMAT_SIGNED_RGBA8888_REV", - GL_RGBA, - GL_SIGNED_NORMALIZED, - 8, 8, 8, 8, - 0, 0, 0, 0, 0, - 1, 1, 4 - }, - { - MESA_FORMAT_SIGNED_RGBA_16, - "MESA_FORMAT_SIGNED_RGBA_16", - GL_RGBA, - GL_SIGNED_NORMALIZED, - 16, 16, 16, 16, - 0, 0, 0, 0, 0, - 1, 1, 8 - } + uint8_t Swizzle[4]; + mesa_array_format ArrayFormat; }; - +#include "format_info.h" static const struct gl_format_info * -_mesa_get_format_info(gl_format format) +_mesa_get_format_info(mesa_format format) { const struct gl_format_info *info = &format_info[format]; assert(info->Name == format); @@ -679,10 +88,9 @@ _mesa_get_format_info(gl_format format) /** Return string name of format (for debugging) */ const char * -_mesa_get_format_name(gl_format format) +_mesa_get_format_name(mesa_format format) { const struct gl_format_info *info = _mesa_get_format_info(format); - ASSERT(info->BytesPerBlock); return info->StrName; } @@ -692,12 +100,16 @@ _mesa_get_format_name(gl_format format) * Return bytes needed to store a block of pixels in the given format. * Normally, a block is 1x1 (a single pixel). But for compressed formats * a block may be 4x4 or 8x4, etc. + * + * Note: not GLuint, so as not to coerce math to unsigned. cf. fdo #37351 */ -GLuint -_mesa_get_format_bytes(gl_format format) +GLint +_mesa_get_format_bytes(mesa_format format) { const struct gl_format_info *info = _mesa_get_format_info(format); - ASSERT(info->BytesPerBlock); + assert(info->BytesPerBlock); + assert(info->BytesPerBlock <= MAX_PIXEL_BYTES || + _mesa_is_format_compressed(format)); return info->BytesPerBlock; } @@ -708,7 +120,7 @@ _mesa_get_format_bytes(gl_format format) * \param pname the component, such as GL_RED_BITS, GL_TEXTURE_BLUE_BITS, etc. */ GLint -_mesa_get_format_bits(gl_format format, GLenum pname) +_mesa_get_format_bits(mesa_format format, GLenum pname) { const struct gl_format_info *info = _mesa_get_format_info(format); @@ -738,8 +150,7 @@ _mesa_get_format_bits(gl_format format, GLenum pname) case GL_TEXTURE_LUMINANCE_SIZE: return info->LuminanceBits; case GL_INDEX_BITS: - case GL_TEXTURE_INDEX_SIZE_EXT: - return info->IndexBits; + return 0; case GL_DEPTH_BITS: case GL_TEXTURE_DEPTH_SIZE_ARB: case GL_RENDERBUFFER_DEPTH_SIZE_EXT: @@ -757,6 +168,36 @@ _mesa_get_format_bits(gl_format format, GLenum pname) } +GLuint +_mesa_get_format_max_bits(mesa_format format) +{ + const struct gl_format_info *info = _mesa_get_format_info(format); + GLuint max = MAX2(info->RedBits, info->GreenBits); + max = MAX2(max, info->BlueBits); + max = MAX2(max, info->AlphaBits); + max = MAX2(max, info->LuminanceBits); + max = MAX2(max, info->IntensityBits); + max = MAX2(max, info->DepthBits); + max = MAX2(max, info->StencilBits); + return max; +} + + +/** + * Return the layout type of the given format. + * The return value will be one of: + * MESA_FORMAT_LAYOUT_ARRAY + * MESA_FORMAT_LAYOUT_PACKED + * MESA_FORMAT_LAYOUT_OTHER + */ +extern enum mesa_format_layout +_mesa_get_format_layout(mesa_format format) +{ + const struct gl_format_info *info = _mesa_get_format_info(format); + return info->Layout; +} + + /** * Return the data type (or more specifically, the data representation) * for the given format. @@ -764,27 +205,97 @@ _mesa_get_format_bits(gl_format format, GLenum pname) * GL_UNSIGNED_NORMALIZED = unsigned int representing [0,1] * GL_SIGNED_NORMALIZED = signed int representing [-1, 1] * GL_UNSIGNED_INT = an ordinary unsigned integer + * GL_INT = an ordinary signed integer * GL_FLOAT = an ordinary float */ GLenum -_mesa_get_format_datatype(gl_format format) +_mesa_get_format_datatype(mesa_format format) { const struct gl_format_info *info = _mesa_get_format_info(format); return info->DataType; } +static GLenum +get_base_format_for_array_format(mesa_array_format format) +{ + uint8_t swizzle[4]; + int num_channels; + + _mesa_array_format_get_swizzle(format, swizzle); + num_channels = _mesa_array_format_get_num_channels(format); + + switch (num_channels) { + case 4: + /* FIXME: RGBX formats have 4 channels, but their base format is GL_RGB. + * This is not really a problem for now because we only create array + * formats from GL format/type combinations, and these cannot specify + * RGBX formats. + */ + return GL_RGBA; + case 3: + return GL_RGB; + case 2: + if (swizzle[0] == 0 && + swizzle[1] == 0 && + swizzle[2] == 0 && + swizzle[3] == 1) + return GL_LUMINANCE_ALPHA; + if (swizzle[0] == 1 && + swizzle[1] == 1 && + swizzle[2] == 1 && + swizzle[3] == 0) + return GL_LUMINANCE_ALPHA; + if (swizzle[0] == 0 && + swizzle[1] == 1 && + swizzle[2] == 4 && + swizzle[3] == 5) + return GL_RG; + if (swizzle[0] == 1 && + swizzle[1] == 0 && + swizzle[2] == 4 && + swizzle[3] == 5) + return GL_RG; + break; + case 1: + if (swizzle[0] == 0 && + swizzle[1] == 0 && + swizzle[2] == 0 && + swizzle[3] == 5) + return GL_LUMINANCE; + if (swizzle[0] == 0 && + swizzle[1] == 0 && + swizzle[2] == 0 && + swizzle[3] == 0) + return GL_INTENSITY; + if (swizzle[0] <= MESA_FORMAT_SWIZZLE_W) + return GL_RED; + if (swizzle[1] <= MESA_FORMAT_SWIZZLE_W) + return GL_GREEN; + if (swizzle[2] <= MESA_FORMAT_SWIZZLE_W) + return GL_BLUE; + if (swizzle[3] <= MESA_FORMAT_SWIZZLE_W) + return GL_ALPHA; + break; + } + + unreachable("Unsupported format"); +} /** - * Return the basic format for the given type. The result will be - * one of GL_RGB, GL_RGBA, GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, - * GL_INTENSITY, GL_YCBCR_MESA, GL_COLOR_INDEX, GL_DEPTH_COMPONENT, - * GL_STENCIL_INDEX, GL_DEPTH_STENCIL. + * Return the basic format for the given type. The result will be one of + * GL_RGB, GL_RGBA, GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_INTENSITY, + * GL_YCBCR_MESA, GL_DEPTH_COMPONENT, GL_STENCIL_INDEX, GL_DEPTH_STENCIL. + * This functions accepts a mesa_format or a mesa_array_format. */ GLenum -_mesa_get_format_base_format(gl_format format) +_mesa_get_format_base_format(uint32_t format) { - const struct gl_format_info *info = _mesa_get_format_info(format); - return info->BaseFormat; + if (!_mesa_format_is_mesa_array_format(format)) { + const struct gl_format_info *info = _mesa_get_format_info(format); + return info->BaseFormat; + } else { + return get_base_format_for_array_format(format); + } } @@ -796,7 +307,7 @@ _mesa_get_format_base_format(gl_format format) * \param bh returns block height in pixels */ void -_mesa_get_format_block_size(gl_format format, GLuint *bw, GLuint *bh) +_mesa_get_format_block_size(mesa_format format, GLuint *bw, GLuint *bh) { const struct gl_format_info *info = _mesa_get_format_info(format); *bw = info->BlockWidth; @@ -804,33 +315,264 @@ _mesa_get_format_block_size(gl_format format, GLuint *bw, GLuint *bh) } +/** + * Returns the an array of four numbers representing the transformation + * from the RGBA or SZ colorspace to the given format. For array formats, + * the i'th RGBA component is given by: + * + * if (swizzle[i] <= MESA_FORMAT_SWIZZLE_W) + * comp = data[swizzle[i]]; + * else if (swizzle[i] == MESA_FORMAT_SWIZZLE_ZERO) + * comp = 0; + * else if (swizzle[i] == MESA_FORMAT_SWIZZLE_ONE) + * comp = 1; + * else if (swizzle[i] == MESA_FORMAT_SWIZZLE_NONE) + * // data does not contain a channel of this format + * + * For packed formats, the swizzle gives the number of components left of + * the least significant bit. + * + * Compressed formats have no swizzle. + */ +void +_mesa_get_format_swizzle(mesa_format format, uint8_t swizzle_out[4]) +{ + const struct gl_format_info *info = _mesa_get_format_info(format); + memcpy(swizzle_out, info->Swizzle, sizeof(info->Swizzle)); +} + +mesa_array_format +_mesa_array_format_flip_channels(mesa_array_format format) +{ + int num_channels; + uint8_t swizzle[4]; + + num_channels = _mesa_array_format_get_num_channels(format); + _mesa_array_format_get_swizzle(format, swizzle); + + if (num_channels == 1) + return format; + + if (num_channels == 2) { + _mesa_array_format_set_swizzle(&format, swizzle[1], swizzle[0], + swizzle[2], swizzle[3]); + return format; + } + + if (num_channels == 4) { + _mesa_array_format_set_swizzle(&format, swizzle[3], swizzle[2], + swizzle[1], swizzle[0]); + return format; + } + + unreachable("Invalid array format"); +} + +uint32_t +_mesa_format_to_array_format(mesa_format format) +{ + const struct gl_format_info *info = _mesa_get_format_info(format); + if (!_mesa_little_endian() && info->Layout == MESA_FORMAT_LAYOUT_PACKED) + return _mesa_array_format_flip_channels(info->ArrayFormat); + else + return info->ArrayFormat; +} + +static struct hash_table *format_array_format_table; +static once_flag format_array_format_table_exists = ONCE_FLAG_INIT; + +static bool +array_formats_equal(const void *a, const void *b) +{ + return (intptr_t)a == (intptr_t)b; +} + +static void +format_array_format_table_init(void) +{ + const struct gl_format_info *info; + mesa_array_format array_format; + unsigned f; + + format_array_format_table = _mesa_hash_table_create(NULL, NULL, + array_formats_equal); + + if (!format_array_format_table) { + _mesa_error_no_memory(__func__); + return; + } + + for (f = 1; f < MESA_FORMAT_COUNT; ++f) { + info = _mesa_get_format_info(f); + if (!info->ArrayFormat) + continue; + + if (_mesa_little_endian()) { + array_format = info->ArrayFormat; + } else { + array_format = _mesa_array_format_flip_channels(info->ArrayFormat); + } + + /* This can happen and does for some of the BGR formats. Let's take + * the first one in the list. + */ + if (_mesa_hash_table_search_pre_hashed(format_array_format_table, + array_format, + (void *)(intptr_t)array_format)) + continue; + + _mesa_hash_table_insert_pre_hashed(format_array_format_table, + array_format, + (void *)(intptr_t)array_format, + (void *)(intptr_t)f); + } +} + +mesa_format +_mesa_format_from_array_format(uint32_t array_format) +{ + struct hash_entry *entry; + + assert(_mesa_format_is_mesa_array_format(array_format)); + + call_once(&format_array_format_table_exists, format_array_format_table_init); + + if (!format_array_format_table) { + static const once_flag once_flag_init = ONCE_FLAG_INIT; + format_array_format_table_exists = once_flag_init; + return MESA_FORMAT_NONE; + } + + entry = _mesa_hash_table_search_pre_hashed(format_array_format_table, + array_format, + (void *)(intptr_t)array_format); + if (entry) + return (intptr_t)entry->data; + else + return MESA_FORMAT_NONE; +} + /** Is the given format a compressed format? */ GLboolean -_mesa_is_format_compressed(gl_format format) +_mesa_is_format_compressed(mesa_format format) { const struct gl_format_info *info = _mesa_get_format_info(format); return info->BlockWidth > 1 || info->BlockHeight > 1; } +/** + * Determine if the given format represents a packed depth/stencil buffer. + */ +GLboolean +_mesa_is_format_packed_depth_stencil(mesa_format format) +{ + const struct gl_format_info *info = _mesa_get_format_info(format); + + return info->BaseFormat == GL_DEPTH_STENCIL; +} + + +/** + * Is the given format a signed/unsigned integer color format? + */ +GLboolean +_mesa_is_format_integer_color(mesa_format format) +{ + const struct gl_format_info *info = _mesa_get_format_info(format); + return (info->DataType == GL_INT || info->DataType == GL_UNSIGNED_INT) && + info->BaseFormat != GL_DEPTH_COMPONENT && + info->BaseFormat != GL_DEPTH_STENCIL && + info->BaseFormat != GL_STENCIL_INDEX; +} + + +/** + * Is the given format an unsigned integer format? + */ +GLboolean +_mesa_is_format_unsigned(mesa_format format) +{ + const struct gl_format_info *info = _mesa_get_format_info(format); + return _mesa_is_type_unsigned(info->DataType); +} + + +/** + * Does the given format store signed values? + */ +GLboolean +_mesa_is_format_signed(mesa_format format) +{ + if (format == MESA_FORMAT_R11G11B10_FLOAT || + format == MESA_FORMAT_R9G9B9E5_FLOAT) { + /* these packed float formats only store unsigned values */ + return GL_FALSE; + } + else { + const struct gl_format_info *info = _mesa_get_format_info(format); + return (info->DataType == GL_SIGNED_NORMALIZED || + info->DataType == GL_INT || + info->DataType == GL_FLOAT); + } +} + +/** + * Is the given format an integer format? + */ +GLboolean +_mesa_is_format_integer(mesa_format format) +{ + const struct gl_format_info *info = _mesa_get_format_info(format); + return (info->DataType == GL_INT || info->DataType == GL_UNSIGNED_INT); +} + + +/** + * Return true if the given format is a color format. + */ +GLenum +_mesa_is_format_color_format(mesa_format format) +{ + const struct gl_format_info *info = _mesa_get_format_info(format); + switch (info->BaseFormat) { + case GL_DEPTH_COMPONENT: + case GL_STENCIL_INDEX: + case GL_DEPTH_STENCIL: + return false; + default: + return true; + } +} + + /** * Return color encoding for given format. * \return GL_LINEAR or GL_SRGB */ GLenum -_mesa_get_format_color_encoding(gl_format format) +_mesa_get_format_color_encoding(mesa_format format) { /* XXX this info should be encoded in gl_format_info */ switch (format) { - case MESA_FORMAT_SRGB8: - case MESA_FORMAT_SRGBA8: - case MESA_FORMAT_SARGB8: - case MESA_FORMAT_SL8: - case MESA_FORMAT_SLA8: + case MESA_FORMAT_BGR_SRGB8: + case MESA_FORMAT_A8B8G8R8_SRGB: + case MESA_FORMAT_B8G8R8A8_SRGB: + case MESA_FORMAT_A8R8G8B8_SRGB: + case MESA_FORMAT_R8G8B8A8_SRGB: + case MESA_FORMAT_L_SRGB8: + case MESA_FORMAT_L8A8_SRGB: + case MESA_FORMAT_A8L8_SRGB: case MESA_FORMAT_SRGB_DXT1: case MESA_FORMAT_SRGBA_DXT1: case MESA_FORMAT_SRGBA_DXT3: case MESA_FORMAT_SRGBA_DXT5: + case MESA_FORMAT_R8G8B8X8_SRGB: + case MESA_FORMAT_ETC2_SRGB8: + case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC: + case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: + case MESA_FORMAT_B8G8R8X8_SRGB: + case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM: return GL_SRGB; default: return GL_LINEAR; @@ -838,23 +580,237 @@ _mesa_get_format_color_encoding(gl_format format) } +/** + * Return TRUE if format is an ETC2 compressed format specified + * by GL_ARB_ES3_compatibility. + */ +bool +_mesa_is_format_etc2(mesa_format format) +{ + switch (format) { + case MESA_FORMAT_ETC2_RGB8: + case MESA_FORMAT_ETC2_SRGB8: + case MESA_FORMAT_ETC2_RGBA8_EAC: + case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC: + case MESA_FORMAT_ETC2_R11_EAC: + case MESA_FORMAT_ETC2_RG11_EAC: + case MESA_FORMAT_ETC2_SIGNED_R11_EAC: + case MESA_FORMAT_ETC2_SIGNED_RG11_EAC: + case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: + case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: + return GL_TRUE; + default: + return GL_FALSE; + } +} + + +/** + * For an sRGB format, return the corresponding linear color space format. + * For non-sRGB formats, return the format as-is. + */ +mesa_format +_mesa_get_srgb_format_linear(mesa_format format) +{ + switch (format) { + case MESA_FORMAT_BGR_SRGB8: + format = MESA_FORMAT_BGR_UNORM8; + break; + case MESA_FORMAT_A8B8G8R8_SRGB: + format = MESA_FORMAT_A8B8G8R8_UNORM; + break; + case MESA_FORMAT_B8G8R8A8_SRGB: + format = MESA_FORMAT_B8G8R8A8_UNORM; + break; + case MESA_FORMAT_A8R8G8B8_SRGB: + format = MESA_FORMAT_A8R8G8B8_UNORM; + break; + case MESA_FORMAT_R8G8B8A8_SRGB: + format = MESA_FORMAT_R8G8B8A8_UNORM; + break; + case MESA_FORMAT_L_SRGB8: + format = MESA_FORMAT_L_UNORM8; + break; + case MESA_FORMAT_L8A8_SRGB: + format = MESA_FORMAT_L8A8_UNORM; + break; + case MESA_FORMAT_A8L8_SRGB: + format = MESA_FORMAT_A8L8_UNORM; + break; + case MESA_FORMAT_SRGB_DXT1: + format = MESA_FORMAT_RGB_DXT1; + break; + case MESA_FORMAT_SRGBA_DXT1: + format = MESA_FORMAT_RGBA_DXT1; + break; + case MESA_FORMAT_SRGBA_DXT3: + format = MESA_FORMAT_RGBA_DXT3; + break; + case MESA_FORMAT_SRGBA_DXT5: + format = MESA_FORMAT_RGBA_DXT5; + break; + case MESA_FORMAT_R8G8B8X8_SRGB: + format = MESA_FORMAT_R8G8B8X8_UNORM; + break; + case MESA_FORMAT_X8B8G8R8_SRGB: + format = MESA_FORMAT_X8B8G8R8_UNORM; + break; + case MESA_FORMAT_ETC2_SRGB8: + format = MESA_FORMAT_ETC2_RGB8; + break; + case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC: + format = MESA_FORMAT_ETC2_RGBA8_EAC; + break; + case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: + format = MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1; + break; + case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM: + format = MESA_FORMAT_BPTC_RGBA_UNORM; + break; + case MESA_FORMAT_B8G8R8X8_SRGB: + format = MESA_FORMAT_B8G8R8X8_UNORM; + break; + case MESA_FORMAT_X8R8G8B8_SRGB: + format = MESA_FORMAT_X8R8G8B8_UNORM; + break; + default: + break; + } + return format; +} + + +/** + * If the given format is a compressed format, return a corresponding + * uncompressed format. + */ +mesa_format +_mesa_get_uncompressed_format(mesa_format format) +{ + switch (format) { + case MESA_FORMAT_RGB_FXT1: + return MESA_FORMAT_BGR_UNORM8; + case MESA_FORMAT_RGBA_FXT1: + return MESA_FORMAT_A8B8G8R8_UNORM; + case MESA_FORMAT_RGB_DXT1: + case MESA_FORMAT_SRGB_DXT1: + return MESA_FORMAT_BGR_UNORM8; + case MESA_FORMAT_RGBA_DXT1: + case MESA_FORMAT_SRGBA_DXT1: + return MESA_FORMAT_A8B8G8R8_UNORM; + case MESA_FORMAT_RGBA_DXT3: + case MESA_FORMAT_SRGBA_DXT3: + return MESA_FORMAT_A8B8G8R8_UNORM; + case MESA_FORMAT_RGBA_DXT5: + case MESA_FORMAT_SRGBA_DXT5: + return MESA_FORMAT_A8B8G8R8_UNORM; + case MESA_FORMAT_R_RGTC1_UNORM: + return MESA_FORMAT_R_UNORM8; + case MESA_FORMAT_R_RGTC1_SNORM: + return MESA_FORMAT_R_SNORM8; + case MESA_FORMAT_RG_RGTC2_UNORM: + return MESA_FORMAT_R8G8_UNORM; + case MESA_FORMAT_RG_RGTC2_SNORM: + return MESA_FORMAT_R8G8_SNORM; + case MESA_FORMAT_L_LATC1_UNORM: + return MESA_FORMAT_L_UNORM8; + case MESA_FORMAT_L_LATC1_SNORM: + return MESA_FORMAT_L_SNORM8; + case MESA_FORMAT_LA_LATC2_UNORM: + return MESA_FORMAT_L8A8_UNORM; + case MESA_FORMAT_LA_LATC2_SNORM: + return MESA_FORMAT_L8A8_SNORM; + case MESA_FORMAT_ETC1_RGB8: + case MESA_FORMAT_ETC2_RGB8: + case MESA_FORMAT_ETC2_SRGB8: + return MESA_FORMAT_BGR_UNORM8; + case MESA_FORMAT_ETC2_RGBA8_EAC: + case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC: + case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: + case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: + return MESA_FORMAT_A8B8G8R8_UNORM; + case MESA_FORMAT_ETC2_R11_EAC: + case MESA_FORMAT_ETC2_SIGNED_R11_EAC: + return MESA_FORMAT_R_UNORM16; + case MESA_FORMAT_ETC2_RG11_EAC: + case MESA_FORMAT_ETC2_SIGNED_RG11_EAC: + return MESA_FORMAT_R16G16_UNORM; + case MESA_FORMAT_BPTC_RGBA_UNORM: + case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM: + return MESA_FORMAT_A8B8G8R8_UNORM; + case MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT: + case MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT: + return MESA_FORMAT_RGB_FLOAT32; + default: +#ifdef DEBUG + assert(!_mesa_is_format_compressed(format)); +#endif + return format; + } +} + + +GLuint +_mesa_format_num_components(mesa_format format) +{ + const struct gl_format_info *info = _mesa_get_format_info(format); + return ((info->RedBits > 0) + + (info->GreenBits > 0) + + (info->BlueBits > 0) + + (info->AlphaBits > 0) + + (info->LuminanceBits > 0) + + (info->IntensityBits > 0) + + (info->DepthBits > 0) + + (info->StencilBits > 0)); +} + + +/** + * Returns true if a color format has data stored in the R/G/B/A channels, + * given an index from 0 to 3. + */ +bool +_mesa_format_has_color_component(mesa_format format, int component) +{ + const struct gl_format_info *info = _mesa_get_format_info(format); + + assert(info->BaseFormat != GL_DEPTH_COMPONENT && + info->BaseFormat != GL_DEPTH_STENCIL && + info->BaseFormat != GL_STENCIL_INDEX); + + switch (component) { + case 0: + return (info->RedBits + info->IntensityBits + info->LuminanceBits) > 0; + case 1: + return (info->GreenBits + info->IntensityBits + info->LuminanceBits) > 0; + case 2: + return (info->BlueBits + info->IntensityBits + info->LuminanceBits) > 0; + case 3: + return (info->AlphaBits + info->IntensityBits) > 0; + default: + assert(!"Invalid color component: must be 0..3"); + return false; + } +} + + /** * Return number of bytes needed to store an image of the given size * in the given format. */ GLuint -_mesa_format_image_size(gl_format format, GLsizei width, +_mesa_format_image_size(mesa_format format, GLsizei width, GLsizei height, GLsizei depth) { const struct gl_format_info *info = _mesa_get_format_info(format); /* Strictly speaking, a conditional isn't needed here */ if (info->BlockWidth > 1 || info->BlockHeight > 1) { - /* compressed format */ + /* compressed format (2D only for now) */ const GLuint bw = info->BlockWidth, bh = info->BlockHeight; const GLuint wblocks = (width + bw - 1) / bw; const GLuint hblocks = (height + bh - 1) / bh; const GLuint sz = wblocks * hblocks * info->BytesPerBlock; - return sz; + return sz * depth; } else { /* non-compressed */ @@ -864,9 +820,38 @@ _mesa_format_image_size(gl_format format, GLsizei width, } +/** + * Same as _mesa_format_image_size() but returns a 64-bit value to + * accommodate very large textures. + */ +uint64_t +_mesa_format_image_size64(mesa_format format, GLsizei width, + GLsizei height, GLsizei depth) +{ + const struct gl_format_info *info = _mesa_get_format_info(format); + /* Strictly speaking, a conditional isn't needed here */ + if (info->BlockWidth > 1 || info->BlockHeight > 1) { + /* compressed format (2D only for now) */ + const uint64_t bw = info->BlockWidth, bh = info->BlockHeight; + const uint64_t wblocks = (width + bw - 1) / bw; + const uint64_t hblocks = (height + bh - 1) / bh; + const uint64_t sz = wblocks * hblocks * info->BytesPerBlock; + return sz * depth; + } + else { + /* non-compressed */ + const uint64_t sz = ((uint64_t) width * + (uint64_t) height * + (uint64_t) depth * + info->BytesPerBlock); + return sz; + } +} + + GLint -_mesa_format_row_stride(gl_format format, GLsizei width) +_mesa_format_row_stride(mesa_format format, GLsizei width) { const struct gl_format_info *info = _mesa_get_format_info(format); /* Strictly speaking, a conditional isn't needed here */ @@ -884,6 +869,26 @@ _mesa_format_row_stride(gl_format format, GLsizei width) } +/** + * Debug/test: check that all formats are handled in the + * _mesa_format_to_type_and_comps() function. When new pixel formats + * are added to Mesa, that function needs to be updated. + * This is a no-op after the first call. + */ +static void +check_format_to_type_and_comps(void) +{ + mesa_format f; + + for (f = MESA_FORMAT_NONE + 1; f < MESA_FORMAT_COUNT; f++) { + GLenum datatype = 0; + GLuint comps = 0; + /* This function will emit a problem/warning if the format is + * not handled. + */ + _mesa_format_to_type_and_comps(f, &datatype, &comps); + } +} /** * Do sanity checking of the format info table. @@ -893,7 +898,7 @@ _mesa_test_formats(void) { GLuint i; - assert(Elements(format_info) == MESA_FORMAT_COUNT); + STATIC_ASSERT(ARRAY_SIZE(format_info) == MESA_FORMAT_COUNT); for (i = 0; i < MESA_FORMAT_COUNT; i++) { const struct gl_format_info *info = _mesa_get_format_info(i); @@ -908,7 +913,7 @@ _mesa_test_formats(void) if (info->RedBits > 0) { GLuint t = info->RedBits + info->GreenBits + info->BlueBits + info->AlphaBits; - assert(t / 8 == info->BytesPerBlock); + assert(t / 8 <= info->BytesPerBlock); (void) t; } } @@ -916,7 +921,10 @@ _mesa_test_formats(void) assert(info->DataType == GL_UNSIGNED_NORMALIZED || info->DataType == GL_SIGNED_NORMALIZED || info->DataType == GL_UNSIGNED_INT || - info->DataType == GL_FLOAT); + info->DataType == GL_INT || + info->DataType == GL_FLOAT || + /* Z32_FLOAT_X24S8 has DataType of GL_NONE */ + info->DataType == GL_NONE); if (info->BaseFormat == GL_RGB) { assert(info->RedBits > 0); @@ -934,6 +942,22 @@ _mesa_test_formats(void) assert(info->LuminanceBits == 0); assert(info->IntensityBits == 0); } + else if (info->BaseFormat == GL_RG) { + assert(info->RedBits > 0); + assert(info->GreenBits > 0); + assert(info->BlueBits == 0); + assert(info->AlphaBits == 0); + assert(info->LuminanceBits == 0); + assert(info->IntensityBits == 0); + } + else if (info->BaseFormat == GL_RED) { + assert(info->RedBits > 0); + assert(info->GreenBits == 0); + assert(info->BlueBits == 0); + assert(info->AlphaBits == 0); + assert(info->LuminanceBits == 0); + assert(info->IntensityBits == 0); + } else if (info->BaseFormat == GL_LUMINANCE) { assert(info->RedBits == 0); assert(info->GreenBits == 0); @@ -950,168 +974,289 @@ _mesa_test_formats(void) assert(info->LuminanceBits == 0); assert(info->IntensityBits > 0); } - } + + check_format_to_type_and_comps(); } /** - * Return datatype and number of components per texel for the given gl_format. + * Return datatype and number of components per texel for the given mesa_format. * Only used for mipmap generation code. */ void -_mesa_format_to_type_and_comps(gl_format format, +_mesa_format_to_type_and_comps(mesa_format format, GLenum *datatype, GLuint *comps) { switch (format) { - case MESA_FORMAT_RGBA8888: - case MESA_FORMAT_RGBA8888_REV: - case MESA_FORMAT_ARGB8888: - case MESA_FORMAT_ARGB8888_REV: - case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_A8B8G8R8_UNORM: + case MESA_FORMAT_R8G8B8A8_UNORM: + case MESA_FORMAT_B8G8R8A8_UNORM: + case MESA_FORMAT_A8R8G8B8_UNORM: + case MESA_FORMAT_X8B8G8R8_UNORM: + case MESA_FORMAT_R8G8B8X8_UNORM: + case MESA_FORMAT_B8G8R8X8_UNORM: + case MESA_FORMAT_X8R8G8B8_UNORM: *datatype = GL_UNSIGNED_BYTE; *comps = 4; return; - case MESA_FORMAT_RGB888: - case MESA_FORMAT_BGR888: + case MESA_FORMAT_BGR_UNORM8: + case MESA_FORMAT_RGB_UNORM8: *datatype = GL_UNSIGNED_BYTE; *comps = 3; return; - case MESA_FORMAT_RGB565: - case MESA_FORMAT_RGB565_REV: + case MESA_FORMAT_B5G6R5_UNORM: + case MESA_FORMAT_R5G6B5_UNORM: *datatype = GL_UNSIGNED_SHORT_5_6_5; *comps = 3; return; - case MESA_FORMAT_ARGB4444: - case MESA_FORMAT_ARGB4444_REV: + case MESA_FORMAT_B4G4R4A4_UNORM: + case MESA_FORMAT_A4R4G4B4_UNORM: + case MESA_FORMAT_B4G4R4X4_UNORM: *datatype = GL_UNSIGNED_SHORT_4_4_4_4; *comps = 4; return; - case MESA_FORMAT_ARGB1555: - case MESA_FORMAT_ARGB1555_REV: + case MESA_FORMAT_B5G5R5A1_UNORM: + case MESA_FORMAT_A1R5G5B5_UNORM: + case MESA_FORMAT_B5G5R5X1_UNORM: *datatype = GL_UNSIGNED_SHORT_1_5_5_5_REV; *comps = 4; return; - case MESA_FORMAT_AL88: - case MESA_FORMAT_AL88_REV: - *datatype = GL_UNSIGNED_BYTE; - *comps = 2; + case MESA_FORMAT_B10G10R10A2_UNORM: + *datatype = GL_UNSIGNED_INT_2_10_10_10_REV; + *comps = 4; return; - case MESA_FORMAT_AL1616: - case MESA_FORMAT_AL1616_REV: - *datatype = GL_UNSIGNED_SHORT; - *comps = 2; + case MESA_FORMAT_A1B5G5R5_UNORM: + *datatype = GL_UNSIGNED_SHORT_5_5_5_1; + *comps = 4; return; - case MESA_FORMAT_RGB332: - *datatype = GL_UNSIGNED_BYTE_3_3_2; - *comps = 3; + case MESA_FORMAT_L4A4_UNORM: + *datatype = MESA_UNSIGNED_BYTE_4_4; + *comps = 2; return; - case MESA_FORMAT_A8: - case MESA_FORMAT_L8: - case MESA_FORMAT_I8: - case MESA_FORMAT_CI8: + case MESA_FORMAT_L8A8_UNORM: + case MESA_FORMAT_A8L8_UNORM: + case MESA_FORMAT_R8G8_UNORM: + case MESA_FORMAT_G8R8_UNORM: *datatype = GL_UNSIGNED_BYTE; - *comps = 1; + *comps = 2; return; - case MESA_FORMAT_YCBCR: - case MESA_FORMAT_YCBCR_REV: + case MESA_FORMAT_L16A16_UNORM: + case MESA_FORMAT_A16L16_UNORM: + case MESA_FORMAT_R16G16_UNORM: + case MESA_FORMAT_G16R16_UNORM: *datatype = GL_UNSIGNED_SHORT; *comps = 2; return; - case MESA_FORMAT_Z24_S8: - *datatype = GL_UNSIGNED_INT; - *comps = 1; /* XXX OK? */ - return; - - case MESA_FORMAT_S8_Z24: - *datatype = GL_UNSIGNED_INT; - *comps = 1; /* XXX OK? */ - return; - - case MESA_FORMAT_Z16: + case MESA_FORMAT_R_UNORM16: + case MESA_FORMAT_A_UNORM16: + case MESA_FORMAT_L_UNORM16: + case MESA_FORMAT_I_UNORM16: *datatype = GL_UNSIGNED_SHORT; *comps = 1; return; - case MESA_FORMAT_X8_Z24: - *datatype = GL_UNSIGNED_INT; - *comps = 1; + case MESA_FORMAT_R3G3B2_UNORM: + *datatype = GL_UNSIGNED_BYTE_2_3_3_REV; + *comps = 3; + return; + case MESA_FORMAT_A4B4G4R4_UNORM: + *datatype = GL_UNSIGNED_SHORT_4_4_4_4; + *comps = 4; return; - case MESA_FORMAT_Z24_X8: + case MESA_FORMAT_R4G4B4A4_UNORM: + *datatype = GL_UNSIGNED_SHORT_4_4_4_4; + *comps = 4; + return; + case MESA_FORMAT_R5G5B5A1_UNORM: + *datatype = GL_UNSIGNED_SHORT_1_5_5_5_REV; + *comps = 4; + return; + case MESA_FORMAT_A2B10G10R10_UNORM: + case MESA_FORMAT_A2B10G10R10_UINT: + *datatype = GL_UNSIGNED_INT_10_10_10_2; + *comps = 4; + return; + case MESA_FORMAT_A2R10G10B10_UNORM: + case MESA_FORMAT_A2R10G10B10_UINT: + *datatype = GL_UNSIGNED_INT_10_10_10_2; + *comps = 4; + return; + + case MESA_FORMAT_B2G3R3_UNORM: + *datatype = GL_UNSIGNED_BYTE_3_3_2; + *comps = 3; + return; + + case MESA_FORMAT_A_UNORM8: + case MESA_FORMAT_L_UNORM8: + case MESA_FORMAT_I_UNORM8: + case MESA_FORMAT_R_UNORM8: + case MESA_FORMAT_S_UINT8: + *datatype = GL_UNSIGNED_BYTE; + *comps = 1; + return; + + case MESA_FORMAT_YCBCR: + case MESA_FORMAT_YCBCR_REV: + *datatype = GL_UNSIGNED_SHORT; + *comps = 2; + return; + + case MESA_FORMAT_S8_UINT_Z24_UNORM: + *datatype = GL_UNSIGNED_INT_24_8_MESA; + *comps = 2; + return; + + case MESA_FORMAT_Z24_UNORM_S8_UINT: + *datatype = GL_UNSIGNED_INT_8_24_REV_MESA; + *comps = 2; + return; + + case MESA_FORMAT_Z_UNORM16: + *datatype = GL_UNSIGNED_SHORT; + *comps = 1; + return; + + case MESA_FORMAT_Z24_UNORM_X8_UINT: + *datatype = GL_UNSIGNED_INT; + *comps = 1; + return; + + case MESA_FORMAT_X8_UINT_Z24_UNORM: *datatype = GL_UNSIGNED_INT; *comps = 1; return; - case MESA_FORMAT_Z32: + case MESA_FORMAT_Z_UNORM32: *datatype = GL_UNSIGNED_INT; *comps = 1; return; - case MESA_FORMAT_DUDV8: + case MESA_FORMAT_Z_FLOAT32: + *datatype = GL_FLOAT; + *comps = 1; + return; + + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + *datatype = GL_FLOAT_32_UNSIGNED_INT_24_8_REV; + *comps = 1; + return; + + case MESA_FORMAT_R_SNORM8: + case MESA_FORMAT_A_SNORM8: + case MESA_FORMAT_L_SNORM8: + case MESA_FORMAT_I_SNORM8: + *datatype = GL_BYTE; + *comps = 1; + return; + case MESA_FORMAT_R8G8_SNORM: + case MESA_FORMAT_L8A8_SNORM: + case MESA_FORMAT_A8L8_SNORM: *datatype = GL_BYTE; *comps = 2; return; - - case MESA_FORMAT_SIGNED_RGBA8888: - case MESA_FORMAT_SIGNED_RGBA8888_REV: + case MESA_FORMAT_A8B8G8R8_SNORM: + case MESA_FORMAT_R8G8B8A8_SNORM: + case MESA_FORMAT_X8B8G8R8_SNORM: *datatype = GL_BYTE; *comps = 4; return; - case MESA_FORMAT_SIGNED_RGBA_16: + + case MESA_FORMAT_RGBA_UNORM16: + *datatype = GL_UNSIGNED_SHORT; + *comps = 4; + return; + + case MESA_FORMAT_R_SNORM16: + case MESA_FORMAT_A_SNORM16: + case MESA_FORMAT_L_SNORM16: + case MESA_FORMAT_I_SNORM16: + *datatype = GL_SHORT; + *comps = 1; + return; + case MESA_FORMAT_R16G16_SNORM: + case MESA_FORMAT_LA_SNORM16: + *datatype = GL_SHORT; + *comps = 2; + return; + case MESA_FORMAT_RGB_SNORM16: + *datatype = GL_SHORT; + *comps = 3; + return; + case MESA_FORMAT_RGBA_SNORM16: *datatype = GL_SHORT; *comps = 4; return; -#if FEATURE_EXT_texture_sRGB - case MESA_FORMAT_SRGB8: + case MESA_FORMAT_BGR_SRGB8: *datatype = GL_UNSIGNED_BYTE; *comps = 3; return; - case MESA_FORMAT_SRGBA8: - case MESA_FORMAT_SARGB8: + case MESA_FORMAT_A8B8G8R8_SRGB: + case MESA_FORMAT_B8G8R8A8_SRGB: + case MESA_FORMAT_A8R8G8B8_SRGB: + case MESA_FORMAT_R8G8B8A8_SRGB: *datatype = GL_UNSIGNED_BYTE; *comps = 4; return; - case MESA_FORMAT_SL8: + case MESA_FORMAT_L_SRGB8: *datatype = GL_UNSIGNED_BYTE; *comps = 1; return; - case MESA_FORMAT_SLA8: + case MESA_FORMAT_L8A8_SRGB: + case MESA_FORMAT_A8L8_SRGB: *datatype = GL_UNSIGNED_BYTE; *comps = 2; return; -#endif -#if FEATURE_texture_fxt1 case MESA_FORMAT_RGB_FXT1: case MESA_FORMAT_RGBA_FXT1: -#endif -#if FEATURE_texture_s3tc case MESA_FORMAT_RGB_DXT1: case MESA_FORMAT_RGBA_DXT1: case MESA_FORMAT_RGBA_DXT3: case MESA_FORMAT_RGBA_DXT5: -#if FEATURE_EXT_texture_sRGB case MESA_FORMAT_SRGB_DXT1: case MESA_FORMAT_SRGBA_DXT1: case MESA_FORMAT_SRGBA_DXT3: case MESA_FORMAT_SRGBA_DXT5: -#endif + case MESA_FORMAT_R_RGTC1_UNORM: + case MESA_FORMAT_R_RGTC1_SNORM: + case MESA_FORMAT_RG_RGTC2_UNORM: + case MESA_FORMAT_RG_RGTC2_SNORM: + case MESA_FORMAT_L_LATC1_UNORM: + case MESA_FORMAT_L_LATC1_SNORM: + case MESA_FORMAT_LA_LATC2_UNORM: + case MESA_FORMAT_LA_LATC2_SNORM: + case MESA_FORMAT_ETC1_RGB8: + case MESA_FORMAT_ETC2_RGB8: + case MESA_FORMAT_ETC2_SRGB8: + case MESA_FORMAT_ETC2_RGBA8_EAC: + case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC: + case MESA_FORMAT_ETC2_R11_EAC: + case MESA_FORMAT_ETC2_RG11_EAC: + case MESA_FORMAT_ETC2_SIGNED_R11_EAC: + case MESA_FORMAT_ETC2_SIGNED_RG11_EAC: + case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: + case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: + case MESA_FORMAT_BPTC_RGBA_UNORM: + case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM: + case MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT: + case MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT: /* XXX generate error instead? */ *datatype = GL_UNSIGNED_BYTE; *comps = 0; return; -#endif case MESA_FORMAT_RGBA_FLOAT32: *datatype = GL_FLOAT; @@ -1129,30 +1274,906 @@ _mesa_format_to_type_and_comps(gl_format format, *datatype = GL_HALF_FLOAT_ARB; *comps = 3; return; - case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32: + case MESA_FORMAT_LA_FLOAT32: + case MESA_FORMAT_RG_FLOAT32: *datatype = GL_FLOAT; *comps = 2; return; - case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16: + case MESA_FORMAT_LA_FLOAT16: + case MESA_FORMAT_RG_FLOAT16: *datatype = GL_HALF_FLOAT_ARB; *comps = 2; return; - case MESA_FORMAT_ALPHA_FLOAT32: - case MESA_FORMAT_LUMINANCE_FLOAT32: - case MESA_FORMAT_INTENSITY_FLOAT32: + case MESA_FORMAT_A_FLOAT32: + case MESA_FORMAT_L_FLOAT32: + case MESA_FORMAT_I_FLOAT32: + case MESA_FORMAT_R_FLOAT32: *datatype = GL_FLOAT; *comps = 1; return; - case MESA_FORMAT_ALPHA_FLOAT16: - case MESA_FORMAT_LUMINANCE_FLOAT16: - case MESA_FORMAT_INTENSITY_FLOAT16: + case MESA_FORMAT_A_FLOAT16: + case MESA_FORMAT_L_FLOAT16: + case MESA_FORMAT_I_FLOAT16: + case MESA_FORMAT_R_FLOAT16: *datatype = GL_HALF_FLOAT_ARB; *comps = 1; return; + case MESA_FORMAT_A_UINT8: + case MESA_FORMAT_L_UINT8: + case MESA_FORMAT_I_UINT8: + *datatype = GL_UNSIGNED_BYTE; + *comps = 1; + return; + case MESA_FORMAT_LA_UINT8: + *datatype = GL_UNSIGNED_BYTE; + *comps = 2; + return; + + case MESA_FORMAT_A_UINT16: + case MESA_FORMAT_L_UINT16: + case MESA_FORMAT_I_UINT16: + *datatype = GL_UNSIGNED_SHORT; + *comps = 1; + return; + case MESA_FORMAT_LA_UINT16: + *datatype = GL_UNSIGNED_SHORT; + *comps = 2; + return; + case MESA_FORMAT_A_UINT32: + case MESA_FORMAT_L_UINT32: + case MESA_FORMAT_I_UINT32: + *datatype = GL_UNSIGNED_INT; + *comps = 1; + return; + case MESA_FORMAT_LA_UINT32: + *datatype = GL_UNSIGNED_INT; + *comps = 2; + return; + case MESA_FORMAT_A_SINT8: + case MESA_FORMAT_L_SINT8: + case MESA_FORMAT_I_SINT8: + *datatype = GL_BYTE; + *comps = 1; + return; + case MESA_FORMAT_LA_SINT8: + *datatype = GL_BYTE; + *comps = 2; + return; + + case MESA_FORMAT_A_SINT16: + case MESA_FORMAT_L_SINT16: + case MESA_FORMAT_I_SINT16: + *datatype = GL_SHORT; + *comps = 1; + return; + case MESA_FORMAT_LA_SINT16: + *datatype = GL_SHORT; + *comps = 2; + return; + + case MESA_FORMAT_A_SINT32: + case MESA_FORMAT_L_SINT32: + case MESA_FORMAT_I_SINT32: + *datatype = GL_INT; + *comps = 1; + return; + case MESA_FORMAT_LA_SINT32: + *datatype = GL_INT; + *comps = 2; + return; + + case MESA_FORMAT_R_SINT8: + *datatype = GL_BYTE; + *comps = 1; + return; + case MESA_FORMAT_RG_SINT8: + *datatype = GL_BYTE; + *comps = 2; + return; + case MESA_FORMAT_RGB_SINT8: + *datatype = GL_BYTE; + *comps = 3; + return; + case MESA_FORMAT_RGBA_SINT8: + *datatype = GL_BYTE; + *comps = 4; + return; + case MESA_FORMAT_R_SINT16: + *datatype = GL_SHORT; + *comps = 1; + return; + case MESA_FORMAT_RG_SINT16: + *datatype = GL_SHORT; + *comps = 2; + return; + case MESA_FORMAT_RGB_SINT16: + *datatype = GL_SHORT; + *comps = 3; + return; + case MESA_FORMAT_RGBA_SINT16: + *datatype = GL_SHORT; + *comps = 4; + return; + case MESA_FORMAT_R_SINT32: + *datatype = GL_INT; + *comps = 1; + return; + case MESA_FORMAT_RG_SINT32: + *datatype = GL_INT; + *comps = 2; + return; + case MESA_FORMAT_RGB_SINT32: + *datatype = GL_INT; + *comps = 3; + return; + case MESA_FORMAT_RGBA_SINT32: + *datatype = GL_INT; + *comps = 4; + return; + + /** + * \name Non-normalized unsigned integer formats. + */ + case MESA_FORMAT_R_UINT8: + *datatype = GL_UNSIGNED_BYTE; + *comps = 1; + return; + case MESA_FORMAT_RG_UINT8: + *datatype = GL_UNSIGNED_BYTE; + *comps = 2; + return; + case MESA_FORMAT_RGB_UINT8: + *datatype = GL_UNSIGNED_BYTE; + *comps = 3; + return; + case MESA_FORMAT_RGBA_UINT8: + *datatype = GL_UNSIGNED_BYTE; + *comps = 4; + return; + case MESA_FORMAT_R_UINT16: + *datatype = GL_UNSIGNED_SHORT; + *comps = 1; + return; + case MESA_FORMAT_RG_UINT16: + *datatype = GL_UNSIGNED_SHORT; + *comps = 2; + return; + case MESA_FORMAT_RGB_UINT16: + *datatype = GL_UNSIGNED_SHORT; + *comps = 3; + return; + case MESA_FORMAT_RGBA_UINT16: + *datatype = GL_UNSIGNED_SHORT; + *comps = 4; + return; + case MESA_FORMAT_R_UINT32: + *datatype = GL_UNSIGNED_INT; + *comps = 1; + return; + case MESA_FORMAT_RG_UINT32: + *datatype = GL_UNSIGNED_INT; + *comps = 2; + return; + case MESA_FORMAT_RGB_UINT32: + *datatype = GL_UNSIGNED_INT; + *comps = 3; + return; + case MESA_FORMAT_RGBA_UINT32: + *datatype = GL_UNSIGNED_INT; + *comps = 4; + return; + + case MESA_FORMAT_R9G9B9E5_FLOAT: + *datatype = GL_UNSIGNED_INT_5_9_9_9_REV; + *comps = 3; + return; + + case MESA_FORMAT_R11G11B10_FLOAT: + *datatype = GL_UNSIGNED_INT_10F_11F_11F_REV; + *comps = 3; + return; + + case MESA_FORMAT_B10G10R10A2_UINT: + case MESA_FORMAT_R10G10B10A2_UINT: + *datatype = GL_UNSIGNED_INT_2_10_10_10_REV; + *comps = 4; + return; + + case MESA_FORMAT_R8G8B8X8_SRGB: + case MESA_FORMAT_X8B8G8R8_SRGB: + case MESA_FORMAT_RGBX_UINT8: + *datatype = GL_UNSIGNED_BYTE; + *comps = 4; + return; + + case MESA_FORMAT_R8G8B8X8_SNORM: + case MESA_FORMAT_RGBX_SINT8: + *datatype = GL_BYTE; + *comps = 4; + return; + + case MESA_FORMAT_B10G10R10X2_UNORM: + case MESA_FORMAT_R10G10B10X2_UNORM: + *datatype = GL_UNSIGNED_INT_2_10_10_10_REV; + *comps = 4; + return; + + case MESA_FORMAT_RGBX_UNORM16: + case MESA_FORMAT_RGBX_UINT16: + *datatype = GL_UNSIGNED_SHORT; + *comps = 4; + return; + + case MESA_FORMAT_RGBX_SNORM16: + case MESA_FORMAT_RGBX_SINT16: + *datatype = GL_SHORT; + *comps = 4; + return; + + case MESA_FORMAT_RGBX_FLOAT16: + *datatype = GL_HALF_FLOAT; + *comps = 4; + return; + + case MESA_FORMAT_RGBX_FLOAT32: + *datatype = GL_FLOAT; + *comps = 4; + return; + + case MESA_FORMAT_RGBX_UINT32: + *datatype = GL_UNSIGNED_INT; + *comps = 4; + return; + + case MESA_FORMAT_RGBX_SINT32: + *datatype = GL_INT; + *comps = 4; + return; + + case MESA_FORMAT_R10G10B10A2_UNORM: + *datatype = GL_UNSIGNED_INT_2_10_10_10_REV; + *comps = 4; + return; + + case MESA_FORMAT_G8R8_SNORM: + *datatype = GL_BYTE; + *comps = 2; + return; + + case MESA_FORMAT_G16R16_SNORM: + *datatype = GL_SHORT; + *comps = 2; + return; + + case MESA_FORMAT_B8G8R8X8_SRGB: + case MESA_FORMAT_X8R8G8B8_SRGB: + *datatype = GL_UNSIGNED_BYTE; + *comps = 4; + return; + + case MESA_FORMAT_COUNT: + assert(0); + return; + + case MESA_FORMAT_NONE: + /* For debug builds, warn if any formats are not handled */ +#ifdef DEBUG default: - _mesa_problem(NULL, "bad format in _mesa_format_to_type_and_comps"); +#endif + _mesa_problem(NULL, "bad format %s in _mesa_format_to_type_and_comps", + _mesa_get_format_name(format)); *datatype = 0; *comps = 1; } } + +/** + * Check if a mesa_format exactly matches a GL format/type combination + * such that we can use memcpy() from one to the other. + * \param mesa_format a MESA_FORMAT_x value + * \param format the user-specified image format + * \param type the user-specified image datatype + * \param swapBytes typically the current pixel pack/unpack byteswap state + * \return GL_TRUE if the formats match, GL_FALSE otherwise. + */ +GLboolean +_mesa_format_matches_format_and_type(mesa_format mesa_format, + GLenum format, GLenum type, + GLboolean swapBytes) +{ + const GLboolean littleEndian = _mesa_little_endian(); + + /* Note: When reading a GL format/type combination, the format lists channel + * assignments from most significant channel in the type to least + * significant. A type with _REV indicates that the assignments are + * swapped, so they are listed from least significant to most significant. + * + * For sanity, please keep this switch statement ordered the same as the + * enums in formats.h. + */ + + switch (mesa_format) { + + case MESA_FORMAT_NONE: + case MESA_FORMAT_COUNT: + return GL_FALSE; + + case MESA_FORMAT_A8B8G8R8_UNORM: + case MESA_FORMAT_A8B8G8R8_SRGB: + if (format == GL_RGBA && type == GL_UNSIGNED_INT_8_8_8_8 && !swapBytes) + return GL_TRUE; + + if (format == GL_RGBA && type == GL_UNSIGNED_INT_8_8_8_8_REV && swapBytes) + return GL_TRUE; + + if (format == GL_RGBA && type == GL_UNSIGNED_BYTE && !littleEndian) + return GL_TRUE; + + if (format == GL_ABGR_EXT && type == GL_UNSIGNED_INT_8_8_8_8_REV + && !swapBytes) + return GL_TRUE; + + if (format == GL_ABGR_EXT && type == GL_UNSIGNED_INT_8_8_8_8 + && swapBytes) + return GL_TRUE; + + if (format == GL_ABGR_EXT && type == GL_UNSIGNED_BYTE && littleEndian) + return GL_TRUE; + + return GL_FALSE; + + case MESA_FORMAT_R8G8B8A8_UNORM: + case MESA_FORMAT_R8G8B8A8_SRGB: + if (format == GL_RGBA && type == GL_UNSIGNED_INT_8_8_8_8_REV && + !swapBytes) + return GL_TRUE; + + if (format == GL_RGBA && type == GL_UNSIGNED_INT_8_8_8_8 && swapBytes) + return GL_TRUE; + + if (format == GL_RGBA && type == GL_UNSIGNED_BYTE && littleEndian) + return GL_TRUE; + + if (format == GL_ABGR_EXT && type == GL_UNSIGNED_INT_8_8_8_8 && + !swapBytes) + return GL_TRUE; + + if (format == GL_ABGR_EXT && type == GL_UNSIGNED_INT_8_8_8_8_REV && + swapBytes) + return GL_TRUE; + + if (format == GL_ABGR_EXT && type == GL_UNSIGNED_BYTE && !littleEndian) + return GL_TRUE; + + return GL_FALSE; + + case MESA_FORMAT_B8G8R8A8_UNORM: + case MESA_FORMAT_B8G8R8A8_SRGB: + if (format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV && + !swapBytes) + return GL_TRUE; + + if (format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8 && swapBytes) + return GL_TRUE; + + if (format == GL_BGRA && type == GL_UNSIGNED_BYTE && littleEndian) + return GL_TRUE; + + return GL_FALSE; + + case MESA_FORMAT_A8R8G8B8_UNORM: + case MESA_FORMAT_A8R8G8B8_SRGB: + if (format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8 && !swapBytes) + return GL_TRUE; + + if (format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV && + swapBytes) + return GL_TRUE; + + if (format == GL_BGRA && type == GL_UNSIGNED_BYTE && !littleEndian) + return GL_TRUE; + + return GL_FALSE; + + case MESA_FORMAT_X8B8G8R8_UNORM: + case MESA_FORMAT_R8G8B8X8_UNORM: + return GL_FALSE; + + case MESA_FORMAT_B8G8R8X8_UNORM: + case MESA_FORMAT_X8R8G8B8_UNORM: + return GL_FALSE; + + case MESA_FORMAT_BGR_UNORM8: + case MESA_FORMAT_BGR_SRGB8: + return format == GL_BGR && type == GL_UNSIGNED_BYTE && littleEndian; + + case MESA_FORMAT_RGB_UNORM8: + return format == GL_RGB && type == GL_UNSIGNED_BYTE && littleEndian; + + case MESA_FORMAT_B5G6R5_UNORM: + return ((format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) || + (format == GL_BGR && type == GL_UNSIGNED_SHORT_5_6_5_REV)) && + !swapBytes; + + case MESA_FORMAT_R5G6B5_UNORM: + return ((format == GL_BGR && type == GL_UNSIGNED_SHORT_5_6_5) || + (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5_REV)) && + !swapBytes; + + case MESA_FORMAT_B4G4R4A4_UNORM: + return format == GL_BGRA && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && + !swapBytes; + + case MESA_FORMAT_A4R4G4B4_UNORM: + return GL_FALSE; + + case MESA_FORMAT_A1B5G5R5_UNORM: + return format == GL_RGBA && type == GL_UNSIGNED_SHORT_5_5_5_1 && + !swapBytes; + + case MESA_FORMAT_B5G5R5A1_UNORM: + return format == GL_BGRA && type == GL_UNSIGNED_SHORT_1_5_5_5_REV && + !swapBytes; + + case MESA_FORMAT_A1R5G5B5_UNORM: + return format == GL_BGRA && type == GL_UNSIGNED_SHORT_5_5_5_1 && + !swapBytes; + + case MESA_FORMAT_L4A4_UNORM: + return GL_FALSE; + case MESA_FORMAT_L8A8_UNORM: + case MESA_FORMAT_L8A8_SRGB: + return format == GL_LUMINANCE_ALPHA && type == GL_UNSIGNED_BYTE && littleEndian; + case MESA_FORMAT_A8L8_UNORM: + case MESA_FORMAT_A8L8_SRGB: + return GL_FALSE; + + case MESA_FORMAT_L16A16_UNORM: + return format == GL_LUMINANCE_ALPHA && type == GL_UNSIGNED_SHORT && littleEndian && !swapBytes; + case MESA_FORMAT_A16L16_UNORM: + return GL_FALSE; + + case MESA_FORMAT_B2G3R3_UNORM: + return format == GL_RGB && type == GL_UNSIGNED_BYTE_3_3_2; + + case MESA_FORMAT_R3G3B2_UNORM: + return format == GL_RGB && type == GL_UNSIGNED_BYTE_2_3_3_REV; + + case MESA_FORMAT_A4B4G4R4_UNORM: + if (format == GL_RGBA && type == GL_UNSIGNED_SHORT_4_4_4_4 && !swapBytes) + return GL_TRUE; + + if (format == GL_RGBA && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && swapBytes) + return GL_TRUE; + + if (format == GL_ABGR_EXT && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && !swapBytes) + return GL_TRUE; + + if (format == GL_ABGR_EXT && type == GL_UNSIGNED_SHORT_4_4_4_4 && swapBytes) + return GL_TRUE; + + return GL_FALSE; + + case MESA_FORMAT_R4G4B4A4_UNORM: + if (format == GL_ABGR_EXT && type == GL_UNSIGNED_SHORT_4_4_4_4 && !swapBytes) + return GL_TRUE; + + if (format == GL_ABGR_EXT && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && swapBytes) + return GL_TRUE; + + if (format == GL_RGBA && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && !swapBytes) + return GL_TRUE; + + if (format == GL_RGBA && type == GL_UNSIGNED_SHORT_4_4_4_4 && swapBytes) + return GL_TRUE; + + return GL_FALSE; + + case MESA_FORMAT_R5G5B5A1_UNORM: + return format == GL_RGBA && type == GL_UNSIGNED_SHORT_1_5_5_5_REV; + + case MESA_FORMAT_A2B10G10R10_UNORM: + return format == GL_RGBA && type == GL_UNSIGNED_INT_10_10_10_2; + + case MESA_FORMAT_A2B10G10R10_UINT: + return format == GL_RGBA_INTEGER_EXT && type == GL_UNSIGNED_INT_10_10_10_2; + + case MESA_FORMAT_A2R10G10B10_UNORM: + return format == GL_BGRA && type == GL_UNSIGNED_INT_10_10_10_2; + + case MESA_FORMAT_A2R10G10B10_UINT: + return format == GL_BGRA_INTEGER_EXT && type == GL_UNSIGNED_INT_10_10_10_2; + + case MESA_FORMAT_A_UNORM8: + return format == GL_ALPHA && type == GL_UNSIGNED_BYTE; + case MESA_FORMAT_A_UNORM16: + return format == GL_ALPHA && type == GL_UNSIGNED_SHORT && !swapBytes; + case MESA_FORMAT_L_UNORM8: + case MESA_FORMAT_L_SRGB8: + return format == GL_LUMINANCE && type == GL_UNSIGNED_BYTE; + case MESA_FORMAT_L_UNORM16: + return format == GL_LUMINANCE && type == GL_UNSIGNED_SHORT && !swapBytes; + case MESA_FORMAT_I_UNORM8: + return format == GL_RED && type == GL_UNSIGNED_BYTE; + case MESA_FORMAT_I_UNORM16: + return format == GL_RED && type == GL_UNSIGNED_SHORT && !swapBytes; + + case MESA_FORMAT_YCBCR: + return format == GL_YCBCR_MESA && + ((type == GL_UNSIGNED_SHORT_8_8_MESA && littleEndian != swapBytes) || + (type == GL_UNSIGNED_SHORT_8_8_REV_MESA && littleEndian == swapBytes)); + case MESA_FORMAT_YCBCR_REV: + return format == GL_YCBCR_MESA && + ((type == GL_UNSIGNED_SHORT_8_8_MESA && littleEndian == swapBytes) || + (type == GL_UNSIGNED_SHORT_8_8_REV_MESA && littleEndian != swapBytes)); + + case MESA_FORMAT_R_UNORM8: + return format == GL_RED && type == GL_UNSIGNED_BYTE; + case MESA_FORMAT_R8G8_UNORM: + return format == GL_RG && type == GL_UNSIGNED_BYTE && littleEndian; + case MESA_FORMAT_G8R8_UNORM: + return GL_FALSE; + + case MESA_FORMAT_R_UNORM16: + return format == GL_RED && type == GL_UNSIGNED_SHORT && + !swapBytes; + case MESA_FORMAT_R16G16_UNORM: + return format == GL_RG && type == GL_UNSIGNED_SHORT && littleEndian && + !swapBytes; + case MESA_FORMAT_G16R16_UNORM: + return GL_FALSE; + + case MESA_FORMAT_B10G10R10A2_UNORM: + return format == GL_BGRA && type == GL_UNSIGNED_INT_2_10_10_10_REV && + !swapBytes; + + case MESA_FORMAT_S8_UINT_Z24_UNORM: + return format == GL_DEPTH_STENCIL && type == GL_UNSIGNED_INT_24_8 && + !swapBytes; + case MESA_FORMAT_X8_UINT_Z24_UNORM: + case MESA_FORMAT_Z24_UNORM_S8_UINT: + return GL_FALSE; + + case MESA_FORMAT_Z_UNORM16: + return format == GL_DEPTH_COMPONENT && type == GL_UNSIGNED_SHORT && + !swapBytes; + + case MESA_FORMAT_Z24_UNORM_X8_UINT: + return GL_FALSE; + + case MESA_FORMAT_Z_UNORM32: + return format == GL_DEPTH_COMPONENT && type == GL_UNSIGNED_INT && + !swapBytes; + + case MESA_FORMAT_S_UINT8: + return format == GL_STENCIL_INDEX && type == GL_UNSIGNED_BYTE; + + case MESA_FORMAT_SRGB_DXT1: + case MESA_FORMAT_SRGBA_DXT1: + case MESA_FORMAT_SRGBA_DXT3: + case MESA_FORMAT_SRGBA_DXT5: + return GL_FALSE; + + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: + case MESA_FORMAT_RGB_DXT1: + case MESA_FORMAT_RGBA_DXT1: + case MESA_FORMAT_RGBA_DXT3: + case MESA_FORMAT_RGBA_DXT5: + return GL_FALSE; + + case MESA_FORMAT_BPTC_RGBA_UNORM: + case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM: + case MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT: + case MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT: + return GL_FALSE; + + case MESA_FORMAT_RGBA_FLOAT32: + return format == GL_RGBA && type == GL_FLOAT && !swapBytes; + case MESA_FORMAT_RGBA_FLOAT16: + return format == GL_RGBA && type == GL_HALF_FLOAT && !swapBytes; + + case MESA_FORMAT_RGB_FLOAT32: + return format == GL_RGB && type == GL_FLOAT && !swapBytes; + case MESA_FORMAT_RGB_FLOAT16: + return format == GL_RGB && type == GL_HALF_FLOAT && !swapBytes; + + case MESA_FORMAT_A_FLOAT32: + return format == GL_ALPHA && type == GL_FLOAT && !swapBytes; + case MESA_FORMAT_A_FLOAT16: + return format == GL_ALPHA && type == GL_HALF_FLOAT && !swapBytes; + + case MESA_FORMAT_L_FLOAT32: + return format == GL_LUMINANCE && type == GL_FLOAT && !swapBytes; + case MESA_FORMAT_L_FLOAT16: + return format == GL_LUMINANCE && type == GL_HALF_FLOAT && !swapBytes; + + case MESA_FORMAT_LA_FLOAT32: + return format == GL_LUMINANCE_ALPHA && type == GL_FLOAT && !swapBytes; + case MESA_FORMAT_LA_FLOAT16: + return format == GL_LUMINANCE_ALPHA && type == GL_HALF_FLOAT && !swapBytes; + + case MESA_FORMAT_I_FLOAT32: + return format == GL_RED && type == GL_FLOAT && !swapBytes; + case MESA_FORMAT_I_FLOAT16: + return format == GL_RED && type == GL_HALF_FLOAT && !swapBytes; + + case MESA_FORMAT_R_FLOAT32: + return format == GL_RED && type == GL_FLOAT && !swapBytes; + case MESA_FORMAT_R_FLOAT16: + return format == GL_RED && type == GL_HALF_FLOAT && !swapBytes; + + case MESA_FORMAT_RG_FLOAT32: + return format == GL_RG && type == GL_FLOAT && !swapBytes; + case MESA_FORMAT_RG_FLOAT16: + return format == GL_RG && type == GL_HALF_FLOAT && !swapBytes; + + case MESA_FORMAT_A_UINT8: + return format == GL_ALPHA_INTEGER && type == GL_UNSIGNED_BYTE; + case MESA_FORMAT_A_UINT16: + return format == GL_ALPHA_INTEGER && type == GL_UNSIGNED_SHORT && + !swapBytes; + case MESA_FORMAT_A_UINT32: + return format == GL_ALPHA_INTEGER && type == GL_UNSIGNED_INT && + !swapBytes; + case MESA_FORMAT_A_SINT8: + return format == GL_ALPHA_INTEGER && type == GL_BYTE; + case MESA_FORMAT_A_SINT16: + return format == GL_ALPHA_INTEGER && type == GL_SHORT && !swapBytes; + case MESA_FORMAT_A_SINT32: + return format == GL_ALPHA_INTEGER && type == GL_INT && !swapBytes; + + case MESA_FORMAT_I_UINT8: + return format == GL_RED_INTEGER && type == GL_UNSIGNED_BYTE; + case MESA_FORMAT_I_UINT16: + return format == GL_RED_INTEGER && type == GL_UNSIGNED_SHORT && !swapBytes; + case MESA_FORMAT_I_UINT32: + return format == GL_RED_INTEGER && type == GL_UNSIGNED_INT && !swapBytes; + case MESA_FORMAT_I_SINT8: + return format == GL_RED_INTEGER && type == GL_BYTE; + case MESA_FORMAT_I_SINT16: + return format == GL_RED_INTEGER && type == GL_SHORT && !swapBytes; + case MESA_FORMAT_I_SINT32: + return format == GL_RED_INTEGER && type == GL_INT && !swapBytes; + + case MESA_FORMAT_L_UINT8: + return format == GL_LUMINANCE_INTEGER_EXT && type == GL_UNSIGNED_BYTE; + case MESA_FORMAT_L_UINT16: + return format == GL_LUMINANCE_INTEGER_EXT && type == GL_UNSIGNED_SHORT && + !swapBytes; + case MESA_FORMAT_L_UINT32: + return format == GL_LUMINANCE_INTEGER_EXT && type == GL_UNSIGNED_INT && + !swapBytes; + case MESA_FORMAT_L_SINT8: + return format == GL_LUMINANCE_INTEGER_EXT && type == GL_BYTE; + case MESA_FORMAT_L_SINT16: + return format == GL_LUMINANCE_INTEGER_EXT && type == GL_SHORT && + !swapBytes; + case MESA_FORMAT_L_SINT32: + return format == GL_LUMINANCE_INTEGER_EXT && type == GL_INT && !swapBytes; + + case MESA_FORMAT_LA_UINT8: + return format == GL_LUMINANCE_ALPHA_INTEGER_EXT && + type == GL_UNSIGNED_BYTE && !swapBytes; + case MESA_FORMAT_LA_UINT16: + return format == GL_LUMINANCE_ALPHA_INTEGER_EXT && + type == GL_UNSIGNED_SHORT && !swapBytes; + case MESA_FORMAT_LA_UINT32: + return format == GL_LUMINANCE_ALPHA_INTEGER_EXT && + type == GL_UNSIGNED_INT && !swapBytes; + case MESA_FORMAT_LA_SINT8: + return format == GL_LUMINANCE_ALPHA_INTEGER_EXT && type == GL_BYTE && + !swapBytes; + case MESA_FORMAT_LA_SINT16: + return format == GL_LUMINANCE_ALPHA_INTEGER_EXT && type == GL_SHORT && + !swapBytes; + case MESA_FORMAT_LA_SINT32: + return format == GL_LUMINANCE_ALPHA_INTEGER_EXT && type == GL_INT && + !swapBytes; + + case MESA_FORMAT_R_SINT8: + return format == GL_RED_INTEGER && type == GL_BYTE; + case MESA_FORMAT_RG_SINT8: + return format == GL_RG_INTEGER && type == GL_BYTE && !swapBytes; + case MESA_FORMAT_RGB_SINT8: + return format == GL_RGB_INTEGER && type == GL_BYTE && !swapBytes; + case MESA_FORMAT_RGBA_SINT8: + return format == GL_RGBA_INTEGER && type == GL_BYTE && !swapBytes; + case MESA_FORMAT_R_SINT16: + return format == GL_RED_INTEGER && type == GL_SHORT && !swapBytes; + case MESA_FORMAT_RG_SINT16: + return format == GL_RG_INTEGER && type == GL_SHORT && !swapBytes; + case MESA_FORMAT_RGB_SINT16: + return format == GL_RGB_INTEGER && type == GL_SHORT && !swapBytes; + case MESA_FORMAT_RGBA_SINT16: + return format == GL_RGBA_INTEGER && type == GL_SHORT && !swapBytes; + case MESA_FORMAT_R_SINT32: + return format == GL_RED_INTEGER && type == GL_INT && !swapBytes; + case MESA_FORMAT_RG_SINT32: + return format == GL_RG_INTEGER && type == GL_INT && !swapBytes; + case MESA_FORMAT_RGB_SINT32: + return format == GL_RGB_INTEGER && type == GL_INT && !swapBytes; + case MESA_FORMAT_RGBA_SINT32: + return format == GL_RGBA_INTEGER && type == GL_INT && !swapBytes; + + case MESA_FORMAT_R_UINT8: + return format == GL_RED_INTEGER && type == GL_UNSIGNED_BYTE; + case MESA_FORMAT_RG_UINT8: + return format == GL_RG_INTEGER && type == GL_UNSIGNED_BYTE && !swapBytes; + case MESA_FORMAT_RGB_UINT8: + return format == GL_RGB_INTEGER && type == GL_UNSIGNED_BYTE && !swapBytes; + case MESA_FORMAT_RGBA_UINT8: + return format == GL_RGBA_INTEGER && type == GL_UNSIGNED_BYTE && + !swapBytes; + case MESA_FORMAT_R_UINT16: + return format == GL_RED_INTEGER && type == GL_UNSIGNED_SHORT && + !swapBytes; + case MESA_FORMAT_RG_UINT16: + return format == GL_RG_INTEGER && type == GL_UNSIGNED_SHORT && !swapBytes; + case MESA_FORMAT_RGB_UINT16: + return format == GL_RGB_INTEGER && type == GL_UNSIGNED_SHORT && + !swapBytes; + case MESA_FORMAT_RGBA_UINT16: + return format == GL_RGBA_INTEGER && type == GL_UNSIGNED_SHORT && + !swapBytes; + case MESA_FORMAT_R_UINT32: + return format == GL_RED_INTEGER && type == GL_UNSIGNED_INT && !swapBytes; + case MESA_FORMAT_RG_UINT32: + return format == GL_RG_INTEGER && type == GL_UNSIGNED_INT && !swapBytes; + case MESA_FORMAT_RGB_UINT32: + return format == GL_RGB_INTEGER && type == GL_UNSIGNED_INT && !swapBytes; + case MESA_FORMAT_RGBA_UINT32: + return format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT && !swapBytes; + + case MESA_FORMAT_R_SNORM8: + return format == GL_RED && type == GL_BYTE; + case MESA_FORMAT_R8G8_SNORM: + return format == GL_RG && type == GL_BYTE && littleEndian && + !swapBytes; + case MESA_FORMAT_X8B8G8R8_SNORM: + return GL_FALSE; + + case MESA_FORMAT_A8B8G8R8_SNORM: + if (format == GL_RGBA && type == GL_BYTE && !littleEndian) + return GL_TRUE; + + if (format == GL_ABGR_EXT && type == GL_BYTE && littleEndian) + return GL_TRUE; + + return GL_FALSE; + + case MESA_FORMAT_R8G8B8A8_SNORM: + if (format == GL_RGBA && type == GL_BYTE && littleEndian) + return GL_TRUE; + + if (format == GL_ABGR_EXT && type == GL_BYTE && !littleEndian) + return GL_TRUE; + + return GL_FALSE; + + case MESA_FORMAT_R_SNORM16: + return format == GL_RED && type == GL_SHORT && + !swapBytes; + case MESA_FORMAT_R16G16_SNORM: + return format == GL_RG && type == GL_SHORT && littleEndian && !swapBytes; + case MESA_FORMAT_RGB_SNORM16: + return format == GL_RGB && type == GL_SHORT && !swapBytes; + case MESA_FORMAT_RGBA_SNORM16: + return format == GL_RGBA && type == GL_SHORT && !swapBytes; + case MESA_FORMAT_RGBA_UNORM16: + return format == GL_RGBA && type == GL_UNSIGNED_SHORT && + !swapBytes; + + case MESA_FORMAT_R_RGTC1_UNORM: + case MESA_FORMAT_R_RGTC1_SNORM: + case MESA_FORMAT_RG_RGTC2_UNORM: + case MESA_FORMAT_RG_RGTC2_SNORM: + return GL_FALSE; + + case MESA_FORMAT_L_LATC1_UNORM: + case MESA_FORMAT_L_LATC1_SNORM: + case MESA_FORMAT_LA_LATC2_UNORM: + case MESA_FORMAT_LA_LATC2_SNORM: + return GL_FALSE; + + case MESA_FORMAT_ETC1_RGB8: + case MESA_FORMAT_ETC2_RGB8: + case MESA_FORMAT_ETC2_SRGB8: + case MESA_FORMAT_ETC2_RGBA8_EAC: + case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC: + case MESA_FORMAT_ETC2_R11_EAC: + case MESA_FORMAT_ETC2_RG11_EAC: + case MESA_FORMAT_ETC2_SIGNED_R11_EAC: + case MESA_FORMAT_ETC2_SIGNED_RG11_EAC: + case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: + case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: + return GL_FALSE; + + case MESA_FORMAT_A_SNORM8: + return format == GL_ALPHA && type == GL_BYTE; + case MESA_FORMAT_L_SNORM8: + return format == GL_LUMINANCE && type == GL_BYTE; + case MESA_FORMAT_L8A8_SNORM: + return format == GL_LUMINANCE_ALPHA && type == GL_BYTE && + littleEndian && !swapBytes; + case MESA_FORMAT_A8L8_SNORM: + return format == GL_LUMINANCE_ALPHA && type == GL_BYTE && + !littleEndian && !swapBytes; + case MESA_FORMAT_I_SNORM8: + return format == GL_RED && type == GL_BYTE; + case MESA_FORMAT_A_SNORM16: + return format == GL_ALPHA && type == GL_SHORT && !swapBytes; + case MESA_FORMAT_L_SNORM16: + return format == GL_LUMINANCE && type == GL_SHORT && !swapBytes; + case MESA_FORMAT_LA_SNORM16: + return format == GL_LUMINANCE_ALPHA && type == GL_SHORT && + littleEndian && !swapBytes; + case MESA_FORMAT_I_SNORM16: + return format == GL_RED && type == GL_SHORT && littleEndian && + !swapBytes; + + case MESA_FORMAT_B10G10R10A2_UINT: + return (format == GL_BGRA_INTEGER_EXT && + type == GL_UNSIGNED_INT_2_10_10_10_REV && + !swapBytes); + + case MESA_FORMAT_R10G10B10A2_UINT: + return (format == GL_RGBA_INTEGER_EXT && + type == GL_UNSIGNED_INT_2_10_10_10_REV && + !swapBytes); + + case MESA_FORMAT_R9G9B9E5_FLOAT: + return format == GL_RGB && type == GL_UNSIGNED_INT_5_9_9_9_REV && + !swapBytes; + + case MESA_FORMAT_R11G11B10_FLOAT: + return format == GL_RGB && type == GL_UNSIGNED_INT_10F_11F_11F_REV && + !swapBytes; + + case MESA_FORMAT_Z_FLOAT32: + return format == GL_DEPTH_COMPONENT && type == GL_FLOAT && !swapBytes; + + case MESA_FORMAT_Z32_FLOAT_S8X24_UINT: + return format == GL_DEPTH_STENCIL && + type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV && !swapBytes; + + case MESA_FORMAT_B4G4R4X4_UNORM: + case MESA_FORMAT_B5G5R5X1_UNORM: + case MESA_FORMAT_R8G8B8X8_SNORM: + case MESA_FORMAT_R8G8B8X8_SRGB: + case MESA_FORMAT_X8B8G8R8_SRGB: + case MESA_FORMAT_RGBX_UINT8: + case MESA_FORMAT_RGBX_SINT8: + case MESA_FORMAT_B10G10R10X2_UNORM: + case MESA_FORMAT_R10G10B10X2_UNORM: + case MESA_FORMAT_RGBX_UNORM16: + case MESA_FORMAT_RGBX_SNORM16: + case MESA_FORMAT_RGBX_FLOAT16: + case MESA_FORMAT_RGBX_UINT16: + case MESA_FORMAT_RGBX_SINT16: + case MESA_FORMAT_RGBX_FLOAT32: + case MESA_FORMAT_RGBX_UINT32: + case MESA_FORMAT_RGBX_SINT32: + return GL_FALSE; + + case MESA_FORMAT_R10G10B10A2_UNORM: + return format == GL_RGBA && type == GL_UNSIGNED_INT_2_10_10_10_REV && + !swapBytes; + + case MESA_FORMAT_G8R8_SNORM: + return format == GL_RG && type == GL_BYTE && !littleEndian && + !swapBytes; + + case MESA_FORMAT_G16R16_SNORM: + return format == GL_RG && type == GL_SHORT && !littleEndian && + !swapBytes; + + case MESA_FORMAT_B8G8R8X8_SRGB: + case MESA_FORMAT_X8R8G8B8_SRGB: + return GL_FALSE; + } + + return GL_FALSE; +} +