summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri
diff options
context:
space:
mode:
authorFrancisco Jerez <[email protected]>2015-02-04 18:24:47 +0200
committerFrancisco Jerez <[email protected]>2015-02-19 14:06:42 +0200
commit6c07279e5ad67d925b99ff9e0345dcaeffc37283 (patch)
tree3192f2d4831485e694ae9cbb9ee05b8974573a77 /src/mesa/drivers/dri
parent437d401e6398eebc2ecd061650d16d1ad2d947f1 (diff)
i965: Handle F16TO32/F32TO16 with dword src/dst consistently on both back-ends.
Due to the way it's implemented in hardware, the F16TO32/F32TO16 instructions require the source/destination register to be of some 16-bit type in Align1 mode, while they require it to be some 32-bit type in Align16 mode (and as an undocumented feature the high 16 bits of the destination register are zeroed out in the case of the F32TO16 instruction on Gen7). Make their behaviour consistent so you can specify a 32 bit register type as source or destination and get predictable results in the most significant bits no matter what access mode is being used. Reviewed-by: Matt Turner <[email protected]>
Diffstat (limited to 'src/mesa/drivers/dri')
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu_emit.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index d9e01fdd9bd..1d6fd673de1 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -1155,13 +1155,14 @@ brw_F32TO16(struct brw_compile *p, struct brw_reg dst, struct brw_reg src)
* an undocumented feature.
*/
const bool needs_zero_fill = (dst.type == BRW_REGISTER_TYPE_UD &&
- brw->gen >= 8);
+ (!align16 || brw->gen >= 8));
brw_inst *inst;
if (align16) {
assert(dst.type == BRW_REGISTER_TYPE_UD);
} else {
- assert(dst.type == BRW_REGISTER_TYPE_W ||
+ assert(dst.type == BRW_REGISTER_TYPE_UD ||
+ dst.type == BRW_REGISTER_TYPE_W ||
dst.type == BRW_REGISTER_TYPE_UW ||
dst.type == BRW_REGISTER_TYPE_HF);
}
@@ -1199,6 +1200,15 @@ brw_F16TO32(struct brw_compile *p, struct brw_reg dst, struct brw_reg src)
if (align16) {
assert(src.type == BRW_REGISTER_TYPE_UD);
} else {
+ /* From the Ivybridge PRM, Vol4, Part3, Section 6.26 f16to32:
+ *
+ * Because this instruction does not have a 16-bit floating-point
+ * type, the source data type must be Word (W). The destination type
+ * must be F (Float).
+ */
+ if (src.type == BRW_REGISTER_TYPE_UD)
+ src = spread(retype(src, BRW_REGISTER_TYPE_W), 2);
+
assert(src.type == BRW_REGISTER_TYPE_W ||
src.type == BRW_REGISTER_TYPE_UW ||
src.type == BRW_REGISTER_TYPE_HF);