1 /* -*- mesa-c++ -*- 2 * Copyright 2022 Collabora LTD 3 * Author: Gert Wollny <[email protected]> 4 * SPDX-License-Identifier: MIT 5 */ 6 7 #ifndef INSTR_TEX_H 8 #define INSTR_TEX_H 9 10 #include "sfn_instr.h" 11 #include "sfn_shader.h" 12 #include "sfn_valuefactory.h" 13 14 namespace r600 { 15 16 class TexInstr : public InstrWithVectorResult { 17 public: 18 enum Opcode { 19 ld = FETCH_OP_LD, 20 get_resinfo = FETCH_OP_GET_TEXTURE_RESINFO, 21 get_nsamples = FETCH_OP_GET_NUMBER_OF_SAMPLES, 22 get_tex_lod = FETCH_OP_GET_LOD, 23 get_gradient_h = FETCH_OP_GET_GRADIENTS_H, 24 get_gradient_v = FETCH_OP_GET_GRADIENTS_V, 25 set_offsets = FETCH_OP_SET_TEXTURE_OFFSETS, 26 keep_gradients = FETCH_OP_KEEP_GRADIENTS, 27 set_gradient_h = FETCH_OP_SET_GRADIENTS_H, 28 set_gradient_v = FETCH_OP_SET_GRADIENTS_V, 29 sample = FETCH_OP_SAMPLE, 30 sample_l = FETCH_OP_SAMPLE_L, 31 sample_lb = FETCH_OP_SAMPLE_LB, 32 sample_lz = FETCH_OP_SAMPLE_LZ, 33 sample_g = FETCH_OP_SAMPLE_G, 34 sample_g_lb = FETCH_OP_SAMPLE_G_L, 35 gather4 = FETCH_OP_GATHER4, 36 gather4_o = FETCH_OP_GATHER4_O, 37 38 sample_c = FETCH_OP_SAMPLE_C, 39 sample_c_l = FETCH_OP_SAMPLE_C_L, 40 sample_c_lb = FETCH_OP_SAMPLE_C_LB, 41 sample_c_lz = FETCH_OP_SAMPLE_C_LZ, 42 sample_c_g = FETCH_OP_SAMPLE_C_G, 43 sample_c_g_lb = FETCH_OP_SAMPLE_C_G_L, 44 gather4_c = FETCH_OP_GATHER4_C, 45 gather4_c_o = FETCH_OP_GATHER4_C_O, 46 unknown = 255 47 }; 48 49 enum Flags { 50 x_unnormalized, 51 y_unnormalized, 52 z_unnormalized, 53 w_unnormalized, 54 grad_fine, 55 num_tex_flag 56 }; 57 58 static constexpr Flags TexFlags[] = {x_unnormalized, 59 y_unnormalized, 60 z_unnormalized, 61 w_unnormalized, 62 grad_fine, 63 num_tex_flag}; 64 65 struct Inputs { 66 Inputs(const nir_tex_instr& instr, ValueFactory& vf); 67 const nir_variable *sampler_deref; 68 const nir_variable *texture_deref; 69 RegisterVec4 coord; 70 PVirtualValue bias; 71 PVirtualValue comperator; 72 PVirtualValue lod; 73 RegisterVec4 ddx; 74 RegisterVec4 ddy; 75 nir_src *offset; 76 PVirtualValue gather_comp; 77 PVirtualValue ms_index; 78 PRegister texture_offset; 79 PRegister sampler_offset; 80 nir_src *backend1; 81 nir_src *backend2; 82 83 RegisterVec4::Swizzle swizzle_from_ncomps(int comps) const; 84 85 Opcode opcode; 86 87 private: 88 auto get_opcode(const nir_tex_instr& instr) -> Opcode; 89 }; 90 91 TexInstr(Opcode op, 92 const RegisterVec4& dest, 93 const RegisterVec4::Swizzle& dest_swizzle, 94 const RegisterVec4& src, 95 unsigned resource_id, 96 PRegister resource_offs, 97 int sampler_id = 0, 98 PRegister sampler_offset = nullptr); 99 100 TexInstr(const TexInstr& orig) = delete; 101 TexInstr(const TexInstr&& orig) = delete; 102 TexInstr& operator=(const TexInstr& orig) = delete; 103 TexInstr& operator=(const TexInstr&& orig) = delete; 104 105 void accept(ConstInstrVisitor& visitor) const override; 106 void accept(InstrVisitor& visitor) override; 107 src()108 const auto& src() const { return m_src; } src()109 auto& src() { return m_src; } 110 opcode()111 unsigned opcode() const { return m_opcode; } 112 sampler_id()113 unsigned sampler_id() const { return m_sampler.resource_id(); } sampler_offset()114 auto sampler_offset() const { return m_sampler.resource_offset(); } set_sampler_offset(PRegister offs)115 void set_sampler_offset(PRegister offs) { m_sampler.set_resource_offset(offs); } sampler_index_mode()116 auto sampler_index_mode() const { return m_sampler.resource_index_mode(); } 117 118 void set_offset(unsigned index, int32_t val); 119 int get_offset(unsigned index) const; 120 set_inst_mode(int inst_mode)121 void set_inst_mode(int inst_mode) { m_inst_mode = inst_mode; } inst_mode()122 int inst_mode() const { return m_inst_mode; } 123 set_tex_flag(Flags flag)124 void set_tex_flag(Flags flag) { m_tex_flags.set(flag); } has_tex_flag(Flags flag)125 bool has_tex_flag(Flags flag) const { return m_tex_flags.test(flag); } 126 127 void set_gather_comp(int cmp); 128 bool is_equal_to(const TexInstr& lhs) const; 129 130 static Opcode op_from_string(const std::string& s); 131 static Instr::Pointer from_string(std::istream& is, ValueFactory& value_fctory); 132 133 static bool from_nir(nir_tex_instr *tex, Shader& shader); 134 slots()135 uint32_t slots() const override { return 1; }; 136 prepare_instr()137 auto prepare_instr() const { return m_prepare_instr; } 138 139 bool replace_source(PRegister old_src, PVirtualValue new_src) override; 140 void update_indirect_addr(PRegister old_reg, PRegister addr) override; 141 142 uint8_t allowed_src_chan_mask() const override; 143 144 private: 145 bool do_ready() const override; 146 void do_print(std::ostream& os) const override; 147 bool propagate_death() override; 148 149 static const char *opname(Opcode code); 150 static bool is_gather(Opcode op); 151 152 void read_tex_coord_normalitazion(const std::string& next_token); 153 void set_tex_param(const std::string& next_token); 154 155 static auto prepare_source(nir_tex_instr *tex, const Inputs& inputs, Shader& shader) 156 -> RegisterVec4; 157 158 static bool emit_buf_txf(nir_tex_instr *tex, Inputs& src, Shader& shader); 159 static bool emit_tex_txs(nir_tex_instr *tex, 160 Inputs& src, 161 RegisterVec4::Swizzle dest_swz, 162 Shader& shader); 163 static bool emit_tex_lod(nir_tex_instr *tex, Inputs& src, Shader& shader); 164 static bool 165 emit_tex_texture_samples(nir_tex_instr *instr, Inputs& src, Shader& shader); 166 static bool emit_lowered_tex(nir_tex_instr *instr, Inputs& src, Shader& shader); 167 static void emit_set_gradients( 168 nir_tex_instr *tex, int texture_id, Inputs& src, TexInstr *irt, Shader& shader); 169 static void emit_set_offsets( 170 nir_tex_instr *tex, int texture_id, Inputs& src, TexInstr *irt, Shader& shader); 171 172 bool set_coord_offsets(nir_src *offset); 173 void set_rect_coordinate_flags(nir_tex_instr *instr); add_prepare_instr(TexInstr * ir)174 void add_prepare_instr(TexInstr *ir) { m_prepare_instr.push_back(ir); }; 175 void forward_set_blockid(int id, int index) override; 176 177 178 Opcode m_opcode; 179 180 RegisterVec4 m_src; 181 std::bitset<num_tex_flag> m_tex_flags; 182 int m_coord_offset[3]; 183 int m_inst_mode; 184 185 static const std::map<Opcode, std::string> s_opcode_map; 186 std::list<TexInstr *, Allocator<TexInstr *>> m_prepare_instr; 187 188 Resource m_sampler; 189 }; 190 191 bool 192 r600_nir_lower_tex_to_backend(nir_shader *shader, amd_gfx_level chip_class); 193 194 } // namespace r600 195 196 #endif // INSTR_TEX_H 197