[Mesa-dev] [PATCH v2 10/23] mesa: Add a concept of an array format
Iago Toral Quiroga
itoral at igalia.com
Mon Dec 1 03:04:19 PST 2014
From: Jason Ekstrand <jason.ekstrand at intel.com>
An array format is a 32-bit integer format identifier that can represent
any format that can be represented as an array of standard GL datatypes.
While the MESA_FORMAT enums provide several of these, they don't account
for all of them.
v2 by Iago Toral Quiroga <itoral at igalia.com>:
- Set pad to 0 and array_format_bit to 1 for all mesa array formats.
- Fix array_format_flip_channels, since it was not doing what was expected.
---
src/mesa/main/format_info.py | 41 +++++++++++++++++++++++++++++
src/mesa/main/formats.c | 56 ++++++++++++++++++++++++++++++++++++++-
src/mesa/main/formats.h | 62 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 158 insertions(+), 1 deletion(-)
diff --git a/src/mesa/main/format_info.py b/src/mesa/main/format_info.py
index 7424fe0..315767d 100644
--- a/src/mesa/main/format_info.py
+++ b/src/mesa/main/format_info.py
@@ -98,6 +98,32 @@ def get_gl_data_type(fmat):
else:
assert False
+def get_array_format_datatype(chan):
+ if chan.type == parser.FLOAT:
+ if chan.size == 16:
+ return 'MESA_ARRAY_FORMAT_TYPE_HALF'
+ elif chan.size == 32:
+ return 'MESA_ARRAY_FORMAT_TYPE_FLOAT'
+ else:
+ assert False
+ elif chan.type in (parser.SIGNED, parser.UNSIGNED):
+ datatype = 'MESA_ARRAY_FORMAT_TYPE_'
+ if chan.type == parser.UNSIGNED:
+ datatype += 'U'
+
+ if chan.size == 8:
+ datatype += 'BYTE'
+ elif chan.size == 16:
+ datatype += 'SHORT'
+ elif chan.size == 32:
+ datatype += 'INT'
+ else:
+ print chan.size
+ assert False
+ return datatype
+ else:
+ assert False
+
def get_mesa_layout(fmat):
if fmat.layout == 'array':
return 'MESA_FORMAT_LAYOUT_ARRAY'
@@ -192,6 +218,21 @@ for fmat in formats:
int(fmat.block_size() / 8))
print ' {{ {0} }},'.format(', '.join(map(str, fmat.swizzle)))
+ if fmat.is_array() and fmat.colorspace in ('rgb', 'srgb'):
+ chan = fmat.array_element()
+ print ' {{{{ {0} }}}},'.format(', '.join([
+ get_array_format_datatype(chan),
+ str(int(chan.norm)),
+ str(len(fmat.channels)),
+ str(fmat.swizzle[0]),
+ str(fmat.swizzle[1]),
+ str(fmat.swizzle[2]),
+ str(fmat.swizzle[3]),
+ str(int(0)),
+ str(int(1))
+ ]))
+ else:
+ print ' {{ MESA_ARRAY_FORMAT_TYPE_UBYTE, 0, 0, 0, 0, 0, 0, 0, 0 }},'
print ' },'
print '};'
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
index 7ec0507..f86925e 100644
--- a/src/mesa/main/formats.c
+++ b/src/mesa/main/formats.c
@@ -71,6 +71,7 @@ struct gl_format_info
GLubyte BytesPerBlock;
uint8_t Swizzle[4];
+ mesa_array_format ArrayFormat;
};
#include "format_info.c"
@@ -269,6 +270,60 @@ _mesa_get_format_swizzle(mesa_format format, uint8_t swizzle_out[4])
memcpy(swizzle_out, info->Swizzle, sizeof(info->Swizzle));
}
+static mesa_array_format
+array_format_flip_channels(mesa_array_format format)
+{
+ if (format.num_channels == 1)
+ return format;
+
+ if (format.num_channels == 2) {
+ int tmp = format.swizzle_x;
+ format.swizzle_x = format.swizzle_y;
+ format.swizzle_y = tmp;
+ return format;
+ }
+
+ if (format.num_channels == 4) {
+ int tmp = format.swizzle_x;
+ format.swizzle_x = format.swizzle_w;
+ format.swizzle_w = tmp;
+ tmp = format.swizzle_y;
+ format.swizzle_y = format.swizzle_z;
+ format.swizzle_z = tmp;
+ return format;
+ }
+
+ assert(!"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())
+ return info->ArrayFormat.as_uint;
+ else
+ return array_format_flip_channels(info->ArrayFormat).as_uint;
+}
+
+mesa_format
+_mesa_format_from_array_format(uint32_t array_format)
+{
+ mesa_array_format af;
+ unsigned f;
+
+ af.as_uint = array_format;
+ af.pad = 0;
+ if (!_mesa_little_endian())
+ af = array_format_flip_channels(af);
+
+ assert(af.array_format_bit);
+ for (f = 1; f < MESA_FORMAT_COUNT; ++f)
+ if (_mesa_get_format_info(f)->ArrayFormat.as_uint == af.as_uint)
+ return f;
+
+ return MESA_FORMAT_NONE;
+}
/** Is the given format a compressed format? */
GLboolean
@@ -278,7 +333,6 @@ _mesa_is_format_compressed(mesa_format format)
return info->BlockWidth > 1 || info->BlockHeight > 1;
}
-
/**
* Determine if the given format represents a packed depth/stencil buffer.
*/
diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h
index 213ab56..8b62788 100644
--- a/src/mesa/main/formats.h
+++ b/src/mesa/main/formats.h
@@ -81,6 +81,62 @@ enum {
MESA_FORMAT_SWIZZLE_NONE = 6,
};
+enum mesa_array_format_datatype {
+ MESA_ARRAY_FORMAT_TYPE_UBYTE = 0x0,
+ MESA_ARRAY_FORMAT_TYPE_USHORT = 0x1,
+ MESA_ARRAY_FORMAT_TYPE_UINT = 0x2,
+ MESA_ARRAY_FORMAT_TYPE_BYTE = 0x4,
+ MESA_ARRAY_FORMAT_TYPE_SHORT = 0x5,
+ MESA_ARRAY_FORMAT_TYPE_INT = 0x6,
+ MESA_ARRAY_FORMAT_TYPE_HALF = 0xd,
+ MESA_ARRAY_FORMAT_TYPE_FLOAT = 0xe,
+};
+
+#define MESA_ARRAY_FORMAT_TYPE_IS_SIGNED 0x4
+#define MESA_ARRAY_FORMAT_TYPE_IS_FLOAT 0x8
+#define MESA_ARRAY_FORMAT_BIT 0x80000000
+
+typedef union {
+ struct {
+ enum mesa_array_format_datatype type:4;
+ bool normalized:1;
+ unsigned num_channels:3;
+ unsigned swizzle_x:3;
+ unsigned swizzle_y:3;
+ unsigned swizzle_z:3;
+ unsigned swizzle_w:3;
+ unsigned pad:11;
+ unsigned array_format_bit:1; /* Must always be 1 */
+ };
+ uint32_t as_uint;
+} mesa_array_format;
+
+static const mesa_array_format _mesa_array_format_none = {{
+ MESA_ARRAY_FORMAT_TYPE_UBYTE,
+ 0, 0, 0, 0, 0, 0, 0, 0
+}};
+
+static inline unsigned
+_mesa_ilog2(unsigned x)
+{
+ uint8_t i;
+ for (i = 1; i < 32; ++i)
+ if (x <= (1u << i))
+ return i;
+ return 32;
+}
+
+#define MESA_ARRAY_FORMAT_TYPE(SIZE, SIGNED, IS_FLOAT, NORM) ( \
+ ((_mesa_ilog2(SIZE)) & MESA_ARRAY_FORMAT_TYPE_SIZE_MASK) | \
+ (((SIGNED) << 2 ) & MESA_ARRAY_FORMAT_TYPE_IS_SIGNED) | \
+ (((IS_FLOAT) << 3 ) & MESA_ARRAY_FORMAT_TYPE_IS_FLOAT)
+
+static inline int
+_mesa_array_format_datatype_size(enum mesa_array_format_datatype type)
+{
+ return 1 << (type & 0x3);
+}
+
/**
* Mesa texture/renderbuffer image formats.
*/
@@ -469,6 +525,12 @@ _mesa_get_format_block_size(mesa_format format, GLuint *bw, GLuint *bh);
extern void
_mesa_get_format_swizzle(mesa_format format, uint8_t swizzle_out[4]);
+extern uint32_t
+_mesa_format_to_array_format(mesa_format format);
+
+extern mesa_format
+_mesa_format_from_array_format(uint32_t array_format);
+
extern GLboolean
_mesa_is_format_compressed(mesa_format format);
--
1.9.1
More information about the mesa-dev
mailing list