[Mesa-dev] [PATCH 1/2] u_vbuf: Simplify the format fallback translation.

Marek Olšák maraeo at gmail.com
Sat Aug 23 10:12:03 PDT 2014


On Fri, Aug 22, 2014 at 10:54 PM, Eric Anholt <eric at anholt.net> wrote:
> Individual caps made supporting new fallbacks more complicated than it
> needed to be.  Instead, just make a table of fallbacks at context init
> time.
> ---
>  src/gallium/auxiliary/cso_cache/cso_context.c |  12 +-
>  src/gallium/auxiliary/util/u_vbuf.c           | 178 ++++++++++++--------------
>  src/gallium/auxiliary/util/u_vbuf.h           |  11 +-
>  3 files changed, 84 insertions(+), 117 deletions(-)
>
> diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
> index ca91b67..3d8860f 100644
> --- a/src/gallium/auxiliary/cso_cache/cso_context.c
> +++ b/src/gallium/auxiliary/cso_cache/cso_context.c
> @@ -239,18 +239,8 @@ static void cso_init_vbuf(struct cso_context *cso)
>  {
>     struct u_vbuf_caps caps;
>
> -   u_vbuf_get_caps(cso->pipe->screen, &caps);
> -
>     /* Install u_vbuf if there is anything unsupported. */
> -   if (!caps.buffer_offset_unaligned ||
> -       !caps.buffer_stride_unaligned ||
> -       !caps.velem_src_offset_unaligned ||
> -       !caps.format_fixed32 ||
> -       !caps.format_float16 ||
> -       !caps.format_float64 ||
> -       !caps.format_norm32 ||
> -       !caps.format_scaled32 ||
> -       !caps.user_vertex_buffers) {
> +   if (u_vbuf_get_caps(cso->pipe->screen, &caps)) {
>        cso->vbuf = u_vbuf_create(cso->pipe, &caps,
>                                  cso->aux_vertex_buffer_index);
>     }
> diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c
> index c475ee1..42f5915 100644
> --- a/src/gallium/auxiliary/util/u_vbuf.c
> +++ b/src/gallium/auxiliary/util/u_vbuf.c
> @@ -191,47 +191,87 @@ u_vbuf_create_vertex_elements(struct u_vbuf *mgr, unsigned count,
>                                const struct pipe_vertex_element *attribs);
>  static void u_vbuf_delete_vertex_elements(struct u_vbuf *mgr, void *cso);
>
> +static const struct {
> +   enum pipe_format from, to;
> +} vbuf_format_fallbacks[] = {
> +   { PIPE_FORMAT_R32_FIXED,            PIPE_FORMAT_R32_FLOAT },
> +   { PIPE_FORMAT_R32G32_FIXED,         PIPE_FORMAT_R32G32_FLOAT },
> +   { PIPE_FORMAT_R32G32B32_FIXED,      PIPE_FORMAT_R32G32B32_FLOAT },
> +   { PIPE_FORMAT_R32G32B32A32_FIXED,   PIPE_FORMAT_R32G32B32A32_FLOAT },
> +   { PIPE_FORMAT_R16_FLOAT,            PIPE_FORMAT_R32_FLOAT },
> +   { PIPE_FORMAT_R16G16_FLOAT,         PIPE_FORMAT_R32G32_FLOAT },
> +   { PIPE_FORMAT_R16G16B16_FLOAT,      PIPE_FORMAT_R32G32B32_FLOAT },
> +   { PIPE_FORMAT_R16G16B16A16_FLOAT,   PIPE_FORMAT_R32G32B32A32_FLOAT },
> +   { PIPE_FORMAT_R64_FLOAT,            PIPE_FORMAT_R32_FLOAT },
> +   { PIPE_FORMAT_R64G64_FLOAT,         PIPE_FORMAT_R32G32_FLOAT },
> +   { PIPE_FORMAT_R64G64B64_FLOAT,      PIPE_FORMAT_R32G32B32_FLOAT },
> +   { PIPE_FORMAT_R64G64B64A64_FLOAT,   PIPE_FORMAT_R32G32B32A32_FLOAT },
> +   { PIPE_FORMAT_R32_UNORM,            PIPE_FORMAT_R32_FLOAT },
> +   { PIPE_FORMAT_R32G32_UNORM,         PIPE_FORMAT_R32G32_FLOAT },
> +   { PIPE_FORMAT_R32G32B32_UNORM,      PIPE_FORMAT_R32G32B32_FLOAT },
> +   { PIPE_FORMAT_R32G32B32A32_UNORM,   PIPE_FORMAT_R32G32B32A32_FLOAT },
> +   { PIPE_FORMAT_R32_SNORM,            PIPE_FORMAT_R32_FLOAT },
> +   { PIPE_FORMAT_R32G32_SNORM,         PIPE_FORMAT_R32G32_FLOAT },
> +   { PIPE_FORMAT_R32G32B32_SNORM,      PIPE_FORMAT_R32G32B32_FLOAT },
> +   { PIPE_FORMAT_R32G32B32A32_SNORM,   PIPE_FORMAT_R32G32B32A32_FLOAT },
> +   { PIPE_FORMAT_R32_USCALED,          PIPE_FORMAT_R32_FLOAT },
> +   { PIPE_FORMAT_R32G32_USCALED,       PIPE_FORMAT_R32G32_FLOAT },
> +   { PIPE_FORMAT_R32G32B32_USCALED,    PIPE_FORMAT_R32G32B32_FLOAT },
> +   { PIPE_FORMAT_R32G32B32A32_USCALED, PIPE_FORMAT_R32G32B32A32_FLOAT },
> +   { PIPE_FORMAT_R32_SSCALED,          PIPE_FORMAT_R32_FLOAT },
> +   { PIPE_FORMAT_R32G32_SSCALED,       PIPE_FORMAT_R32G32_FLOAT },
> +   { PIPE_FORMAT_R32G32B32_SSCALED,    PIPE_FORMAT_R32G32B32_FLOAT },
> +   { PIPE_FORMAT_R32G32B32A32_SSCALED, PIPE_FORMAT_R32G32B32A32_FLOAT },
> +};
>
> -void u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps)
> +boolean u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps)
>  {
> -   caps->format_fixed32 =
> -      screen->is_format_supported(screen, PIPE_FORMAT_R32_FIXED, PIPE_BUFFER,
> -                                  0, PIPE_BIND_VERTEX_BUFFER);
> -
> -   caps->format_float16 =
> -      screen->is_format_supported(screen, PIPE_FORMAT_R16_FLOAT, PIPE_BUFFER,
> -                                  0, PIPE_BIND_VERTEX_BUFFER);
> -
> -   caps->format_float64 =
> -      screen->is_format_supported(screen, PIPE_FORMAT_R64_FLOAT, PIPE_BUFFER,
> -                                  0, PIPE_BIND_VERTEX_BUFFER);
> -
> -   caps->format_norm32 =
> -      screen->is_format_supported(screen, PIPE_FORMAT_R32_UNORM, PIPE_BUFFER,
> -                                  0, PIPE_BIND_VERTEX_BUFFER) &&
> -      screen->is_format_supported(screen, PIPE_FORMAT_R32_SNORM, PIPE_BUFFER,
> -                                  0, PIPE_BIND_VERTEX_BUFFER);
> -
> -   caps->format_scaled32 =
> -      screen->is_format_supported(screen, PIPE_FORMAT_R32_USCALED, PIPE_BUFFER,
> -                                  0, PIPE_BIND_VERTEX_BUFFER) &&
> -      screen->is_format_supported(screen, PIPE_FORMAT_R32_SSCALED, PIPE_BUFFER,
> -                                  0, PIPE_BIND_VERTEX_BUFFER);
> -
> -   caps->buffer_offset_unaligned =
> -      !screen->get_param(screen,
> -                        PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY);
> -
> -   caps->buffer_stride_unaligned =
> -      !screen->get_param(screen,
> -                        PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY);
> -
> -   caps->velem_src_offset_unaligned =
> -      !screen->get_param(screen,
> -                        PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY);
> -
> -   caps->user_vertex_buffers =
> -      screen->get_param(screen, PIPE_CAP_USER_VERTEX_BUFFERS);
> +   unsigned i;
> +   boolean fallback = TRUE;

Did you mean "FALSE" here?

> +
> +   /* I'd rather have a bitfield of which formats are supported and a static
> +    * table of the translations indexed by format, but since we don't have C99
> +    * we can't easily make a sparsely-populated table indexed by format.  So,
> +    * we construct the sparse table here.
> +    */
> +   for (i = 0; i < PIPE_FORMAT_COUNT; i++)
> +      caps->format_translation[i] = i;
> +
> +   for (i = 0; i < Elements(vbuf_format_fallbacks); i++) {
> +      enum pipe_format format = vbuf_format_fallbacks[i].from;
> +
> +      if (!screen->is_format_supported(screen, format, PIPE_BUFFER, 0,
> +                                       PIPE_BIND_VERTEX_BUFFER)) {
> +         caps->format_translation[format] = vbuf_format_fallbacks[i].to;
> +         fallback = TRUE;
> +      }
> +   }
> +
> +   if (!screen->get_param(screen,
> +                          PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY)) {
> +      caps->buffer_offset_unaligned = TRUE;
> +      fallback = TRUE;

This is actually an inverse "cap". It doesn't report a hardware
capability, it reports a limitation. If the cap is FALSE, meaning that
buffer_offset_unaligned is TRUE, no fallback should be done.

> +   }
> +
> +   if (!screen->get_param(screen,
> +                          PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY)) {
> +      caps->buffer_stride_unaligned = TRUE;
> +      fallback = TRUE;

Inverted behavior. Same as above.

> +   }
> +
> +   if (!screen->get_param(screen,
> +                          PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY)) {
> +      caps->velem_src_offset_unaligned = TRUE;
> +      fallback = TRUE;

Inverted behavior. Same as above.

The rest looks good.

Marek


More information about the mesa-dev mailing list