X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fbrw_fs.h;h=ee612079f2a8860e18b8fbb52219e69d1470d301;hb=b55777f39d00a0c54023eba012d326ff09fa530b;hp=02311a6e5150c411eb20f1ea9faaa6cc431dd1cd;hpb=6e61892aea542593875ebb8ae209af18bbad84bd;p=mesa.git diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h index 02311a6e515..ee612079f2a 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.h +++ b/src/mesa/drivers/dri/i965/brw_fs.h @@ -39,22 +39,22 @@ extern "C" { #include "program/prog_parameter.h" #include "program/prog_print.h" #include "program/prog_optimize.h" -#include "program/register_allocate.h" +#include "util/register_allocate.h" #include "program/sampler.h" #include "program/hash_table.h" #include "brw_context.h" #include "brw_eu.h" #include "brw_wm.h" #include "brw_shader.h" -#include "intel_asm_printer.h" +#include "intel_asm_annotation.h" } -#include "gen8_generator.h" #include "glsl/glsl_types.h" #include "glsl/ir.h" #define MAX_SAMPLER_MESSAGE_SIZE 11 +#define MAX_VGRF_SIZE 16 -class bblock_t; +struct bblock_t; namespace { struct acp_entry; } @@ -63,94 +63,131 @@ namespace brw { class fs_live_variables; } -class fs_reg { +class fs_inst; +class fs_visitor; + +class fs_reg : public backend_reg { public: DECLARE_RALLOC_CXX_OPERATORS(fs_reg) void init(); fs_reg(); - fs_reg(float f); - fs_reg(int32_t i); - fs_reg(uint32_t u); + explicit fs_reg(float f); + explicit fs_reg(int32_t i); + explicit fs_reg(uint32_t u); fs_reg(struct brw_reg fixed_hw_reg); fs_reg(enum register_file file, int reg); - fs_reg(enum register_file file, int reg, uint32_t type); - fs_reg(class fs_visitor *v, const struct glsl_type *type); + 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); + fs_reg(fs_visitor *v, const struct glsl_type *type); bool equals(const fs_reg &r) const; - bool is_zero() const; - bool is_one() const; - bool is_null() const; - bool is_valid_3src() const; bool is_contiguous() const; - bool is_accumulator() const; - fs_reg &apply_stride(unsigned stride); /** Smear a channel of the reg to all channels. */ fs_reg &set_smear(unsigned subreg); - /** Register file: GRF, MRF, IMM. */ - enum register_file file; - /** Register type. BRW_REGISTER_TYPE_* */ - uint8_t type; - /** - * Register number. For MRF, it's the hardware register. For - * GRF, it's a virtual register number until register allocation - */ - uint16_t reg; - /** - * Offset from the start of the contiguous register block. - * - * For pre-register-allocation GRFs, this is in units of a float per pixel - * (1 hardware register for SIMD8 mode, or 2 registers for SIMD16 mode). - * For uniforms, this is in units of 1 float. - */ - int reg_offset; /** * Offset in bytes from the start of the register. Values up to a * backend_reg::reg_offset unit are valid. */ int subreg_offset; - /** Value for file == IMM */ - union { - int32_t i; - uint32_t u; - float f; - } imm; - - struct brw_reg fixed_hw_reg; - fs_reg *reladdr; - bool negate; - bool abs; + /** + * 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 -retype(fs_reg reg, unsigned type) +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: + 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: + 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(delta == 0 || (reg.file != HW_REG && reg.file != IMM)); - reg.reg_offset += delta; + assert(reg.stride > 0); + switch (reg.file) { + case BAD_FILE: + break; + case GRF: + case MRF: + 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 -byte_offset(fs_reg reg, unsigned delta) +component(fs_reg reg, unsigned idx) { - assert(delta == 0 || (reg.file != HW_REG && reg.file != IMM)); - reg.subreg_offset += delta; + assert(reg.subreg_offset == 0); + assert(idx < reg.width); + reg.subreg_offset = idx * type_sz(reg.type); + reg.width = 1; return reg; } @@ -160,45 +197,43 @@ byte_offset(fs_reg reg, unsigned delta) * Note: this also works if \c reg represents a SIMD16 pair of registers. */ static inline fs_reg -half(const fs_reg ®, unsigned idx) +half(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)); + assert(reg.width == 16); + reg.width = 8; + return horiz_offset(reg, 8 * idx); } 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)); -static const fs_reg reg_null_ud(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD)); - -class ip_record : public exec_node { -public: - DECLARE_RALLOC_CXX_OPERATORS(ip_record) - - ip_record(int ip) - { - this->ip = ip; - } - - int ip; -}; 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) - void init(enum opcode opcode, const fs_reg &dst, fs_reg *src, int sources); - - fs_inst(enum opcode opcode = BRW_OPCODE_NOP, const fs_reg &dst = reg_undef); + 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); @@ -208,6 +243,7 @@ public: 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; @@ -215,29 +251,25 @@ public: fs_reg dst; fs_reg *src; - uint32_t texture_offset; /**< Texture offset bitfield */ - uint32_t offset; /* spill/unspill offset */ - uint8_t sources; /**< Number of fs_reg sources. */ - uint8_t conditional_mod; /**< BRW_CONDITIONAL_* */ + + /** + * 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 mlen; /**< SEND message length */ uint8_t regs_written; /**< Number of vgrfs written by a SEND message, or 1 */ - int8_t base_mrf; /**< First MRF in the SEND message, if mlen is nonzero. */ - uint8_t sampler; - uint8_t target; /**< MRT target. */ - bool saturate:1; bool eot:1; - bool header_present:1; - bool shadow_compare:1; bool force_uncompressed:1; bool force_sechalf:1; - bool force_writemask_all:1; + bool pi_noperspective:1; /**< Pixel interpolator noperspective flag */ }; /** @@ -248,6 +280,9 @@ public: class fs_visitor : public backend_visitor { public: + const fs_reg reg_null_f; + const fs_reg reg_null_d; + const fs_reg reg_null_ud; fs_visitor(struct brw_context *brw, void *mem_ctx, @@ -257,6 +292,7 @@ public: struct gl_fragment_program *fp, unsigned dispatch_width); ~fs_visitor(); + void init(); fs_reg *variable_storage(ir_variable *var); int virtual_grf_alloc(int size); @@ -282,68 +318,77 @@ public: void visit(ir_emit_vertex *); void visit(ir_end_primitive *); - uint32_t gather_channel(ir_texture *ir, int sampler); - void swizzle_result(ir_texture *ir, fs_reg orig_val, int sampler); - - bool can_do_source_mods(fs_inst *inst); + uint32_t gather_channel(int orig_chan, uint32_t sampler); + void swizzle_result(ir_texture_opcode op, int dest_components, + fs_reg orig_val, uint32_t sampler); fs_inst *emit(fs_inst *inst); void emit(exec_list list); fs_inst *emit(enum opcode opcode); - fs_inst *emit(enum opcode opcode, fs_reg dst); - fs_inst *emit(enum opcode opcode, fs_reg dst, fs_reg src0); - fs_inst *emit(enum opcode opcode, fs_reg dst, fs_reg src0, fs_reg src1); - fs_inst *emit(enum opcode opcode, fs_reg dst, - fs_reg src0, fs_reg src1, fs_reg src2); - fs_inst *emit(enum opcode opcode, fs_reg dst, + fs_inst *emit(enum opcode opcode, const fs_reg &dst); + fs_inst *emit(enum opcode opcode, const fs_reg &dst, const fs_reg &src0); + fs_inst *emit(enum opcode opcode, const fs_reg &dst, const fs_reg &src0, + const fs_reg &src1); + fs_inst *emit(enum opcode opcode, const fs_reg &dst, + const fs_reg &src0, const fs_reg &src1, const fs_reg &src2); + fs_inst *emit(enum opcode opcode, const fs_reg &dst, fs_reg src[], int sources); - fs_inst *MOV(fs_reg dst, fs_reg src); - fs_inst *NOT(fs_reg dst, fs_reg src); - fs_inst *RNDD(fs_reg dst, fs_reg src); - fs_inst *RNDE(fs_reg dst, fs_reg src); - fs_inst *RNDZ(fs_reg dst, fs_reg src); - fs_inst *FRC(fs_reg dst, fs_reg src); - fs_inst *ADD(fs_reg dst, fs_reg src0, fs_reg src1); - fs_inst *MUL(fs_reg dst, fs_reg src0, fs_reg src1); - fs_inst *MACH(fs_reg dst, fs_reg src0, fs_reg src1); - fs_inst *MAC(fs_reg dst, fs_reg src0, fs_reg src1); - fs_inst *SHL(fs_reg dst, fs_reg src0, fs_reg src1); - fs_inst *SHR(fs_reg dst, fs_reg src0, fs_reg src1); - fs_inst *ASR(fs_reg dst, fs_reg src0, fs_reg src1); - fs_inst *AND(fs_reg dst, fs_reg src0, fs_reg src1); - fs_inst *OR(fs_reg dst, fs_reg src0, fs_reg src1); - fs_inst *XOR(fs_reg dst, fs_reg src0, fs_reg src1); - fs_inst *IF(uint32_t predicate); - fs_inst *IF(fs_reg src0, fs_reg src1, uint32_t condition); + fs_inst *MOV(const fs_reg &dst, const fs_reg &src); + fs_inst *NOT(const fs_reg &dst, const fs_reg &src); + fs_inst *RNDD(const fs_reg &dst, const fs_reg &src); + fs_inst *RNDE(const fs_reg &dst, const fs_reg &src); + fs_inst *RNDZ(const fs_reg &dst, const fs_reg &src); + fs_inst *FRC(const fs_reg &dst, const fs_reg &src); + fs_inst *ADD(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1); + fs_inst *MUL(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1); + fs_inst *MACH(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1); + fs_inst *MAC(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1); + fs_inst *SHL(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1); + fs_inst *SHR(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1); + fs_inst *ASR(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1); + fs_inst *AND(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1); + fs_inst *OR(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1); + fs_inst *XOR(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1); + fs_inst *IF(enum brw_predicate predicate); + fs_inst *IF(const fs_reg &src0, const fs_reg &src1, + enum brw_conditional_mod condition); fs_inst *CMP(fs_reg dst, fs_reg src0, fs_reg src1, - uint32_t condition); - fs_inst *LRP(fs_reg dst, fs_reg a, fs_reg y, fs_reg x); + enum brw_conditional_mod condition); + fs_inst *LRP(const fs_reg &dst, const fs_reg &a, const fs_reg &y, + const fs_reg &x); fs_inst *DEP_RESOLVE_MOV(int grf); - fs_inst *BFREV(fs_reg dst, fs_reg value); - fs_inst *BFE(fs_reg dst, fs_reg bits, fs_reg offset, fs_reg value); - fs_inst *BFI1(fs_reg dst, fs_reg bits, fs_reg offset); - fs_inst *BFI2(fs_reg dst, fs_reg bfi1_dst, fs_reg insert, fs_reg base); - fs_inst *FBH(fs_reg dst, fs_reg value); - fs_inst *FBL(fs_reg dst, fs_reg value); - fs_inst *CBIT(fs_reg dst, fs_reg value); - fs_inst *MAD(fs_reg dst, fs_reg c, fs_reg b, fs_reg a); - fs_inst *ADDC(fs_reg dst, fs_reg src0, fs_reg src1); - fs_inst *SUBB(fs_reg dst, fs_reg src0, fs_reg src1); - fs_inst *SEL(fs_reg dst, fs_reg src0, fs_reg src1); + fs_inst *BFREV(const fs_reg &dst, const fs_reg &value); + fs_inst *BFE(const fs_reg &dst, const fs_reg &bits, const fs_reg &offset, + const fs_reg &value); + fs_inst *BFI1(const fs_reg &dst, const fs_reg &bits, const fs_reg &offset); + fs_inst *BFI2(const fs_reg &dst, const fs_reg &bfi1_dst, + const fs_reg &insert, const fs_reg &base); + fs_inst *FBH(const fs_reg &dst, const fs_reg &value); + fs_inst *FBL(const fs_reg &dst, const fs_reg &value); + fs_inst *CBIT(const fs_reg &dst, const fs_reg &value); + fs_inst *MAD(const fs_reg &dst, const fs_reg &c, const fs_reg &b, + const fs_reg &a); + fs_inst *ADDC(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1); + fs_inst *SUBB(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1); + fs_inst *SEL(const fs_reg &dst, const fs_reg &src0, const fs_reg &src1); int type_size(const struct glsl_type *type); fs_inst *get_instruction_generating_reg(fs_inst *start, fs_inst *end, const fs_reg ®); + fs_inst *LOAD_PAYLOAD(const fs_reg &dst, fs_reg *src, int sources); + exec_list VARYING_PULL_CONSTANT_LOAD(const fs_reg &dst, const fs_reg &surf_index, const fs_reg &varying_offset, uint32_t const_offset); bool run(); + void optimize(); + void allocate_registers(); void assign_binding_table_offsets(); void setup_payload_gen4(); void setup_payload_gen6(); @@ -360,7 +405,7 @@ public: int choose_spill_reg(struct ra_graph *g); void spill_reg(int spill_reg); void split_virtual_grfs(); - void compact_virtual_grfs(); + bool compact_virtual_grfs(); void move_uniform_array_access_to_pull_constants(); void assign_constant_locations(); void demote_pull_constants(); @@ -369,13 +414,14 @@ public: void calculate_register_pressure(); bool opt_algebraic(); bool opt_cse(); - bool opt_cse_local(bblock_t *block, exec_list *aeb); + bool opt_cse_local(bblock_t *block); bool opt_copy_propagate(); 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_propagate_local(void *mem_ctx, bblock_t *block, exec_list *acp); void opt_drop_redundant_mov_to_flags(); + bool opt_register_renaming(); bool register_coalesce(); bool compute_to_mrf(); bool dead_code_eliminate(); @@ -383,46 +429,70 @@ public: bool virtual_grf_interferes(int a, int b); void schedule_instructions(instruction_scheduler_mode mode); void insert_gen4_send_dependency_workarounds(); - void insert_gen4_pre_send_dependency_workarounds(fs_inst *inst); - void insert_gen4_post_send_dependency_workarounds(fs_inst *inst); + 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 no16(const char *msg, ...); void lower_uniform_pull_constant_loads(); - - void push_force_uncompressed(); - void pop_force_uncompressed(); + bool lower_load_payload(); void emit_dummy_fs(); + void emit_repclear_shader(); 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_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); + fs_reg *emit_frontfacing_interpolation(); + fs_reg *emit_samplepos_setup(); + fs_reg *emit_sampleid_setup(); fs_reg *emit_general_interpolation(ir_variable *ir); void emit_interpolation_setup_gen4(); void emit_interpolation_setup_gen6(); void compute_sample_position(fs_reg dst, fs_reg int_sample_pos); - fs_reg rescale_texcoord(ir_texture *ir, fs_reg coordinate, - bool is_rect, int sampler, int texunit); - fs_inst *emit_texture_gen4(ir_texture *ir, fs_reg dst, fs_reg coordinate, - fs_reg shadow_comp, fs_reg lod, fs_reg lod2); - fs_inst *emit_texture_gen5(ir_texture *ir, fs_reg dst, fs_reg coordinate, - fs_reg shadow_comp, fs_reg lod, fs_reg lod2, - 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, int sampler); - fs_reg emit_mcs_fetch(ir_texture *ir, fs_reg coordinate, int sampler); + fs_reg rescale_texcoord(fs_reg coordinate, const glsl_type *coord_type, + bool is_rect, uint32_t sampler, int texunit); + fs_inst *emit_texture_gen4(ir_texture_opcode op, fs_reg dst, + fs_reg coordinate, int coord_components, + fs_reg shadow_comp, + fs_reg lod, fs_reg lod2, int grad_components, + uint32_t sampler); + fs_inst *emit_texture_gen5(ir_texture_opcode op, fs_reg dst, + fs_reg coordinate, int coord_components, + fs_reg shadow_comp, + fs_reg lod, fs_reg lod2, int grad_components, + fs_reg sample_index, uint32_t sampler, + bool has_offset); + fs_inst *emit_texture_gen7(ir_texture_opcode op, fs_reg dst, + fs_reg coordinate, int coord_components, + fs_reg shadow_comp, + fs_reg lod, fs_reg lod2, int grad_components, + fs_reg sample_index, fs_reg mcs, fs_reg sampler, + fs_reg offset_value); + void emit_texture(ir_texture_opcode op, + const glsl_type *dest_type, + fs_reg coordinate, const struct glsl_type *coord_type, + 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 mcs, + int gather_component, + bool is_cube_array, + bool is_rect, + uint32_t sampler, + fs_reg sampler_reg, + 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); 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); void emit_lrp(const fs_reg &dst, const fs_reg &x, const fs_reg &y, const fs_reg &a); - void emit_minmax(uint32_t conditionalmod, const fs_reg &dst, + void emit_minmax(enum brw_conditional_mod conditionalmod, const fs_reg &dst, const fs_reg &src0, const fs_reg &src1); bool try_emit_saturate(ir_expression *ir); bool try_emit_mad(ir_expression *ir); @@ -432,8 +502,10 @@ public: 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, - int count); + void emit_unspill(bblock_t *block, fs_inst *inst, fs_reg reg, + uint32_t spill_offset, int count); + void emit_spill(bblock_t *block, fs_inst *inst, fs_reg reg, + uint32_t spill_offset, int count); void emit_fragment_program_code(); void setup_fp_regs(); @@ -454,12 +526,14 @@ public: void emit_fp_minmax(const struct prog_instruction *fpi, fs_reg dst, fs_reg src0, fs_reg src1); - void emit_fp_sop(uint32_t conditional_mod, + void emit_fp_sop(enum brw_conditional_mod conditional_mod, const struct prog_instruction *fpi, fs_reg dst, fs_reg src0, fs_reg src1, fs_reg one); - void emit_color_write(int target, int index, int first_color_mrf); + int setup_color_payload(fs_reg *dst, fs_reg color, unsigned components); void emit_alpha_test(); + fs_inst *emit_single_fb_write(fs_reg color1, fs_reg color2, + fs_reg src0_alpha, unsigned components); void emit_fb_writes(); void emit_shader_time_begin(); @@ -474,6 +548,8 @@ public: void emit_untyped_surface_read(unsigned surf_index, fs_reg dst, fs_reg offset); + void emit_interpolate_expression(ir_expression *ir); + bool try_rewrite_rhs_to_dst(ir_assignment *ir, fs_reg dst, fs_reg src, @@ -498,9 +574,8 @@ public: void visit_atomic_counter_intrinsic(ir_call *ir); - struct gl_fragment_program *fp; - const struct brw_wm_prog_key *const key; - struct brw_wm_prog_data *prog_data; + const void *const key; + struct brw_stage_prog_data *prog_data; unsigned int sanity_param_count; int *param_size; @@ -588,8 +663,6 @@ public: bool spilled_any_registers; const unsigned dispatch_width; /**< 8 or 16 */ - - int force_uncompressed_stack; }; /** @@ -604,48 +677,40 @@ public: void *mem_ctx, const struct brw_wm_prog_key *key, struct brw_wm_prog_data *prog_data, - struct gl_shader_program *prog, + struct gl_shader_program *shader_prog, struct gl_fragment_program *fp, - bool dual_source_output, bool runtime_check_aads_emit, bool debug_flag); ~fs_generator(); - const unsigned *generate_assembly(exec_list *simd8_instructions, - exec_list *simd16_instructions, - unsigned *assembly_size); + int generate_code(const cfg_t *cfg, int dispatch_width); + const unsigned *get_assembly(unsigned int *assembly_size); private: - void generate_code(exec_list *instructions); - void generate_fb_write(fs_inst *inst); + void fire_fb_write(fs_inst *inst, + struct brw_reg payload, + struct brw_reg implied_header, + GLuint nr); + void generate_fb_write(fs_inst *inst, struct brw_reg payload); 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); - void generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src); - void generate_math1_gen7(fs_inst *inst, - struct brw_reg dst, - struct brw_reg src); - void generate_math2_gen7(fs_inst *inst, - struct brw_reg dst, - struct brw_reg src0, - struct brw_reg src1); - void generate_math1_gen6(fs_inst *inst, - struct brw_reg dst, - struct brw_reg src); - void generate_math2_gen6(fs_inst *inst, - struct brw_reg dst, - struct brw_reg src0, - struct brw_reg src1); + void generate_tex(fs_inst *inst, struct brw_reg dst, struct brw_reg src, + struct brw_reg sampler_index); + void generate_math_gen6(fs_inst *inst, + struct brw_reg dst, + struct brw_reg src0, + struct brw_reg src1); void generate_math_gen4(fs_inst *inst, struct brw_reg dst, struct brw_reg src); void generate_math_g45(fs_inst *inst, struct brw_reg dst, struct brw_reg src); - void generate_ddx(fs_inst *inst, struct brw_reg dst, struct brw_reg src); + void generate_ddx(fs_inst *inst, struct brw_reg dst, struct brw_reg src, struct brw_reg quality); void generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src, - bool negate_value); + struct brw_reg quality, bool negate_value); 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); @@ -665,6 +730,12 @@ private: struct brw_reg offset); 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_omask(fs_inst *inst, struct brw_reg dst, struct brw_reg sample_mask); @@ -694,11 +765,13 @@ private: void generate_untyped_atomic(fs_inst *inst, struct brw_reg dst, + struct brw_reg payload, struct brw_reg atomic_op, struct brw_reg surf_index); void generate_untyped_surface_read(fs_inst *inst, struct brw_reg dst, + struct brw_reg payload, struct brw_reg surf_index); bool patch_discard_jumps_to_fb_writes(); @@ -707,108 +780,22 @@ private: struct gl_context *ctx; struct brw_compile *p; - const struct brw_wm_prog_key *const key; - struct brw_wm_prog_data *prog_data; + gl_shader_stage stage; + const void * const key; + struct brw_stage_prog_data * const prog_data; - struct gl_shader_program *prog; - const struct gl_fragment_program *fp; + struct gl_shader_program * const shader_prog; + const struct gl_program *prog; unsigned dispatch_width; /**< 8 or 16 */ exec_list discard_halt_patches; - bool dual_source_output; bool runtime_check_aads_emit; const bool debug_flag; void *mem_ctx; }; -/** - * The fragment shader code generator. - * - * Translates FS IR to actual i965 assembly code. - */ -class gen8_fs_generator : public gen8_generator -{ -public: - gen8_fs_generator(struct brw_context *brw, - void *mem_ctx, - const struct brw_wm_prog_key *key, - struct brw_wm_prog_data *prog_data, - struct gl_shader_program *prog, - struct gl_fragment_program *fp, - bool dual_source_output); - ~gen8_fs_generator(); - - const unsigned *generate_assembly(exec_list *simd8_instructions, - exec_list *simd16_instructions, - unsigned *assembly_size); - -private: - void generate_code(exec_list *instructions); - void generate_fb_write(fs_inst *inst); - void 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 src); - void generate_math1(fs_inst *inst, struct brw_reg dst, struct brw_reg src); - void generate_math2(fs_inst *inst, struct brw_reg dst, - struct brw_reg src0, struct brw_reg src1); - void generate_ddx(fs_inst *inst, struct brw_reg dst, struct brw_reg src); - void generate_ddy(fs_inst *inst, struct brw_reg dst, struct brw_reg src, - bool negate_value); - 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_varying_pull_constant_load(fs_inst *inst, - struct brw_reg dst, - struct brw_reg index, - struct brw_reg offset); - void generate_mov_dispatch_to_flags(fs_inst *ir); - void generate_set_omask(fs_inst *ir, - struct brw_reg dst, - struct brw_reg sample_mask); - void generate_set_sample_id(fs_inst *ir, - struct brw_reg dst, - struct brw_reg src0, - struct brw_reg src1); - void generate_set_simd4x2_offset(fs_inst *ir, - struct brw_reg dst, - struct brw_reg offset); - void generate_pack_half_2x16_split(fs_inst *inst, - struct brw_reg dst, - struct brw_reg x, - struct brw_reg y); - void generate_unpack_half_2x16_split(fs_inst *inst, - struct brw_reg dst, - struct brw_reg src); - void generate_untyped_atomic(fs_inst *inst, - struct brw_reg dst, - struct brw_reg atomic_op, - struct brw_reg surf_index); - - void generate_untyped_surface_read(fs_inst *inst, - struct brw_reg dst, - struct brw_reg surf_index); - void generate_discard_jump(fs_inst *ir); - - bool patch_discard_jumps_to_fb_writes(); - - const struct brw_wm_prog_key *const key; - struct brw_wm_prog_data *prog_data; - const struct gl_fragment_program *fp; - - unsigned dispatch_width; /** 8 or 16 */ - - bool dual_source_output; - - exec_list discard_halt_patches; -}; - bool brw_do_channel_expressions(struct exec_list *instructions); bool brw_do_vector_splitting(struct exec_list *instructions); -bool brw_fs_precompile(struct gl_context *ctx, struct gl_shader_program *prog); struct brw_reg brw_reg_from_fs_reg(fs_reg *reg);