[Mesa-dev] [PATCH] u_vbuf: Simplify the format fallback translation.
Marek Olšák
maraeo at gmail.com
Sat Aug 23 16:50:35 PDT 2014
Reviewed-by: Marek Olšák <marek.olsak at amd.com>
Marek
On Sun, Aug 24, 2014 at 1:38 AM, 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.
>
> v2: Fix inverted "do we need to install vbuf?" flagging caught by Marek.
> ---
>
> Sorry for the crap patch, hopefully this has the fixees from your review.
>
> src/gallium/auxiliary/cso_cache/cso_context.c | 12 +-
> src/gallium/auxiliary/util/u_vbuf.c | 181 ++++++++++++--------------
> src/gallium/auxiliary/util/u_vbuf.h | 11 +-
> 3 files changed, 87 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..26017fa 100644
> --- a/src/gallium/auxiliary/util/u_vbuf.c
> +++ b/src/gallium/auxiliary/util/u_vbuf.c
> @@ -191,47 +191,90 @@ 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 = FALSE;
> +
> + /* 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;
> + } else {
> + fallback = TRUE;
> + }
> +
> + if (!screen->get_param(screen,
> + PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY)) {
> + caps->buffer_stride_unaligned = TRUE;
> + } else {
> + fallback = TRUE;
> + }
> +
> + if (!screen->get_param(screen,
> + PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY)) {
> + caps->velem_src_offset_unaligned = TRUE;
> + } else {
> + fallback = TRUE;
> + }
> +
> + if (screen->get_param(screen, PIPE_CAP_USER_VERTEX_BUFFERS)) {
> + caps->user_vertex_buffers = TRUE;
> + } else {
> + fallback = TRUE;
> + }
> +
> + return fallback;
> }
>
> struct u_vbuf *
> @@ -664,9 +707,6 @@ static void u_vbuf_translate_end(struct u_vbuf *mgr)
> }
> }
>
> -#define FORMAT_REPLACE(what, withwhat) \
> - case PIPE_FORMAT_##what: format = PIPE_FORMAT_##withwhat; break
> -
> static void *
> u_vbuf_create_vertex_elements(struct u_vbuf *mgr, unsigned count,
> const struct pipe_vertex_element *attribs)
> @@ -695,62 +735,7 @@ u_vbuf_create_vertex_elements(struct u_vbuf *mgr, unsigned count,
> ve->noninstance_vb_mask_any |= 1 << ve->ve[i].vertex_buffer_index;
> }
>
> - /* Choose a native format.
> - * For now we don't care about the alignment, that's going to
> - * be sorted out later. */
> - if (!mgr->caps.format_fixed32) {
> - switch (format) {
> - FORMAT_REPLACE(R32_FIXED, R32_FLOAT);
> - FORMAT_REPLACE(R32G32_FIXED, R32G32_FLOAT);
> - FORMAT_REPLACE(R32G32B32_FIXED, R32G32B32_FLOAT);
> - FORMAT_REPLACE(R32G32B32A32_FIXED, R32G32B32A32_FLOAT);
> - default:;
> - }
> - }
> - if (!mgr->caps.format_float16) {
> - switch (format) {
> - FORMAT_REPLACE(R16_FLOAT, R32_FLOAT);
> - FORMAT_REPLACE(R16G16_FLOAT, R32G32_FLOAT);
> - FORMAT_REPLACE(R16G16B16_FLOAT, R32G32B32_FLOAT);
> - FORMAT_REPLACE(R16G16B16A16_FLOAT, R32G32B32A32_FLOAT);
> - default:;
> - }
> - }
> - if (!mgr->caps.format_float64) {
> - switch (format) {
> - FORMAT_REPLACE(R64_FLOAT, R32_FLOAT);
> - FORMAT_REPLACE(R64G64_FLOAT, R32G32_FLOAT);
> - FORMAT_REPLACE(R64G64B64_FLOAT, R32G32B32_FLOAT);
> - FORMAT_REPLACE(R64G64B64A64_FLOAT, R32G32B32A32_FLOAT);
> - default:;
> - }
> - }
> - if (!mgr->caps.format_norm32) {
> - switch (format) {
> - FORMAT_REPLACE(R32_UNORM, R32_FLOAT);
> - FORMAT_REPLACE(R32G32_UNORM, R32G32_FLOAT);
> - FORMAT_REPLACE(R32G32B32_UNORM, R32G32B32_FLOAT);
> - FORMAT_REPLACE(R32G32B32A32_UNORM, R32G32B32A32_FLOAT);
> - FORMAT_REPLACE(R32_SNORM, R32_FLOAT);
> - FORMAT_REPLACE(R32G32_SNORM, R32G32_FLOAT);
> - FORMAT_REPLACE(R32G32B32_SNORM, R32G32B32_FLOAT);
> - FORMAT_REPLACE(R32G32B32A32_SNORM, R32G32B32A32_FLOAT);
> - default:;
> - }
> - }
> - if (!mgr->caps.format_scaled32) {
> - switch (format) {
> - FORMAT_REPLACE(R32_USCALED, R32_FLOAT);
> - FORMAT_REPLACE(R32G32_USCALED, R32G32_FLOAT);
> - FORMAT_REPLACE(R32G32B32_USCALED, R32G32B32_FLOAT);
> - FORMAT_REPLACE(R32G32B32A32_USCALED,R32G32B32A32_FLOAT);
> - FORMAT_REPLACE(R32_SSCALED, R32_FLOAT);
> - FORMAT_REPLACE(R32G32_SSCALED, R32G32_FLOAT);
> - FORMAT_REPLACE(R32G32B32_SSCALED, R32G32B32_FLOAT);
> - FORMAT_REPLACE(R32G32B32A32_SSCALED,R32G32B32A32_FLOAT);
> - default:;
> - }
> - }
> + format = mgr->caps.format_translation[format];
>
> driver_attribs[i].src_format = format;
> ve->native_format[i] = format;
> diff --git a/src/gallium/auxiliary/util/u_vbuf.h b/src/gallium/auxiliary/util/u_vbuf.h
> index a608184..9e8b135 100644
> --- a/src/gallium/auxiliary/util/u_vbuf.h
> +++ b/src/gallium/auxiliary/util/u_vbuf.h
> @@ -35,19 +35,14 @@
>
> #include "pipe/p_context.h"
> #include "pipe/p_state.h"
> +#include "pipe/p_format.h"
>
> struct cso_context;
> struct u_vbuf;
>
> /* Hardware vertex fetcher limitations can be described by this structure. */
> struct u_vbuf_caps {
> - /* Vertex format CAPs. */
> - /* TRUE if hardware supports it. */
> - unsigned format_fixed32:1; /* PIPE_FORMAT_*32*_FIXED */
> - unsigned format_float16:1; /* PIPE_FORMAT_*16*_FLOAT */
> - unsigned format_float64:1; /* PIPE_FORMAT_*64*_FLOAT */
> - unsigned format_norm32:1; /* PIPE_FORMAT_*32*NORM */
> - unsigned format_scaled32:1; /* PIPE_FORMAT_*32*SCALED */
> + enum pipe_format format_translation[PIPE_FORMAT_COUNT];
>
> /* Whether vertex fetches don't have to be 4-byte-aligned. */
> /* TRUE if hardware supports it. */
> @@ -60,7 +55,7 @@ struct u_vbuf_caps {
> };
>
>
> -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);
>
> struct u_vbuf *
> u_vbuf_create(struct pipe_context *pipe,
> --
> 2.1.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list