ilo: use a dynamic array for global bindings
authorChia-I Wu <olvaffe@gmail.com>
Thu, 30 Oct 2014 06:35:00 +0000 (14:35 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Thu, 6 Nov 2014 02:43:31 +0000 (10:43 +0800)
Use util_dynarray in ilo_set_global_binding() to allow for unlimited number of
global bindings.  Add a comment for global bindings.

Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
src/gallium/drivers/ilo/ilo_state.c
src/gallium/drivers/ilo/ilo_state.h

index 18c1566d93ae6194cb944a270f0455cf8b52b951..217d22c614b8cb65d65f9c096225d8634b124848 100644 (file)
@@ -25,6 +25,7 @@
  *    Chia-I Wu <olv@lunarg.com>
  */
 
+#include "util/u_dynarray.h"
 #include "util/u_helpers.h"
 #include "util/u_upload_mgr.h"
 
@@ -1138,30 +1139,52 @@ ilo_set_global_binding(struct pipe_context *pipe,
                        uint32_t **handles)
 {
    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
-   struct ilo_global_binding *dst = &vec->global_binding;
+   struct ilo_global_binding_cso *dst;
    unsigned i;
 
-   assert(start + count <= Elements(dst->resources));
+   /* make room */
+   if (vec->global_binding.count < start + count) {
+      if (resources) {
+         const unsigned old_size = vec->global_binding.bindings.size;
+         const unsigned new_size = sizeof(*dst) * (start + count);
 
-   if (resources) {
-      for (i = 0; i < count; i++)
-         pipe_resource_reference(&dst->resources[start + i], resources[i]);
+         if (old_size < new_size) {
+            util_dynarray_resize(&vec->global_binding.bindings, new_size);
+            memset(vec->global_binding.bindings.data + old_size, 0,
+                  new_size - old_size);
+         }
+      } else {
+         count = vec->global_binding.count - start;
+      }
    }
-   else {
-      for (i = 0; i < count; i++)
-         pipe_resource_reference(&dst->resources[start + i], NULL);
+
+   dst = util_dynarray_element(&vec->global_binding.bindings,
+         struct ilo_global_binding_cso, start);
+
+   if (resources) {
+      for (i = 0; i < count; i++) {
+         pipe_resource_reference(&dst[i].resource, resources[i]);
+         dst[i].handle = handles[i];
+      }
+   } else {
+      for (i = 0; i < count; i++) {
+         pipe_resource_reference(&dst[i].resource, NULL);
+         dst[i].handle = NULL;
+      }
    }
 
-   if (dst->count <= start + count) {
+   if (vec->global_binding.count <= start + count) {
+      dst = util_dynarray_begin(&vec->global_binding.bindings);
+
       if (resources)
          count += start;
       else
          count = start;
 
-      while (count > 0 && !dst->resources[count - 1])
+      while (count > 0 && !dst[count - 1].resource)
          count--;
 
-      dst->count = count;
+      vec->global_binding.count = count;
    }
 
    vec->dirty |= ILO_DIRTY_GLOBAL_BINDING;
@@ -1240,6 +1263,8 @@ ilo_state_vector_init(const struct ilo_dev_info *dev,
    ilo_gpe_init_zs_surface(dev, NULL, PIPE_FORMAT_NONE,
          0, 0, 1, &vec->fb.null_zs);
 
+   util_dynarray_init(&vec->global_binding.bindings);
+
    vec->dirty = ILO_DIRTY_ALL;
 }
 
@@ -1283,8 +1308,14 @@ ilo_state_vector_cleanup(struct ilo_state_vector *vec)
    for (i = 0; i < vec->cs_resource.count; i++)
       pipe_surface_reference(&vec->cs_resource.states[i], NULL);
 
-   for (i = 0; i < vec->global_binding.count; i++)
-      pipe_resource_reference(&vec->global_binding.resources[i], NULL);
+   for (i = 0; i < vec->global_binding.count; i++) {
+      struct ilo_global_binding_cso *cso =
+         util_dynarray_element(&vec->global_binding.bindings,
+               struct ilo_global_binding_cso, i);
+      pipe_resource_reference(&cso->resource, NULL);
+   }
+
+   util_dynarray_fini(&vec->global_binding.bindings);
 }
 
 /**
@@ -1405,7 +1436,11 @@ ilo_state_vector_resource_renamed(struct ilo_state_vector *vec,
    }
 
    for (i = 0; i < vec->global_binding.count; i++) {
-      if (vec->global_binding.resources[i] == res) {
+      struct ilo_global_binding_cso *cso =
+         util_dynarray_element(&vec->global_binding.bindings,
+               struct ilo_global_binding_cso, i);
+
+      if (cso->resource == res) {
          states |= ILO_DIRTY_GLOBAL_BINDING;
          break;
       }
index a1d4b7bffcb9e084ab827dd43a1b60dd924403f3..7343b20e3572a888c23984e0d0af2319b0411798 100644 (file)
@@ -29,6 +29,7 @@
 #define ILO_STATE_H
 
 #include "pipe/p_state.h"
+#include "util/u_dynarray.h"
 
 #include "ilo_common.h"
 
@@ -349,25 +350,27 @@ struct ilo_fb_state {
    unsigned num_samples;
 };
 
+struct ilo_global_binding_cso {
+   struct pipe_resource *resource;
+   uint32_t *handle;
+};
+
+/*
+ * In theory, we would like a "virtual" bo that serves as the global memory
+ * region.  The virtual bo would reserve a region in the GTT aperture, but the
+ * pages of it would come from those of the global bindings.
+ *
+ * The virtual bo would be created in launch_grid().  The global bindings
+ * would be added to the virtual bo.  A SURFACE_STATE for the virtual bo would
+ * be created.  The handles returned by set_global_binding() would be offsets
+ * into the virtual bo.
+ *
+ * But for now, we will create a SURFACE_STATE for each of the bindings.  The
+ * handle of a global binding consists of the offset and the binding table
+ * index.
+ */
 struct ilo_global_binding {
-   /*
-    * XXX These should not be treated as real resources (and there could be
-    * thousands of them).  They should be treated as regions in GLOBAL
-    * resource, which is the only real resource.
-    *
-    * That is, a resource here should instead be
-    *
-    *   struct ilo_global_region {
-    *     struct pipe_resource base;
-    *     int offset;
-    *     int size;
-    *   };
-    *
-    * and it describes the region [offset, offset + size) in GLOBAL
-    * resource.
-    */
-   struct pipe_resource *resources[PIPE_MAX_SHADER_RESOURCES];
-   uint32_t *handles[PIPE_MAX_SHADER_RESOURCES];
+   struct util_dynarray bindings;
    unsigned count;
 };