📄 brw_vs_tnl.c
字号:
static struct ureg register_param5( struct tnl_program *p, GLint s0, GLint s1, GLint s2, GLint s3, GLint s4){ gl_state_index tokens[STATE_LENGTH]; GLint idx; tokens[0] = s0; tokens[1] = s1; tokens[2] = s2; tokens[3] = s3; tokens[4] = s4; idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens ); return make_ureg(PROGRAM_STATE_VAR, idx);}#define register_param1(p,s0) register_param5(p,s0,0,0,0,0)#define register_param2(p,s0,s1) register_param5(p,s0,s1,0,0,0)#define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0)#define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0)static void register_matrix_param5( struct tnl_program *p, GLint s0, /* matrix name */ GLint s1, /* texture matrix number */ GLint s2, /* first row */ GLint s3, /* last row */ GLint s4, /* modifier */ struct ureg *matrix ){ GLint i; /* This is a bit sad as the support is there to pull the whole * matrix out in one go: */ for (i = 0; i <= s3 - s2; i++) matrix[i] = register_param5( p, s0, s1, i, i, s4 );}static void emit_arg( struct prog_src_register *src, struct ureg reg ){ src->File = reg.file; src->Index = reg.idx; src->Swizzle = reg.swz; src->RelAddr = 0; src->NegateBase = reg.negate; src->Abs = 0; src->NegateAbs = 0;}static void emit_dst( struct prog_dst_register *dst, struct ureg reg, GLuint mask ){ dst->File = reg.file; dst->Index = reg.idx; /* allow zero as a shorthand for xyzw */ dst->WriteMask = mask ? mask : WRITEMASK_XYZW; dst->CondMask = 0; dst->CondSwizzle = 0; dst->CondSrc = 0; dst->pad = 0;}static void debug_insn( struct prog_instruction *inst, const char *fn, GLuint line ){ if (DISASSEM) { static const char *last_fn; if (fn != last_fn) { last_fn = fn; _mesa_printf("%s:\n", fn); } _mesa_printf("%d:\t", line); _mesa_print_instruction(inst); }}static void emit_op3fn(struct tnl_program *p, GLuint op, struct ureg dest, GLuint mask, struct ureg src0, struct ureg src1, struct ureg src2, const char *fn, GLuint line){ GLuint nr = p->program->Base.NumInstructions++; if (nr >= p->nr_instructions) { int new_nr_instructions = p->nr_instructions * 2; p->program->Base.Instructions = _mesa_realloc(p->program->Base.Instructions, sizeof(struct prog_instruction) * p->nr_instructions, sizeof(struct prog_instruction) * new_nr_instructions); p->nr_instructions = new_nr_instructions; } { struct prog_instruction *inst = &p->program->Base.Instructions[nr]; memset(inst, 0, sizeof(*inst)); inst->Opcode = op; inst->StringPos = 0; inst->Data = 0; emit_arg( &inst->SrcReg[0], src0 ); emit_arg( &inst->SrcReg[1], src1 ); emit_arg( &inst->SrcReg[2], src2 ); emit_dst( &inst->DstReg, dest, mask ); debug_insn(inst, fn, line); }} #define emit_op3(p, op, dst, mask, src0, src1, src2) \ emit_op3fn(p, op, dst, mask, src0, src1, src2, __FUNCTION__, __LINE__)#define emit_op2(p, op, dst, mask, src0, src1) \ emit_op3fn(p, op, dst, mask, src0, src1, undef, __FUNCTION__, __LINE__)#define emit_op1(p, op, dst, mask, src0) \ emit_op3fn(p, op, dst, mask, src0, undef, undef, __FUNCTION__, __LINE__)static struct ureg make_temp( struct tnl_program *p, struct ureg reg ){ if (reg.file == PROGRAM_TEMPORARY && !(p->temp_reserved & (1<<reg.idx))) return reg; else { struct ureg temp = get_temp(p); emit_op1(p, OPCODE_MOV, temp, 0, reg); return temp; }}/* Currently no tracking performed of input/output/register size or * active elements. Could be used to reduce these operations, as * could the matrix type. */static void emit_matrix_transform_vec4( struct tnl_program *p, struct ureg dest, const struct ureg *mat, struct ureg src){ emit_op2(p, OPCODE_DP4, dest, WRITEMASK_X, src, mat[0]); emit_op2(p, OPCODE_DP4, dest, WRITEMASK_Y, src, mat[1]); emit_op2(p, OPCODE_DP4, dest, WRITEMASK_Z, src, mat[2]); emit_op2(p, OPCODE_DP4, dest, WRITEMASK_W, src, mat[3]);}/* This version is much easier to implement if writemasks are not * supported natively on the target or (like SSE), the target doesn't * have a clean/obvious dotproduct implementation. */static void emit_transpose_matrix_transform_vec4( struct tnl_program *p, struct ureg dest, const struct ureg *mat, struct ureg src){ struct ureg tmp; if (dest.file != PROGRAM_TEMPORARY) tmp = get_temp(p); else tmp = dest; emit_op2(p, OPCODE_MUL, tmp, 0, swizzle1(src,X), mat[0]); emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Y), mat[1], tmp); emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Z), mat[2], tmp); emit_op3(p, OPCODE_MAD, dest, 0, swizzle1(src,W), mat[3], tmp); if (dest.file != PROGRAM_TEMPORARY) release_temp(p, tmp);}static void emit_matrix_transform_vec3( struct tnl_program *p, struct ureg dest, const struct ureg *mat, struct ureg src){ emit_op2(p, OPCODE_DP3, dest, WRITEMASK_X, src, mat[0]); emit_op2(p, OPCODE_DP3, dest, WRITEMASK_Y, src, mat[1]); emit_op2(p, OPCODE_DP3, dest, WRITEMASK_Z, src, mat[2]);}static void emit_normalize_vec3( struct tnl_program *p, struct ureg dest, struct ureg src ){ emit_op2(p, OPCODE_DP3, dest, WRITEMASK_W, src, src); emit_op1(p, OPCODE_RSQ, dest, WRITEMASK_W, swizzle1(dest,W)); emit_op2(p, OPCODE_MUL, dest, WRITEMASK_XYZ, src, swizzle1(dest,W));}static void emit_passthrough( struct tnl_program *p, GLuint input, GLuint output ){ struct ureg out = register_output(p, output); emit_op1(p, OPCODE_MOV, out, 0, register_input(p, input)); }static struct ureg get_eye_position( struct tnl_program *p ){ if (is_undef(p->eye_position)) { struct ureg pos = register_input( p, VERT_ATTRIB_POS ); struct ureg modelview[4]; p->eye_position = reserve_temp(p); if (PREFER_DP4) { register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, 0, modelview ); emit_matrix_transform_vec4(p, p->eye_position, modelview, pos); } else { register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, STATE_MATRIX_TRANSPOSE, modelview ); emit_transpose_matrix_transform_vec4(p, p->eye_position, modelview, pos); } } return p->eye_position;}#if 0static struct ureg get_eye_z( struct tnl_program *p ){ if (!is_undef(p->eye_position)) { return swizzle1(p->eye_position, Z); } else if (!is_undef(p->eye_z)) { struct ureg pos = register_input( p, BRW_ATTRIB_POS ); struct ureg modelview2; p->eye_z = reserve_temp(p); register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 2, 1, STATE_MATRIX, &modelview2 ); emit_matrix_transform_vec4(p, p->eye_position, modelview, pos); emit_op2(p, OPCODE_DP4, p->eye_z, WRITEMASK_Z, pos, modelview2); } return swizzle1(p->eye_z, Z)}#endifstatic struct ureg get_eye_position_normalized( struct tnl_program *p ){ if (is_undef(p->eye_position_normalized)) { struct ureg eye = get_eye_position(p); p->eye_position_normalized = reserve_temp(p); emit_normalize_vec3(p, p->eye_position_normalized, eye); } return p->eye_position_normalized;}static struct ureg get_eye_normal( struct tnl_program *p ){ if (is_undef(p->eye_normal)) { struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL ); struct ureg mvinv[3]; register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 2, STATE_MATRIX_INVTRANS, mvinv ); p->eye_normal = reserve_temp(p); /* Transform to eye space: */ emit_matrix_transform_vec3( p, p->eye_normal, mvinv, normal ); /* Normalize/Rescale: */ if (p->state->normalize) { emit_normalize_vec3( p, p->eye_normal, p->eye_normal ); } else if (p->state->rescale_normals) { struct ureg rescale = register_param2(p, STATE_INTERNAL, STATE_NORMAL_SCALE); emit_op2( p, OPCODE_MUL, p->eye_normal, 0, p->eye_normal, swizzle1(rescale, X)); } } return p->eye_normal;}static void build_hpos( struct tnl_program *p ){ struct ureg pos = register_input( p, VERT_ATTRIB_POS ); struct ureg hpos = register_output( p, VERT_RESULT_HPOS ); struct ureg mvp[4]; if (PREFER_DP4) { register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, 0, mvp ); emit_matrix_transform_vec4( p, hpos, mvp, pos ); } else { register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, STATE_MATRIX_TRANSPOSE, mvp ); emit_transpose_matrix_transform_vec4( p, hpos, mvp, pos ); }}static GLuint material_attrib( GLuint side, GLuint property ){ return (property - STATE_AMBIENT) * 2 + side;}/* Get a bitmask of which material values vary on a per-vertex basis. */static void set_material_flags( struct tnl_program *p ){ p->color_materials = 0; p->materials = 0; if (p->state->light_color_material) { p->materials = p->color_materials = p->state->light_color_material_mask; } p->materials |= p->state->light_material_mask;}static struct ureg get_material( struct tnl_program *p, GLuint side, GLuint property ){ GLuint attrib = material_attrib(side, property); if (p->color_materials & (1<<attrib)) return register_input(p, VERT_ATTRIB_COLOR0); else if (p->materials & (1<<attrib)) return register_input( p, attrib + _TNL_ATTRIB_MAT_FRONT_AMBIENT ); else return register_param3( p, STATE_MATERIAL, side, property );}#define SCENE_COLOR_BITS(side) ((MAT_BIT_FRONT_EMISSION | \ MAT_BIT_FRONT_AMBIENT | \ MAT_BIT_FRONT_DIFFUSE) << (side))/* Either return a precalculated constant value or emit code to * calculate these values dynamically in the case where material calls * are present between begin/end pairs. * * Probably want to shift this to the program compilation phase - if * we always emitted the calculation here, a smart compiler could * detect that it was constant (given a certain set of inputs), and * lift it out of the main loop. That way the programs created here * would be independent of the vertex_buffer details. */static struct ureg get_scenecolor( struct tnl_program *p, GLuint side ){ if (p->materials & SCENE_COLOR_BITS(side)) { struct ureg lm_ambient = register_param1(p, STATE_LIGHTMODEL_AMBIENT); struct ureg material_emission = get_material(p, side, STATE_EMISSION); struct ureg material_ambient = get_material(p, side, STATE_AMBIENT); struct ureg material_diffuse = get_material(p, side, STATE_DIFFUSE); struct ureg tmp = make_temp(p, material_diffuse); emit_op3(p, OPCODE_MAD, tmp, WRITEMASK_XYZ, lm_ambient, material_ambient, material_emission); return tmp; } else return register_param2( p, STATE_LIGHTMODEL_SCENECOLOR, side );}static struct ureg get_lightprod( struct tnl_program *p, GLuint light, GLuint side, GLuint property ){ GLuint attrib = material_attrib(side, property); if (p->materials & (1<<attrib)) { struct ureg light_value = register_param3(p, STATE_LIGHT, light, property); struct ureg material_value = get_material(p, side, property); struct ureg tmp = get_temp(p); emit_op2(p, OPCODE_MUL, tmp, 0, light_value, material_value); return tmp; } else return register_param4(p, STATE_LIGHTPROD, light, side, property);}static struct ureg calculate_light_attenuation( struct tnl_program *p, GLuint i, struct ureg VPpli, struct ureg dist ){ struct ureg attenuation = register_param3(p, STATE_LIGHT, i, STATE_ATTENUATION); struct ureg att = get_temp(p); /* Calculate spot attenuation: */ if (!p->state->unit[i].light_spotcutoff_is_180) { struct ureg spot_dir_norm = register_param3(p, STATE_INTERNAL, STATE_SPOT_DIR_NORMALIZED, i);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -