[Mesa-dev] [WIP 23/25] i965/fs: Lower double precision scalars into vectors
Topi Pohjolainen
topi.pohjolainen at intel.com
Thu Oct 16 05:24:35 PDT 2014
On gen7 the hardware supports only single precision scalar operands. This
patch modifies fs_visitor to allocate temporary general registers and to
manually copy the original 64-bits into the temporary 8- or 16-wide vector
depending on the execution size.
Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 43 +++++++++++++++++++++++++---
1 file changed, 39 insertions(+), 4 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
index fa3fc41..7ad01d6 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
@@ -162,7 +162,15 @@ fs_visitor::visit(ir_dereference_variable *ir)
this->result = fs_reg(reg_null_d);
return;
}
- this->result = *reg;
+
+ if (is_df_uniform_and_needs_separate_load(*reg) &&
+ ir->var->type == glsl_type::double_type) {
+ fs_reg res = fs_reg(this, glsl_type::double_type);
+ emit(FS_OPCODE_UNIFORM_DOUBLE_LOAD, res, *reg);
+ this->result = res;
+ } else {
+ this->result = *reg;
+ }
}
void
@@ -182,6 +190,13 @@ fs_visitor::visit(ir_dereference_record *ir)
}
this->result = offset(this->result, off);
this->result.type = brw_type_for_base_type(ir->type);
+
+ if (is_df_uniform_and_needs_separate_load(this->result) &&
+ ir->type == glsl_type::double_type) {
+ fs_reg res = fs_reg(this, glsl_type::double_type);
+ emit(FS_OPCODE_UNIFORM_DOUBLE_LOAD, res, this->result);
+ this->result = res;
+ }
}
void
@@ -223,7 +238,15 @@ fs_visitor::visit(ir_dereference_array *ir)
src.reladdr = ralloc(mem_ctx, fs_reg);
memcpy(src.reladdr, &index_reg, sizeof(index_reg));
}
- this->result = src;
+
+ if (is_df_uniform_and_needs_separate_load(src) &&
+ ir->type == glsl_type::double_type) {
+ fs_reg res(this, glsl_type::double_type);
+ emit(FS_OPCODE_UNIFORM_DOUBLE_LOAD, res, src);
+ this->result = res;
+ } else {
+ this->result = src;
+ }
}
void
@@ -1202,7 +1225,10 @@ fs_visitor::visit(ir_assignment *ir)
ir->lhs->type->is_vector()) {
for (int i = 0; i < ir->lhs->type->vector_elements; i++) {
if (ir->write_mask & (1 << i)) {
- inst = emit(MOV(l, r));
+ if (is_df_uniform_and_needs_separate_load(r))
+ inst = emit(FS_OPCODE_UNIFORM_DOUBLE_LOAD, l, r);
+ else
+ inst = emit(MOV(l, r));
if (ir->condition)
inst->predicate = BRW_PREDICATE_NORMAL;
r = offset(r, 1);
@@ -2192,6 +2218,12 @@ fs_visitor::visit(ir_swizzle *ir)
if (ir->type->vector_elements == 1) {
this->result = offset(this->result, ir->mask.x);
+ if (is_df_uniform_and_needs_separate_load(this->result)) {
+ fs_reg src = this->result;
+ fs_reg res = fs_reg(this, ir->type);
+ emit(FS_OPCODE_UNIFORM_DOUBLE_LOAD, res, src);
+ this->result = res;
+ }
return;
}
@@ -2217,7 +2249,10 @@ fs_visitor::visit(ir_swizzle *ir)
break;
}
- emit(MOV(result, offset(channel, swiz)));
+ if (is_df_uniform_and_needs_separate_load(channel))
+ emit(FS_OPCODE_UNIFORM_DOUBLE_LOAD, result, offset(channel, swiz));
+ else
+ emit(MOV(result, offset(channel, swiz)));
result = offset(result, 1);
}
}
--
1.8.3.1
More information about the mesa-dev
mailing list