<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Dec 1, 2014 at 3:04 AM, Iago Toral Quiroga <span dir="ltr"><<a href="mailto:itoral@igalia.com" target="_blank">itoral@igalia.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">If we need the base format for a mesa_array_format we have to find the<br>
matching mesa_format first. This is expensive because it requires<br>
to loop through all existing mesa formats until we find the right match.<br>
<br>
We can resolve the base format of an array format directly by looking<br>
at its swizzle information. Also, we can have _mesa_get_format_base_format<br>
accept an uint32_t which can pack either a mesa_format or a mesa_array_format<br>
and resolve the base format for either type. This way clients do not need to<br>
check if they have a mesa_format or a mesa_array_format and call different<br>
functions depending on the case.<br>
<br>
Another reason to resolve the base format for array formats directly is that<br>
we don't have matching mesa_format enums for every possible array format, so<br>
for some GL format/type combinations we can produce array formats that don't<br>
have a corresponding mesa format, in which case we would not be able to<br>
find the base format. Example format=GL_RGB, type=GL_UNSIGNED_SHORT. This type<br>
would map to something like MESA_FORMAT_RGB_UNORM16, but we don't have that.<br>
---<br>
src/mesa/main/formats.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++---<br>
src/mesa/main/formats.h | 2 +-<br>
2 files changed, 67 insertions(+), 4 deletions(-)<br>
<br>
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c<br>
index f86925e..05b6aea 100644<br>
--- a/src/mesa/main/formats.c<br>
+++ b/src/mesa/main/formats.c<br>
@@ -214,17 +214,80 @@ _mesa_get_format_datatype(mesa_format format)<br>
return info->DataType;<br>
}<br>
<br>
+static GLenum<br>
+get_base_format_for_array_format(mesa_array_format format)<br>
+{<br>
+ switch (format.num_channels) {<br>
+ case 4:<br>
+ /* FIXME: RGBX formats have 4 channels, but their base format is GL_RGB.<br>
+ * This is not really a problem for now because we only create array<br>
+ * formats from GL format/type combinations, and these cannot specify<br>
+ * RGBX formats.<br>
+ */<br>
+ return GL_RGBA;<br>
+ case 3:<br>
+ return GL_RGB;<br>
+ case 2:<br>
+ if (format.swizzle_x == 0 &&<br>
+ format.swizzle_y == 0 &&<br>
+ format.swizzle_z == 0 &&<br>
+ format.swizzle_w == 1)<br>
+ return GL_LUMINANCE_ALPHA;<br>
+ if (format.swizzle_x == 1 &&<br>
+ format.swizzle_y == 1 &&<br>
+ format.swizzle_z == 1 &&<br>
+ format.swizzle_w == 0)<br>
+ return GL_LUMINANCE_ALPHA;<br>
+ if (format.swizzle_x == 0 &&<br>
+ format.swizzle_y == 1 &&<br>
+ format.swizzle_z == 4 &&<br>
+ format.swizzle_w == 5)<br>
+ return GL_RG;<br>
+ if (format.swizzle_x == 1 &&<br>
+ format.swizzle_y == 0 &&<br>
+ format.swizzle_z == 4 &&<br>
+ format.swizzle_w == 5)<br>
+ return GL_RG;<br>
+ break;<br>
+ case 1:<br>
+ if (format.swizzle_x == 0 &&<br>
+ format.swizzle_y == 0 &&<br>
+ format.swizzle_z == 0 &&<br>
+ format.swizzle_w == 5)<br>
+ return GL_LUMINANCE;<br>
+ if (format.swizzle_x == 0 &&<br>
+ format.swizzle_y == 0 &&<br>
+ format.swizzle_z == 0 &&<br>
+ format.swizzle_w == 0)<br>
+ return GL_INTENSITY;<br>
+ if (format.swizzle_x <= MESA_FORMAT_SWIZZLE_W)<br>
+ return GL_RED;<br>
+ if (format.swizzle_y <= MESA_FORMAT_SWIZZLE_W)<br>
+ return GL_GREEN;<br>
+ if (format.swizzle_z <= MESA_FORMAT_SWIZZLE_W)<br>
+ return GL_BLUE;<br>
+ if (format.swizzle_w <= MESA_FORMAT_SWIZZLE_W)<br>
+ return GL_ALPHA;<br>
+ break;<br>
+ }<br>
+ assert(!"Unsupported format");<br>
+}<br>
<br>
/**<br>
* Return the basic format for the given type. The result will be one of<br>
* GL_RGB, GL_RGBA, GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_INTENSITY,<br>
* GL_YCBCR_MESA, GL_DEPTH_COMPONENT, GL_STENCIL_INDEX, GL_DEPTH_STENCIL.<br>
+ * This functions accepts a mesa_format or a mesa_array_format.<br>
*/<br>
GLenum<br>
-_mesa_get_format_base_format(mesa_format format)<br>
+_mesa_get_format_base_format(uint32_t format)<br>
{<br>
- const struct gl_format_info *info = _mesa_get_format_info(format);<br>
- return info->BaseFormat;<br>
+ if (!(format & MESA_ARRAY_FORMAT_BIT)) {<br>
+ const struct gl_format_info *info = _mesa_get_format_info(format);<br>
+ return info->BaseFormat;<br>
+ } else {<br>
+ return get_base_format_for_array_format((mesa_array_format) format);<br></blockquote><div><br></div><div>I'm kind of surprised that this cast even works. Let's make a temporary variable somewhere and use the union the way it was intended. With that changed,<br></div><div>Reviewed-by <<a href="mailto:jason.ekstrand@intel.com">jason.ekstrand@intel.com</a>><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ }<br>
}<br>
<br>
<br>
diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h<br>
index 8b62788..cba12dc 100644<br>
--- a/src/mesa/main/formats.h<br>
+++ b/src/mesa/main/formats.h<br>
@@ -517,7 +517,7 @@ extern GLenum<br>
_mesa_get_format_datatype(mesa_format format);<br>
<br>
extern GLenum<br>
-_mesa_get_format_base_format(mesa_format format);<br>
+_mesa_get_format_base_format(uint32_t format);<br>
<br>
extern void<br>
_mesa_get_format_block_size(mesa_format format, GLuint *bw, GLuint *bh);<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.9.1<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>