📄 brw_wm_emit.c
字号:
brw_MOV(p, brw_message_reg(reg), aa); brw_pop_insn_state(p);}/* Post-fragment-program processing. Send the results to the * framebuffer. */static void emit_fb_write( struct brw_wm_compile *c, struct brw_reg *arg0, struct brw_reg *arg1, struct brw_reg *arg2, GLuint target, GLuint eot){ struct brw_compile *p = &c->func; GLuint nr = 2; GLuint channel; /* Reserve a space for AA - may not be needed: */ if (c->key.aa_dest_stencil_reg) nr += 1; /* I don't really understand how this achieves the color interleave * (ie RGBARGBA) in the result: [Do the saturation here] */ { brw_push_insn_state(p); for (channel = 0; channel < 4; channel++) { /* mov (8) m2.0<1>:ud r28.0<8;8,1>:ud { Align1 } */ /* mov (8) m6.0<1>:ud r29.0<8;8,1>:ud { Align1 SecHalf } */ brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MOV(p, brw_message_reg(nr + channel), arg0[channel]); brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF); brw_MOV(p, brw_message_reg(nr + channel + 4), sechalf(arg0[channel])); } /* skip over the regs populated above: */ nr += 8; brw_pop_insn_state(p); } if (c->key.source_depth_to_render_target) { if (c->key.computes_depth) brw_MOV(p, brw_message_reg(nr), arg2[2]); else brw_MOV(p, brw_message_reg(nr), arg1[1]); /* ? */ nr += 2; } if (c->key.dest_depth_reg) { GLuint comp = c->key.dest_depth_reg / 2; GLuint off = c->key.dest_depth_reg % 2; if (off != 0) { brw_push_insn_state(p); brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_MOV(p, brw_message_reg(nr), offset(arg1[comp],1)); /* 2nd half? */ brw_MOV(p, brw_message_reg(nr+1), arg1[comp+1]); brw_pop_insn_state(p); } else { brw_MOV(p, brw_message_reg(nr), arg1[comp]); } nr += 2; } if (!c->key.runtime_check_aads_emit) { if (c->key.aa_dest_stencil_reg) emit_aa(c, arg1, 2); fire_fb_write(c, 0, nr, target, eot); } else { struct brw_reg v1_null_ud = vec1(retype(brw_null_reg(), BRW_REGISTER_TYPE_UD)); struct brw_reg ip = brw_ip_reg(); struct brw_instruction *jmp; brw_set_compression_control(p, BRW_COMPRESSION_NONE); brw_set_conditionalmod(p, BRW_CONDITIONAL_Z); brw_AND(p, v1_null_ud, get_element_ud(brw_vec8_grf(1,0), 6), brw_imm_ud(1<<26)); jmp = brw_JMPI(p, ip, ip, brw_imm_w(0)); { emit_aa(c, arg1, 2); fire_fb_write(c, 0, nr, target, eot); /* note - thread killed in subroutine */ } brw_land_fwd_jump(p, jmp); /* ELSE: Shuffle up one register to fill in the hole left for AA: */ fire_fb_write(c, 1, nr-1, target, eot); }}/* Post-fragment-program processing. Send the results to the * framebuffer. */static void emit_spill( struct brw_wm_compile *c, struct brw_reg reg, GLuint slot ){ struct brw_compile *p = &c->func; /* mov (16) m2.0<1>:ud r2.0<8;8,1>:ud { Align1 Compr } */ brw_MOV(p, brw_message_reg(2), reg); /* mov (1) r0.2<1>:d 0x00000080:d { Align1 NoMask } send (16) null.0<1>:uw m1 r0.0<8;8,1>:uw 0x053003ff:ud { Align1 } */ brw_dp_WRITE_16(p, retype(vec16(brw_vec8_grf(0, 0)), BRW_REGISTER_TYPE_UW), 1, slot);}static void emit_unspill( struct brw_wm_compile *c, struct brw_reg reg, GLuint slot ){ struct brw_compile *p = &c->func; /* Slot 0 is the undef value. */ if (slot == 0) { brw_MOV(p, reg, brw_imm_f(0)); return; } /* mov (1) r0.2<1>:d 0x000000c0:d { Align1 NoMask } send (16) r110.0<1>:uw m1 r0.0<8;8,1>:uw 0x041243ff:ud { Align1 } */ brw_dp_READ_16(p, retype(vec16(reg), BRW_REGISTER_TYPE_UW), 1, slot);}/** * Retrieve upto 4 GEN4 register pairs for the given wm reg: */static void get_argument_regs( struct brw_wm_compile *c, struct brw_wm_ref *arg[], struct brw_reg *regs ){ GLuint i; for (i = 0; i < 4; i++) { if (arg[i]) { if (arg[i]->unspill_reg) emit_unspill(c, brw_vec8_grf(arg[i]->unspill_reg, 0), arg[i]->value->spill_slot); regs[i] = arg[i]->hw_reg; } else { regs[i] = brw_null_reg(); } }}static void spill_values( struct brw_wm_compile *c, struct brw_wm_value *values, GLuint nr ){ GLuint i; for (i = 0; i < nr; i++) if (values[i].spill_slot) emit_spill(c, values[i].hw_reg, values[i].spill_slot);}/* Emit the fragment program instructions here. */void brw_wm_emit( struct brw_wm_compile *c ){ struct brw_compile *p = &c->func; GLuint insn; brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED); /* Check if any of the payload regs need to be spilled: */ spill_values(c, c->payload.depth, 4); spill_values(c, c->creg, c->nr_creg); spill_values(c, c->payload.input_interp, FRAG_ATTRIB_MAX); for (insn = 0; insn < c->nr_insns; insn++) { struct brw_wm_instruction *inst = &c->instruction[insn]; struct brw_reg args[3][4], dst[4]; GLuint i, dst_flags; /* Get argument regs: */ for (i = 0; i < 3; i++) get_argument_regs(c, inst->src[i], args[i]); /* Get dest regs: */ for (i = 0; i < 4; i++) if (inst->dst[i]) dst[i] = inst->dst[i]->hw_reg; else dst[i] = brw_null_reg(); /* Flags */ dst_flags = inst->writemask; if (inst->saturate) dst_flags |= SATURATE; switch (inst->opcode) { /* Generated instructions for calculating triangle interpolants: */ case WM_PIXELXY: emit_pixel_xy(p, dst, dst_flags, args[0]); break; case WM_DELTAXY: emit_delta_xy(p, dst, dst_flags, args[0], args[1]); break; case WM_WPOSXY: emit_wpos_xy(c, dst, dst_flags, args[0]); break; case WM_PIXELW: emit_pixel_w(p, dst, dst_flags, args[0], args[1]); break; case WM_LINTERP: emit_linterp(p, dst, dst_flags, args[0], args[1]); break; case WM_PINTERP: emit_pinterp(p, dst, dst_flags, args[0], args[1], args[2]); break; case WM_CINTERP: emit_cinterp(p, dst, dst_flags, args[0]); break; case WM_FB_WRITE: emit_fb_write(c, args[0], args[1], args[2], inst->target, inst->eot); break; /* Straightforward arithmetic: */ case OPCODE_ADD: emit_alu2(p, brw_ADD, dst, dst_flags, args[0], args[1]); break; case OPCODE_FRC: emit_alu1(p, brw_FRC, dst, dst_flags, args[0]); break; case OPCODE_FLR: emit_alu1(p, brw_RNDD, dst, dst_flags, args[0]); break; case OPCODE_DP3: /* */ emit_dp3(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_DP4: emit_dp4(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_DPH: emit_dph(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_LRP: /* */ emit_lrp(p, dst, dst_flags, args[0], args[1], args[2]); break; case OPCODE_MAD: emit_mad(p, dst, dst_flags, args[0], args[1], args[2]); break; case OPCODE_MOV: case OPCODE_SWZ: emit_alu1(p, brw_MOV, dst, dst_flags, args[0]); break; case OPCODE_MUL: emit_alu2(p, brw_MUL, dst, dst_flags, args[0], args[1]); break; case OPCODE_XPD: emit_xpd(p, dst, dst_flags, args[0], args[1]); break; /* Higher math functions: */ case OPCODE_RCP: emit_math1(p, BRW_MATH_FUNCTION_INV, dst, dst_flags, args[0]); break; case OPCODE_RSQ: emit_math1(p, BRW_MATH_FUNCTION_RSQ, dst, dst_flags, args[0]); break; case OPCODE_SIN: emit_math1(p, BRW_MATH_FUNCTION_SIN, dst, dst_flags, args[0]); break; case OPCODE_COS: emit_math1(p, BRW_MATH_FUNCTION_COS, dst, dst_flags, args[0]); break; case OPCODE_EX2: emit_math1(p, BRW_MATH_FUNCTION_EXP, dst, dst_flags, args[0]); break; case OPCODE_LG2: emit_math1(p, BRW_MATH_FUNCTION_LOG, dst, dst_flags, args[0]); break; case OPCODE_SCS: /* There is an scs math function, but it would need some * fixup for 16-element execution. */ if (dst_flags & WRITEMASK_X) emit_math1(p, BRW_MATH_FUNCTION_COS, dst, (dst_flags&SATURATE)|WRITEMASK_X, args[0]); if (dst_flags & WRITEMASK_Y) emit_math1(p, BRW_MATH_FUNCTION_SIN, dst+1, (dst_flags&SATURATE)|WRITEMASK_X, args[0]); break; case OPCODE_POW: emit_math2(p, BRW_MATH_FUNCTION_POW, dst, dst_flags, args[0], args[1]); break; /* Comparisons: */ case OPCODE_CMP: emit_cmp(p, dst, dst_flags, args[0], args[1], args[2]); break; case OPCODE_MAX: emit_max(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_MIN: emit_min(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_SLT: emit_slt(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_SLE: emit_sle(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_SGT: emit_sgt(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_SGE: emit_sge(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_SEQ: emit_seq(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_SNE: emit_sne(p, dst, dst_flags, args[0], args[1]); break; case OPCODE_LIT: emit_lit(p, dst, dst_flags, args[0]); break; /* Texturing operations: */ case OPCODE_TEX: emit_tex(c, inst, dst, dst_flags, args[0]); break; case OPCODE_TXB: emit_txb(c, inst, dst, dst_flags, args[0]); break; case OPCODE_KIL: emit_kil(c, args[0]); break; default: _mesa_printf("unsupport opcode %d in fragment program\n", inst->opcode); } for (i = 0; i < 4; i++) if (inst->dst[i] && inst->dst[i]->spill_slot) emit_spill(c, inst->dst[i]->hw_reg, inst->dst[i]->spill_slot); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -