this->file = IMM;
this->type = BRW_REGISTER_TYPE_F;
this->fixed_hw_reg.dw1.f = f;
+ this->width = 1;
}
/** Immediate value constructor. */
this->file = IMM;
this->type = BRW_REGISTER_TYPE_D;
this->fixed_hw_reg.dw1.d = i;
+ this->width = 1;
}
/** Immediate value constructor. */
this->file = IMM;
this->type = BRW_REGISTER_TYPE_UD;
this->fixed_hw_reg.dw1.ud = u;
+ this->width = 1;
}
/** Fixed brw_reg. */
this->file = HW_REG;
this->fixed_hw_reg = fixed_hw_reg;
this->type = fixed_hw_reg.type;
+ this->width = 1 << fixed_hw_reg.width;
}
bool
negate == r.negate &&
abs == r.abs &&
!reladdr && !r.reladdr &&
- memcmp(&fixed_hw_reg, &r.fixed_hw_reg,
- sizeof(fixed_hw_reg)) == 0 &&
+ memcmp(&fixed_hw_reg, &r.fixed_hw_reg, sizeof(fixed_hw_reg)) == 0 &&
+ width == r.width &&
stride == r.stride);
}
+uint8_t
+fs_reg::effective_width(const fs_visitor *v) const
+{
+ switch (this->file) {
+ case BAD_FILE:
+ return 8;
+ case UNIFORM:
+ case IMM:
+ assert(this->width == 1);
+ return v->dispatch_width;
+ case GRF:
+ case HW_REG:
+ assert(this->width > 1 && this->width <= v->dispatch_width);
+ assert(this->width % 8 == 0);
+ return this->width;
+ case MRF:
+ unreachable("MRF registers cannot be used as sources");
+ default:
+ unreachable("Invalid register file");
+ }
+}
+
fs_reg &
fs_reg::apply_stride(unsigned stride)
{
this->file = file;
this->reg = reg;
this->type = BRW_REGISTER_TYPE_F;
+
+ switch (file) {
+ case UNIFORM:
+ this->width = 1;
+ break;
+ default:
+ this->width = 8;
+ }
}
/** Fixed HW reg constructor. */
this->file = file;
this->reg = reg;
this->type = type;
+
+ switch (file) {
+ case UNIFORM:
+ this->width = 1;
+ break;
+ default:
+ this->width = 8;
+ }
+}
+
+/** Fixed HW reg constructor. */
+fs_reg::fs_reg(enum register_file file, int reg, enum brw_reg_type type,
+ uint8_t width)
+{
+ init();
+ this->file = file;
+ this->reg = reg;
+ this->type = type;
+ this->width = width;
}
/** Automatic reg constructor. */
-fs_reg::fs_reg(class fs_visitor *v, const struct glsl_type *type)
+fs_reg::fs_reg(fs_visitor *v, const struct glsl_type *type)
{
init();
this->reg = v->virtual_grf_alloc(v->type_size(type));
this->reg_offset = 0;
this->type = brw_type_for_base_type(type);
+ this->width = v->dispatch_width;
+ assert(this->width == 8 || this->width == 16);
}
fs_reg *
class fs_live_variables;
}
+class fs_visitor;
+
class fs_reg : public backend_reg {
public:
DECLARE_RALLOC_CXX_OPERATORS(fs_reg)
fs_reg(struct brw_reg fixed_hw_reg);
fs_reg(enum register_file file, int reg);
fs_reg(enum register_file file, int reg, enum brw_reg_type type);
- fs_reg(class fs_visitor *v, const struct glsl_type *type);
+ fs_reg(enum register_file file, int reg, enum brw_reg_type type, uint8_t width);
+ fs_reg(fs_visitor *v, const struct glsl_type *type);
bool equals(const fs_reg &r) const;
bool is_valid_3src() const;
fs_reg *reladdr;
+ /**
+ * The register width. This indicates how many hardware values are
+ * represented by each virtual value. Valid values are 1, 8, or 16.
+ * For immediate values, this is 1. Most of the rest of the time, it
+ * will be equal to the dispatch width.
+ */
+ uint8_t width;
+
+ /**
+ * Returns the effective register width when used as a source in the
+ * given instruction. Registers such as uniforms and immediates
+ * effectively take on the width of the instruction in which they are
+ * used.
+ */
+ uint8_t effective_width(const fs_visitor *v) const;
+
/** Register region horizontal stride */
uint8_t stride;
};