i965/fs: Fix stride for immediate registers.
authorFrancisco Jerez <currojerez@riseup.net>
Mon, 13 Jul 2015 11:50:24 +0000 (14:50 +0300)
committerFrancisco Jerez <currojerez@riseup.net>
Tue, 21 Jul 2015 14:54:00 +0000 (17:54 +0300)
When the width field was removed from fs_reg the BROADCAST handling
code in opt_algebraic() started to miss a number of trivial
optimization cases resulting in the ugly indirect-addressing sequence
to be emitted unnecessarily for some variable-indexed texturing and
UBO loads regardless of one of the sources of BROADCAST being
immediate.  Apparently the reason was that we were setting the stride
field to one for immediates even though they are typically uniform.
Width used to be set to one too which is why this optimization used to
work previously until the "reg.width == 1" check was removed.

The stride field of vector immediates is intentionally left equal to
one, because they are strictly speaking not uniform.  The assertion in
fs_generator makes sure that immediates have the expected stride as
consistency check.

Reviewed-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_fs_generator.cpp

index 51ef32c1b6ac01c774442a73eac9d78f18c45318..f7fdb174efbec7bc6e41041166fc07d9a54cdd43 100644 (file)
@@ -362,6 +362,7 @@ fs_reg::fs_reg(float f)
    init();
    this->file = IMM;
    this->type = BRW_REGISTER_TYPE_F;
+   this->stride = 0;
    this->fixed_hw_reg.dw1.f = f;
 }
 
@@ -371,6 +372,7 @@ fs_reg::fs_reg(int32_t i)
    init();
    this->file = IMM;
    this->type = BRW_REGISTER_TYPE_D;
+   this->stride = 0;
    this->fixed_hw_reg.dw1.d = i;
 }
 
@@ -380,6 +382,7 @@ fs_reg::fs_reg(uint32_t u)
    init();
    this->file = IMM;
    this->type = BRW_REGISTER_TYPE_UD;
+   this->stride = 0;
    this->fixed_hw_reg.dw1.ud = u;
 }
 
index bae7216797251a04cc881f6cbc0c45fe739448aa..7f5ac6b9665ef7a8b25ecbc248baa2257ce2182f 100644 (file)
@@ -79,6 +79,10 @@ brw_reg_from_fs_reg(fs_inst *inst, fs_reg *reg)
       brw_reg = byte_offset(brw_reg, reg->subreg_offset);
       break;
    case IMM:
+      assert(reg->stride == ((reg->type == BRW_REGISTER_TYPE_V ||
+                              reg->type == BRW_REGISTER_TYPE_UV ||
+                              reg->type == BRW_REGISTER_TYPE_VF) ? 1 : 0));
+
       switch (reg->type) {
       case BRW_REGISTER_TYPE_F:
         brw_reg = brw_imm_f(reg->fixed_hw_reg.dw1.f);