1 /* -*- mesa-c++ -*- 2 * 3 * Copyright (c) 2022 Collabora LTD 4 * 5 * Author: Gert Wollny <gert.wollny@collabora.com> 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * on the rights to use, copy, modify, merge, publish, distribute, sub 11 * license, and/or sell copies of the Software, and to permit persons to whom 12 * the Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the next 15 * paragraph) shall be included in all copies or substantial portions of the 16 * Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 21 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 24 * USE OR OTHER DEALINGS IN THE SOFTWARE. 25 */ 26 27 #ifndef INSTR_TEX_H 28 #define INSTR_TEX_H 29 30 #include "sfn_instr.h" 31 #include "sfn_valuefactory.h" 32 33 #include "sfn_shader.h" 34 35 namespace r600 { 36 37 class TexInstr : public InstrWithVectorResult { 38 public: 39 enum Opcode { 40 ld = FETCH_OP_LD, 41 get_resinfo = FETCH_OP_GET_TEXTURE_RESINFO, 42 get_nsamples = FETCH_OP_GET_NUMBER_OF_SAMPLES, 43 get_tex_lod = FETCH_OP_GET_LOD, 44 get_gradient_h = FETCH_OP_GET_GRADIENTS_H, 45 get_gradient_v = FETCH_OP_GET_GRADIENTS_V, 46 set_offsets = FETCH_OP_SET_TEXTURE_OFFSETS, 47 keep_gradients = FETCH_OP_KEEP_GRADIENTS, 48 set_gradient_h = FETCH_OP_SET_GRADIENTS_H, 49 set_gradient_v = FETCH_OP_SET_GRADIENTS_V, 50 sample = FETCH_OP_SAMPLE, 51 sample_l = FETCH_OP_SAMPLE_L, 52 sample_lb = FETCH_OP_SAMPLE_LB, 53 sample_lz = FETCH_OP_SAMPLE_LZ, 54 sample_g = FETCH_OP_SAMPLE_G, 55 sample_g_lb = FETCH_OP_SAMPLE_G_L, 56 gather4 = FETCH_OP_GATHER4, 57 gather4_o = FETCH_OP_GATHER4_O, 58 59 sample_c = FETCH_OP_SAMPLE_C, 60 sample_c_l = FETCH_OP_SAMPLE_C_L, 61 sample_c_lb = FETCH_OP_SAMPLE_C_LB, 62 sample_c_lz = FETCH_OP_SAMPLE_C_LZ, 63 sample_c_g = FETCH_OP_SAMPLE_C_G, 64 sample_c_g_lb = FETCH_OP_SAMPLE_C_G_L, 65 gather4_c = FETCH_OP_GATHER4_C, 66 gather4_c_o = FETCH_OP_GATHER4_C_O, 67 unknown = 255 68 }; 69 70 enum Flags { 71 x_unnormalized, 72 y_unnormalized, 73 z_unnormalized, 74 w_unnormalized, 75 grad_fine, 76 num_tex_flag 77 }; 78 79 struct Inputs { 80 Inputs(const nir_tex_instr& instr, ValueFactory &vf); 81 const nir_variable *sampler_deref; 82 const nir_variable *texture_deref; 83 RegisterVec4 coord; 84 PVirtualValue bias; 85 PVirtualValue comperator; 86 PVirtualValue lod; 87 RegisterVec4 ddx; 88 RegisterVec4 ddy; 89 nir_src *offset; 90 PVirtualValue gather_comp; 91 PVirtualValue ms_index; 92 PVirtualValue sampler_offset; 93 PVirtualValue texture_offset; 94 95 RegisterVec4::Swizzle swizzle_from_ncomps(int comps) const; 96 97 Opcode opcode; 98 private: 99 auto get_opcode(const nir_tex_instr& instr) -> Opcode; 100 }; 101 102 TexInstr(Opcode op, const RegisterVec4& dest, 103 const RegisterVec4::Swizzle& dest_swizzle, 104 const RegisterVec4& src, unsigned sid, unsigned rid, 105 PVirtualValue sampler_offs = nullptr); 106 107 TexInstr(const TexInstr& orig) = delete; 108 TexInstr(const TexInstr&& orig) = delete; 109 TexInstr& operator =(const TexInstr& orig) = delete; 110 TexInstr& operator =(const TexInstr&& orig) = delete; 111 112 void accept(ConstInstrVisitor& visitor) const override; 113 void accept(InstrVisitor& visitor) override; 114 src()115 const auto& src() const {return m_src;} src()116 auto& src() {return m_src;} 117 opcode()118 unsigned opcode() const {return m_opcode;} sampler_id()119 unsigned sampler_id() const {return m_sampler_id;} resource_id()120 unsigned resource_id() const {return m_resource_id;} 121 122 void set_offset(unsigned index, int32_t val); 123 int get_offset(unsigned index) const; 124 set_inst_mode(int inst_mode)125 void set_inst_mode(int inst_mode) { m_inst_mode = inst_mode;} inst_mode()126 int inst_mode() const { return m_inst_mode;} 127 set_tex_flag(Flags flag)128 void set_tex_flag(Flags flag) {m_tex_flags.set(flag);} has_tex_flag(Flags flag)129 bool has_tex_flag(Flags flag) const {return m_tex_flags.test(flag);} 130 set_sampler_offset(PVirtualValue ofs)131 void set_sampler_offset(PVirtualValue ofs) {m_sampler_offset = ofs;} sampler_offset()132 auto* sampler_offset() const {return m_sampler_offset;} 133 134 void set_gather_comp(int cmp); 135 bool is_equal_to(const TexInstr& lhs) const; 136 137 static Opcode op_from_string(const std::string& s); 138 static Instr::Pointer from_string(std::istream& is, ValueFactory& value_fctory); 139 140 static bool from_nir(nir_tex_instr *tex, Shader& shader); 141 slots()142 uint32_t slots() const override {return 1;}; 143 prepare_instr()144 auto prepare_instr() const { return m_prepare_instr;} 145 146 private: 147 148 bool do_ready() const override; 149 void do_print(std::ostream& os) const override; 150 bool propagate_death() override; 151 152 static const char *opname(Opcode code); 153 static bool is_gather(Opcode op); 154 155 void read_tex_coord_normalitazion(const std::string& next_token); 156 void set_tex_param(const std::string& next_token); 157 158 static auto prepare_source(nir_tex_instr *tex, const Inputs& inputs, Shader &shader) -> RegisterVec4; 159 160 static bool emit_buf_txf(nir_tex_instr *tex, Inputs& src, Shader& shader); 161 static bool emit_tex_txf(nir_tex_instr *tex, Inputs& src, Shader& shader); 162 static bool emit_tex_tex_ms_direct(nir_tex_instr *tex, Inputs& src, Shader& shader); 163 static bool emit_tex_tex_ms(nir_tex_instr *tex, Inputs& src, Shader& shader); 164 static bool emit_tex_tex(nir_tex_instr *tex, Inputs& src, Shader& shader); 165 static bool emit_tex_txl_txb(nir_tex_instr *tex, Inputs& src, Shader& shader); 166 static bool emit_tex_txs(nir_tex_instr *tex, Inputs& src, 167 RegisterVec4::Swizzle dest_swz, Shader& shader); 168 static bool emit_tex_lod(nir_tex_instr* tex, Inputs& src, Shader& shader); 169 static bool emit_tex_txd(nir_tex_instr *tex, Inputs& src, Shader& shader); 170 static bool emit_tex_tg4(nir_tex_instr* instr, Inputs& src , Shader& shader); 171 static bool emit_tex_texture_samples(nir_tex_instr* instr, Inputs& src, Shader& shader); 172 173 void set_coord_offsets(nir_src *offset); 174 void set_rect_coordinate_flags(nir_tex_instr* instr); add_prepare_instr(TexInstr * ir)175 void add_prepare_instr(TexInstr *ir) {m_prepare_instr.push_back(ir);}; 176 177 Opcode m_opcode; 178 179 RegisterVec4 m_src; 180 PVirtualValue m_sampler_offset; 181 std::bitset<num_tex_flag> m_tex_flags; 182 int m_offset[3]; 183 int m_inst_mode; 184 unsigned m_sampler_id; 185 unsigned m_resource_id; 186 187 static const std::map<Opcode, std::string> s_opcode_map; 188 std::list<TexInstr *> m_prepare_instr; 189 }; 190 191 } 192 193 #endif // INSTR_TEX_H 194