📄 brw_eu_emit.c
字号:
if (p->current->header.destreg__conditonalmod) { p->current->header.destreg__conditonalmod = 0; p->current->header.predicate_control = BRW_PREDICATE_NORMAL; } insn->header.opcode = opcode; return insn;}static struct brw_instruction *brw_alu1( struct brw_compile *p, GLuint opcode, struct brw_reg dest, struct brw_reg src ){ struct brw_instruction *insn = next_insn(p, opcode); brw_set_dest(insn, dest); brw_set_src0(insn, src); return insn;}static struct brw_instruction *brw_alu2(struct brw_compile *p, GLuint opcode, struct brw_reg dest, struct brw_reg src0, struct brw_reg src1 ){ struct brw_instruction *insn = next_insn(p, opcode); brw_set_dest(insn, dest); brw_set_src0(insn, src0); brw_set_src1(insn, src1); return insn;}/*********************************************************************** * Convenience routines. */#define ALU1(OP) \struct brw_instruction *brw_##OP(struct brw_compile *p, \ struct brw_reg dest, \ struct brw_reg src0) \{ \ return brw_alu1(p, BRW_OPCODE_##OP, dest, src0); \}#define ALU2(OP) \struct brw_instruction *brw_##OP(struct brw_compile *p, \ struct brw_reg dest, \ struct brw_reg src0, \ struct brw_reg src1) \{ \ return brw_alu2(p, BRW_OPCODE_##OP, dest, src0, src1); \}ALU1(MOV)ALU2(SEL)ALU1(NOT)ALU2(AND)ALU2(OR)ALU2(XOR)ALU2(SHR)ALU2(SHL)ALU2(RSR)ALU2(RSL)ALU2(ASR)ALU2(ADD)ALU2(MUL)ALU1(FRC)ALU1(RNDD)ALU2(MAC)ALU2(MACH)ALU1(LZD)ALU2(DP4)ALU2(DPH)ALU2(DP3)ALU2(DP2)ALU2(LINE)void brw_NOP(struct brw_compile *p){ struct brw_instruction *insn = next_insn(p, BRW_OPCODE_NOP); brw_set_dest(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD)); brw_set_src0(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD)); brw_set_src1(insn, brw_imm_ud(0x0));}/*********************************************************************** * Comparisons, if/else/endif */struct brw_instruction *brw_JMPI(struct brw_compile *p, struct brw_reg dest, struct brw_reg src0, struct brw_reg src1){ struct brw_instruction *insn = brw_alu2(p, BRW_OPCODE_JMPI, dest, src0, src1); p->current->header.predicate_control = BRW_PREDICATE_NONE; return insn;}/* EU takes the value from the flag register and pushes it onto some * sort of a stack (presumably merging with any flag value already on * the stack). Within an if block, the flags at the top of the stack * control execution on each channel of the unit, eg. on each of the * 16 pixel values in our wm programs. * * When the matching 'else' instruction is reached (presumably by * countdown of the instruction count patched in by our ELSE/ENDIF * functions), the relevent flags are inverted. * * When the matching 'endif' instruction is reached, the flags are * popped off. If the stack is now empty, normal execution resumes. * * No attempt is made to deal with stack overflow (14 elements?). */struct brw_instruction *brw_IF(struct brw_compile *p, GLuint execute_size){ struct brw_instruction *insn; if (p->single_program_flow) { assert(execute_size == BRW_EXECUTE_1); insn = next_insn(p, BRW_OPCODE_ADD); insn->header.predicate_inverse = 1; } else { insn = next_insn(p, BRW_OPCODE_IF); } /* Override the defaults for this instruction: */ brw_set_dest(insn, brw_ip_reg()); brw_set_src0(insn, brw_ip_reg()); brw_set_src1(insn, brw_imm_d(0x0)); insn->header.execution_size = execute_size; insn->header.compression_control = BRW_COMPRESSION_NONE; insn->header.predicate_control = BRW_PREDICATE_NORMAL; insn->header.mask_control = BRW_MASK_ENABLE; if (!p->single_program_flow) insn->header.thread_control = BRW_THREAD_SWITCH; p->current->header.predicate_control = BRW_PREDICATE_NONE; return insn;}struct brw_instruction *brw_ELSE(struct brw_compile *p, struct brw_instruction *if_insn){ struct brw_instruction *insn; if (p->single_program_flow) { insn = next_insn(p, BRW_OPCODE_ADD); } else { insn = next_insn(p, BRW_OPCODE_ELSE); } brw_set_dest(insn, brw_ip_reg()); brw_set_src0(insn, brw_ip_reg()); brw_set_src1(insn, brw_imm_d(0x0)); insn->header.compression_control = BRW_COMPRESSION_NONE; insn->header.execution_size = if_insn->header.execution_size; insn->header.mask_control = BRW_MASK_ENABLE; if (!p->single_program_flow) insn->header.thread_control = BRW_THREAD_SWITCH; /* Patch the if instruction to point at this instruction. */ if (p->single_program_flow) { assert(if_insn->header.opcode == BRW_OPCODE_ADD); if_insn->bits3.ud = (insn - if_insn + 1) * 16; } else { assert(if_insn->header.opcode == BRW_OPCODE_IF); if_insn->bits3.if_else.jump_count = insn - if_insn; if_insn->bits3.if_else.pop_count = 1; if_insn->bits3.if_else.pad0 = 0; } return insn;}void brw_ENDIF(struct brw_compile *p, struct brw_instruction *patch_insn){ if (p->single_program_flow) { /* In single program flow mode, there's no need to execute an ENDIF, * since we don't need to do any stack operations, and if we're executing * currently, we want to just continue executing. */ struct brw_instruction *next = &p->store[p->nr_insn]; assert(patch_insn->header.opcode == BRW_OPCODE_ADD); patch_insn->bits3.ud = (next - patch_insn) * 16; } else { struct brw_instruction *insn = next_insn(p, BRW_OPCODE_ENDIF); brw_set_dest(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD)); brw_set_src0(insn, retype(brw_vec4_grf(0,0), BRW_REGISTER_TYPE_UD)); brw_set_src1(insn, brw_imm_d(0x0)); insn->header.compression_control = BRW_COMPRESSION_NONE; insn->header.execution_size = patch_insn->header.execution_size; insn->header.mask_control = BRW_MASK_ENABLE; insn->header.thread_control = BRW_THREAD_SWITCH; assert(patch_insn->bits3.if_else.jump_count == 0); /* Patch the if or else instructions to point at this or the next * instruction respectively. */ if (patch_insn->header.opcode == BRW_OPCODE_IF) { /* Automagically turn it into an IFF: */ patch_insn->header.opcode = BRW_OPCODE_IFF; patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1; patch_insn->bits3.if_else.pop_count = 0; patch_insn->bits3.if_else.pad0 = 0; } else if (patch_insn->header.opcode == BRW_OPCODE_ELSE) { patch_insn->bits3.if_else.jump_count = insn - patch_insn + 1; patch_insn->bits3.if_else.pop_count = 1; patch_insn->bits3.if_else.pad0 = 0; } else { assert(0); } /* Also pop item off the stack in the endif instruction: */ insn->bits3.if_else.jump_count = 0; insn->bits3.if_else.pop_count = 1; insn->bits3.if_else.pad0 = 0; }}struct brw_instruction *brw_BREAK(struct brw_compile *p){ struct brw_instruction *insn; insn = next_insn(p, BRW_OPCODE_BREAK); brw_set_dest(insn, brw_ip_reg()); brw_set_src0(insn, brw_ip_reg()); brw_set_src1(insn, brw_imm_d(0x0)); insn->header.compression_control = BRW_COMPRESSION_NONE; insn->header.execution_size = BRW_EXECUTE_8; /* insn->header.mask_control = BRW_MASK_DISABLE; */ insn->bits3.if_else.pad0 = 0; return insn;}struct brw_instruction *brw_CONT(struct brw_compile *p){ struct brw_instruction *insn; insn = next_insn(p, BRW_OPCODE_CONTINUE); brw_set_dest(insn, brw_ip_reg()); brw_set_src0(insn, brw_ip_reg()); brw_set_src1(insn, brw_imm_d(0x0)); insn->header.compression_control = BRW_COMPRESSION_NONE; insn->header.execution_size = BRW_EXECUTE_8; /* insn->header.mask_control = BRW_MASK_DISABLE; */ insn->bits3.if_else.pad0 = 0; return insn;}/* DO/WHILE loop: */struct brw_instruction *brw_DO(struct brw_compile *p, GLuint execute_size){ if (p->single_program_flow) { return &p->store[p->nr_insn]; } else { struct brw_instruction *insn = next_insn(p, BRW_OPCODE_DO); /* Override the defaults for this instruction: */ brw_set_dest(insn, brw_null_reg()); brw_set_src0(insn, brw_null_reg()); brw_set_src1(insn, brw_null_reg()); insn->header.compression_control = BRW_COMPRESSION_NONE; insn->header.execution_size = execute_size; insn->header.predicate_control = BRW_PREDICATE_NONE; /* insn->header.mask_control = BRW_MASK_ENABLE; */ /* insn->header.mask_control = BRW_MASK_DISABLE; */ return insn; }}struct brw_instruction *brw_WHILE(struct brw_compile *p, struct brw_instruction *do_insn){ struct brw_instruction *insn; if (p->single_program_flow) insn = next_insn(p, BRW_OPCODE_ADD); else insn = next_insn(p, BRW_OPCODE_WHILE); brw_set_dest(insn, brw_ip_reg()); brw_set_src0(insn, brw_ip_reg()); brw_set_src1(insn, brw_imm_d(0x0)); insn->header.compression_control = BRW_COMPRESSION_NONE; if (p->single_program_flow) { insn->header.execution_size = BRW_EXECUTE_1; insn->bits3.d = (do_insn - insn) * 16; } else { insn->header.execution_size = do_insn->header.execution_size; assert(do_insn->header.opcode == BRW_OPCODE_DO); insn->bits3.if_else.jump_count = do_insn - insn + 1; insn->bits3.if_else.pop_count = 0; insn->bits3.if_else.pad0 = 0; }/* insn->header.mask_control = BRW_MASK_ENABLE; */ /* insn->header.mask_control = BRW_MASK_DISABLE; */ p->current->header.predicate_control = BRW_PREDICATE_NONE; return insn;}/* FORWARD JUMPS: */void brw_land_fwd_jump(struct brw_compile *p, struct brw_instruction *jmp_insn){ struct brw_instruction *landing = &p->store[p->nr_insn]; assert(jmp_insn->header.opcode == BRW_OPCODE_JMPI); assert(jmp_insn->bits1.da1.src1_reg_file = BRW_IMMEDIATE_VALUE); jmp_insn->bits3.ud = (landing - jmp_insn) - 1; }/* To integrate with the above, it makes sense that the comparison * instruction should populate the flag register. It might be simpler * just to use the flag reg for most WM tasks? */void brw_CMP(struct brw_compile *p, struct brw_reg dest, GLuint conditional, struct brw_reg src0, struct brw_reg src1){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -