[Mesa-dev] [PATCH 1/3] st/mesa: prefer native texture formats when possible.

Brian Paul brianp at vmware.com
Mon Jun 20 17:14:56 PDT 2011


On 06/20/2011 05:31 PM, Stéphane Marchesin wrote:
> If possible, we want to match the hardware format to what the app uses. By
> doing so, we avoid the need for pixel conversions and therefore greatly speed
> up texture uploads.
> ---
>   src/mesa/state_tracker/st_atom_pixeltransfer.c |    2 +-
>   src/mesa/state_tracker/st_cb_drawpixels.c      |   10 ++-
>   src/mesa/state_tracker/st_format.c             |   94 +++++++++++++++++++++++-
>   src/mesa/state_tracker/st_format.h             |    1 +
>   4 files changed, 99 insertions(+), 8 deletions(-)
>
> diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c
> index 95b706c..1f833d2 100644
> --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c
> +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c
> @@ -94,7 +94,7 @@ create_color_map_texture(struct gl_context *ctx)
>      const uint texSize = 256; /* simple, and usually perfect */
>
>      /* find an RGBA texture format */
> -   format = st_choose_format(pipe->screen, GL_RGBA,
> +   format = st_choose_format(pipe->screen, GL_RGBA, GL_NONE, GL_NONE,
>                                PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW);
>
>      /* create texture for color map/table */
> diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
> index 965fbcd..c730975 100644
> --- a/src/mesa/state_tracker/st_cb_drawpixels.c
> +++ b/src/mesa/state_tracker/st_cb_drawpixels.c
> @@ -989,8 +989,9 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
>         /* can we write to stencil if not fallback */
>         if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT))
>   	 goto stencil_fallback;
> -
> +
>         tex_format = st_choose_format(st->pipe->screen, base_format(format),
> +                                    GL_NONE, GL_NONE,
>                                       PIPE_TEXTURE_2D,
>   				    0, PIPE_BIND_SAMPLER_VIEW);
>         if (tex_format == PIPE_FORMAT_Z24_UNORM_S8_USCALED)
> @@ -1399,13 +1400,14 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
>         /* srcFormat can't be used as a texture format */
>         if (type == GL_DEPTH) {
>            texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT,
> -                                      st->internal_target, sample_count,
> -                                      PIPE_BIND_DEPTH_STENCIL);
> +                                      st->internal_target, GL_NONE, GL_NONE,
> +				      sample_count, PIPE_BIND_DEPTH_STENCIL);
>            assert(texFormat != PIPE_FORMAT_NONE);
>         }
>         else {
>            /* default color format */
> -         texFormat = st_choose_format(screen, GL_RGBA, st->internal_target,
> +         texFormat = st_choose_format(screen, GL_RGBA,
> +                                      st->internal_target, GL_NONE, GL_NONE,
>                                         sample_count, PIPE_BIND_SAMPLER_VIEW);
>            assert(texFormat != PIPE_FORMAT_NONE);
>         }
> diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
> index 45e4766..6f43c03 100644
> --- a/src/mesa/state_tracker/st_format.c
> +++ b/src/mesa/state_tracker/st_format.c
> @@ -1124,6 +1124,87 @@ find_supported_format(struct pipe_screen *screen,
>      return PIPE_FORMAT_NONE;
>   }
>
> +struct exact_format_mapping
> +{
> +   GLenum format;
> +   GLenum type;
> +   enum pipe_format pformat;
> +};
> +
> +static struct exact_format_mapping rgba8888_tbl[] =

I'd put a const qualifier on these tables, just to be safe.  I need to 
do that on the main format table too.


> +{
> +   { GL_RGBA,     GL_UNSIGNED_INT_8_8_8_8,        PIPE_FORMAT_A8B8G8R8_UNORM },
> +   { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV,    PIPE_FORMAT_A8B8G8R8_UNORM },
> +   { GL_RGBA,     GL_UNSIGNED_INT_8_8_8_8_REV,    PIPE_FORMAT_R8G8B8A8_UNORM },
> +   { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8,        PIPE_FORMAT_R8G8B8A8_UNORM },
> +   { GL_BGRA,     GL_UNSIGNED_INT_8_8_8_8,        PIPE_FORMAT_A8R8G8B8_UNORM },
> +   { GL_BGRA,     GL_UNSIGNED_INT_8_8_8_8_REV,    PIPE_FORMAT_B8G8R8A8_UNORM },
> +   { GL_RGBA,     GL_UNSIGNED_BYTE,               PIPE_FORMAT_R8G8B8A8_UNORM },
> +   { GL_ABGR_EXT, GL_UNSIGNED_BYTE,               PIPE_FORMAT_A8B8G8R8_UNORM },
> +   { GL_BGRA,     GL_UNSIGNED_BYTE,               PIPE_FORMAT_B8G8R8A8_UNORM },
> +   { 0,           0,                              0                          }
> +};
> +
> +static struct exact_format_mapping rgbx8888_tbl[] =
> +{
> +   { GL_RGBA,     GL_UNSIGNED_INT_8_8_8_8,        PIPE_FORMAT_X8B8G8R8_UNORM },
> +   { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV,    PIPE_FORMAT_X8B8G8R8_UNORM },
> +   { GL_RGBA,     GL_UNSIGNED_INT_8_8_8_8_REV,    PIPE_FORMAT_R8G8B8X8_UNORM },
> +   { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8,        PIPE_FORMAT_R8G8B8X8_UNORM },
> +   { GL_BGRA,     GL_UNSIGNED_INT_8_8_8_8,        PIPE_FORMAT_X8R8G8B8_UNORM },
> +   { GL_BGRA,     GL_UNSIGNED_INT_8_8_8_8_REV,    PIPE_FORMAT_B8G8R8X8_UNORM },
> +   { GL_RGBA,     GL_UNSIGNED_BYTE,               PIPE_FORMAT_R8G8B8X8_UNORM },
> +   { GL_ABGR_EXT, GL_UNSIGNED_BYTE,               PIPE_FORMAT_X8B8G8R8_UNORM },
> +   { GL_BGRA,     GL_UNSIGNED_BYTE,               PIPE_FORMAT_B8G8R8X8_UNORM },
> +   { 0,           0,                              0                          }
> +};
> +
> +static struct exact_format_mapping rgba1010102_tbl[] =
> +{
> +   { GL_BGRA,     GL_UNSIGNED_INT_2_10_10_10_REV, PIPE_FORMAT_B10G10R10A2_UNORM },
> +   { GL_RGBA,     GL_UNSIGNED_INT_2_10_10_10_REV, PIPE_FORMAT_R10G10B10A2_UNORM },
> +   { GL_ABGR_EXT, GL_UNSIGNED_INT_10_10_10_2,     PIPE_FORMAT_R10G10B10A2_UNORM },
> +   { GL_ABGR_EXT, GL_UNSIGNED_INT,                PIPE_FORMAT_R10G10B10A2_UNORM },
> +   { 0,           0,                              0                             }
> +};
> +
> +/**
> + * If there is an exact pipe_format match for {internalFormat, format, type}
> + * return that, otherwise return PIPE_FORMAT_NONE so we can do fuzzy matching.
> + */
> +static enum pipe_format
> +find_exact_format(GLint internalFormat, GLenum format, GLenum type)
> +{
> +   uint i;
> +   struct exact_format_mapping* tbl;
> +
> +   if ( format == GL_NONE || type == GL_NONE )

Minor whitespace nitpick:
       if (format == GL_NONE || type == GL_NONE)


> +      return PIPE_FORMAT_NONE;
> +
> +   switch (internalFormat) {
> +   case 4:
> +   case GL_RGBA:
> +   case GL_RGBA8:
> +      tbl = rgba8888_tbl;
> +      break;
> +   case 3:
> +   case GL_RGB:
> +   case GL_RGB8:
> +      tbl = rgbx8888_tbl;
> +      break;
> +   case GL_RGB10_A2:
> +      tbl = rgba1010102_tbl;
> +      break;
> +   default:
> +      return PIPE_FORMAT_NONE;
> +   }
> +
> +   for(i = 0; tbl[i].format; i++)

Another whitespace nit:
       for (i = 0; tbl[i].format; i++)


> +      if (tbl[i].format == format&&  tbl[i].type == type)
> +         return tbl[i].pformat;

I don't see where you check if the chosen pipe format is actually 
supported by the driver.

Looks good otherwise, assuming you've run piglit, etc.  You might also 
try demos/tests/packedpixels (press 'f' to cycle through all the formats).

Thanks for doing this!

-Brian


More information about the mesa-dev mailing list