i965/nir/vec4: Add setup for system values
authorAlejandro Piñeiro <apinheiro@igalia.com>
Tue, 16 Jun 2015 15:08:04 +0000 (17:08 +0200)
committerJason Ekstrand <jason.ekstrand@intel.com>
Mon, 3 Aug 2015 16:40:47 +0000 (09:40 -0700)
Similar to other variable setups, system values will initialize the
corresponding register inside a 'nir_system_values' map, which will then
be queried later when processing the different system value intrinsics
for the appropriate register.

Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
src/mesa/drivers/dri/i965/brw_vec4.h
src/mesa/drivers/dri/i965/brw_vec4_nir.cpp

index d429310563ff380962ca4d5ced073d7593e30250..722f9a1f4c5ed8893a3a5ac90d537d07533bf9b7 100644 (file)
@@ -397,6 +397,7 @@ public:
    virtual void nir_setup_uniforms(nir_shader *shader);
    virtual void nir_setup_uniform(nir_variable *var);
    virtual void nir_setup_builtin_uniform(nir_variable *var);
+   virtual void nir_setup_system_value_intrinsic(nir_intrinsic_instr *instr);
    virtual void nir_setup_system_values(nir_shader *shader);
    virtual void nir_emit_impl(nir_function_impl *impl);
    virtual void nir_emit_cf_list(exec_list *list);
@@ -415,6 +416,7 @@ public:
 
    src_reg *nir_inputs;
    unsigned *nir_uniform_driver_location;
+   dst_reg *nir_system_values;
 
 protected:
    void emit_vertex();
index feafcbe3cceb7004ae040204ded216541e30555a..989b8e3b6b5623361608b9346da01d68be960817 100644 (file)
@@ -48,16 +48,63 @@ vec4_visitor::emit_nir_code()
    }
 }
 
+void
+vec4_visitor::nir_setup_system_value_intrinsic(nir_intrinsic_instr *instr)
+{
+   dst_reg *reg;
+
+   switch (instr->intrinsic) {
+   case nir_intrinsic_load_vertex_id:
+      unreachable("should be lowered by lower_vertex_id().");
+
+   case nir_intrinsic_load_vertex_id_zero_base:
+      reg = &this->nir_system_values[SYSTEM_VALUE_VERTEX_ID_ZERO_BASE];
+      if (reg->file == BAD_FILE)
+         *reg =
+            *this->make_reg_for_system_value(SYSTEM_VALUE_VERTEX_ID_ZERO_BASE,
+                                             glsl_type::int_type);
+      break;
+
+   case nir_intrinsic_load_base_vertex:
+      reg = &this->nir_system_values[SYSTEM_VALUE_BASE_VERTEX];
+      if (reg->file == BAD_FILE)
+         *reg = *this->make_reg_for_system_value(SYSTEM_VALUE_BASE_VERTEX,
+                                                 glsl_type::int_type);
+      break;
+
+   case nir_intrinsic_load_instance_id:
+      reg = &this->nir_system_values[SYSTEM_VALUE_INSTANCE_ID];
+      if (reg->file == BAD_FILE)
+         *reg = *this->make_reg_for_system_value(SYSTEM_VALUE_INSTANCE_ID,
+                                                 glsl_type::int_type);
+      break;
+
+   default:
+      break;
+   }
+}
+
 static bool
 setup_system_values_block(nir_block *block, void *void_visitor)
 {
-   /* @TODO: Not yet implemented */
+   vec4_visitor *v = (vec4_visitor *)void_visitor;
+
+   nir_foreach_instr(block, instr) {
+      if (instr->type != nir_instr_type_intrinsic)
+         continue;
+
+      nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
+      v->nir_setup_system_value_intrinsic(intrin);
+   }
+
    return true;
 }
 
 void
 vec4_visitor::nir_setup_system_values(nir_shader *shader)
 {
+   nir_system_values = ralloc_array(mem_ctx, dst_reg, SYSTEM_VALUE_MAX);
+
    nir_foreach_overload(shader, overload) {
       assert(strcmp(overload->function->name, "main") == 0);
       assert(overload->impl);