diff options
author | Alejandro Piñeiro <[email protected]> | 2016-03-23 12:20:05 +0100 |
---|---|---|
committer | Alejandro Piñeiro <[email protected]> | 2016-05-17 07:34:40 +0200 |
commit | 96c276dda909ddf12714b9e64b7207156e8fd4bb (patch) | |
tree | c40e541b966984561bd3728c0ec84e16a69e0d6b /src | |
parent | 1ff32ae8b2367950c543770ee5e6e459312cebce (diff) |
i965/fs: half exec_size when dealing with 64 bits attributes
The HW has a restriction that only vertical stride may cross register
boundaries. Until now this was only handled on VGRFs at
rw_reg_from_fs_reg, but it is also needed for attributes.
v2:
* Remove reference to commit id on commit message (Juan Suarez)
* Simplify code that compute final exec_size (Ian Romanick)
* Use REG_SIZE on that same code (Kenneth Graunke)
Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs.cpp | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index 06a5de1785f..e8baf6c0706 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -1729,11 +1729,28 @@ fs_visitor::convert_attr_sources_to_hw_regs(fs_inst *inst) inst->src[i].nr + inst->src[i].reg_offset; - unsigned width = inst->src[i].stride == 0 ? 1 : inst->exec_size; + /* As explained at brw_reg_from_fs_reg, From the Haswell PRM: + * + * VertStride must be used to cross GRF register boundaries. This + * rule implies that elements within a 'Width' cannot cross GRF + * boundaries. + * + * So, for registers that are large enough, we have to split the exec + * size in two and trust the compression state to sort it out. + */ + unsigned total_size = inst->exec_size * + inst->src[i].stride * + type_sz(inst->src[i].type); + + assert(total_size <= 2 * REG_SIZE); + const unsigned exec_size = + (total_size <= REG_SIZE) ? inst->exec_size : inst->exec_size / 2; + + unsigned width = inst->src[i].stride == 0 ? 1 : exec_size; struct brw_reg reg = stride(byte_offset(retype(brw_vec8_grf(grf, 0), inst->src[i].type), inst->src[i].subreg_offset), - inst->exec_size * inst->src[i].stride, + exec_size * inst->src[i].stride, width, inst->src[i].stride); reg.abs = inst->src[i].abs; reg.negate = inst->src[i].negate; |