[Mesa-dev] [PATCH 09/20] mesa: Add a concept of an array format

2014-11-18 Thread Iago Toral Quiroga
From: Jason Ekstrand jason.ekstr...@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 ito...@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  | 55 +++
 3 files changed, 151 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..7642875 100644
--- a/src/mesa/main/formats.h
+++ b/src/mesa/main/formats.h
@@ -81,6 +81,55 @@ enum {
MESA_FORMAT_SWIZZLE_NONE = 6,
 };
 
+enum  mesa_array_format_datatype {
+   MESA_ARRAY_FORMAT_TYPE_UBYTE = 0x0,
+   

Re: [Mesa-dev] [PATCH 09/20] mesa: Add a concept of an array format

2014-11-18 Thread Jason Ekstrand
On Tue, Nov 18, 2014 at 12:43 AM, Iago Toral Quiroga ito...@igalia.com
wrote:

 From: Jason Ekstrand jason.ekstr...@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 ito...@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.


I'm not terribly surprised, I never got a chance to test that function
before I handed it off to you.  I'm curious how you found it though, given
that it's only run on big endian architectures.  Maybe it was just
obviously wrong.  (silly me).  In any case, the new version looks good to
me.
--Jason


 ---
  src/mesa/main/format_info.py | 41 
  src/mesa/main/formats.c  | 56
 +++-
  src/mesa/main/formats.h  | 55
 +++
  3 files changed, 151 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 

Re: [Mesa-dev] [PATCH 09/20] mesa: Add a concept of an array format

2014-11-18 Thread Iago Toral
On Tue, 2014-11-18 at 10:46 -0800, Jason Ekstrand wrote:
 
 
 On Tue, Nov 18, 2014 at 12:43 AM, Iago Toral Quiroga
 ito...@igalia.com wrote:
 From: Jason Ekstrand jason.ekstr...@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 ito...@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.
 
 
 I'm not terribly surprised, I never got a chance to test that function
 before I handed it off to you.  I'm curious how you found it though,
 given that it's only run on big endian architectures.  Maybe it was
 just obviously wrong.  (silly me).  In any case, the new version looks
 good to me.

I noticed that because at some point I thought I needed to flip the
channels for GL_UNSIGNED_INT_8_8_8_8 in certain cases (I was wrong about
that in the end, but that drove me to look into it), and when I looked
at the function it was pretty obvious that it was not doing what it was
expected.

Iago

 --Jason
 
  
 ---
  src/mesa/main/format_info.py | 41
 
  src/mesa/main/formats.c  | 56
 +++-
  src/mesa/main/formats.h  | 55
 +++
  3 files changed, 151 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;
 +