xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/r600/sfn/sfn_instr_tex.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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