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 R600_SFN_SHADER_FS_H 28 #define R600_SFN_SHADER_FS_H 29 30 #include "sfn_shader.h" 31 32 namespace r600 { 33 34 class FragmentShader : public Shader { 35 public: 36 FragmentShader(const r600_shader_key& key); 37 bool load_input(nir_intrinsic_instr *intr) override; 38 bool store_output(nir_intrinsic_instr *intr) override; 39 40 bool process_stage_intrinsic(nir_intrinsic_instr *intr) override; 41 42 protected: 43 44 static const int s_max_interpolators = 6; interpolators_used(int i)45 bool interpolators_used(int i) const {return m_interpolators_used.test(i);} 46 private: 47 48 bool load_interpolated_input(nir_intrinsic_instr *intr); 49 50 virtual int allocate_interpolators_or_inputs() = 0; 51 virtual bool load_input_hw(nir_intrinsic_instr *intr) = 0; 52 virtual bool process_stage_intrinsic_hw(nir_intrinsic_instr *intr) = 0; 53 virtual bool load_interpolated_input_hw(nir_intrinsic_instr *intr) = 0; 54 55 bool do_scan_instruction(nir_instr *instr) override; 56 int do_allocate_reserved_registers() override; 57 58 void do_get_shader_info(r600_shader *sh_info) override; 59 60 bool scan_input(nir_intrinsic_instr *instr, int index_src_id); 61 62 63 bool emit_export_pixel(nir_intrinsic_instr& intr); 64 bool emit_load_sample_mask_in(nir_intrinsic_instr* instr); 65 bool emit_load_helper_invocation(nir_intrinsic_instr* instr); 66 bool emit_load_sample_pos(nir_intrinsic_instr* instr); 67 void do_finalize() override; 68 69 bool read_prop(std::istream& is) override; 70 71 void do_print_properties(std::ostream& os) const override; 72 73 bool m_dual_source_blend; 74 unsigned m_max_color_exports; 75 unsigned m_export_highest; 76 unsigned m_num_color_exports; 77 unsigned m_color_export_mask; 78 unsigned m_depth_exports; 79 ExportInstr *m_last_pixel_export; 80 81 std::bitset<s_max_interpolators> m_interpolators_used; 82 RegisterVec4 m_pos_input; 83 Register *m_face_input{nullptr}; 84 bool m_fs_write_all; 85 bool m_uses_discard{false}; 86 bool m_gs_prim_id_input{false}; 87 int m_ps_prim_id_input{0}; 88 Register *m_sample_id_reg{nullptr}; 89 Register *m_sample_mask_reg{nullptr}; 90 Register *m_helper_invocation{nullptr}; 91 int m_nsys_inputs{0}; 92 bool m_apply_sample_mask{false}; 93 int m_rat_base{0}; 94 int m_pos_driver_loc{0}; 95 int m_face_driver_loc{0}; 96 }; 97 98 class FragmentShaderR600 : public FragmentShader { 99 public: 100 using FragmentShader::FragmentShader; 101 private: 102 int allocate_interpolators_or_inputs() override; 103 bool load_input_hw(nir_intrinsic_instr *intr) override; 104 bool process_stage_intrinsic_hw(nir_intrinsic_instr *intr) override; 105 bool load_interpolated_input_hw(nir_intrinsic_instr *intr) override; 106 107 IOMap<RegisterVec4> m_interpolated_inputs; 108 }; 109 110 111 class FragmentShaderEG : public FragmentShader { 112 public: 113 using FragmentShader::FragmentShader; 114 115 private: 116 class Interpolator { 117 public: 118 Interpolator(); 119 bool enabled : 1; 120 unsigned ij_index : 4; 121 PRegister i; 122 PRegister j; 123 }; 124 125 struct InterpolateParams { 126 PVirtualValue i,j; 127 int base; 128 }; 129 130 int allocate_interpolators_or_inputs() override; 131 bool load_input_hw(nir_intrinsic_instr *intr) override; 132 bool process_stage_intrinsic_hw(nir_intrinsic_instr *intr) override; 133 bool load_interpolated_input_hw(nir_intrinsic_instr *intr) override; 134 135 bool load_barycentric_pixel(nir_intrinsic_instr *intr); 136 bool load_barycentric_at_sample(nir_intrinsic_instr* instr); 137 bool load_barycentric_at_offset(nir_intrinsic_instr* instr); 138 bool load_interpolated(RegisterVec4& dest, const InterpolateParams& params, 139 int num_dest_comp, int start_comp); 140 141 bool load_interpolated_one_comp(RegisterVec4& dest, const InterpolateParams& params, EAluOp op); 142 bool load_interpolated_two_comp(RegisterVec4& dest, const InterpolateParams& params, EAluOp op, int writemask); 143 bool load_interpolated_two_comp_for_one(RegisterVec4& dest, const InterpolateParams& params, EAluOp op, 144 int dest_slot); 145 146 std::array<Interpolator, s_max_interpolators> m_interpolator; 147 148 }; 149 150 } 151 152 #endif 153