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 image_size_const_offset()42 unsigned image_size_const_offset() override { return m_image_size_const_offset;} 43 44 protected: 45 static const int s_max_interpolators = 6; interpolators_used(int i)46 bool interpolators_used(int i) const { return m_interpolators_used.test(i); } 47 48 private: 49 bool load_interpolated_input(nir_intrinsic_instr *intr); 50 51 virtual int allocate_interpolators_or_inputs() = 0; 52 virtual bool load_input_hw(nir_intrinsic_instr *intr) = 0; 53 virtual bool process_stage_intrinsic_hw(nir_intrinsic_instr *intr) = 0; 54 virtual bool load_interpolated_input_hw(nir_intrinsic_instr *intr) = 0; 55 56 bool do_scan_instruction(nir_instr *instr) override; 57 int do_allocate_reserved_registers() override; 58 59 void do_get_shader_info(r600_shader *sh_info) override; 60 61 bool scan_input(nir_intrinsic_instr *instr, int index_src_id); 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{false}; 74 unsigned m_max_color_exports{0}; 75 unsigned m_export_highest{0}; 76 unsigned m_num_color_exports{0}; 77 unsigned m_color_export_mask{0}; 78 unsigned m_color_export_written_mask{0}; 79 ExportInstr *m_last_pixel_export{nullptr}; 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{false}; 85 bool m_uses_discard{false}; 86 bool m_gs_prim_id_input{false}; 87 Register *m_sample_id_reg{nullptr}; 88 Register *m_sample_mask_reg{nullptr}; 89 Register *m_helper_invocation{nullptr}; 90 int m_nsys_inputs{0}; 91 bool m_apply_sample_mask{false}; 92 int m_rat_base{0}; 93 int m_pos_driver_loc{0}; 94 int m_face_driver_loc{0}; 95 int m_image_size_const_offset{0}; 96 }; 97 98 class FragmentShaderR600 : public FragmentShader { 99 public: 100 using FragmentShader::FragmentShader; 101 102 private: 103 int allocate_interpolators_or_inputs() override; 104 bool load_input_hw(nir_intrinsic_instr *intr) override; 105 bool process_stage_intrinsic_hw(nir_intrinsic_instr *intr) override; 106 bool load_interpolated_input_hw(nir_intrinsic_instr *intr) override; 107 108 IOMap<RegisterVec4> m_interpolated_inputs; 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, 139 const InterpolateParams& params, 140 int num_dest_comp, 141 int start_comp); 142 143 bool load_interpolated_one_comp(RegisterVec4& dest, 144 const InterpolateParams& params, 145 EAluOp op); 146 bool load_interpolated_two_comp(RegisterVec4& dest, 147 const InterpolateParams& params, 148 EAluOp op, 149 int writemask); 150 bool load_interpolated_two_comp_for_one(RegisterVec4& dest, 151 const InterpolateParams& params, 152 EAluOp op, 153 int dest_slot); 154 155 std::array<Interpolator, s_max_interpolators> m_interpolator; 156 }; 157 158 } // namespace r600 159 160 #endif 161