X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fbrw_fs.h;h=608262fd24640c86417e86e0efb8ffe98c241966;hb=8a0946f3b1522e5f91afe14c8c3b22ba6009ed04;hp=25197cd6ba718f09376903f10ea2d344a83d4888;hpb=112d738b91aac44c2509aafe68bdbf9ab74bb3c1;p=mesa.git diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 25197cd6ba7..608262fd246 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -28,6 +28,7 @@ #pragma once #include "brw_shader.h" +#include "brw_ir_fs.h" extern "C" { @@ -44,7 +45,6 @@ extern "C" { #include "brw_context.h" #include "brw_eu.h" #include "brw_wm.h" -#include "brw_shader.h" #include "intel_asm_annotation.h" } #include "glsl/glsl_types.h" @@ -52,9 +52,6 @@ extern "C" { #include "glsl/nir/nir.h" #include "program/sampler.h" -#define MAX_SAMPLER_MESSAGE_SIZE 11 -#define MAX_VGRF_SIZE 16 - struct bblock_t; namespace { struct acp_entry; @@ -64,231 +61,6 @@ namespace brw { class fs_live_variables; } -class fs_inst; -class fs_visitor; - -class fs_reg : public backend_reg { -public: - DECLARE_RALLOC_CXX_OPERATORS(fs_reg) - - void init(); - - fs_reg(); - explicit fs_reg(float f); - explicit fs_reg(int32_t i); - explicit fs_reg(uint32_t u); - explicit fs_reg(uint8_t vf[4]); - explicit fs_reg(uint8_t vf0, uint8_t vf1, uint8_t vf2, uint8_t vf3); - fs_reg(struct brw_reg fixed_hw_reg); - fs_reg(enum register_file file, int reg); - fs_reg(enum register_file file, int reg, enum brw_reg_type type); - fs_reg(enum register_file file, int reg, enum brw_reg_type type, uint8_t width); - - bool equals(const fs_reg &r) const; - bool is_contiguous() const; - - /** Smear a channel of the reg to all channels. */ - fs_reg &set_smear(unsigned subreg); - - /** - * Offset in bytes from the start of the register. Values up to a - * backend_reg::reg_offset unit are valid. - */ - int subreg_offset; - - fs_reg *reladdr; - - /** - * The register width. This indicates how many hardware values are - * represented by each virtual value. Valid values are 1, 8, or 16. - * For immediate values, this is 1. Most of the rest of the time, it - * will be equal to the dispatch width. - */ - uint8_t width; - - /** - * Returns the effective register width when used as a source in the - * given instruction. Registers such as uniforms and immediates - * effectively take on the width of the instruction in which they are - * used. - */ - uint8_t effective_width; - - /** Register region horizontal stride */ - uint8_t stride; -}; - -static inline fs_reg -negate(fs_reg reg) -{ - assert(reg.file != HW_REG && reg.file != IMM); - reg.negate = !reg.negate; - return reg; -} - -static inline fs_reg -retype(fs_reg reg, enum brw_reg_type type) -{ - reg.fixed_hw_reg.type = reg.type = type; - return reg; -} - -static inline fs_reg -byte_offset(fs_reg reg, unsigned delta) -{ - switch (reg.file) { - case BAD_FILE: - break; - case GRF: - case ATTR: - reg.reg_offset += delta / 32; - break; - case MRF: - reg.reg += delta / 32; - break; - default: - assert(delta == 0); - } - reg.subreg_offset += delta % 32; - return reg; -} - -static inline fs_reg -horiz_offset(fs_reg reg, unsigned delta) -{ - switch (reg.file) { - case BAD_FILE: - case UNIFORM: - case IMM: - /* These only have a single component that is implicitly splatted. A - * horizontal offset should be a harmless no-op. - */ - break; - case GRF: - case MRF: - case ATTR: - return byte_offset(reg, delta * reg.stride * type_sz(reg.type)); - default: - assert(delta == 0); - } - return reg; -} - -static inline fs_reg -offset(fs_reg reg, unsigned delta) -{ - assert(reg.stride > 0); - switch (reg.file) { - case BAD_FILE: - break; - case GRF: - case MRF: - case ATTR: - return byte_offset(reg, delta * reg.width * reg.stride * type_sz(reg.type)); - case UNIFORM: - reg.reg_offset += delta; - break; - default: - assert(delta == 0); - } - return reg; -} - -static inline fs_reg -component(fs_reg reg, unsigned idx) -{ - assert(reg.subreg_offset == 0); - assert(idx < reg.width); - reg.subreg_offset = idx * type_sz(reg.type); - reg.width = 1; - 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(fs_reg reg, unsigned idx) -{ - assert(idx < 2); - - if (reg.file == UNIFORM) - return reg; - - assert(idx == 0 || (reg.file != HW_REG && reg.file != IMM)); - assert(reg.width == 16); - reg.width = 8; - return horiz_offset(reg, 8 * idx); -} - -static const fs_reg reg_undef; - -class fs_inst : public backend_instruction { - fs_inst &operator=(const fs_inst &); - - void init(enum opcode opcode, uint8_t exec_width, const fs_reg &dst, - fs_reg *src, int sources); - -public: - DECLARE_RALLOC_CXX_OPERATORS(fs_inst) - - fs_inst(); - fs_inst(enum opcode opcode, uint8_t exec_size); - fs_inst(enum opcode opcode, const fs_reg &dst); - fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst, - const fs_reg &src0); - fs_inst(enum opcode opcode, const fs_reg &dst, const fs_reg &src0); - fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst, - const fs_reg &src0, const fs_reg &src1); - fs_inst(enum opcode opcode, const fs_reg &dst, const fs_reg &src0, - const fs_reg &src1); - fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst, - const fs_reg &src0, const fs_reg &src1, const fs_reg &src2); - fs_inst(enum opcode opcode, const fs_reg &dst, const fs_reg &src0, - const fs_reg &src1, const fs_reg &src2); - fs_inst(enum opcode opcode, const fs_reg &dst, fs_reg src[], int sources); - fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst, - fs_reg src[], int sources); - fs_inst(const fs_inst &that); - - void resize_sources(uint8_t num_sources); - - bool equals(fs_inst *inst) const; - bool overwrites_reg(const fs_reg ®) const; - bool is_send_from_grf() const; - bool is_partial_write() const; - int regs_read(fs_visitor *v, int arg) const; - bool can_do_source_mods(struct brw_context *brw); - - bool reads_flag() const; - bool writes_flag() const; - - fs_reg dst; - fs_reg *src; - - uint8_t sources; /**< Number of fs_reg sources. */ - - /** - * Execution size of the instruction. This is used by the generator to - * generate the correct binary for the given fs_inst. Current valid - * values are 1, 8, 16. - */ - uint8_t exec_size; - - /* Chooses which flag subregister (f0.0 or f0.1) is used for conditional - * mod and predication. - */ - uint8_t flag_subreg; - - uint8_t regs_written; /**< Number of vgrfs written by a SEND message, or 1 */ - bool eot:1; - bool force_uncompressed:1; - bool force_sechalf:1; - bool pi_noperspective:1; /**< Pixel interpolator noperspective flag */ -}; - /** * The fragment shader front-end. * @@ -321,7 +93,6 @@ public: void init(); fs_reg *variable_storage(ir_variable *var); - int virtual_grf_alloc(int size); fs_reg vgrf(const glsl_type *const type); fs_reg vgrf(int num_components); void import_uniforms(fs_visitor *v); @@ -447,6 +218,7 @@ public: void calculate_live_intervals(); void calculate_register_pressure(); bool opt_algebraic(); + bool opt_redundant_discard_jumps(); bool opt_cse(); bool opt_cse_local(bblock_t *block); bool opt_copy_propagate(); @@ -471,6 +243,7 @@ public: void no16(const char *msg, ...); void lower_uniform_pull_constant_loads(); bool lower_load_payload(); + bool opt_combine_constants(); void emit_dummy_fs(); void emit_repclear_shader(); @@ -487,7 +260,7 @@ public: glsl_interp_qualifier interpolation_mode, int location, bool mod_centroid, bool mod_sample); - fs_reg *emit_vs_system_value(enum brw_reg_type type, int location); + fs_reg *emit_vs_system_value(int location); void emit_interpolation_setup_gen4(); void emit_interpolation_setup_gen6(); void compute_sample_position(fs_reg dst, fs_reg int_sample_pos); @@ -516,7 +289,7 @@ public: fs_reg shadow_c, fs_reg lod, fs_reg dpdy, int grad_components, fs_reg sample_index, - fs_reg offset, unsigned offset_components, + fs_reg offset, fs_reg mcs, int gather_component, bool is_cube_array, @@ -526,6 +299,7 @@ public: int texunit); fs_reg emit_mcs_fetch(fs_reg coordinate, int components, fs_reg sampler); void emit_gen6_gather_wa(uint8_t wa, fs_reg dst); + void resolve_source_modifiers(fs_reg *src); 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); @@ -533,15 +307,19 @@ public: const fs_reg &a); void emit_minmax(enum brw_conditional_mod conditionalmod, const fs_reg &dst, const fs_reg &src0, const fs_reg &src1); + void emit_discard_jump(); + bool try_emit_b2f_of_comparison(ir_expression *ir); bool try_emit_saturate(ir_expression *ir); bool try_emit_line(ir_expression *ir); bool try_emit_mad(ir_expression *ir); bool try_replace_with_sel(); + bool try_opt_frontfacing_ternary(ir_if *ir); bool opt_peephole_sel(); bool opt_peephole_predicated_break(); bool opt_saturate_propagation(); bool opt_cmod_propagation(); void emit_bool_to_cond_code(ir_rvalue *condition); + void emit_bool_to_cond_code_of_reg(ir_expression *expr, fs_reg op[3]); void emit_if_gen6(ir_if *ir); void emit_unspill(bblock_t *block, fs_inst *inst, fs_reg reg, uint32_t spill_offset, int count); @@ -589,21 +367,24 @@ public: void nir_emit_texture(nir_tex_instr *instr); void nir_emit_jump(nir_jump_instr *instr); fs_reg get_nir_src(nir_src src); - fs_reg get_nir_alu_src(nir_alu_instr *instr, unsigned src); fs_reg get_nir_dest(nir_dest dest); void emit_percomp(fs_inst *inst, unsigned wr_mask); - int setup_color_payload(fs_reg *dst, fs_reg color, unsigned components); + bool optimize_frontfacing_ternary(nir_alu_instr *instr, + const fs_reg &result); + + int setup_color_payload(fs_reg *dst, fs_reg color, unsigned components, + bool use_2nd_half); void emit_alpha_test(); fs_inst *emit_single_fb_write(fs_reg color1, fs_reg color2, - fs_reg src0_alpha, unsigned components); + fs_reg src0_alpha, unsigned components, + bool use_2nd_half = false); void emit_fb_writes(); void emit_urb_writes(); void emit_shader_time_begin(); void emit_shader_time_end(); - void emit_shader_time_write(enum shader_time_shader_type type, - fs_reg value); + fs_inst *SHADER_TIME_ADD(enum shader_time_shader_type type, fs_reg value); void emit_untyped_atomic(unsigned atomic_op, unsigned surf_index, fs_reg dst, fs_reg offset, fs_reg src0, @@ -624,7 +405,7 @@ public: void resolve_ud_negate(fs_reg *reg); void resolve_bool_comparison(ir_rvalue *rvalue, fs_reg *reg); - fs_reg get_timestamp(); + fs_reg get_timestamp(fs_inst **out_mov); struct brw_reg interp_reg(int location, int channel); void setup_uniform_values(ir_variable *ir); @@ -639,14 +420,13 @@ public: void visit_atomic_counter_intrinsic(ir_call *ir); const void *const key; + const struct brw_sampler_prog_key_data *key_tex; + struct brw_stage_prog_data *prog_data; unsigned int sanity_param_count; int *param_size; - int *virtual_grf_sizes; - int virtual_grf_count; - int virtual_grf_array_size; int *virtual_grf_start; int *virtual_grf_end; brw::fs_live_variables *live_intervals; @@ -656,6 +436,9 @@ public: /** Number of uniform variable components visited. */ unsigned uniforms; + /** Total number of direct uniforms we can get from NIR */ + unsigned num_direct_uniforms; + /** Byte-offset for the next available spot in the scratch space buffer. */ unsigned last_scratch; @@ -680,7 +463,7 @@ public: bool do_dual_src; int first_non_payload_grf; /** Either BRW_MAX_GRF or GEN7_MRF_HACK_START */ - int max_grf; + unsigned max_grf; fs_reg *fp_temp_regs; fs_reg *fp_input_regs; @@ -689,7 +472,6 @@ public: fs_reg *nir_globals; fs_reg nir_inputs; fs_reg nir_outputs; - fs_reg nir_uniforms; fs_reg *nir_system_values; /** @{ debug annotation info */ @@ -731,10 +513,12 @@ public: fs_reg shader_start_time; fs_reg userplane[MAX_CLIP_PLANES]; - int grf_used; + unsigned grf_used; bool spilled_any_registers; const unsigned dispatch_width; /**< 8 or 16 */ + + unsigned promoted_constants; }; /** @@ -750,6 +534,7 @@ public: const void *key, struct brw_stage_prog_data *prog_data, struct gl_program *fp, + unsigned promoted_constants, bool runtime_check_aads_emit, const char *stage_abbrev); ~fs_generator(); @@ -861,6 +646,7 @@ private: unsigned dispatch_width; /**< 8 or 16 */ exec_list discard_halt_patches; + unsigned promoted_constants; bool runtime_check_aads_emit; bool debug_flag; const char *shader_name;