On Mon, Dec 1, 2014 at 3:04 AM, Iago Toral Quiroga <ito...@igalia.com> wrote:
> If we need the base format for a mesa_array_format we have to find the > matching mesa_format first. This is expensive because it requires > to loop through all existing mesa formats until we find the right match. > > We can resolve the base format of an array format directly by looking > at its swizzle information. Also, we can have _mesa_get_format_base_format > accept an uint32_t which can pack either a mesa_format or a > mesa_array_format > and resolve the base format for either type. This way clients do not need > to > check if they have a mesa_format or a mesa_array_format and call different > functions depending on the case. > > Another reason to resolve the base format for array formats directly is > that > we don't have matching mesa_format enums for every possible array format, > so > for some GL format/type combinations we can produce array formats that > don't > have a corresponding mesa format, in which case we would not be able to > find the base format. Example format=GL_RGB, type=GL_UNSIGNED_SHORT. This > type > would map to something like MESA_FORMAT_RGB_UNORM16, but we don't have > that. > --- > src/mesa/main/formats.c | 69 > ++++++++++++++++++++++++++++++++++++++++++++++--- > src/mesa/main/formats.h | 2 +- > 2 files changed, 67 insertions(+), 4 deletions(-) > > diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c > index f86925e..05b6aea 100644 > --- a/src/mesa/main/formats.c > +++ b/src/mesa/main/formats.c > @@ -214,17 +214,80 @@ _mesa_get_format_datatype(mesa_format format) > return info->DataType; > } > > +static GLenum > +get_base_format_for_array_format(mesa_array_format format) > +{ > + switch (format.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 (format.swizzle_x == 0 && > + format.swizzle_y == 0 && > + format.swizzle_z == 0 && > + format.swizzle_w == 1) > + return GL_LUMINANCE_ALPHA; > + if (format.swizzle_x == 1 && > + format.swizzle_y == 1 && > + format.swizzle_z == 1 && > + format.swizzle_w == 0) > + return GL_LUMINANCE_ALPHA; > + if (format.swizzle_x == 0 && > + format.swizzle_y == 1 && > + format.swizzle_z == 4 && > + format.swizzle_w == 5) > + return GL_RG; > + if (format.swizzle_x == 1 && > + format.swizzle_y == 0 && > + format.swizzle_z == 4 && > + format.swizzle_w == 5) > + return GL_RG; > + break; > + case 1: > + if (format.swizzle_x == 0 && > + format.swizzle_y == 0 && > + format.swizzle_z == 0 && > + format.swizzle_w == 5) > + return GL_LUMINANCE; > + if (format.swizzle_x == 0 && > + format.swizzle_y == 0 && > + format.swizzle_z == 0 && > + format.swizzle_w == 0) > + return GL_INTENSITY; > + if (format.swizzle_x <= MESA_FORMAT_SWIZZLE_W) > + return GL_RED; > + if (format.swizzle_y <= MESA_FORMAT_SWIZZLE_W) > + return GL_GREEN; > + if (format.swizzle_z <= MESA_FORMAT_SWIZZLE_W) > + return GL_BLUE; > + if (format.swizzle_w <= MESA_FORMAT_SWIZZLE_W) > + return GL_ALPHA; > + break; > + } > + assert(!"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_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(mesa_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 (!(format & MESA_ARRAY_FORMAT_BIT)) { > + const struct gl_format_info *info = _mesa_get_format_info(format); > + return info->BaseFormat; > + } else { > + return get_base_format_for_array_format((mesa_array_format) format); > 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, Reviewed-by <jason.ekstr...@intel.com> > + } > } > > > diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h > index 8b62788..cba12dc 100644 > --- a/src/mesa/main/formats.h > +++ b/src/mesa/main/formats.h > @@ -517,7 +517,7 @@ extern GLenum > _mesa_get_format_datatype(mesa_format format); > > extern GLenum > -_mesa_get_format_base_format(mesa_format format); > +_mesa_get_format_base_format(uint32_t format); > > extern void > _mesa_get_format_block_size(mesa_format format, GLuint *bw, GLuint *bh); > -- > 1.9.1 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev