summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2015-12-09 18:26:19 -0800
committerKenneth Graunke <kenneth@whitecape.org>2015-12-14 14:39:38 -0800
commit9f3917bf372aa19f85875dbe30ca12adc9b67b90 (patch)
tree0712c3eaa95a7cf0f33592c9a837b1d72fb6a725
parent8c4deb10dfbef683a2052a7bd62450aa76ad8fde (diff)
i965: Fix partial variable access for geometry shaders in SSO mode.
Without varying packing, if a VS writes a compound variable, and the GS only reads part of it, the base location of the variable may not actually be in the VUE map. To cope with this, we do lowering in terms of varying slots, add any constant offsets to the base, and then do the VUE map remapping. This ensures we only look up VUE map entries for slots which actually exist. Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
-rw-r--r--src/mesa/drivers/dri/i965/brw_nir.c38
1 files changed, 34 insertions, 4 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_nir.c b/src/mesa/drivers/dri/i965/brw_nir.c
index c9a2767b39..88457e4f9c 100644
--- a/src/mesa/drivers/dri/i965/brw_nir.c
+++ b/src/mesa/drivers/dri/i965/brw_nir.c
@@ -114,6 +114,27 @@ remap_vs_attrs(nir_block *block, void *closure)
return true;
}
+static bool
+remap_inputs_with_vue_map(nir_block *block, void *closure)
+{
+ const struct brw_vue_map *vue_map = closure;
+
+ nir_foreach_instr(block, instr) {
+ if (instr->type != nir_instr_type_intrinsic)
+ continue;
+
+ nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
+
+ if (intrin->intrinsic == nir_intrinsic_load_input ||
+ intrin->intrinsic == nir_intrinsic_load_per_vertex_input) {
+ int vue_slot = vue_map->varying_to_slot[intrin->const_index[0]];
+ assert(vue_slot != -1);
+ intrin->const_index[0] = vue_slot;
+ }
+ }
+ return true;
+}
+
static void
brw_nir_lower_inputs(nir_shader *nir,
const struct brw_device_info *devinfo,
@@ -182,15 +203,24 @@ brw_nir_lower_inputs(nir_shader *nir,
brw_compute_vue_map(devinfo, &input_vue_map, inputs_read,
nir->info.separate_shader);
- /* Start with the slot for the variable's base. */
foreach_list_typed(nir_variable, var, node, &nir->inputs) {
- assert(input_vue_map.varying_to_slot[var->data.location] != -1);
- var->data.driver_location =
- input_vue_map.varying_to_slot[var->data.location];
+ var->data.driver_location = var->data.location;
}
/* Inputs are stored in vec4 slots, so use type_size_vec4(). */
nir_lower_io(nir, nir_var_shader_in, type_size_vec4);
+
+ /* This pass needs actual constants */
+ nir_opt_constant_folding(nir);
+
+ nir_foreach_overload(nir, overload) {
+ if (overload->impl) {
+ nir_builder_init(&params.b, overload->impl);
+ nir_foreach_block(overload->impl, add_const_offset_to_base, &params);
+ nir_foreach_block(overload->impl, remap_inputs_with_vue_map,
+ &input_vue_map);
+ }
+ }
}
break;
}