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