#include "imports.h"
#include "formats.h"
-#include "config.h"
-#include "texstore.h"
+#include "mfeatures.h"
/**
const char *StrName;
/**
- * Base format is 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.
+ * 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_COLOR_INDEX, GL_DEPTH_COMPONENT, GL_STENCIL_INDEX,
+ * GL_DEPTH_STENCIL, GL_DUDV_ATI.
*/
GLenum BaseFormat;
/**
* Logical data type: one of GL_UNSIGNED_NORMALIZED, GL_SIGNED_NORMALED,
- * GL_UNSIGNED_INT, GL_SIGNED_INT, GL_FLOAT.
+ * GL_UNSIGNED_INT, GL_INT, GL_FLOAT.
*/
GLenum DataType;
0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
1, 1, 2 /* BlockWidth/Height,Bytes */
},
+ {
+ MESA_FORMAT_AL44, /* Name */
+ "MESA_FORMAT_AL44", /* StrName */
+ GL_LUMINANCE_ALPHA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED, /* DataType */
+ 0, 0, 0, 4, /* Red/Green/Blue/AlphaBits */
+ 4, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
+ 1, 1, 1 /* BlockWidth/Height,Bytes */
+ },
{
MESA_FORMAT_AL88, /* Name */
"MESA_FORMAT_AL88", /* StrName */
0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
1, 1, 1 /* BlockWidth/Height,Bytes */
},
+ {
+ MESA_FORMAT_A16, /* Name */
+ "MESA_FORMAT_A16", /* StrName */
+ GL_ALPHA, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED, /* DataType */
+ 0, 0, 0, 16, /* Red/Green/Blue/AlphaBits */
+ 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
+ 1, 1, 2 /* BlockWidth/Height,Bytes */
+ },
{
MESA_FORMAT_L8, /* Name */
"MESA_FORMAT_L8", /* StrName */
8, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
1, 1, 1 /* BlockWidth/Height,Bytes */
},
+ {
+ MESA_FORMAT_L16, /* Name */
+ "MESA_FORMAT_L16", /* StrName */
+ GL_LUMINANCE, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED, /* DataType */
+ 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
+ 16, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
+ 1, 1, 2 /* BlockWidth/Height,Bytes */
+ },
{
MESA_FORMAT_I8, /* Name */
"MESA_FORMAT_I8", /* StrName */
0, 8, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
1, 1, 1 /* BlockWidth/Height,Bytes */
},
+ {
+ MESA_FORMAT_I16, /* Name */
+ "MESA_FORMAT_I16", /* StrName */
+ GL_INTENSITY, /* BaseFormat */
+ GL_UNSIGNED_NORMALIZED, /* DataType */
+ 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
+ 0, 16, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
+ 1, 1, 2 /* BlockWidth/Height,Bytes */
+ },
{
MESA_FORMAT_CI8, /* Name */
"MESA_FORMAT_CI8", /* StrName */
0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
1, 1, 2 /* BlockWidth/Height,Bytes */
},
+ {
+ MESA_FORMAT_R8,
+ "MESA_FORMAT_R8",
+ GL_RED,
+ GL_UNSIGNED_NORMALIZED,
+ 8, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 1, 1
+ },
+ {
+ MESA_FORMAT_RG88,
+ "MESA_FORMAT_RG88",
+ GL_RG,
+ GL_UNSIGNED_NORMALIZED,
+ 8, 8, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 1, 2
+ },
+ {
+ MESA_FORMAT_RG88_REV,
+ "MESA_FORMAT_RG88_REV",
+ GL_RG,
+ GL_UNSIGNED_NORMALIZED,
+ 8, 8, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 1, 2
+ },
+ {
+ MESA_FORMAT_R16,
+ "MESA_FORMAT_R16",
+ GL_RED,
+ GL_UNSIGNED_NORMALIZED,
+ 16, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 1, 2
+ },
+ {
+ MESA_FORMAT_RG1616,
+ "MESA_FORMAT_RG1616",
+ GL_RG,
+ GL_UNSIGNED_NORMALIZED,
+ 16, 16, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 1, 4
+ },
+ {
+ MESA_FORMAT_RG1616_REV,
+ "MESA_FORMAT_RG1616_REV",
+ GL_RG,
+ GL_UNSIGNED_NORMALIZED,
+ 16, 16, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 1, 4
+ },
+ {
+ MESA_FORMAT_ARGB2101010,
+ "MESA_FORMAT_ARGB2101010",
+ GL_RGBA,
+ GL_UNSIGNED_NORMALIZED,
+ 10, 10, 10, 2,
+ 0, 0, 0, 0, 0,
+ 1, 1, 4
+ },
{
MESA_FORMAT_Z24_S8, /* Name */
"MESA_FORMAT_Z24_S8", /* StrName */
0, 16, 0, 0, 0,
1, 1, 2
},
+
+ /* unnormalized signed int formats */
+ {
+ MESA_FORMAT_RGBA_INT8,
+ "MESA_FORMAT_RGBA_INT8",
+ GL_RGBA,
+ GL_INT,
+ 8, 8, 8, 8,
+ 0, 0, 0, 0, 0,
+ 1, 1, 4
+ },
+ {
+ MESA_FORMAT_RGBA_INT16,
+ "MESA_FORMAT_RGBA_INT16",
+ GL_RGBA,
+ GL_INT,
+ 16, 16, 16, 16,
+ 0, 0, 0, 0, 0,
+ 1, 1, 8
+ },
+ {
+ MESA_FORMAT_RGBA_INT32,
+ "MESA_FORMAT_RGBA_INT32",
+ GL_RGBA,
+ GL_INT,
+ 32, 32, 32, 32,
+ 0, 0, 0, 0, 0,
+ 1, 1, 16
+ },
+
+ /* unnormalized unsigned int formats */
+ {
+ MESA_FORMAT_RGBA_UINT8,
+ "MESA_FORMAT_RGBA_UINT8",
+ GL_RGBA,
+ GL_UNSIGNED_INT,
+ 8, 8, 8, 8,
+ 0, 0, 0, 0, 0,
+ 1, 1, 4
+ },
+ {
+ MESA_FORMAT_RGBA_UINT16,
+ "MESA_FORMAT_RGBA_UINT16",
+ GL_RGBA,
+ GL_UNSIGNED_INT,
+ 16, 16, 16, 16,
+ 0, 0, 0, 0, 0,
+ 1, 1, 8
+ },
+ {
+ MESA_FORMAT_RGBA_UINT32,
+ "MESA_FORMAT_RGBA_UINT32",
+ GL_RGBA,
+ GL_UNSIGNED_INT,
+ 32, 32, 32, 32,
+ 0, 0, 0, 0, 0,
+ 1, 1, 16
+ },
+
+
{
MESA_FORMAT_DUDV8,
"MESA_FORMAT_DUDV8",
0, 0, 0, 0, 0,
1, 1, 2
},
+
+ /* Signed 8 bits / channel */
+ {
+ MESA_FORMAT_SIGNED_R8, /* Name */
+ "MESA_FORMAT_SIGNED_R8", /* StrName */
+ GL_RED, /* BaseFormat */
+ GL_SIGNED_NORMALIZED, /* DataType */
+ 8, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
+ 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
+ 1, 1, 1 /* BlockWidth/Height,Bytes */
+ },
+ {
+ MESA_FORMAT_SIGNED_RG88,
+ "MESA_FORMAT_SIGNED_RG88",
+ GL_RG,
+ GL_SIGNED_NORMALIZED,
+ 8, 8, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 1, 2
+ },
+ {
+ MESA_FORMAT_SIGNED_RGBX8888,
+ "MESA_FORMAT_SIGNED_RGBX8888",
+ GL_RGB,
+ GL_SIGNED_NORMALIZED,
+ 8, 8, 8, 0,
+ 0, 0, 0, 0, 0,
+ 1, 1, 4 /* 4 bpp, but no alpha */
+ },
{
MESA_FORMAT_SIGNED_RGBA8888,
"MESA_FORMAT_SIGNED_RGBA8888",
0, 0, 0, 0, 0,
1, 1, 4
},
+
+ /* Signed 16 bits / channel */
+ {
+ MESA_FORMAT_SIGNED_R_16,
+ "MESA_FORMAT_SIGNED_R_16",
+ GL_RED,
+ GL_SIGNED_NORMALIZED,
+ 16, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 1, 2
+ },
+ {
+ MESA_FORMAT_SIGNED_RG_16,
+ "MESA_FORMAT_SIGNED_RG_16",
+ GL_RG,
+ GL_SIGNED_NORMALIZED,
+ 16, 16, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 1, 4
+ },
+ {
+ MESA_FORMAT_SIGNED_RGB_16,
+ "MESA_FORMAT_SIGNED_RGB_16",
+ GL_RGB,
+ GL_SIGNED_NORMALIZED,
+ 16, 16, 16, 0,
+ 0, 0, 0, 0, 0,
+ 1, 1, 6
+ },
{
MESA_FORMAT_SIGNED_RGBA_16,
"MESA_FORMAT_SIGNED_RGBA_16",
16, 16, 16, 16,
0, 0, 0, 0, 0,
1, 1, 8
+ },
+ {
+ MESA_FORMAT_RGBA_16,
+ "MESA_FORMAT_RGBA_16",
+ GL_RGBA,
+ GL_UNSIGNED_NORMALIZED,
+ 16, 16, 16, 16,
+ 0, 0, 0, 0, 0,
+ 1, 1, 8
}
};
_mesa_get_format_name(gl_format format)
{
const struct gl_format_info *info = _mesa_get_format_info(format);
- ASSERT(info->BytesPerBlock);
return info->StrName;
}
* 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
}
+/**
+ * Determine if the given format represents a packed depth/stencil buffer.
+ */
+GLboolean
+_mesa_is_format_packed_depth_stencil(gl_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(gl_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;
+}
+
+
/**
* Return color encoding for given format.
* \return GL_LINEAR or GL_SRGB
}
+/**
+ * For an sRGB format, return the corresponding linear color space format.
+ * For non-sRGB formats, return the format as-is.
+ */
+gl_format
+_mesa_get_srgb_format_linear(gl_format format)
+{
+ switch (format) {
+ case MESA_FORMAT_SRGB8:
+ format = MESA_FORMAT_RGB888;
+ break;
+ case MESA_FORMAT_SRGBA8:
+ format = MESA_FORMAT_RGBA8888;
+ break;
+ case MESA_FORMAT_SARGB8:
+ format = MESA_FORMAT_ARGB8888;
+ break;
+ case MESA_FORMAT_SL8:
+ format = MESA_FORMAT_L8;
+ break;
+ case MESA_FORMAT_SLA8:
+ format = MESA_FORMAT_AL88;
+ 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;
+ default:
+ break;
+ }
+ return format;
+}
+
+
/**
* Return number of bytes needed to store an image of the given size
* in the given format.
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;
+ assert(depth == 1);
return sz;
}
else {
}
+/**
+ * Same as _mesa_format_image_size() but returns a 64-bit value to
+ * accomodate very large textures.
+ */
+uint64_t
+_mesa_format_image_size64(gl_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;
+ assert(depth == 1);
+ return sz;
+ }
+ 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)
}
+/**
+ * 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)
+{
+ gl_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.
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;
}
}
assert(info->DataType == GL_UNSIGNED_NORMALIZED ||
info->DataType == GL_SIGNED_NORMALIZED ||
info->DataType == GL_UNSIGNED_INT ||
+ info->DataType == GL_INT ||
info->DataType == GL_FLOAT);
if (info->BaseFormat == GL_RGB) {
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);
assert(info->LuminanceBits == 0);
assert(info->IntensityBits > 0);
}
-
}
+
+ check_format_to_type_and_comps();
}
case MESA_FORMAT_ARGB8888:
case MESA_FORMAT_ARGB8888_REV:
case MESA_FORMAT_XRGB8888:
+ case MESA_FORMAT_XRGB8888_REV:
*datatype = GL_UNSIGNED_BYTE;
*comps = 4;
return;
*comps = 4;
return;
+ case MESA_FORMAT_ARGB2101010:
+ *datatype = GL_UNSIGNED_INT_2_10_10_10_REV;
+ *comps = 4;
+ return;
+
+ case MESA_FORMAT_RGBA5551:
+ *datatype = GL_UNSIGNED_SHORT_5_5_5_1;
+ *comps = 4;
+ return;
+
+ case MESA_FORMAT_AL44: /* XXX this isn't plain GL_UNSIGNED_BYTE */
case MESA_FORMAT_AL88:
case MESA_FORMAT_AL88_REV:
+ case MESA_FORMAT_RG88:
+ case MESA_FORMAT_RG88_REV:
*datatype = GL_UNSIGNED_BYTE;
*comps = 2;
return;
case MESA_FORMAT_AL1616:
case MESA_FORMAT_AL1616_REV:
+ case MESA_FORMAT_RG1616:
+ case MESA_FORMAT_RG1616_REV:
*datatype = GL_UNSIGNED_SHORT;
*comps = 2;
return;
+ case MESA_FORMAT_R16:
+ case MESA_FORMAT_A16:
+ case MESA_FORMAT_L16:
+ case MESA_FORMAT_I16:
+ *datatype = GL_UNSIGNED_SHORT;
+ *comps = 1;
+ return;
+
case MESA_FORMAT_RGB332:
*datatype = GL_UNSIGNED_BYTE_3_3_2;
*comps = 3;
case MESA_FORMAT_L8:
case MESA_FORMAT_I8:
case MESA_FORMAT_CI8:
+ case MESA_FORMAT_R8:
+ case MESA_FORMAT_S8:
*datatype = GL_UNSIGNED_BYTE;
*comps = 1;
return;
*comps = 2;
return;
+ case MESA_FORMAT_SIGNED_R8:
+ *datatype = GL_BYTE;
+ *comps = 1;
+ return;
+ case MESA_FORMAT_SIGNED_RG88:
+ *datatype = GL_BYTE;
+ *comps = 2;
+ return;
case MESA_FORMAT_SIGNED_RGBA8888:
case MESA_FORMAT_SIGNED_RGBA8888_REV:
+ case MESA_FORMAT_SIGNED_RGBX8888:
*datatype = GL_BYTE;
*comps = 4;
return;
+
+ case MESA_FORMAT_RGBA_16:
+ *datatype = GL_UNSIGNED_SHORT;
+ *comps = 4;
+ return;
+
+ case MESA_FORMAT_SIGNED_R_16:
+ *datatype = GL_SHORT;
+ *comps = 1;
+ return;
+ case MESA_FORMAT_SIGNED_RG_16:
+ *datatype = GL_SHORT;
+ *comps = 2;
+ return;
+ case MESA_FORMAT_SIGNED_RGB_16:
+ *datatype = GL_SHORT;
+ *comps = 3;
+ return;
case MESA_FORMAT_SIGNED_RGBA_16:
*datatype = GL_SHORT;
*comps = 4;
case MESA_FORMAT_SRGBA_DXT1:
case MESA_FORMAT_SRGBA_DXT3:
case MESA_FORMAT_SRGBA_DXT5:
+#endif
#endif
/* XXX generate error instead? */
*datatype = GL_UNSIGNED_BYTE;
*comps = 0;
return;
-#endif
case MESA_FORMAT_RGBA_FLOAT32:
*datatype = GL_FLOAT;
*comps = 1;
return;
+ case MESA_FORMAT_RGBA_INT8:
+ *datatype = GL_BYTE;
+ *comps = 4;
+ return;
+ case MESA_FORMAT_RGBA_INT16:
+ *datatype = GL_SHORT;
+ *comps = 4;
+ return;
+ case MESA_FORMAT_RGBA_INT32:
+ *datatype = GL_INT;
+ *comps = 4;
+ return;
+
+ /**
+ * \name Non-normalized unsigned integer formats.
+ */
+ case MESA_FORMAT_RGBA_UINT8:
+ *datatype = GL_UNSIGNED_BYTE;
+ *comps = 4;
+ return;
+ case MESA_FORMAT_RGBA_UINT16:
+ *datatype = GL_UNSIGNED_SHORT;
+ *comps = 4;
+ return;
+ case MESA_FORMAT_RGBA_UINT32:
+ *datatype = GL_UNSIGNED_INT;
+ *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;
}