glsl: fix the type of ir_constant_data::u16
[mesa.git] / src / compiler / glsl / lower_output_reads.cpp
index 8a375ac0ad55b0d5d9996dbb6f92d1b84e4a4d64..7a182130b2e2770a20eb996e85fabf017c7a5c63 100644 (file)
@@ -47,8 +47,6 @@ protected:
     */
    hash_table *replacements;
 
-   void *mem_ctx;
-
    unsigned stage;
 public:
    output_read_remover(unsigned stage);
@@ -74,13 +72,12 @@ static unsigned
 hash_table_var_hash(const void *key)
 {
    const ir_variable * var = static_cast<const ir_variable *>(key);
-   return _mesa_key_hash_string(var->name);
+   return _mesa_hash_string(var->name);
 }
 
 output_read_remover::output_read_remover(unsigned stage)
 {
    this->stage = stage;
-   mem_ctx = ralloc_context(NULL);
    replacements = _mesa_hash_table_create(NULL, hash_table_var_hash,
                                           _mesa_key_pointer_equal);
 }
@@ -88,15 +85,12 @@ output_read_remover::output_read_remover(unsigned stage)
 output_read_remover::~output_read_remover()
 {
    _mesa_hash_table_destroy(replacements, NULL);
-   ralloc_free(mem_ctx);
 }
 
 ir_visitor_status
 output_read_remover::visit(ir_dereference_variable *ir)
 {
-   if (ir->var->data.mode != ir_var_shader_out)
-      return visit_continue;
-   if (stage == MESA_SHADER_TESS_CTRL)
+   if (ir->var->data.mode != ir_var_shader_out || ir->var->data.fb_fetch_output)
       return visit_continue;
 
    hash_entry *entry = _mesa_hash_table_search(replacements, ir->var);
@@ -107,6 +101,10 @@ output_read_remover::visit(ir_dereference_variable *ir)
       void *var_ctx = ralloc_parent(ir->var);
       temp = new(var_ctx) ir_variable(ir->var->type, ir->var->name,
                                       ir_var_temporary);
+      /* copy flags which affect arithematical precision */
+      temp->data.invariant = ir->var->data.invariant;
+      temp->data.precise = ir->var->data.precise;
+      temp->data.precision = ir->var->data.precision;
       _mesa_hash_table_insert(replacements, ir->var, temp);
       ir->var->insert_after(temp);
    }
@@ -173,6 +171,12 @@ output_read_remover::visit_leave(ir_function_signature *sig)
 void
 lower_output_reads(unsigned stage, exec_list *instructions)
 {
+   /* Due to the possible interactions between multiple tessellation control
+    * shader invocations, we leave output variables as-is.
+    */
+   if (stage == MESA_SHADER_TESS_CTRL)
+      return;
+
    output_read_remover v(stage);
    visit_list_elements(&v, instructions);
 }