[Mesa-dev] [RFC 2/3] u_vbuf: add logic to use a limited number of vbufs

Nicolai Hähnle nhaehnle at gmail.com
Mon Jun 13 09:48:32 UTC 2016


On 11.06.2016 21:21, Christian Gmeiner wrote:
> From: "Wladimir J. van der Laan" <laanwj at gmail.com>
>
> Make it possible to limit the number of vertex buffers as there exist
> GPUs with less then 32 supported vertex buffers.
>
> Signed-off-by: Wladimir J. van der Laan <laanwj at gmail.com>
> ---
>   src/gallium/auxiliary/util/u_vbuf.c | 45 +++++++++++++++++++++++++++++++------
>   src/gallium/auxiliary/util/u_vbuf.h |  3 +++
>   2 files changed, 41 insertions(+), 7 deletions(-)
>
> diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c
> index 5b4e527..464c279 100644
> --- a/src/gallium/auxiliary/util/u_vbuf.c
> +++ b/src/gallium/auxiliary/util/u_vbuf.c
> @@ -184,6 +184,8 @@ struct u_vbuf {
>      uint32_t incompatible_vb_mask; /* each bit describes a corresp. buffer */
>      /* Which buffer has a non-zero stride. */
>      uint32_t nonzero_stride_vb_mask; /* each bit describes a corresp. buffer */
> +   /* Which buffers are allowed (supported by hardware). */
> +   uint32_t allowed_vb_mask;
>   };
>
>   static void *
> @@ -291,10 +293,14 @@ boolean u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps)
>      caps->user_vertex_buffers =
>         screen->get_param(screen, PIPE_CAP_USER_VERTEX_BUFFERS);
>
> +   caps->max_vertex_buffers =
> +      screen->get_param(screen, PIPE_CAP_MAX_VERTEX_BUFFERS);
> +
>      if (!caps->buffer_offset_unaligned ||
>          !caps->buffer_stride_unaligned ||
>          !caps->velem_src_offset_unaligned ||
> -       !caps->user_vertex_buffers) {
> +       !caps->user_vertex_buffers ||
> +       !caps->max_vertex_buffers) {
>         fallback = TRUE;
>      }
>
> @@ -313,6 +319,7 @@ u_vbuf_create(struct pipe_context *pipe,
>      mgr->cso_cache = cso_cache_create();
>      mgr->translate_cache = translate_cache_create();
>      memset(mgr->fallback_vbs, ~0, sizeof(mgr->fallback_vbs));
> +   mgr->allowed_vb_mask = (1 << mgr->caps.max_vertex_buffers) - 1;

This is undefined when max_vertex_buffers is 31 or 32. You can use 
u_bit_consecutive.

>
>      mgr->uploader = u_upload_create(pipe, 1024 * 1024,
>                                      PIPE_BIND_VERTEX_BUFFER,
> @@ -523,14 +530,15 @@ u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
>
>   static boolean
>   u_vbuf_translate_find_free_vb_slots(struct u_vbuf *mgr,
> -                                    unsigned mask[VB_NUM])
> +                                    unsigned mask[VB_NUM],
> +                                    unsigned extra_free_vb_mask)
>   {
>      unsigned type;
>      unsigned fallback_vbs[VB_NUM];
>      /* Set the bit for each buffer which is incompatible, or isn't set. */
>      uint32_t unused_vb_mask =
> -      mgr->ve->incompatible_vb_mask_all | mgr->incompatible_vb_mask |
> -      ~mgr->enabled_vb_mask;
> +      (mgr->ve->incompatible_vb_mask_all | mgr->incompatible_vb_mask |
> +      ~mgr->enabled_vb_mask | extra_free_vb_mask) & mgr->allowed_vb_mask;
>
>      memset(fallback_vbs, ~0, sizeof(fallback_vbs));
>
> @@ -573,6 +581,7 @@ u_vbuf_translate_begin(struct u_vbuf *mgr,
>      unsigned i, type;
>      unsigned incompatible_vb_mask = mgr->incompatible_vb_mask &
>                                      mgr->ve->used_vb_mask;
> +   unsigned extra_free_vb_mask = 0;
>
>      int start[VB_NUM] = {
>         start_vertex,     /* VERTEX */
> @@ -618,8 +627,15 @@ u_vbuf_translate_begin(struct u_vbuf *mgr,
>
>      assert(mask[VB_VERTEX] || mask[VB_INSTANCE] || mask[VB_CONST]);
>
> +   /* In the case of unroll_indices, we can regard all non-constant
> +    * vertex buffers with only non-instance vertex elements as incompatible
> +    * and thus free.
> +    */
> +   if (unroll_indices)
> +       extra_free_vb_mask = mask[VB_VERTEX] & ~mask[VB_INSTANCE];
> +
>      /* Find free vertex buffer slots. */
> -   if (!u_vbuf_translate_find_free_vb_slots(mgr, mask)) {
> +   if (!u_vbuf_translate_find_free_vb_slots(mgr, mask, extra_free_vb_mask)) {
>         return FALSE;
>      }

This logic of using extra space in case of unroll_indices looks 
unrelated to the caps->max_vertex_buffers stuff, can you put it into a 
separate patch?

>
> @@ -778,6 +794,17 @@ u_vbuf_create_vertex_elements(struct u_vbuf *mgr, unsigned count,
>         }
>      }
>
> +   if (used_buffers & ~mgr->allowed_vb_mask) {
> +      /* More vertex buffers are used than the hardware supports.  In
> +       * principle, we only need to make sure that less vertex buffers are
> +       * used, and mark some of the latter vertex buffers as incompatible.
> +       * For now, mark all vertex buffers as incompatible.
> +       */
> +      ve->incompatible_vb_mask_any = used_buffers;
> +      ve->compatible_vb_mask_any = 0;
> +      ve->incompatible_elem_mask = (1 << count) - 1;
> +   }
> +
>      ve->used_vb_mask = used_buffers;
>      ve->compatible_vb_mask_all = ~ve->incompatible_vb_mask_any & used_buffers;
>      ve->incompatible_vb_mask_all = ~ve->compatible_vb_mask_any & used_buffers;
> @@ -790,8 +817,12 @@ u_vbuf_create_vertex_elements(struct u_vbuf *mgr, unsigned count,
>         }
>      }
>
> -   ve->driver_cso =
> -      pipe->create_vertex_elements_state(pipe, count, driver_attribs);
> +   /* Only create driver CSO if no incompatible elements */
> +   if (!ve->incompatible_elem_mask) {
> +      ve->driver_cso =
> +         pipe->create_vertex_elements_state(pipe, count, driver_attribs);
> +   }
> +

This looks like a logically separate change, can you put it into a 
separate patch?

Cheers,
Nicolai

>      return ve;
>   }
>
> diff --git a/src/gallium/auxiliary/util/u_vbuf.h b/src/gallium/auxiliary/util/u_vbuf.h
> index 9e8b135..9ff9938 100644
> --- a/src/gallium/auxiliary/util/u_vbuf.h
> +++ b/src/gallium/auxiliary/util/u_vbuf.h
> @@ -52,6 +52,9 @@ struct u_vbuf_caps {
>
>      /* Whether the driver supports user vertex buffers. */
>      unsigned user_vertex_buffers:1;
> +
> +   /* Maximum number of vertex buffers */
> +   unsigned max_vertex_buffers:6;
>   };
>
>
>


More information about the mesa-dev mailing list