diff options
author | Topi Pohjolainen <topi.pohjolainen@intel.com> | 2014-10-01 10:03:11 +0300 |
---|---|---|
committer | Topi Pohjolainen <topi.pohjolainen@intel.com> | 2014-10-01 10:36:48 +0300 |
commit | c7cff16a7404d2b6eab1ef6d5714dba110d35a49 (patch) | |
tree | d4a165a1b05886a2a9a625c9759957f47126ead1 | |
parent | 7986237345b216145f8588ece0e8c27f9e9c7f85 (diff) |
i965/fs: Lower double precision scalars into vectors
Signed-off-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.h | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 44 |
2 files changed, 45 insertions, 1 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index de4a25dc22..d8ab47998f 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -547,6 +547,8 @@ public: void visit_atomic_counter_intrinsic(ir_call *ir); + fs_reg lower_double_scalar(const fs_reg *reg); + const struct brw_wm_prog_key *const key; struct brw_wm_prog_data *prog_data; unsigned int sanity_param_count; diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp index a733037af8..f2ee142178 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp @@ -150,6 +150,44 @@ fs_visitor::visit(ir_variable *ir) hash_table_insert(this->variable_ht, reg, ir); } +/** + * Lower double precision scalar into a vector. Hardware can operate only + * with scalars of single precision. + * + * Quotes from the docs: + * + * IVB PRM vol4 part 3, section 3.1 (about align1 mode): + * "A single precision float scalar is allowed." + * + * Section 3.3.9 (Register region restrictions): + * "If ExecSize = Width = 1, both VertStride and HorzStride must be 0. This + * defines a scalar." + * "If VertStride = HorzStride = 0, Width must be 1 regardless of the value of + * ExecSize." + * + * "In Align1 mode, all regioning parameters like stride, execution size, and + * width must use the syntax of a pair of packed floats. The offsets for + * these data types must be 64 - bit aligned. The execution size and + * regioning parameters are in terms of floats. + * + * Example: mov (8) r10.0<1>:df r11.0<8;8,1>:df + * The above instruction moves four double floats" + * + * Hence in case of "double scalar", one should set width = 2 violating the + * second constraint. + */ +fs_reg +fs_visitor::lower_double_scalar(const fs_reg *reg) +{ + fs_reg res = fs_reg(this, glsl_type::double_type); + fs_reg lo = retype(*reg, BRW_REGISTER_TYPE_UD); + fs_reg hi = offset(lo, 1); + + emit(FS_OPCODE_PACK_DOUBLE_2x32, res, lo, hi); + + return res; +} + void fs_visitor::visit(ir_dereference_variable *ir) { @@ -160,7 +198,11 @@ fs_visitor::visit(ir_dereference_variable *ir) this->result = fs_reg(reg_null_d); return; } - this->result = *reg; + + if (reg->file == UNIFORM && reg->type == BRW_REGISTER_TYPE_DF) + this->result = lower_double_scalar(reg); + else + this->result = *reg; } void |