📄 brw_wm_glsl.c
字号:
#include "macros.h"#include "shader/prog_parameter.h"#include "brw_context.h"#include "brw_eu.h"#include "brw_wm.h"/* Only guess, need a flag in gl_fragment_program later */GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp){ int i; for (i = 0; i < fp->Base.NumInstructions; i++) { struct prog_instruction *inst = &fp->Base.Instructions[i]; switch (inst->Opcode) { case OPCODE_IF: case OPCODE_INT: case OPCODE_ENDIF: case OPCODE_CAL: case OPCODE_BRK: case OPCODE_RET: case OPCODE_DDX: case OPCODE_DDY: case OPCODE_BGNLOOP: return GL_TRUE; default: break; } } return GL_FALSE; }static void set_reg(struct brw_wm_compile *c, int file, int index, int component, struct brw_reg reg){ c->wm_regs[file][index][component].reg = reg; c->wm_regs[file][index][component].inited = GL_TRUE;}static int get_scalar_dst_index(struct prog_instruction *inst){ int i; for (i = 0; i < 4; i++) if (inst->DstReg.WriteMask & (1<<i)) break; return i;}static struct brw_reg alloc_tmp(struct brw_wm_compile *c){ struct brw_reg reg; reg = brw_vec8_grf(c->tmp_index--, 0); return reg;}static void release_tmps(struct brw_wm_compile *c){ c->tmp_index = 127;}static struct brw_reg get_reg(struct brw_wm_compile *c, int file, int index, int component, int nr, GLuint neg, GLuint abs){ struct brw_reg reg; switch (file) { case PROGRAM_STATE_VAR: case PROGRAM_CONSTANT: case PROGRAM_UNIFORM: file = PROGRAM_STATE_VAR; break; case PROGRAM_UNDEFINED: return brw_null_reg(); default: break; } if(c->wm_regs[file][index][component].inited) reg = c->wm_regs[file][index][component].reg; else reg = brw_vec8_grf(c->reg_index, 0); if(!c->wm_regs[file][index][component].inited) { set_reg(c, file, index, component, reg); c->reg_index++; } if (neg & (1<< component)) { reg = negate(reg); } if (abs) reg = brw_abs(reg); return reg;}static void prealloc_reg(struct brw_wm_compile *c){ int i, j; struct brw_reg reg; int nr_interp_regs = 0; GLuint inputs = FRAG_BIT_WPOS | c->fp_interp_emitted | c->fp_deriv_emitted; for (i = 0; i < 4; i++) { reg = (i < c->key.nr_depth_regs) ? brw_vec8_grf(i*2, 0) : brw_vec8_grf(0, 0); set_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, i, reg); } c->reg_index += 2*c->key.nr_depth_regs; { int nr_params = c->fp->program.Base.Parameters->NumParameters; struct gl_program_parameter_list *plist = c->fp->program.Base.Parameters; int index = 0; c->prog_data.nr_params = 4*nr_params; for (i = 0; i < nr_params; i++) { for (j = 0; j < 4; j++, index++) { reg = brw_vec1_grf(c->reg_index + index/8, index%8); c->prog_data.param[index] = &plist->ParameterValues[i][j]; set_reg(c, PROGRAM_STATE_VAR, i, j, reg); } } c->nr_creg = 2*((4*nr_params+15)/16); c->reg_index += c->nr_creg; } for (i = 0; i < FRAG_ATTRIB_MAX; i++) { if (inputs & (1<<i)) { nr_interp_regs++; reg = brw_vec8_grf(c->reg_index, 0); for (j = 0; j < 4; j++) set_reg(c, PROGRAM_PAYLOAD, i, j, reg); c->reg_index += 2; } } c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2; c->prog_data.urb_read_length = nr_interp_regs * 2; c->prog_data.curb_read_length = c->nr_creg; c->emit_mask_reg = brw_uw1_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0); c->reg_index++; c->stack = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0); c->reg_index += 2;}static struct brw_reg get_dst_reg(struct brw_wm_compile *c, struct prog_instruction *inst, int component, int nr){ return get_reg(c, inst->DstReg.File, inst->DstReg.Index, component, nr, 0, 0);}static struct brw_reg get_src_reg(struct brw_wm_compile *c, struct prog_src_register *src, int index, int nr){ int component = GET_SWZ(src->Swizzle, index); return get_reg(c, src->File, src->Index, component, nr, src->NegateBase, src->Abs);}static void emit_abs( struct brw_wm_compile *c, struct prog_instruction *inst){ int i; struct brw_compile *p = &c->func; brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF); for (i = 0; i < 4; i++) { if (inst->DstReg.WriteMask & (1<<i)) { struct brw_reg src, dst; dst = get_dst_reg(c, inst, i, 1); src = get_src_reg(c, &inst->SrcReg[0], i, 1); brw_MOV(p, dst, brw_abs(src)); } } brw_set_saturate(p, 0);}static void emit_int( struct brw_wm_compile *c, struct prog_instruction *inst){ int i; struct brw_compile *p = &c->func; GLuint mask = inst->DstReg.WriteMask; brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF); for (i = 0; i < 4; i++) { if (mask & (1<<i)) { struct brw_reg src, dst; dst = get_dst_reg(c, inst, i, 1) ; src = get_src_reg(c, &inst->SrcReg[0], i, 1); brw_RNDD(p, dst, src); } } brw_set_saturate(p, 0);}static void emit_mov( struct brw_wm_compile *c, struct prog_instruction *inst){ int i; struct brw_compile *p = &c->func; GLuint mask = inst->DstReg.WriteMask; brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF); for (i = 0; i < 4; i++) { if (mask & (1<<i)) { struct brw_reg src, dst; dst = get_dst_reg(c, inst, i, 1); src = get_src_reg(c, &inst->SrcReg[0], i, 1); brw_MOV(p, dst, src); } } brw_set_saturate(p, 0);}static void emit_pixel_xy(struct brw_wm_compile *c, struct prog_instruction *inst){ struct brw_reg r1 = brw_vec1_grf(1, 0); struct brw_reg r1_uw = retype(r1, BRW_REGISTER_TYPE_UW); struct brw_reg dst0, dst1; struct brw_compile *p = &c->func; GLuint mask = inst->DstReg.WriteMask; dst0 = get_dst_reg(c, inst, 0, 1); dst1 = get_dst_reg(c, inst, 1, 1); /* Calculate pixel centers by adding 1 or 0 to each of the * micro-tile coordinates passed in r1. */ if (mask & WRITEMASK_X) { brw_ADD(p, vec8(retype(dst0, BRW_REGISTER_TYPE_UW)), stride(suboffset(r1_uw, 4), 2, 4, 0), brw_imm_v(0x10101010)); } if (mask & WRITEMASK_Y) { brw_ADD(p, vec8(retype(dst1, BRW_REGISTER_TYPE_UW)), stride(suboffset(r1_uw, 5), 2, 4, 0), brw_imm_v(0x11001100)); }}static void emit_delta_xy(struct brw_wm_compile *c, struct prog_instruction *inst){ struct brw_reg r1 = brw_vec1_grf(1, 0); struct brw_reg dst0, dst1, src0, src1; struct brw_compile *p = &c->func; GLuint mask = inst->DstReg.WriteMask; dst0 = get_dst_reg(c, inst, 0, 1); dst1 = get_dst_reg(c, inst, 1, 1); src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1); src1 = get_src_reg(c, &inst->SrcReg[0], 1, 1); /* Calc delta X,Y by subtracting origin in r1 from the pixel * centers. */ if (mask & WRITEMASK_X) { brw_ADD(p, dst0, retype(src0, BRW_REGISTER_TYPE_UW), negate(r1)); } if (mask & WRITEMASK_Y) { brw_ADD(p, dst1, retype(src1, BRW_REGISTER_TYPE_UW), negate(suboffset(r1,1))); }}static void fire_fb_write( struct brw_wm_compile *c, GLuint base_reg, GLuint nr, GLuint target, GLuint eot){ struct brw_compile *p = &c->func; /* Pass through control information: */ /* mov (8) m1.0<1>:ud r1.0<8;8,1>:ud { Align1 NoMask } */ { brw_push_insn_state(p); brw_set_mask_control(p, BRW_MASK_DISABLE); /* ? */ brw_MOV(p, brw_message_reg(base_reg + 1), brw_vec8_grf(1, 0)); brw_pop_insn_state(p); } /* Send framebuffer write message: */ brw_fb_WRITE(p, retype(vec8(brw_null_reg()), BRW_REGISTER_TYPE_UW), base_reg, retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW), target, nr, 0, eot);}static void emit_fb_write(struct brw_wm_compile *c, struct prog_instruction *inst){ struct brw_compile *p = &c->func; int nr = 2; int channel; GLuint target, eot; struct brw_reg src0; /* Reserve a space for AA - may not be needed: */ if (c->key.aa_dest_stencil_reg) nr += 1; { brw_push_insn_state(p); for (channel = 0; channel < 4; channel++) { src0 = get_src_reg(c, &inst->SrcReg[0], channel, 1); /* 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_MOV(p, brw_message_reg(nr + channel), src0); } /* 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) { src0 = get_src_reg(c, &inst->SrcReg[2], 2, 1); brw_MOV(p, brw_message_reg(nr), src0); } else { src0 = get_src_reg(c, &inst->SrcReg[1], 1, 1); brw_MOV(p, brw_message_reg(nr), src0); } nr += 2; } target = inst->Sampler >> 1; eot = inst->Sampler & 1; fire_fb_write(c, 0, nr, target, eot);}static void emit_pixel_w( struct brw_wm_compile *c, struct prog_instruction *inst){ struct brw_compile *p = &c->func; GLuint mask = inst->DstReg.WriteMask; if (mask & WRITEMASK_W) { struct brw_reg dst, src0, delta0, delta1; struct brw_reg interp3; dst = get_dst_reg(c, inst, 3, 1); src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1); delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1); delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1); interp3 = brw_vec1_grf(src0.nr+1, 4); /* Calc 1/w - just linterp wpos[3] optimized by putting the * result straight into a message reg. */ brw_LINE(p, brw_null_reg(), interp3, delta0); brw_MAC(p, brw_message_reg(2), suboffset(interp3, 1), delta1); /* Calc w */ brw_math_16( p, dst, BRW_MATH_FUNCTION_INV, BRW_MATH_SATURATE_NONE, 2, brw_null_reg(), BRW_MATH_PRECISION_FULL); }}static void emit_linterp(struct brw_wm_compile *c, struct prog_instruction *inst){ struct brw_compile *p = &c->func; GLuint mask = inst->DstReg.WriteMask; struct brw_reg interp[4]; struct brw_reg dst, delta0, delta1; struct brw_reg src0; src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1); delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1); delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1); GLuint nr = src0.nr; int i; interp[0] = brw_vec1_grf(nr, 0); interp[1] = brw_vec1_grf(nr, 4); interp[2] = brw_vec1_grf(nr+1, 0); interp[3] = brw_vec1_grf(nr+1, 4); for(i = 0; i < 4; i++ ) { if (mask & (1<<i)) { dst = get_dst_reg(c, inst, i, 1); brw_LINE(p, brw_null_reg(), interp[i], delta0); brw_MAC(p, dst, suboffset(interp[i],1), delta1); } }}static void emit_cinterp(struct brw_wm_compile *c, struct prog_instruction *inst){ struct brw_compile *p = &c->func; GLuint mask = inst->DstReg.WriteMask; struct brw_reg interp[4]; struct brw_reg dst, src0; src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1); GLuint nr = src0.nr; int i; interp[0] = brw_vec1_grf(nr, 0); interp[1] = brw_vec1_grf(nr, 4); interp[2] = brw_vec1_grf(nr+1, 0); interp[3] = brw_vec1_grf(nr+1, 4); for(i = 0; i < 4; i++ ) { if (mask & (1<<i)) { dst = get_dst_reg(c, inst, i, 1); brw_MOV(p, dst, suboffset(interp[i],3)); } }}static void emit_pinterp(struct brw_wm_compile *c, struct prog_instruction *inst){ struct brw_compile *p = &c->func; GLuint mask = inst->DstReg.WriteMask; struct brw_reg interp[4]; struct brw_reg dst, delta0, delta1; struct brw_reg src0, w; src0 = get_src_reg(c, &inst->SrcReg[0], 0, 1); delta0 = get_src_reg(c, &inst->SrcReg[1], 0, 1); delta1 = get_src_reg(c, &inst->SrcReg[1], 1, 1); w = get_src_reg(c, &inst->SrcReg[2], 3, 1); GLuint nr = src0.nr; int i; interp[0] = brw_vec1_grf(nr, 0); interp[1] = brw_vec1_grf(nr, 4); interp[2] = brw_vec1_grf(nr+1, 0); interp[3] = brw_vec1_grf(nr+1, 4); for(i = 0; i < 4; i++ ) { if (mask & (1<<i)) { dst = get_dst_reg(c, inst, i, 1); brw_LINE(p, brw_null_reg(), interp[i], delta0); brw_MAC(p, dst, suboffset(interp[i],1), delta1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -