gallium/util: add a helper to compute vertex count from primitive count
authorIago Toral Quiroga <itoral@igalia.com>
Thu, 1 Aug 2019 09:56:29 +0000 (11:56 +0200)
committerIago Toral Quiroga <itoral@igalia.com>
Thu, 8 Aug 2019 06:36:52 +0000 (08:36 +0200)
v2:
  - Only compute vertex counts for base primitives.
  - Add a unit test (Eric)

Reviewed-by: Eric Anholt <eric@anholt.net>
src/gallium/auxiliary/util/u_prim.h
src/gallium/tests/unit/meson.build
src/gallium/tests/unit/u_prim_verts_test.c [new file with mode: 0644]

index fb9290d62caf899136d37c6c25915889e7652eec..ae05788702c278ab63d0ab7c94a83d0562dc4601 100644 (file)
@@ -283,6 +283,50 @@ u_reduced_prims_for_vertices(enum pipe_prim_type primitive, int vertices)
    }
 }
 
+static inline enum pipe_prim_type
+u_base_prim_type(enum pipe_prim_type prim_type)
+{
+   switch(prim_type) {
+      case PIPE_PRIM_POINTS:
+         return PIPE_PRIM_POINTS;
+      case PIPE_PRIM_LINES:
+      case PIPE_PRIM_LINE_LOOP:
+      case PIPE_PRIM_LINE_STRIP:
+      case PIPE_PRIM_LINES_ADJACENCY:
+      case PIPE_PRIM_LINE_STRIP_ADJACENCY:
+         return PIPE_PRIM_LINES;
+      case PIPE_PRIM_TRIANGLES:
+      case PIPE_PRIM_TRIANGLE_STRIP:
+      case PIPE_PRIM_TRIANGLE_FAN:
+      case PIPE_PRIM_TRIANGLES_ADJACENCY:
+      case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
+         return PIPE_PRIM_TRIANGLES;
+      case PIPE_PRIM_QUADS:
+      case PIPE_PRIM_QUAD_STRIP:
+         return PIPE_PRIM_QUADS;
+      default:
+         return prim_type;
+   }
+}
+
+static inline unsigned
+u_vertices_for_prims(enum pipe_prim_type prim_type, int count)
+{
+   if (count <= 0)
+      return 0;
+
+   /* We can only figure out the number of vertices from a number of primitives
+    * if we are using basic primitives (so no loops, strips, fans, etc).
+    */
+   assert(prim_type == u_base_prim_type(prim_type) &&
+          prim_type != PIPE_PRIM_PATCHES && prim_type != PIPE_PRIM_POLYGON);
+
+   const struct u_prim_vertex_count *info = u_prim_vertex_count(prim_type);
+   assert(info);
+
+   return info->min + (count - 1) * info->incr;
+}
+
 const char *u_prim_name(enum pipe_prim_type pipe_prim);
 
 
index d4f3aed08775b7ae0a44aa8022486e6133f2aacc..afde9840c370d6ec4dba2cdf5797c229869e1053 100644 (file)
@@ -19,7 +19,8 @@
 # SOFTWARE.
 
 foreach t : ['pipe_barrier_test', 'u_cache_test', 'u_half_test',
-             'u_format_test', 'u_format_compatible_test', 'translate_test']
+             'u_format_test', 'u_format_compatible_test', 'translate_test',
+             'u_prim_verts_test' ]
   exe = executable(
     t,
     '@0@.c'.format(t),
diff --git a/src/gallium/tests/unit/u_prim_verts_test.c b/src/gallium/tests/unit/u_prim_verts_test.c
new file mode 100644 (file)
index 0000000..94b64f7
--- /dev/null
@@ -0,0 +1,45 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "util/u_prim.h"
+
+struct test_info {
+   enum pipe_prim_type prim_type;
+   uint32_t count;
+   uint32_t expected;
+};
+
+struct test_info tests[] = {
+   { PIPE_PRIM_POINTS, 0, 0 },
+   { PIPE_PRIM_POINTS, 1, 1 },
+   { PIPE_PRIM_POINTS, 2, 2 },
+
+   { PIPE_PRIM_LINES, 0, 0 },
+   { PIPE_PRIM_LINES, 1, 2 },
+   { PIPE_PRIM_LINES, 2, 4 },
+
+   { PIPE_PRIM_TRIANGLES, 0, 0 },
+   { PIPE_PRIM_TRIANGLES, 1, 3 },
+   { PIPE_PRIM_TRIANGLES, 2, 6 },
+
+   { PIPE_PRIM_QUADS, 0, 0 },
+   { PIPE_PRIM_QUADS, 1, 4 },
+   { PIPE_PRIM_QUADS, 2, 8 },
+};
+
+int
+main(int argc, char **argv)
+{
+   for(int i = 0; i < ARRAY_SIZE(tests); i++) {
+      struct test_info *info = &tests[i];
+      uint32_t n = u_vertices_for_prims(info->prim_type, info->count);
+      if (n != info->expected) {
+         printf("Failure! Expected %u vertices for %u x %s, but got %u.\n",
+                info->expected, info->count, u_prim_name(info->prim_type), n);
+         return 1;
+      }
+   }
+
+   printf("Success!\n");
+   return 0;
+}