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

Stéphane Marchesin stephane.marchesin at gmail.com
Mon Jun 20 17:25:13 PDT 2011


2011/6/20 Brian Paul <brianp at vmware.com>:
> 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.
>

Hrrrm you're right, I totally missed that. I'll fix that thing (and
the rest) and resend. Also if you can see other formats which need
this, please tell me, but I don't see anything else.

Stéphane


More information about the mesa-dev mailing list