diff options
author | Ilia Mirkin <[email protected]> | 2016-11-27 21:05:34 -0500 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2016-11-29 07:44:01 -0800 |
commit | 4f2d1d6ea713df8f8d816b48b9e99c7117cf36d7 (patch) | |
tree | d281d7a0596eb53729beab251c4fad37df597c19 | |
parent | faf20df143a63e58aa729446f21c38ae39a438f2 (diff) |
i965: support constant gather offsets larger than 4 bits
Offsets that don't fit into 4 bits need to force gather_po to be
selected. Adjust the logic so that this happens.
Signed-off-by: Ilia Mirkin <[email protected]>
Reviewed-by: Jason Ekstrand <[email protected]>
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 8 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_shader.cpp | 17 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_shader.h | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_vec4_nir.cpp | 7 |
4 files changed, 24 insertions, 12 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp index baa973c31a0..855266f78ac 100644 --- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp @@ -4485,8 +4485,12 @@ fs_visitor::nir_emit_texture(const fs_builder &bld, nir_tex_instr *instr) case nir_tex_src_offset: { nir_const_value *const_offset = nir_src_as_const_value(instr->src[i].src); - if (const_offset) { - header_bits |= brw_texture_offset(const_offset->i32, 3); + unsigned offset_bits = 0; + if (const_offset && + brw_texture_offset(const_offset->i32, + nir_tex_instr_src_size(instr, i), + &offset_bits)) { + header_bits |= offset_bits; } else { srcs[TEX_LOGICAL_SRC_TG4_OFFSET] = retype(src, BRW_REGISTER_TYPE_D); diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp index bee4d8875c5..25f745d23a6 100644 --- a/src/mesa/drivers/dri/i965/brw_shader.cpp +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp @@ -127,10 +127,15 @@ brw_math_function(enum opcode op) } } -uint32_t -brw_texture_offset(int *offsets, unsigned num_components) +bool +brw_texture_offset(int *offsets, unsigned num_components, uint32_t *offset_bits) { - if (!offsets) return 0; /* nonconstant offset; caller will handle it. */ + if (!offsets) return false; /* nonconstant offset; caller will handle it. */ + + /* offset out of bounds; caller will handle it. */ + for (unsigned i = 0; i < num_components; i++) + if (offsets[i] > 7 || offsets[i] < -8) + return false; /* Combine all three offsets into a single unsigned dword: * @@ -138,12 +143,12 @@ brw_texture_offset(int *offsets, unsigned num_components) * bits 7:4 - V Offset (Y component) * bits 3:0 - R Offset (Z component) */ - unsigned offset_bits = 0; + *offset_bits = 0; for (unsigned i = 0; i < num_components; i++) { const unsigned shift = 4 * (2 - i); - offset_bits |= (offsets[i] << shift) & (0xF << shift); + *offset_bits |= (offsets[i] << shift) & (0xF << shift); } - return offset_bits; + return true; } const char * diff --git a/src/mesa/drivers/dri/i965/brw_shader.h b/src/mesa/drivers/dri/i965/brw_shader.h index 12113b97e10..e8b34d59ab6 100644 --- a/src/mesa/drivers/dri/i965/brw_shader.h +++ b/src/mesa/drivers/dri/i965/brw_shader.h @@ -215,7 +215,9 @@ public: virtual void invalidate_live_intervals() = 0; }; -uint32_t brw_texture_offset(int *offsets, unsigned num_components); +bool brw_texture_offset(int *offsets, + unsigned num_components, + uint32_t *offset_bits); void brw_setup_image_uniform_values(gl_shader_stage stage, struct brw_stage_prog_data *stage_prog_data, diff --git a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp index 0d54907cadf..dde07d0d141 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_nir.cpp @@ -1880,9 +1880,10 @@ vec4_visitor::nir_emit_texture(nir_tex_instr *instr) case nir_tex_src_offset: { nir_const_value *const_offset = nir_src_as_const_value(instr->src[i].src); - if (const_offset) { - constant_offset = brw_texture_offset(const_offset->i32, 3); - } else { + if (!const_offset || + !brw_texture_offset(const_offset->i32, + nir_tex_instr_src_size(instr, i), + &constant_offset)) { offset_value = get_nir_src(instr->src[i].src, BRW_REGISTER_TYPE_D, 2); } |