diff --git a/src/gallium/drivers/r600/r600_pipe_common.c b/src/gallium/drivers/r600/r600_pipe_common.c index 5a10aad5907..89de599a310 100644 --- a/src/gallium/drivers/r600/r600_pipe_common.c +++ b/src/gallium/drivers/r600/r600_pipe_common.c @@ -1404,6 +1404,7 @@ bool r600_common_screen_init(struct r600_common_screen *rscreen, .lower_uniforms_to_ubo = true, .lower_image_offset_to_range_base = 1, .vectorize_tess_levels = 1, + .has_ddx_intrinsics = true, }; rscreen->nir_options = nir_options; diff --git a/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp b/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp index b5091c64361..598ce109a0c 100644 --- a/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_instr_alu.cpp @@ -1432,9 +1432,6 @@ emit_alu_trans_op2_cayman(const nir_alu_instr& alu, EAluOp opcode, Shader& shade static bool emit_alu_f2i32_or_u32_eg(const nir_alu_instr& alu, EAluOp opcode, Shader& shader); -static bool -emit_tex_fdd(const nir_alu_instr& alu, TexInstr::Opcode opcode, bool fine, Shader& shader); - static bool emit_alu_cube(const nir_alu_instr& alu, Shader& shader); @@ -1860,17 +1857,7 @@ AluInstr::from_nir(nir_alu_instr *alu, Shader& shader) case nir_op_vec4: return emit_create_vec(*alu, 4, shader); - case nir_op_fddx: - case nir_op_fddx_coarse: - return emit_tex_fdd(*alu, TexInstr::get_gradient_h, false, shader); - case nir_op_fddx_fine: - return emit_tex_fdd(*alu, TexInstr::get_gradient_h, true, shader); - case nir_op_fddy: - case nir_op_fddy_coarse: - return emit_tex_fdd(*alu, TexInstr::get_gradient_v, false, shader); - case nir_op_fddy_fine: - return emit_tex_fdd(*alu, TexInstr::get_gradient_v, true, shader); - case nir_op_cube_amd: + case nir_op_cube_amd: return emit_alu_cube(*alu, shader); default: fprintf(stderr, "Unknown instruction '"); @@ -2985,46 +2972,6 @@ emit_alu_trans_op2_cayman(const nir_alu_instr& alu, EAluOp opcode, Shader& shade return true; } -static bool -emit_tex_fdd(const nir_alu_instr& alu, TexInstr::Opcode opcode, bool fine, Shader& shader) -{ - auto& value_factory = shader.value_factory(); - - int ncomp = alu.def.num_components; - RegisterVec4::Swizzle src_swz = {7, 7, 7, 7}; - RegisterVec4::Swizzle tmp_swz = {7, 7, 7, 7}; - for (auto i = 0; i < ncomp; ++i) { - src_swz[i] = alu.src[0].swizzle[i]; - tmp_swz[i] = i; - } - - auto src = value_factory.src_vec4(alu.src[0].src, pin_none, src_swz); - - auto tmp = value_factory.temp_vec4(pin_group, tmp_swz); - AluInstr *mv = nullptr; - for (int i = 0; i < ncomp; ++i) { - mv = new AluInstr(op1_mov, tmp[i], src[i], AluInstr::write); - shader.emit_instruction(mv); - } - if (mv) - mv->set_alu_flag(alu_last_instr); - - auto dst = value_factory.dest_vec4(alu.def, pin_group); - RegisterVec4::Swizzle dst_swz = {7, 7, 7, 7}; - for (auto i = 0; i < ncomp; ++i) { - dst_swz[i] = i; - } - - auto tex = new TexInstr(opcode, dst, dst_swz, tmp, R600_MAX_CONST_BUFFERS, nullptr); - - if (fine) - tex->set_tex_flag(TexInstr::grad_fine); - - shader.emit_instruction(tex); - - return true; -} - static bool emit_alu_cube(const nir_alu_instr& alu, Shader& shader) { diff --git a/src/gallium/drivers/r600/sfn/sfn_shader.cpp b/src/gallium/drivers/r600/sfn/sfn_shader.cpp index e5189636b4b..6d0aac5b0b6 100644 --- a/src/gallium/drivers/r600/sfn/sfn_shader.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_shader.cpp @@ -19,6 +19,7 @@ #include "sfn_instr_fetch.h" #include "sfn_instr_lds.h" #include "sfn_instr_mem.h" +#include "sfn_instr_tex.h" #include "sfn_liverangeevaluator.h" #include "sfn_shader_cs.h" #include "sfn_shader_fs.h" @@ -828,6 +829,46 @@ Shader::process_instr(nir_instr *instr) return m_instr_factory->from_nir(instr, *this); } +bool +Shader::emit_tex_fdd(const nir_intrinsic_instr* intr, int opcode, bool fine) +{ + auto& value_factory_ = value_factory(); + + int ncomp = intr->def.num_components; + RegisterVec4::Swizzle src_swz = {7, 7, 7, 7}; + RegisterVec4::Swizzle tmp_swz = {7, 7, 7, 7}; + for (auto i = 0; i < ncomp; ++i) { + src_swz[i] = i; + tmp_swz[i] = i; + } + + auto src = value_factory_.src_vec4(intr->src[0], pin_none, src_swz); + + auto tmp = value_factory_.temp_vec4(pin_group, tmp_swz); + AluInstr *mv = nullptr; + for (int i = 0; i < ncomp; ++i) { + mv = new AluInstr(op1_mov, tmp[i], src[i], AluInstr::write); + emit_instruction(mv); + } + if (mv) + mv->set_alu_flag(alu_last_instr); + + auto dst = value_factory_.dest_vec4(intr->def, pin_group); + RegisterVec4::Swizzle dst_swz = {7, 7, 7, 7}; + for (auto i = 0; i < ncomp; ++i) { + dst_swz[i] = i; + } + + auto tex = new TexInstr((TexInstr::Opcode)opcode, dst, dst_swz, tmp, R600_MAX_CONST_BUFFERS, nullptr); + + if (fine) + tex->set_tex_flag(TexInstr::grad_fine); + + emit_instruction(tex); + + return true; +} + bool Shader::process_intrinsic(nir_intrinsic_instr *intr) { @@ -871,6 +912,16 @@ Shader::process_intrinsic(nir_intrinsic_instr *intr) return emit_atomic_local_shared(intr); case nir_intrinsic_shader_clock: return emit_shader_clock(intr); + case nir_intrinsic_ddx: + case nir_intrinsic_ddx_coarse: + return emit_tex_fdd(intr, TexInstr::get_gradient_h, false); + case nir_intrinsic_ddx_fine: + return emit_tex_fdd(intr, TexInstr::get_gradient_h, true); + case nir_intrinsic_ddy: + case nir_intrinsic_ddy_coarse: + return emit_tex_fdd(intr, TexInstr::get_gradient_v, false); + case nir_intrinsic_ddy_fine: + return emit_tex_fdd(intr, TexInstr::get_gradient_v, true); case nir_intrinsic_load_reg: return emit_load_reg(intr); case nir_intrinsic_load_reg_indirect: diff --git a/src/gallium/drivers/r600/sfn/sfn_shader.h b/src/gallium/drivers/r600/sfn/sfn_shader.h index ef176363866..131fe50623e 100644 --- a/src/gallium/drivers/r600/sfn/sfn_shader.h +++ b/src/gallium/drivers/r600/sfn/sfn_shader.h @@ -315,6 +315,7 @@ private: bool emit_shader_clock(nir_intrinsic_instr *instr); bool emit_wait_ack(); bool emit_barrier(nir_intrinsic_instr *instr); + bool emit_tex_fdd(const nir_intrinsic_instr* intr, int opcode, bool fine); bool emit_load_reg(nir_intrinsic_instr *intr); bool emit_load_reg_indirect(nir_intrinsic_instr *intr); bool emit_store_reg(nir_intrinsic_instr *intr);