i965/nir/vec4: Implement store_output intrinsic
authorEduardo Lima Mitev <elima@igalia.com>
Tue, 16 Jun 2015 19:31:49 +0000 (21:31 +0200)
committerJason Ekstrand <jason.ekstrand@intel.com>
Mon, 3 Aug 2015 16:40:47 +0000 (09:40 -0700)
This implementation is based on the current URB setup in vec4_visitor, which
requires the output register to be stored in the output_reg array at variable's
original shader location index. But since nir_lower_io() pass uses the value
in var->data.driver_location, we need to put there var->data.location instead,
prior to calling nir_lower_io(), so that we end up with the correct index
in const_index[0].

The driver_location is not used at all, so this patch also disables the
nir_assign_var_locations pass on non-scalar shaders.

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

index b241121..4f73350 100644 (file)
@@ -106,13 +106,16 @@ brw_create_nir(struct brw_context *brw,
                                             &nir->num_direct_uniforms,
                                             &nir->num_uniforms,
                                             is_scalar);
+      nir_assign_var_locations(&nir->outputs, &nir->num_outputs, is_scalar);
    } else {
       nir_assign_var_locations(&nir->uniforms,
                                &nir->num_uniforms,
                                is_scalar);
+
+      foreach_list_typed(nir_variable, var, node, &nir->outputs)
+         var->data.driver_location = var->data.location;
    }
    nir_assign_var_locations(&nir->inputs, &nir->num_inputs, is_scalar);
-   nir_assign_var_locations(&nir->outputs, &nir->num_outputs, is_scalar);
 
    nir_lower_io(nir, is_scalar);
 
index 5bf1dbb..696122d 100644 (file)
@@ -473,10 +473,23 @@ vec4_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
    }
 
    case nir_intrinsic_store_output_indirect:
+      has_indirect = true;
       /* fallthrough */
-   case nir_intrinsic_store_output:
-      /* @TODO: Not yet implemented */
+   case nir_intrinsic_store_output: {
+      int varying = instr->const_index[0];
+
+      src = get_nir_src(instr->src[0], BRW_REGISTER_TYPE_F,
+                        instr->num_components);
+      dest = dst_reg(src);
+
+      if (has_indirect) {
+         dest.reladdr = new(mem_ctx) src_reg(get_nir_src(instr->src[1],
+                                                         BRW_REGISTER_TYPE_D,
+                                                         1));
+      }
+      output_reg[varying] = dest;
       break;
+   }
 
    case nir_intrinsic_load_vertex_id:
       unreachable("should be lowered by lower_vertex_id()");