[Mesa-dev] [PATCH 3/3] draw: simplify vsplit elts code a bit

sroland at vmware.com sroland at vmware.com
Sat Nov 12 23:15:11 UTC 2016


From: Roland Scheidegger <sroland at vmware.com>

vsplit_get_base_idx explicitly returned idx 0 and set the ofbit
in case of overflow. We'd then check the ofbit and use idx 0 instead of
looking it up. This was necessary because DRAW_GET_IDX used to return
DRAW_MAX_FETCH_IDX and not 0 in case of overflows.
However, this is all unnecessary, we can just let DRAW_GET_IDX return 0
in case of overflow. In fact before bbd1e60198548a12be3405fc32dd39a87e8968ab
the code already did that, not sure why this particular bit was changed
(might have been one half of an attempt to get these indices to actual draw
shader execution - in fact I think this would make things less awkward, it
would require moving the eltBias handling to the shader as well).
Note there's other callers of DRAW_GET_IDX - those code paths however
explicitly do not handle index buffer overflows, therefore the overflow
value doesn't matter for them.

Also do some trivial simplification - for (unsigned) a + b, checking res < a
is sufficient for overflow detection, we don't need to check for res < b too
(similar for signed).

And an index buffer overflow check looked bogus - eltMax is the number of
elements in the index buffer, not the maximum element which can be fetched.
(Drop the start check against the idx buffer though, this is already covered
by end check and end < start).
---
 src/gallium/auxiliary/draw/draw_private.h       |  7 ++--
 src/gallium/auxiliary/draw/draw_pt_vsplit.c     | 46 +++++++------------------
 src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h |  5 ++-
 3 files changed, 18 insertions(+), 40 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index a6aa610..030bb2c 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -489,11 +489,10 @@ void draw_update_viewport_flags(struct draw_context *draw);
 
 /** 
  * Return index i from the index buffer.
- * If the index buffer would overflow we return the
- * maximum possible index.
+ * If the index buffer would overflow we return index 0.
  */
 #define DRAW_GET_IDX(_elts, _i)                   \
-   (((_i) >= draw->pt.user.eltMax) ? DRAW_MAX_FETCH_IDX : (_elts)[_i])
+   (((_i) >= draw->pt.user.eltMax) ? 0 : (_elts)[_i])
 
 /**
  * Return index of the given viewport clamping it
@@ -515,7 +514,7 @@ draw_overflow_uadd(unsigned a, unsigned b,
                    unsigned overflow_value)
 {
    unsigned res = a + b;
-   if (res < a || res < b) {
+   if (res < a) {
       res = overflow_value;
    }
    return res;
diff --git a/src/gallium/auxiliary/draw/draw_pt_vsplit.c b/src/gallium/auxiliary/draw/draw_pt_vsplit.c
index 8d448f9..fb131c3 100644
--- a/src/gallium/auxiliary/draw/draw_pt_vsplit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_vsplit.c
@@ -33,7 +33,7 @@
 #define SEGMENT_SIZE 1024
 #define MAP_SIZE     256
 
-/* The largest possible index withing an index buffer */
+/* The largest possible index within an index buffer */
 #define MAX_ELT_IDX 0xffffffff
 
 struct vsplit_frontend {
@@ -108,55 +108,36 @@ vsplit_add_cache(struct vsplit_frontend *vsplit, unsigned fetch, unsigned ofbias
 
 /**
  * Returns the base index to the elements array.
- * The value is checked for overflows (both integer overflows
- * and the elements array overflow).
+ * The value is checked for integer overflow.
  */
 static inline unsigned
-vsplit_get_base_idx(struct vsplit_frontend *vsplit,
-                    unsigned start, unsigned fetch, unsigned *ofbit)
+vsplit_get_base_idx(unsigned start, unsigned fetch)
 {
-   struct draw_context *draw = vsplit->draw;
-   unsigned elt_idx = draw_overflow_uadd(start, fetch, MAX_ELT_IDX);
-   if (ofbit)
-      *ofbit = 0;
-
-   /* Overflown indices need to wrap to the first element
-    * in the index buffer */
-   if (elt_idx >= draw->pt.user.eltMax) {
-      if (ofbit)
-         *ofbit = 1;
-      elt_idx = 0;
-   }
-
-   return elt_idx;
+   return draw_overflow_uadd(start, fetch, MAX_ELT_IDX);
 }
 
 /**
  * Returns the element index adjust for the element bias.
  * The final element index is created from the actual element
- * index, plus the element bias, clamped to maximum elememt
+ * index, plus the element bias, clamped to maximum element
  * index if that addition overflows.
  */
 static inline unsigned
-vsplit_get_bias_idx(struct vsplit_frontend *vsplit,
-                    int idx, int bias, unsigned *ofbias)
+vsplit_get_bias_idx(int idx, int bias, unsigned *ofbias)
 {
    int res = idx + bias;
 
-   if (ofbias)
-      *ofbias = 0;
+   *ofbias = 0;
 
    if (idx > 0 && bias > 0) {
-      if (res < idx || res < bias) {
+      if (res < idx) {
          res = DRAW_MAX_FETCH_IDX;
-         if (ofbias)
-            *ofbias = 1;
+         *ofbias = 1;
       }
    } else if (idx < 0 && bias < 0) {
-      if (res > idx || res > bias) {
+      if (res > idx) {
          res = DRAW_MAX_FETCH_IDX;
-         if (ofbias)
-            *ofbias = 1;
+         *ofbias = 1;
       }
    }
 
@@ -165,10 +146,9 @@ vsplit_get_bias_idx(struct vsplit_frontend *vsplit,
 
 #define VSPLIT_CREATE_IDX(elts, start, fetch, elt_bias)    \
    unsigned elt_idx;                                       \
-   unsigned ofbit;                                         \
    unsigned ofbias;                                        \
-   elt_idx = vsplit_get_base_idx(vsplit, start, fetch, &ofbit);          \
-   elt_idx = vsplit_get_bias_idx(vsplit, ofbit ? 0 : DRAW_GET_IDX(elts, elt_idx), elt_bias, &ofbias)
+   elt_idx = vsplit_get_base_idx(start, fetch);    \
+   elt_idx = vsplit_get_bias_idx(DRAW_GET_IDX(elts, elt_idx), elt_bias, &ofbias)
 
 static inline void
 vsplit_add_cache_ubyte(struct vsplit_frontend *vsplit, const ubyte *elts,
diff --git a/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h b/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h
index 6da79b9..7b08970 100644
--- a/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h
+++ b/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h
@@ -49,9 +49,8 @@ CONCAT(vsplit_primitive_, ELT_TYPE)(struct vsplit_frontend *vsplit,
 
    /* If the index buffer overflows we'll need to run
     * through the normal paths */
-   if (start >= draw->pt.user.eltMax ||
-       end > draw->pt.user.eltMax ||
-       end < istart || end < icount)
+   if (end >= draw->pt.user.eltMax ||
+       end < istart)
       return FALSE;
 
    /* use the ib directly */
-- 
2.7.4



More information about the mesa-dev mailing list