/* -*- mesa-c++ -*- * * Copyright (c) 2022 Collabora LTD * * Author: Gert Wollny * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * on the rights to use, copy, modify, merge, publish, distribute, sub * license, and/or sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef INSTR_TEX_H #define INSTR_TEX_H #include "sfn_instr.h" #include "sfn_valuefactory.h" #include "sfn_shader.h" namespace r600 { class TexInstr : public InstrWithVectorResult { public: enum Opcode { ld = FETCH_OP_LD, get_resinfo = FETCH_OP_GET_TEXTURE_RESINFO, get_nsamples = FETCH_OP_GET_NUMBER_OF_SAMPLES, get_tex_lod = FETCH_OP_GET_LOD, get_gradient_h = FETCH_OP_GET_GRADIENTS_H, get_gradient_v = FETCH_OP_GET_GRADIENTS_V, set_offsets = FETCH_OP_SET_TEXTURE_OFFSETS, keep_gradients = FETCH_OP_KEEP_GRADIENTS, set_gradient_h = FETCH_OP_SET_GRADIENTS_H, set_gradient_v = FETCH_OP_SET_GRADIENTS_V, sample = FETCH_OP_SAMPLE, sample_l = FETCH_OP_SAMPLE_L, sample_lb = FETCH_OP_SAMPLE_LB, sample_lz = FETCH_OP_SAMPLE_LZ, sample_g = FETCH_OP_SAMPLE_G, sample_g_lb = FETCH_OP_SAMPLE_G_L, gather4 = FETCH_OP_GATHER4, gather4_o = FETCH_OP_GATHER4_O, sample_c = FETCH_OP_SAMPLE_C, sample_c_l = FETCH_OP_SAMPLE_C_L, sample_c_lb = FETCH_OP_SAMPLE_C_LB, sample_c_lz = FETCH_OP_SAMPLE_C_LZ, sample_c_g = FETCH_OP_SAMPLE_C_G, sample_c_g_lb = FETCH_OP_SAMPLE_C_G_L, gather4_c = FETCH_OP_GATHER4_C, gather4_c_o = FETCH_OP_GATHER4_C_O, unknown = 255 }; enum Flags { x_unnormalized, y_unnormalized, z_unnormalized, w_unnormalized, grad_fine, num_tex_flag }; struct Inputs { Inputs(const nir_tex_instr& instr, ValueFactory &vf); const nir_variable *sampler_deref; const nir_variable *texture_deref; RegisterVec4 coord; PVirtualValue bias; PVirtualValue comperator; PVirtualValue lod; RegisterVec4 ddx; RegisterVec4 ddy; nir_src *offset; PVirtualValue gather_comp; PVirtualValue ms_index; PVirtualValue sampler_offset; PVirtualValue texture_offset; RegisterVec4::Swizzle swizzle_from_ncomps(int comps) const; Opcode opcode; private: auto get_opcode(const nir_tex_instr& instr) -> Opcode; }; TexInstr(Opcode op, const RegisterVec4& dest, const RegisterVec4::Swizzle& dest_swizzle, const RegisterVec4& src, unsigned sid, unsigned rid, PVirtualValue sampler_offs = nullptr); TexInstr(const TexInstr& orig) = delete; TexInstr(const TexInstr&& orig) = delete; TexInstr& operator =(const TexInstr& orig) = delete; TexInstr& operator =(const TexInstr&& orig) = delete; void accept(ConstInstrVisitor& visitor) const override; void accept(InstrVisitor& visitor) override; const auto& src() const {return m_src;} auto& src() {return m_src;} unsigned opcode() const {return m_opcode;} unsigned sampler_id() const {return m_sampler_id;} unsigned resource_id() const {return m_resource_id;} void set_offset(unsigned index, int32_t val); int get_offset(unsigned index) const; void set_inst_mode(int inst_mode) { m_inst_mode = inst_mode;} int inst_mode() const { return m_inst_mode;} void set_tex_flag(Flags flag) {m_tex_flags.set(flag);} bool has_tex_flag(Flags flag) const {return m_tex_flags.test(flag);} void set_sampler_offset(PVirtualValue ofs) {m_sampler_offset = ofs;} auto* sampler_offset() const {return m_sampler_offset;} void set_gather_comp(int cmp); bool is_equal_to(const TexInstr& lhs) const; static Opcode op_from_string(const std::string& s); static Instr::Pointer from_string(std::istream& is, ValueFactory& value_fctory); static bool from_nir(nir_tex_instr *tex, Shader& shader); uint32_t slots() const override {return 1;}; auto prepare_instr() const { return m_prepare_instr;} private: bool do_ready() const override; void do_print(std::ostream& os) const override; bool propagate_death() override; static const char *opname(Opcode code); static bool is_gather(Opcode op); void read_tex_coord_normalitazion(const std::string& next_token); void set_tex_param(const std::string& next_token); static auto prepare_source(nir_tex_instr *tex, const Inputs& inputs, Shader &shader) -> RegisterVec4; static bool emit_buf_txf(nir_tex_instr *tex, Inputs& src, Shader& shader); static bool emit_tex_txf(nir_tex_instr *tex, Inputs& src, Shader& shader); static bool emit_tex_tex_ms_direct(nir_tex_instr *tex, Inputs& src, Shader& shader); static bool emit_tex_tex_ms(nir_tex_instr *tex, Inputs& src, Shader& shader); static bool emit_tex_tex(nir_tex_instr *tex, Inputs& src, Shader& shader); static bool emit_tex_txl_txb(nir_tex_instr *tex, Inputs& src, Shader& shader); static bool emit_tex_txs(nir_tex_instr *tex, Inputs& src, RegisterVec4::Swizzle dest_swz, Shader& shader); static bool emit_tex_lod(nir_tex_instr* tex, Inputs& src, Shader& shader); static bool emit_tex_txd(nir_tex_instr *tex, Inputs& src, Shader& shader); static bool emit_tex_tg4(nir_tex_instr* instr, Inputs& src , Shader& shader); static bool emit_tex_texture_samples(nir_tex_instr* instr, Inputs& src, Shader& shader); void set_coord_offsets(nir_src *offset); void set_rect_coordinate_flags(nir_tex_instr* instr); void add_prepare_instr(TexInstr *ir) {m_prepare_instr.push_back(ir);}; Opcode m_opcode; RegisterVec4 m_src; PVirtualValue m_sampler_offset; std::bitset m_tex_flags; int m_offset[3]; int m_inst_mode; unsigned m_sampler_id; unsigned m_resource_id; static const std::map s_opcode_map; std::list m_prepare_instr; }; } #endif // INSTR_TEX_H