/*
 * Copyright © 2010 Intel Corporation
 *
 * 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
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS 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.
 *
 * Authors:
 *    Eric Anholt <eric@anholt.net>
 *
 */

#ifndef BRW_FS_H
#define BRW_FS_H

#include "brw_shader.h"
#include "brw_ir_fs.h"
#include "brw_fs_builder.h"
#include "brw_fs_live_variables.h"
#include "brw_ir_performance.h"
#include "compiler/nir/nir.h"

struct bblock_t;
namespace {
   struct acp_entry;
}

class fs_visitor;

namespace brw {
   /**
    * Register pressure analysis of a shader.  Estimates how many registers
    * are live at any point of the program in GRF units.
    */
   struct register_pressure {
      register_pressure(const fs_visitor *v);
      ~register_pressure();

      analysis_dependency_class
      dependency_class() const
      {
         return (DEPENDENCY_INSTRUCTION_IDENTITY |
                 DEPENDENCY_INSTRUCTION_DATA_FLOW |
                 DEPENDENCY_VARIABLES);
      }

      bool
      validate(const fs_visitor *) const
      {
         /* FINISHME */
         return true;
      }

      unsigned *regs_live_at_ip;
   };
}

struct brw_gs_compile;

static inline fs_reg
offset(const fs_reg &reg, const brw::fs_builder &bld, unsigned delta)
{
   return offset(reg, bld.dispatch_width(), delta);
}

#define UBO_START ((1 << 16) - 4)

struct shader_stats {
   const char *scheduler_mode;
   unsigned promoted_constants;
};

/**
 * The fragment shader front-end.
 *
 * Translates either GLSL IR or Mesa IR (for ARB_fragment_program) into FS IR.
 */
class fs_visitor : public backend_shader
{
public:
   fs_visitor(const struct brw_compiler *compiler, void *log_data,
              void *mem_ctx,
              const brw_base_prog_key *key,
              struct brw_stage_prog_data *prog_data,
              const nir_shader *shader,
              unsigned dispatch_width,
              int shader_time_index,
              const struct brw_vue_map *input_vue_map = NULL);
   fs_visitor(const struct brw_compiler *compiler, void *log_data,
              void *mem_ctx,
              struct brw_gs_compile *gs_compile,
              struct brw_gs_prog_data *prog_data,
              const nir_shader *shader,
              int shader_time_index);
   void init();
   ~fs_visitor();

   fs_reg vgrf(const glsl_type *const type);
   void import_uniforms(fs_visitor *v);

   void VARYING_PULL_CONSTANT_LOAD(const brw::fs_builder &bld,
                                   const fs_reg &dst,
                                   const fs_reg &surf_index,
                                   const fs_reg &varying_offset,
                                   uint32_t const_offset,
                                   uint8_t alignment);
   void DEP_RESOLVE_MOV(const brw::fs_builder &bld, int grf);

   bool run_fs(bool allow_spilling, bool do_rep_send);
   bool run_vs();
   bool run_tcs();
   bool run_tes();
   bool run_gs();
   bool run_cs(bool allow_spilling);
   void optimize();
   void allocate_registers(bool allow_spilling);
   void setup_fs_payload_gen4();
   void setup_fs_payload_gen6();
   void setup_vs_payload();
   void setup_gs_payload();
   void setup_cs_payload();
   bool fixup_sends_duplicate_payload();
   void fixup_3src_null_dest();
   bool fixup_nomask_control_flow();
   void assign_curb_setup();
   void assign_urb_setup();
   void convert_attr_sources_to_hw_regs(fs_inst *inst);
   void assign_vs_urb_setup();
   void assign_tcs_urb_setup();
   void assign_tes_urb_setup();
   void assign_gs_urb_setup();
   bool assign_regs(bool allow_spilling, bool spill_all);
   void assign_regs_trivial();
   void calculate_payload_ranges(int payload_node_count,
                                 int *payload_last_use_ip) const;
   void split_virtual_grfs();
   bool compact_virtual_grfs();
   void assign_constant_locations();
   bool get_pull_locs(const fs_reg &src, unsigned *out_surf_index,
                      unsigned *out_pull_index);
   void lower_constant_loads();
   virtual void invalidate_analysis(brw::analysis_dependency_class c);
   void validate();
   bool opt_algebraic();
   bool opt_redundant_discard_jumps();
   bool opt_cse();
   bool opt_cse_local(const brw::fs_live_variables &live, bblock_t *block, int &ip);

   bool opt_copy_propagation();
   bool try_copy_propagate(fs_inst *inst, int arg, acp_entry *entry);
   bool try_constant_propagate(fs_inst *inst, acp_entry *entry);
   bool opt_copy_propagation_local(void *mem_ctx, bblock_t *block,
                                   exec_list *acp);
   bool opt_drop_redundant_mov_to_flags();
   bool opt_register_renaming();
   bool opt_bank_conflicts();
   bool register_coalesce();
   bool compute_to_mrf();
   bool eliminate_find_live_channel();
   bool dead_code_eliminate();
   bool remove_duplicate_mrf_writes();
   bool remove_extra_rounding_modes();

   void schedule_instructions(instruction_scheduler_mode mode);
   void insert_gen4_send_dependency_workarounds();
   void insert_gen4_pre_send_dependency_workarounds(bblock_t *block,
                                                    fs_inst *inst);
   void insert_gen4_post_send_dependency_workarounds(bblock_t *block,
                                                     fs_inst *inst);
   void vfail(const char *msg, va_list args);
   void fail(const char *msg, ...);
   void limit_dispatch_width(unsigned n, const char *msg);
   void lower_uniform_pull_constant_loads();
   bool lower_load_payload();
   bool lower_pack();
   bool lower_regioning();
   bool lower_logical_sends();
   bool lower_integer_multiplication();
   bool lower_minmax();
   bool lower_simd_width();
   bool lower_barycentrics();
   bool lower_scoreboard();
   bool lower_sub_sat();
   bool opt_combine_constants();

   void emit_dummy_fs();
   void emit_repclear_shader();
   void emit_fragcoord_interpolation(fs_reg wpos);
   fs_reg *emit_frontfacing_interpolation();
   fs_reg *emit_samplepos_setup();
   fs_reg *emit_sampleid_setup();
   fs_reg *emit_samplemaskin_setup();
   void emit_interpolation_setup_gen4();
   void emit_interpolation_setup_gen6();
   void compute_sample_position(fs_reg dst, fs_reg int_sample_pos);
   fs_reg emit_mcs_fetch(const fs_reg &coordinate, unsigned components,
                         const fs_reg &texture,
                         const fs_reg &texture_handle);
   void emit_gen6_gather_wa(uint8_t wa, fs_reg dst);
   fs_reg resolve_source_modifiers(const fs_reg &src);
   void emit_discard_jump();
   void emit_fsign(const class brw::fs_builder &, const nir_alu_instr *instr,
                   fs_reg result, fs_reg *op, unsigned fsign_src);
   void emit_shader_float_controls_execution_mode();
   bool opt_peephole_sel();
   bool opt_peephole_predicated_break();
   bool opt_saturate_propagation();
   bool opt_cmod_propagation();
   bool opt_zero_samples();

   void set_tcs_invocation_id();

   void emit_nir_code();
   void nir_setup_outputs();
   void nir_setup_uniforms();
   void nir_emit_system_values();
   void nir_emit_impl(nir_function_impl *impl);
   void nir_emit_cf_list(exec_list *list);
   void nir_emit_if(nir_if *if_stmt);
   void nir_emit_loop(nir_loop *loop);
   void nir_emit_block(nir_block *block);
   void nir_emit_instr(nir_instr *instr);
   void nir_emit_alu(const brw::fs_builder &bld, nir_alu_instr *instr,
                     bool need_dest);
   bool try_emit_b2fi_of_inot(const brw::fs_builder &bld, fs_reg result,
                              nir_alu_instr *instr);
   void nir_emit_load_const(const brw::fs_builder &bld,
                            nir_load_const_instr *instr);
   void nir_emit_vs_intrinsic(const brw::fs_builder &bld,
                              nir_intrinsic_instr *instr);
   void nir_emit_tcs_intrinsic(const brw::fs_builder &bld,
                               nir_intrinsic_instr *instr);
   void nir_emit_gs_intrinsic(const brw::fs_builder &bld,
                              nir_intrinsic_instr *instr);
   void nir_emit_fs_intrinsic(const brw::fs_builder &bld,
                              nir_intrinsic_instr *instr);
   void nir_emit_cs_intrinsic(const brw::fs_builder &bld,
                              nir_intrinsic_instr *instr);
   fs_reg get_nir_image_intrinsic_image(const brw::fs_builder &bld,
                                        nir_intrinsic_instr *instr);
   fs_reg get_nir_ssbo_intrinsic_index(const brw::fs_builder &bld,
                                       nir_intrinsic_instr *instr);
   fs_reg swizzle_nir_scratch_addr(const brw::fs_builder &bld,
                                   const fs_reg &addr,
                                   bool in_dwords);
   void nir_emit_intrinsic(const brw::fs_builder &bld,
                           nir_intrinsic_instr *instr);
   void nir_emit_tes_intrinsic(const brw::fs_builder &bld,
                               nir_intrinsic_instr *instr);
   void nir_emit_ssbo_atomic(const brw::fs_builder &bld,
                             int op, nir_intrinsic_instr *instr);
   void nir_emit_ssbo_atomic_float(const brw::fs_builder &bld,
                                   int op, nir_intrinsic_instr *instr);
   void nir_emit_shared_atomic(const brw::fs_builder &bld,
                               int op, nir_intrinsic_instr *instr);
   void nir_emit_shared_atomic_float(const brw::fs_builder &bld,
                                     int op, nir_intrinsic_instr *instr);
   void nir_emit_global_atomic(const brw::fs_builder &bld,
                               int op, nir_intrinsic_instr *instr);
   void nir_emit_global_atomic_float(const brw::fs_builder &bld,
                                     int op, nir_intrinsic_instr *instr);
   void nir_emit_texture(const brw::fs_builder &bld,
                         nir_tex_instr *instr);
   void nir_emit_jump(const brw::fs_builder &bld,
                      nir_jump_instr *instr);
   fs_reg get_nir_src(const nir_src &src);
   fs_reg get_nir_src_imm(const nir_src &src);
   fs_reg get_nir_dest(const nir_dest &dest);
   fs_reg get_indirect_offset(nir_intrinsic_instr *instr);
   fs_reg get_tcs_single_patch_icp_handle(const brw::fs_builder &bld,
                                          nir_intrinsic_instr *instr);
   fs_reg get_tcs_eight_patch_icp_handle(const brw::fs_builder &bld,
                                         nir_intrinsic_instr *instr);
   struct brw_reg get_tcs_output_urb_handle();

   void emit_percomp(const brw::fs_builder &bld, const fs_inst &inst,
                     unsigned wr_mask);

   bool optimize_extract_to_float(nir_alu_instr *instr,
                                  const fs_reg &result);
   bool optimize_frontfacing_ternary(nir_alu_instr *instr,
                                     const fs_reg &result);

   void emit_alpha_test();
   fs_inst *emit_single_fb_write(const brw::fs_builder &bld,
                                 fs_reg color1, fs_reg color2,
                                 fs_reg src0_alpha, unsigned components);
   void emit_alpha_to_coverage_workaround(const fs_reg &src0_alpha);
   void emit_fb_writes();
   fs_inst *emit_non_coherent_fb_read(const brw::fs_builder &bld,
                                      const fs_reg &dst, unsigned target);
   void emit_urb_writes(const fs_reg &gs_vertex_count = fs_reg());
   void set_gs_stream_control_data_bits(const fs_reg &vertex_count,
                                        unsigned stream_id);
   void emit_gs_control_data_bits(const fs_reg &vertex_count);
   void emit_gs_end_primitive(const nir_src &vertex_count_nir_src);
   void emit_gs_vertex(const nir_src &vertex_count_nir_src,
                       unsigned stream_id);
   void emit_gs_thread_end();
   void emit_gs_input_load(const fs_reg &dst, const nir_src &vertex_src,
                           unsigned base_offset, const nir_src &offset_src,
                           unsigned num_components, unsigned first_component);
   void emit_cs_terminate();
   fs_reg *emit_cs_work_group_id_setup();

   void emit_barrier();

   void emit_shader_time_begin();
   void emit_shader_time_end();
   void SHADER_TIME_ADD(const brw::fs_builder &bld,
                        int shader_time_subindex,
                        fs_reg value);

   fs_reg get_timestamp(const brw::fs_builder &bld);

   fs_reg interp_reg(int location, int channel);

   virtual void dump_instructions() const;
   virtual void dump_instructions(const char *name) const;
   void dump_instruction(const backend_instruction *inst) const;
   void dump_instruction(const backend_instruction *inst, FILE *file) const;

   const brw_base_prog_key *const key;
   const struct brw_sampler_prog_key_data *key_tex;

   struct brw_gs_compile *gs_compile;

   struct brw_stage_prog_data *prog_data;

   const struct brw_vue_map *input_vue_map;

   BRW_ANALYSIS(live_analysis, brw::fs_live_variables,
                backend_shader *) live_analysis;
   BRW_ANALYSIS(regpressure_analysis, brw::register_pressure,
                fs_visitor *) regpressure_analysis;
   BRW_ANALYSIS(performance_analysis, brw::performance,
                fs_visitor *) performance_analysis;

   /** Number of uniform variable components visited. */
   unsigned uniforms;

   /** Byte-offset for the next available spot in the scratch space buffer. */
   unsigned last_scratch;

   /**
    * Array mapping UNIFORM register numbers to the pull parameter index,
    * or -1 if this uniform register isn't being uploaded as a pull constant.
    */
   int *pull_constant_loc;

   /**
    * Array mapping UNIFORM register numbers to the push parameter index,
    * or -1 if this uniform register isn't being uploaded as a push constant.
    */
   int *push_constant_loc;

   fs_reg subgroup_id;
   fs_reg group_size[3];
   fs_reg scratch_base;
   fs_reg frag_depth;
   fs_reg frag_stencil;
   fs_reg sample_mask;
   fs_reg outputs[VARYING_SLOT_MAX];
   fs_reg dual_src_output;
   int first_non_payload_grf;
   /** Either BRW_MAX_GRF or GEN7_MRF_HACK_START */
   unsigned max_grf;

   fs_reg *nir_locals;
   fs_reg *nir_ssa_values;
   fs_reg *nir_system_values;

   bool failed;
   char *fail_msg;

   /** Register numbers for thread payload fields. */
   struct thread_payload {
      uint8_t subspan_coord_reg[2];
      uint8_t source_depth_reg[2];
      uint8_t source_w_reg[2];
      uint8_t aa_dest_stencil_reg[2];
      uint8_t dest_depth_reg[2];
      uint8_t sample_pos_reg[2];
      uint8_t sample_mask_in_reg[2];
      uint8_t barycentric_coord_reg[BRW_BARYCENTRIC_MODE_COUNT][2];
      uint8_t local_invocation_id_reg[2];

      /** The number of thread payload registers the hardware will supply. */
      uint8_t num_regs;
   } payload;

   bool source_depth_to_render_target;
   bool runtime_check_aads_emit;

   fs_reg pixel_x;
   fs_reg pixel_y;
   fs_reg wpos_w;
   fs_reg pixel_w;
   fs_reg delta_xy[BRW_BARYCENTRIC_MODE_COUNT];
   fs_reg shader_start_time;
   fs_reg final_gs_vertex_count;
   fs_reg control_data_bits;
   fs_reg invocation_id;

   unsigned grf_used;
   bool spilled_any_registers;

   const unsigned dispatch_width; /**< 8, 16 or 32 */
   unsigned max_dispatch_width;

   int shader_time_index;

   struct shader_stats shader_stats;

   brw::fs_builder bld;

private:
   fs_reg prepare_alu_destination_and_sources(const brw::fs_builder &bld,
                                              nir_alu_instr *instr,
                                              fs_reg *op,
                                              bool need_dest);

   void resolve_inot_sources(const brw::fs_builder &bld, nir_alu_instr *instr,
                             fs_reg *op);
   void lower_mul_dword_inst(fs_inst *inst, bblock_t *block);
   void lower_mul_qword_inst(fs_inst *inst, bblock_t *block);
   void lower_mulh_inst(fs_inst *inst, bblock_t *block);

   unsigned workgroup_size() const;
};

/**
 * Return the flag register used in fragment shaders to keep track of live
 * samples.  On Gen7+ we use f1.0-f1.1 to allow discard jumps in SIMD32
 * dispatch mode, while earlier generations are constrained to f0.1, which
 * limits the dispatch width to SIMD16 for fragment shaders that use discard.
 */
static inline unsigned
sample_mask_flag_subreg(const fs_visitor *shader)
{
   assert(shader->stage == MESA_SHADER_FRAGMENT);
   return shader->devinfo->gen >= 7 ? 2 : 1;
}

/**
 * The fragment shader code generator.
 *
 * Translates FS IR to actual i965 assembly code.
 */
class fs_generator
{
public:
   fs_generator(const struct brw_compiler *compiler, void *log_data,
                void *mem_ctx,
                struct brw_stage_prog_data *prog_data,
                bool runtime_check_aads_emit,
                gl_shader_stage stage);
   ~fs_generator();

   void enable_debug(const char *shader_name);
   int generate_code(const cfg_t *cfg, int dispatch_width,
                     struct shader_stats shader_stats,
                     const brw::performance &perf,
                     struct brw_compile_stats *stats);
   void add_const_data(void *data, unsigned size);
   const unsigned *get_assembly();

private:
   void fire_fb_write(fs_inst *inst,
                      struct brw_reg payload,
                      struct brw_reg implied_header,
                      GLuint nr);
   void generate_send(fs_inst *inst,
                      struct brw_reg dst,
                      struct brw_reg desc,
                      struct brw_reg ex_desc,
                      struct brw_reg payload,
                      struct brw_reg payload2);
   void generate_fb_write(fs_inst *inst, struct brw_reg payload);
   void generate_fb_read(fs_inst *inst, struct brw_reg dst,
                         struct brw_reg payload);
   void generate_urb_read(fs_inst *inst, struct brw_reg dst, struct brw_reg payload);
   void generate_urb_write(fs_inst *inst, struct brw_reg payload);
   void generate_cs_terminate(fs_inst *inst, struct brw_reg payload);
   void generate_barrier(fs_inst *inst, struct brw_reg src);
   bool generate_linterp(fs_inst *inst, struct brw_reg dst,
			 struct brw_reg *src);
   void generate_tex(fs_inst *inst, struct brw_reg dst,
                     struct brw_reg surface_index,
                     struct brw_reg sampler_index);
   void generate_get_buffer_size(fs_inst *inst, struct brw_reg dst,
                                 struct brw_reg src,
                                 struct brw_reg surf_index);
   void generate_ddx(const fs_inst *inst,
                     struct brw_reg dst, struct brw_reg src);
   void generate_ddy(const fs_inst *inst,
                     struct brw_reg dst, struct brw_reg src);
   void generate_scratch_write(fs_inst *inst, struct brw_reg src);
   void generate_scratch_read(fs_inst *inst, struct brw_reg dst);
   void generate_scratch_read_gen7(fs_inst *inst, struct brw_reg dst);
   void generate_uniform_pull_constant_load(fs_inst *inst, struct brw_reg dst,
                                            struct brw_reg index,
                                            struct brw_reg offset);
   void generate_uniform_pull_constant_load_gen7(fs_inst *inst,
                                                 struct brw_reg dst,
                                                 struct brw_reg surf_index,
                                                 struct brw_reg payload);
   void generate_varying_pull_constant_load_gen4(fs_inst *inst,
                                                 struct brw_reg dst,
                                                 struct brw_reg index);
   void generate_mov_dispatch_to_flags(fs_inst *inst);

   void generate_pixel_interpolator_query(fs_inst *inst,
                                          struct brw_reg dst,
                                          struct brw_reg src,
                                          struct brw_reg msg_data,
                                          unsigned msg_type);

   void generate_set_sample_id(fs_inst *inst,
                               struct brw_reg dst,
                               struct brw_reg src0,
                               struct brw_reg src1);

   void generate_discard_jump(fs_inst *inst);

   void generate_pack_half_2x16_split(fs_inst *inst,
                                      struct brw_reg dst,
                                      struct brw_reg x,
                                      struct brw_reg y);

   void generate_shader_time_add(fs_inst *inst,
                                 struct brw_reg payload,
                                 struct brw_reg offset,
                                 struct brw_reg value);

   void generate_mov_indirect(fs_inst *inst,
                              struct brw_reg dst,
                              struct brw_reg reg,
                              struct brw_reg indirect_byte_offset);

   void generate_shuffle(fs_inst *inst,
                         struct brw_reg dst,
                         struct brw_reg src,
                         struct brw_reg idx);

   void generate_quad_swizzle(const fs_inst *inst,
                              struct brw_reg dst, struct brw_reg src,
                              unsigned swiz);

   bool patch_discard_jumps_to_fb_writes();

   const struct brw_compiler *compiler;
   void *log_data; /* Passed to compiler->*_log functions */

   const struct gen_device_info *devinfo;

   struct brw_codegen *p;
   struct brw_stage_prog_data * const prog_data;

   unsigned dispatch_width; /**< 8, 16 or 32 */

   exec_list discard_halt_patches;
   bool runtime_check_aads_emit;
   bool debug_flag;
   const char *shader_name;
   gl_shader_stage stage;
   void *mem_ctx;
};

namespace brw {
   inline fs_reg
   fetch_payload_reg(const brw::fs_builder &bld, uint8_t regs[2],
                     brw_reg_type type = BRW_REGISTER_TYPE_F)
   {
      if (!regs[0])
         return fs_reg();

      if (bld.dispatch_width() > 16) {
         const fs_reg tmp = bld.vgrf(type);
         const brw::fs_builder hbld = bld.exec_all().group(16, 0);
         const unsigned m = bld.dispatch_width() / hbld.dispatch_width();
         fs_reg *const components = new fs_reg[m];

         for (unsigned g = 0; g < m; g++)
               components[g] = retype(brw_vec8_grf(regs[g], 0), type);

         hbld.LOAD_PAYLOAD(tmp, components, m, 0);

         delete[] components;
         return tmp;

      } else {
         return fs_reg(retype(brw_vec8_grf(regs[0], 0), type));
      }
   }

   inline fs_reg
   fetch_barycentric_reg(const brw::fs_builder &bld, uint8_t regs[2])
   {
      if (!regs[0])
         return fs_reg();

      const fs_reg tmp = bld.vgrf(BRW_REGISTER_TYPE_F, 2);
      const brw::fs_builder hbld = bld.exec_all().group(8, 0);
      const unsigned m = bld.dispatch_width() / hbld.dispatch_width();
      fs_reg *const components = new fs_reg[2 * m];

      for (unsigned c = 0; c < 2; c++) {
         for (unsigned g = 0; g < m; g++)
            components[c * m + g] = offset(brw_vec8_grf(regs[g / 2], 0),
                                           hbld, c + 2 * (g % 2));
      }

      hbld.LOAD_PAYLOAD(tmp, components, 2 * m, 0);

      delete[] components;
      return tmp;
   }

   bool
   lower_src_modifiers(fs_visitor *v, bblock_t *block, fs_inst *inst, unsigned i);
}

void shuffle_from_32bit_read(const brw::fs_builder &bld,
                             const fs_reg &dst,
                             const fs_reg &src,
                             uint32_t first_component,
                             uint32_t components);

fs_reg setup_imm_df(const brw::fs_builder &bld,
                    double v);

fs_reg setup_imm_b(const brw::fs_builder &bld,
                   int8_t v);

fs_reg setup_imm_ub(const brw::fs_builder &bld,
                   uint8_t v);

enum brw_barycentric_mode brw_barycentric_mode(enum glsl_interp_mode mode,
                                               nir_intrinsic_op op);

uint32_t brw_fb_write_msg_control(const fs_inst *inst,
                                  const struct brw_wm_prog_data *prog_data);

void brw_compute_urb_setup_index(struct brw_wm_prog_data *wm_prog_data);

#endif /* BRW_FS_H */
