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

Christian Gmeiner christian.gmeiner at gmail.com
Tue Jun 14 10:13:13 UTC 2016


Hi Nicolai,

2016-06-13 11:48 GMT+02:00 Nicolai Hähnle <nhaehnle at gmail.com>:
> 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.

Ok.

>
>
>>
>>      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?
>

Yes that makes sense.

>>
>> @@ -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?
>

Sure.

> 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;
>>   };
>>
>>
>>
>

Thanks a lot for review.

--
Christian Gmeiner, MSc

https://soundcloud.com/christian-gmeiner


More information about the mesa-dev mailing list