From 4f2d1d6ea713df8f8d816b48b9e99c7117cf36d7 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Sun, 27 Nov 2016 21:05:34 -0500 Subject: [PATCH] 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 Reviewed-by: Jason Ekstrand --- src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 8 ++++++-- src/mesa/drivers/dri/i965/brw_shader.cpp | 17 +++++++++++------ src/mesa/drivers/dri/i965/brw_shader.h | 4 +++- 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 baa973c..855266f 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 bee4d88..25f745d 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 12113b9..e8b34d5 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 0d54907..dde07d0 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); } -- 2.7.4