Mesa (master): glsl: Basic support for built-in intrinsics.

Francisco Jerez currojerez at kemper.freedesktop.org
Tue Oct 29 19:45:41 UTC 2013


Module: Mesa
Branch: master
Commit: 95629223761e076323faab93f72c955e61a38a75
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=95629223761e076323faab93f72c955e61a38a75

Author: Francisco Jerez <currojerez at riseup.net>
Date:   Wed Sep 25 11:55:06 2013 -0700

glsl: Basic support for built-in intrinsics.

Fix the linker to deal with intrinsic functions which are undefined
all the way down to the driver back-end, and introduce intrinsic
definition helpers in the built-in generator.

We still need to figure out what kind of interface we want for drivers
to communicate to the GLSL front-end which of the supported intrinsics
should use a default GLSL implementation and which should use a
hardware-specific override.  As there's no default GLSL implementation
for atomic ops, this seems like something we can worry about later on.

Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>

v2: Define local helper function to generate ir_call nodes in the
    builtin generator.

---

 src/glsl/builtin_functions.cpp |   49 +++++++++++++++++++++++++++++++++++++--
 src/glsl/ir.cpp                |    4 +-
 src/glsl/ir.h                  |    6 +++++
 src/glsl/link_functions.cpp    |   16 ++++++++-----
 4 files changed, 64 insertions(+), 11 deletions(-)

diff --git a/src/glsl/builtin_functions.cpp b/src/glsl/builtin_functions.cpp
index 45fff4c..f122259 100644
--- a/src/glsl/builtin_functions.cpp
+++ b/src/glsl/builtin_functions.cpp
@@ -365,6 +365,7 @@ private:
    ir_variable *gl_Vertex;
 
    void create_shader();
+   void create_intrinsics();
    void create_builtins();
 
    /**
@@ -386,6 +387,14 @@ private:
 
    ir_expression *asin_expr(ir_variable *x);
 
+   /**
+    * Call function \param f with parameters specified as the linked
+    * list \param params of \c ir_variable objects.  \param ret should
+    * point to the ir_variable that will hold the function return
+    * value, or be \c NULL if the function has void return type.
+    */
+   ir_call *call(ir_function *f, ir_variable *ret, exec_list params);
+
    /** Create a new function and add the given signatures. */
    void add_function(const char *name, ...);
 
@@ -609,6 +618,7 @@ builtin_builder::initialize()
 
    mem_ctx = ralloc_context(NULL);
    create_shader();
+   create_intrinsics();
    create_builtins();
 }
 
@@ -646,6 +656,15 @@ builtin_builder::create_shader()
 /** @} */
 
 /**
+ * Create ir_function and ir_function_signature objects for each
+ * intrinsic.
+ */
+void
+builtin_builder::create_intrinsics()
+{
+}
+
+/**
  * Create ir_function and ir_function_signature objects for each built-in.
  *
  * Contains a list of every available built-in.
@@ -2071,8 +2090,6 @@ builtin_builder::add_function(const char *name, ...)
       if (sig == NULL)
          break;
 
-      sig->is_defined = true;
-
       if (false) {
          exec_list stuff;
          stuff.push_tail(sig);
@@ -2170,7 +2187,13 @@ builtin_builder::new_sig(const glsl_type *return_type,
 #define MAKE_SIG(return_type, avail, ...)  \
    ir_function_signature *sig =               \
       new_sig(return_type, avail, __VA_ARGS__);      \
-   ir_factory body(&sig->body, mem_ctx);
+   ir_factory body(&sig->body, mem_ctx);             \
+   sig->is_defined = true;
+
+#define MAKE_INTRINSIC(return_type, avail, ...)      \
+   ir_function_signature *sig =                      \
+      new_sig(return_type, avail, __VA_ARGS__);      \
+   sig->is_intrinsic = true;
 
 ir_function_signature *
 builtin_builder::unop(builtin_available_predicate avail,
@@ -2262,6 +2285,26 @@ builtin_builder::asin_expr(ir_variable *x)
                                           mul(abs(x), imm(-0.03102955f))))))))));
 }
 
+ir_call *
+builtin_builder::call(ir_function *f, ir_variable *ret, exec_list params)
+{
+   exec_list actual_params;
+
+   foreach_iter(exec_list_iterator, it, params) {
+      ir_variable *var = ((ir_instruction *)it.get())->as_variable();
+      actual_params.push_tail(var_ref(var));
+   }
+
+   ir_function_signature *sig =
+      f->exact_matching_signature(NULL, &actual_params);
+   if (!sig)
+      return NULL;
+
+   ir_dereference_variable *deref =
+      (sig->return_type->is_void() ? NULL : var_ref(ret));
+
+   return new(mem_ctx) ir_call(sig, deref, &actual_params);
+}
 
 ir_function_signature *
 builtin_builder::_asin(const glsl_type *type)
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index 09dbf40..768c4dc 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -1647,8 +1647,8 @@ ir_variable::determine_interpolation_mode(bool flat_shade)
 
 ir_function_signature::ir_function_signature(const glsl_type *return_type,
                                              builtin_available_predicate b)
-   : return_type(return_type), is_defined(false), builtin_avail(b),
-     _function(NULL)
+   : return_type(return_type), is_defined(false), is_intrinsic(false),
+     builtin_avail(b), _function(NULL)
 {
    this->ir_type = ir_type_function_signature;
    this->origin = NULL;
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 85b4d05..49de9e3 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -787,6 +787,12 @@ public:
    /** Whether or not this function signature is a built-in. */
    bool is_builtin() const;
 
+   /**
+    * Whether or not this function is an intrinsic to be implemented
+    * by the driver.
+    */
+   bool is_intrinsic;
+
    /** Whether or not a built-in is available for this shader. */
    bool is_builtin_available(const _mesa_glsl_parse_state *state) const;
 
diff --git a/src/glsl/link_functions.cpp b/src/glsl/link_functions.cpp
index fd80099..68aa620 100644
--- a/src/glsl/link_functions.cpp
+++ b/src/glsl/link_functions.cpp
@@ -155,14 +155,17 @@ public:
 
       linked_sig->replace_parameters(&formal_parameters);
 
-      foreach_list_const(node, &sig->body) {
-	 const ir_instruction *const original = (ir_instruction *) node;
+      if (sig->is_defined) {
+         foreach_list_const(node, &sig->body) {
+            const ir_instruction *const original = (ir_instruction *) node;
 
-	 ir_instruction *copy = original->clone(linked, ht);
-	 linked_sig->body.push_tail(copy);
+            ir_instruction *copy = original->clone(linked, ht);
+            linked_sig->body.push_tail(copy);
+         }
+
+         linked_sig->is_defined = true;
       }
 
-      linked_sig->is_defined = true;
       hash_table_dtor(ht);
 
       /* Patch references inside the function to things outside the function
@@ -307,7 +310,8 @@ find_matching_signature(const char *name, const exec_list *actual_parameters,
       ir_function_signature *sig =
          f->matching_signature(NULL, actual_parameters);
 
-      if ((sig == NULL) || !sig->is_defined)
+      if ((sig == NULL) ||
+          (!sig->is_defined && !sig->is_intrinsic))
 	 continue;
 
       /* If this function expects to bind to a built-in function and the




More information about the mesa-commit mailing list