From 9f2e22bf343b21d6b44e6a502f00a86d169f5ade Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Sun, 17 Jan 2016 20:30:14 -0500 Subject: i965/vec4: don't copy ATTR into 3src instructions with complex swizzles The vec4 backend, at the end, does this: if (inst->is_3src()) { for (int i = 0; i < 3; i++) { if (inst->src[i].vstride == BRW_VERTICAL_STRIDE_0) assert(brw_is_single_value_swizzle(inst->src[i].swizzle)); So make sure that we use the same conditions when trying to copy-propagate. UNIFORMs will be converted to vstride 0 in convert_to_hw_regs, but so will ATTRs when interleaved (as will happen in a GS with multiple attributes). Since the vstride is not set at copy-prop time, infer it by inspecting dispatch_mode and reject ATTRs if they have non-scalar swizzles and are interleaved. Fixes assertion errors in dolphin-generated geometry shaders (or misrendering on opt builds) on Sandybridge or on IVB/HSW with INTEL_DEBUG=nodualobj. Co-authored-by: Ilia Mirkin Reviewed-by: Ilia Mirkin Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93418 Cc: "11.0 11.1" --- src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp b/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp index c6f0b0d8a2a..6bd992882b8 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_copy_propagation.cpp @@ -254,8 +254,8 @@ try_constant_propagate(const struct brw_device_info *devinfo, static bool try_copy_propagate(const struct brw_device_info *devinfo, - vec4_instruction *inst, - int arg, struct copy_entry *entry) + vec4_instruction *inst, int arg, + struct copy_entry *entry, int attributes_per_reg) { /* Build up the value we are propagating as if it were the source of a * single MOV @@ -320,7 +320,8 @@ try_copy_propagate(const struct brw_device_info *devinfo, unsigned composed_swizzle = brw_compose_swizzle(inst->src[arg].swizzle, value.swizzle); if (inst->is_3src() && - value.file == UNIFORM && + (value.file == UNIFORM || + (value.file == ATTR && attributes_per_reg != 1)) && !brw_is_single_value_swizzle(composed_swizzle)) return false; @@ -395,6 +396,11 @@ try_copy_propagate(const struct brw_device_info *devinfo, bool vec4_visitor::opt_copy_propagation(bool do_constant_prop) { + /* If we are in dual instanced or single mode, then attributes are going + * to be interleaved, so one register contains two attribute slots. + */ + const int attributes_per_reg = + prog_data->dispatch_mode == DISPATCH_MODE_4X2_DUAL_OBJECT ? 1 : 2; bool progress = false; struct copy_entry entries[alloc.total_size]; @@ -465,7 +471,7 @@ vec4_visitor::opt_copy_propagation(bool do_constant_prop) if (do_constant_prop && try_constant_propagate(devinfo, inst, i, &entry)) progress = true; - if (try_copy_propagate(devinfo, inst, i, &entry)) + if (try_copy_propagate(devinfo, inst, i, &entry, attributes_per_reg)) progress = true; } -- cgit v1.2.3