clover: bind constant buffer if one is provided

We will use that with NIR as it is easier to manage the constant buffer
inside clover instead of letting all drivers to deal with it.

Signed-off-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6569>
diff --git a/src/gallium/frontends/clover/core/kernel.cpp b/src/gallium/frontends/clover/core/kernel.cpp
index 7d83976..013d6f0 100644
--- a/src/gallium/frontends/clover/core/kernel.cpp
+++ b/src/gallium/frontends/clover/core/kernel.cpp
@@ -36,6 +36,19 @@
       if (marg.semantic == module::argument::general)
          _args.emplace_back(argument::create(marg));
    }
+   for (auto &dev : prog.devices()) {
+      auto &m = prog.build(dev).binary;
+      auto msym = find(name_equals(name), m.syms);
+      const auto f = id_type_equals(msym.section, module::section::data_constant);
+      if (!any_of(f, m.secs))
+         continue;
+
+      auto mconst = find(f, m.secs);
+      auto rb = std::make_unique<root_buffer>(prog.context(),
+                                              CL_MEM_COPY_HOST_PTR | CL_MEM_READ_ONLY,
+                                              mconst.size, mconst.data.data());
+      _constant_buffers.emplace(&dev, std::move(rb));
+   }
 }
 
 template<typename V>
@@ -163,7 +176,7 @@
    auto &m = kern.program().build(q->device()).binary;
    auto msym = find(name_equals(kern.name()), m.syms);
    auto margs = msym.args;
-   auto msec = find(id_equals(msym.section), m.secs);
+   auto msec = find(id_type_equals(msym.section, module::section::text_executable), m.secs);
    auto explicit_arg = kern._args.begin();
 
    for (auto &marg : margs) {
@@ -217,6 +230,13 @@
          }
          break;
       }
+      case module::argument::constant_buffer: {
+         auto arg = argument::create(marg);
+         cl_mem buf = kern._constant_buffers.at(&q->device()).get();
+         arg->set(q->device().address_bits() / 8, &buf);
+         arg->bind(*this, marg);
+         break;
+      }
       }
    }
 
diff --git a/src/gallium/frontends/clover/core/kernel.hpp b/src/gallium/frontends/clover/core/kernel.hpp
index 4441091..4d6dcfb 100644
--- a/src/gallium/frontends/clover/core/kernel.hpp
+++ b/src/gallium/frontends/clover/core/kernel.hpp
@@ -23,6 +23,7 @@
 #ifndef CLOVER_CORE_KERNEL_HPP
 #define CLOVER_CORE_KERNEL_HPP
 
+#include <map>
 #include <memory>
 
 #include "core/object.hpp"
@@ -242,6 +243,7 @@
       };
 
       std::vector<std::unique_ptr<argument>> _args;
+      std::map<device *, std::unique_ptr<root_buffer> > _constant_buffers;
       std::string _name;
       exec_context exec;
       const ref_holder program_ref;
diff --git a/src/gallium/frontends/clover/core/module.hpp b/src/gallium/frontends/clover/core/module.hpp
index 2ddd264..fa9f7dd 100644
--- a/src/gallium/frontends/clover/core/module.hpp
+++ b/src/gallium/frontends/clover/core/module.hpp
@@ -76,7 +76,8 @@
             grid_dimension,
             grid_offset,
             image_size,
-            image_format
+            image_format,
+            constant_buffer
          };
 
          argument(enum type type, size_t size,
diff --git a/src/gallium/frontends/clover/util/functional.hpp b/src/gallium/frontends/clover/util/functional.hpp
index a89c4fc..81bfa64 100644
--- a/src/gallium/frontends/clover/util/functional.hpp
+++ b/src/gallium/frontends/clover/util/functional.hpp
@@ -347,21 +347,6 @@
       const std::string &name;
    };
 
-   class id_equals {
-   public:
-      id_equals(const uint32_t id) : id(id) {
-      }
-
-      template<typename T>
-      bool
-      operator()(const T &x) const {
-         return x.id == id;
-      }
-
-   private:
-      const uint32_t id;
-   };
-
    template<typename T>
    class key_equals_t {
    public: