On 11.06.2016 21:21, Christian Gmeiner wrote:
From: "Wladimir J. van der Laan" <laa...@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 <laa...@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;
  };



_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to