X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fvc4%2Fvc4_qir.h;h=5099b7f1f1c908d3c7fa071922b6122dc6cd470e;hb=89918c1e74e454af119e7ae23f3ed66fc26abc4b;hp=62624d4b1e2577fcb1f6b9b10125e59005ce04de;hpb=b145b731ab01937993e2bf7ecc072217932568ff;p=mesa.git diff --git a/src/gallium/drivers/vc4/vc4_qir.h b/src/gallium/drivers/vc4/vc4_qir.h index 62624d4b1e2..5099b7f1f1c 100644 --- a/src/gallium/drivers/vc4/vc4_qir.h +++ b/src/gallium/drivers/vc4/vc4_qir.h @@ -38,6 +38,7 @@ #include "vc4_screen.h" #include "vc4_qpu_defines.h" +#include "vc4_qpu.h" #include "kernel/vc4_packet.h" #include "pipe/p_state.h" @@ -61,6 +62,12 @@ enum qfile { QFILE_FRAG_Y, QFILE_FRAG_REV_FLAG, + /** + * Stores an immediate value in the index field that will be used + * directly by qpu_load_imm(). + */ + QFILE_LOAD_IMM, + /** * Stores an immediate value in the index field that can be turned * into a small immediate field by qpu_encode_small_immediate(). @@ -147,6 +154,8 @@ enum qop { * the destination */ QOP_TEX_RESULT, + + QOP_LOAD_IMM, }; struct queued_qpu_inst { @@ -332,6 +341,27 @@ struct vc4_vs_key { enum pipe_format attr_formats[8]; bool is_coord; bool per_vertex_point_size; + bool clamp_color; +}; + +/** A basic block of QIR intructions. */ +struct qblock { + struct list_head link; + + struct list_head instructions; + + struct set *predecessors; + struct qblock *successors[2]; + + int index; + + /** @{ used by vc4_qir_live_variables.c */ + BITSET_WORD *def; + BITSET_WORD *use; + BITSET_WORD *live_in; + BITSET_WORD *live_out; + int start_ip, end_ip; + /** @} */ }; struct vc4_compile { @@ -379,11 +409,6 @@ struct vc4_compile { uint8_t vattr_sizes[8]; - /* Bitfield for whether a given channel of a sampler needs sRGB - * decode. - */ - uint8_t tex_srgb_decode[VC4_MAX_TEXTURE_SAMPLERS]; - /** * Array of the VARYING_SLOT_* of all FS QFILE_VARY reads. * @@ -406,6 +431,9 @@ struct vc4_compile { struct vc4_fs_key *fs_key; struct vc4_vs_key *vs_key; + /* Live ranges of temps. */ + int *temp_start, *temp_end; + uint32_t *uniform_data; enum quniform_contents *uniform_contents; uint32_t uniform_array_size; @@ -420,7 +448,10 @@ struct vc4_compile { struct qreg undef; enum qstage stage; uint32_t num_temps; - struct list_head instructions; + + struct list_head blocks; + int next_block_index; + struct qblock *cur_block; struct list_head qpu_inst_list; uint64_t *qpu_insts; @@ -446,6 +477,11 @@ struct vc4_compile { struct vc4_compile *qir_compile_init(void); void qir_compile_destroy(struct vc4_compile *c); +struct qblock *qir_new_block(struct vc4_compile *c); +void qir_set_emit_block(struct vc4_compile *c, struct qblock *block); +void qir_link_blocks(struct qblock *predecessor, struct qblock *successor); +struct qblock *qir_entry_block(struct vc4_compile *c); +struct qblock *qir_exit_block(struct vc4_compile *c); struct qinst *qir_inst(enum qop op, struct qreg dst, struct qreg src0, struct qreg src1); struct qinst *qir_inst4(enum qop op, struct qreg dst, @@ -460,15 +496,11 @@ struct qreg qir_uniform(struct vc4_compile *c, void qir_schedule_instructions(struct vc4_compile *c); void qir_reorder_uniforms(struct vc4_compile *c); -void qir_emit(struct vc4_compile *c, struct qinst *inst); -static inline struct qinst * -qir_emit_nodef(struct vc4_compile *c, struct qinst *inst) -{ - list_addtail(&inst->link, &c->instructions); - return inst; -} +struct qreg qir_emit_def(struct vc4_compile *c, struct qinst *inst); +struct qinst *qir_emit_nondef(struct vc4_compile *c, struct qinst *inst); struct qreg qir_get_temp(struct vc4_compile *c); +void qir_calculate_live_intervals(struct vc4_compile *c); int qir_get_op_nsrc(enum qop qop); bool qir_reg_equals(struct qreg a, struct qreg b); bool qir_has_side_effects(struct vc4_compile *c, struct qinst *inst); @@ -480,17 +512,20 @@ bool qir_is_float_input(struct qinst *inst); bool qir_depends_on_flags(struct qinst *inst); bool qir_writes_r4(struct qinst *inst); struct qreg qir_follow_movs(struct vc4_compile *c, struct qreg reg); +uint8_t qir_channels_written(struct qinst *inst); void qir_dump(struct vc4_compile *c); void qir_dump_inst(struct vc4_compile *c, struct qinst *inst); const char *qir_get_stage_name(enum qstage stage); +void qir_validate(struct vc4_compile *c); + void qir_optimize(struct vc4_compile *c); bool qir_opt_algebraic(struct vc4_compile *c); bool qir_opt_constant_folding(struct vc4_compile *c); bool qir_opt_copy_propagation(struct vc4_compile *c); -bool qir_opt_cse(struct vc4_compile *c); bool qir_opt_dead_code(struct vc4_compile *c); +bool qir_opt_peephole_sf(struct vc4_compile *c); bool qir_opt_small_immediates(struct vc4_compile *c); bool qir_opt_vpm(struct vc4_compile *c); void vc4_nir_lower_blend(nir_shader *s, struct vc4_compile *c); @@ -522,68 +557,58 @@ qir_uniform_f(struct vc4_compile *c, float f) static inline struct qreg \ qir_##name(struct vc4_compile *c) \ { \ - struct qreg t = qir_get_temp(c); \ - qir_emit(c, qir_inst(QOP_##name, t, c->undef, c->undef)); \ - return t; \ + return qir_emit_def(c, qir_inst(QOP_##name, c->undef, \ + c->undef, c->undef)); \ +} \ +static inline struct qinst * \ +qir_##name##_dest(struct vc4_compile *c, struct qreg dest) \ +{ \ + return qir_emit_nondef(c, qir_inst(QOP_##name, dest, \ + c->undef, c->undef)); \ } #define QIR_ALU1(name) \ static inline struct qreg \ qir_##name(struct vc4_compile *c, struct qreg a) \ { \ - struct qreg t = qir_get_temp(c); \ - qir_emit(c, qir_inst(QOP_##name, t, a, c->undef)); \ - return t; \ + return qir_emit_def(c, qir_inst(QOP_##name, c->undef, \ + a, c->undef)); \ } \ static inline struct qinst * \ qir_##name##_dest(struct vc4_compile *c, struct qreg dest, \ struct qreg a) \ { \ - return qir_emit_nodef(c, qir_inst(QOP_##name, dest, a, \ - c->undef)); \ + return qir_emit_nondef(c, qir_inst(QOP_##name, dest, a, \ + c->undef)); \ } #define QIR_ALU2(name) \ static inline struct qreg \ qir_##name(struct vc4_compile *c, struct qreg a, struct qreg b) \ { \ - struct qreg t = qir_get_temp(c); \ - qir_emit(c, qir_inst(QOP_##name, t, a, b)); \ - return t; \ + return qir_emit_def(c, qir_inst(QOP_##name, c->undef, a, b)); \ } \ -static inline void \ +static inline struct qinst * \ qir_##name##_dest(struct vc4_compile *c, struct qreg dest, \ struct qreg a, struct qreg b) \ { \ - qir_emit_nodef(c, qir_inst(QOP_##name, dest, a, b)); \ + return qir_emit_nondef(c, qir_inst(QOP_##name, dest, a, b)); \ } #define QIR_NODST_1(name) \ static inline struct qinst * \ qir_##name(struct vc4_compile *c, struct qreg a) \ { \ - struct qinst *inst = qir_inst(QOP_##name, c->undef, \ - a, c->undef); \ - qir_emit(c, inst); \ - return inst; \ + return qir_emit_nondef(c, qir_inst(QOP_##name, c->undef, \ + a, c->undef)); \ } #define QIR_NODST_2(name) \ static inline struct qinst * \ qir_##name(struct vc4_compile *c, struct qreg a, struct qreg b) \ { \ - struct qinst *inst = qir_inst(QOP_##name, c->undef, \ - a, b); \ - qir_emit(c, inst); \ - return inst; \ -} - -#define QIR_PACK(name) \ -static inline struct qreg \ -qir_##name(struct vc4_compile *c, struct qreg dest, struct qreg a) \ -{ \ - qir_emit_nodef(c, qir_inst(QOP_##name, dest, a, c->undef)); \ - return dest; \ + return qir_emit_nondef(c, qir_inst(QOP_##name, c->undef, \ + a, b)); \ } #define QIR_PAYLOAD(name) \ @@ -596,7 +621,8 @@ qir_##name(struct vc4_compile *c) \ *payload = qir_get_temp(c); \ struct qinst *inst = qir_inst(QOP_##name, *payload, \ c->undef, c->undef); \ - list_add(&inst->link, &c->instructions); \ + struct qblock *entry = qir_entry_block(c); \ + list_add(&inst->link, &entry->instructions); \ c->defs[payload->index] = inst; \ return *payload; \ } @@ -655,7 +681,7 @@ qir_SEL(struct vc4_compile *c, uint8_t cond, struct qreg src0, struct qreg src1) struct qinst *a = qir_MOV_dest(c, t, src0); struct qinst *b = qir_MOV_dest(c, t, src1); a->cond = cond; - b->cond = cond ^ 1; + b->cond = qpu_cond_complement(cond); return t; } @@ -696,9 +722,7 @@ qir_PACK_8_F(struct vc4_compile *c, struct qreg dest, struct qreg val, int chan) { assert(!dest.pack); dest.pack = QPU_PACK_MUL_8A + chan; - qir_emit(c, qir_inst(QOP_MMOV, dest, val, c->undef)); - if (dest.file == QFILE_TEMP) - c->defs[dest.index] = NULL; + qir_emit_nondef(c, qir_inst(QOP_MMOV, dest, val, c->undef)); } static inline struct qreg @@ -723,4 +747,37 @@ qir_VPM_WRITE(struct vc4_compile *c, struct qreg val) qir_MOV_dest(c, qir_reg(QFILE_VPM, 0), val); } +static inline struct qreg +qir_LOAD_IMM(struct vc4_compile *c, uint32_t val) +{ + return qir_emit_def(c, qir_inst(QOP_LOAD_IMM, c->undef, + qir_reg(QFILE_LOAD_IMM, val), c->undef)); +} + +#define qir_for_each_block(block, c) \ + list_for_each_entry(struct qblock, block, &c->blocks, link) + +#define qir_for_each_block_rev(block, c) \ + list_for_each_entry_rev(struct qblock, block, &c->blocks, link) + +/* Loop over the non-NULL members of the successors array. */ +#define qir_for_each_successor(succ, block) \ + for (struct qblock *succ = block->successors[0]; \ + succ != NULL; \ + succ = (succ == block->successors[1] ? NULL : \ + block->successors[1])) + +#define qir_for_each_inst(inst, block) \ + list_for_each_entry(struct qinst, inst, &block->instructions, link) + +#define qir_for_each_inst_rev(inst, block) \ + list_for_each_entry_rev(struct qinst, inst, &block->instructions, link) + +#define qir_for_each_inst_safe(inst, block) \ + list_for_each_entry_safe(struct qinst, inst, &block->instructions, link) + +#define qir_for_each_inst_inorder(inst, c) \ + qir_for_each_block(_block, c) \ + qir_for_each_inst(inst, _block) + #endif /* VC4_QIR_H */