i965: Add non-mutating helper functions to modify the register offset.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_fs.h
index 6ed16f6bc02502a5a083f2cce30fd10a0c8acec7..ce5050bd41aac2848482e3c7a8ce51ae324e98e7 100644 (file)
@@ -82,7 +82,9 @@ public:
    bool is_one() const;
    bool is_null() const;
    bool is_valid_3src() const;
+   bool is_contiguous() const;
    fs_reg retype(uint32_t type);
+   fs_reg &apply_stride(unsigned stride);
 
    /** Register file: GRF, MRF, IMM. */
    enum register_file file;
@@ -103,9 +105,10 @@ public:
    int type;
    bool negate;
    bool abs;
-   bool sechalf;
    struct brw_reg fixed_hw_reg;
-   int smear; /* -1, or a channel of the reg to smear to all channels. */
+
+   /** Smear a channel of the reg to all channels. */
+   fs_reg &set_smear(unsigned subreg);
 
    /** Value for file == IMM */
    union {
@@ -114,9 +117,47 @@ public:
       float f;
    } imm;
 
+   /**
+    * Offset in bytes from the start of the register.  Values up to a
+    * backend_reg::reg_offset unit are valid.
+    */
+   int subreg_offset;
+
+   /** Register region horizontal stride */
+   int stride;
+
    fs_reg *reladdr;
 };
 
+static inline fs_reg
+offset(fs_reg reg, unsigned delta)
+{
+   assert(delta == 0 || (reg.file != HW_REG && reg.file != IMM));
+   reg.reg_offset += delta;
+   return reg;
+}
+
+static inline fs_reg
+byte_offset(fs_reg reg, unsigned delta)
+{
+   assert(delta == 0 || (reg.file != HW_REG && reg.file != IMM));
+   reg.subreg_offset += delta;
+   return reg;
+}
+
+/**
+ * Get either of the 8-component halves of a 16-component register.
+ *
+ * Note: this also works if \c reg represents a SIMD16 pair of registers.
+ */
+static inline fs_reg
+half(const fs_reg &reg, unsigned idx)
+{
+   assert(idx < 2);
+   assert(idx == 0 || (reg.file != HW_REG && reg.file != IMM));
+   return byte_offset(reg, 8 * idx * reg.stride * type_sz(reg.type));
+}
+
 static const fs_reg reg_undef;
 static const fs_reg reg_null_f(retype(brw_null_reg(), BRW_REGISTER_TYPE_F));
 static const fs_reg reg_null_d(retype(brw_null_reg(), BRW_REGISTER_TYPE_D));
@@ -310,6 +351,7 @@ public:
    void setup_pull_constants();
    void invalidate_live_intervals();
    void calculate_live_intervals();
+   void calculate_register_pressure();
    bool opt_algebraic();
    bool opt_cse();
    bool opt_cse_local(bblock_t *block, exec_list *aeb);
@@ -339,7 +381,7 @@ public:
    fs_reg *emit_fragcoord_interpolation(ir_variable *ir);
    fs_inst *emit_linterp(const fs_reg &attr, const fs_reg &interp,
                          glsl_interp_qualifier interpolation_mode,
-                         bool is_centroid);
+                         bool is_centroid, bool is_sample);
    fs_reg *emit_frontfacing_interpolation(ir_variable *ir);
    fs_reg *emit_samplepos_setup(ir_variable *ir);
    fs_reg *emit_sampleid_setup(ir_variable *ir);
@@ -357,8 +399,9 @@ public:
                               fs_reg sample_index);
    fs_inst *emit_texture_gen7(ir_texture *ir, fs_reg dst, fs_reg coordinate,
                               fs_reg shadow_comp, fs_reg lod, fs_reg lod2,
-                              fs_reg sample_index, fs_reg mcs);
+                              fs_reg sample_index, fs_reg mcs, int sampler);
    fs_reg emit_mcs_fetch(ir_texture *ir, fs_reg coordinate, int sampler);
+   void emit_gen6_gather_wa(uint8_t wa, fs_reg dst);
    fs_reg fix_math_operand(fs_reg src);
    fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0);
    fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0, fs_reg src1);
@@ -370,6 +413,7 @@ public:
    void try_replace_with_sel();
    bool opt_peephole_sel();
    bool opt_peephole_predicated_break();
+   bool opt_saturate_propagation();
    void emit_bool_to_cond_code(ir_rvalue *condition);
    void emit_if_gen6(ir_if *ir);
    void emit_unspill(fs_inst *inst, fs_reg reg, uint32_t spill_offset,
@@ -431,6 +475,7 @@ public:
    void setup_builtin_uniform_values(ir_variable *ir);
    int implied_mrf_writes(fs_inst *inst);
 
+   virtual void dump_instructions();
    void dump_instruction(backend_instruction *inst);
 
    void visit_atomic_counter_intrinsic(ir_call *ir);
@@ -448,6 +493,8 @@ public:
    int *virtual_grf_end;
    brw::fs_live_variables *live_intervals;
 
+   int *regs_live_at_ip;
+
    /* This is the map from UNIFORM hw_reg + reg_offset as generated by
     * the visitor to the packed uniform number after
     * remove_dead_constants() that represents the actual uploaded
@@ -513,11 +560,13 @@ public:
 
    const unsigned *generate_assembly(exec_list *simd8_instructions,
                                      exec_list *simd16_instructions,
-                                     unsigned *assembly_size);
+                                     unsigned *assembly_size,
+                                     FILE *dump_file = NULL);
 
 private:
-   void generate_code(exec_list *instructions);
+   void generate_code(exec_list *instructions, FILE *dump_file);
    void generate_fb_write(fs_inst *inst);
+   void generate_blorp_fb_write(fs_inst *inst);
    void generate_pixel_xy(struct brw_reg dst, bool is_x);
    void generate_linterp(fs_inst *inst, struct brw_reg dst,
                         struct brw_reg *src);
@@ -600,8 +649,6 @@ private:
                                       struct brw_reg dst,
                                       struct brw_reg surf_index);
 
-   void mark_surface_used(unsigned surf_index);
-
    void patch_discard_jumps_to_fb_writes();
 
    struct brw_context *brw;
@@ -611,7 +658,6 @@ private:
    struct brw_wm_compile *c;
 
    struct gl_shader_program *prog;
-   struct gl_shader *shader;
    const struct gl_fragment_program *fp;
 
    unsigned dispatch_width; /**< 8 or 16 */