glsl: Add a method to get precision from a deref instruction
authorNeil Roberts <nroberts@igalia.com>
Fri, 20 Sep 2019 16:04:15 +0000 (18:04 +0200)
committerMarge Bot <eric+marge@anholt.net>
Tue, 24 Mar 2020 23:21:21 +0000 (23:21 +0000)
Adds ir_dereference::precision(). For a normal variable dereference,
the precision comes from the variable. For a record member it comes
from the field within the record. For an array it can come from
either, depending on where the underlying array is stored. The method
recursively walks the derefs until it finds one of the first two.

Reviewed-by: Kristian H. Kristensen <hoegsberg@google.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3885>

src/compiler/glsl/ir.h

index 2e20f4bee7ae94d8f767b934f7c10cb4f45540cc..e84da9a50278b496f024ca05192969b2f130deb7 100644 (file)
@@ -2047,6 +2047,12 @@ public:
     */
    virtual ir_variable *variable_referenced() const = 0;
 
+   /**
+    * Get the precision. This can either come from the eventual variable that
+    * is dereferenced, or from a record member.
+    */
+   virtual int precision() const = 0;
+
 protected:
    ir_dereference(enum ir_node_type t)
       : ir_rvalue(t)
@@ -2076,6 +2082,11 @@ public:
       return this->var;
    }
 
+   virtual int precision() const
+   {
+      return this->var->data.precision;
+   }
+
    virtual ir_variable *whole_variable_referenced()
    {
       /* ir_dereference_variable objects always dereference the entire
@@ -2124,6 +2135,16 @@ public:
       return this->array->variable_referenced();
    }
 
+   virtual int precision() const
+   {
+      ir_dereference *deref = this->array->as_dereference();
+
+      if (deref == NULL)
+         return GLSL_PRECISION_NONE;
+      else
+         return deref->precision();
+   }
+
    virtual void accept(ir_visitor *v)
    {
       v->visit(this);
@@ -2159,6 +2180,13 @@ public:
       return this->record->variable_referenced();
    }
 
+   virtual int precision() const
+   {
+      glsl_struct_field *field = record->type->fields.structure + field_idx;
+
+      return field->precision;
+   }
+
    virtual void accept(ir_visitor *v)
    {
       v->visit(this);