/* Seems like it could be tighter: */ static void build_pointsize( struct tnl_program *p ) { struct ureg eye = get_eye_position(p); struct ureg state_size = register_param1(p, STATE_POINT_SIZE); struct ureg state_attenuation = register_param1(p, STATE_POINT_ATTENUATION); struct ureg out = register_output(p, VERT_RESULT_PSIZ); struct ureg ut = get_temp(p); /* 1, Z, Z * Z, 1 */ emit_op1(p, OPCODE_MOV, ut, WRITEMASK_XW, swizzle1(get_identity_param(p), W)); emit_op1(p, OPCODE_ABS, ut, WRITEMASK_YZ, swizzle1(eye, Z)); emit_op2(p, OPCODE_MUL, ut, WRITEMASK_Z, ut, ut); /* p1 + p2 * dist + p3 * dist * dist, 0 */ emit_op2(p, OPCODE_DP3, ut, WRITEMASK_X, ut, state_attenuation); /* 1 / sqrt(factor) */ emit_op1(p, OPCODE_RSQ, ut, WRITEMASK_X, ut ); /* ut = pointSize / factor */ emit_op2(p, OPCODE_MUL, ut, WRITEMASK_X, ut, state_size); /* Clamp to min/max - state_size.[yz] */ emit_op2(p, OPCODE_MAX, ut, WRITEMASK_X, ut, swizzle1(state_size, Y)); emit_op2(p, OPCODE_MIN, out, 0, swizzle1(ut, X), swizzle1(state_size, Z)); release_temp(p, ut); }
/** * Point size attenuation computation. */ static void build_atten_pointsize( struct tnl_program *p ) { struct ureg eye = get_eye_position_z(p); struct ureg state_size = register_param1(p, STATE_POINT_SIZE); struct ureg state_attenuation = register_param1(p, STATE_POINT_ATTENUATION); struct ureg out = register_output(p, VERT_RESULT_PSIZ); struct ureg ut = get_temp(p); /* dist = |eyez| */ emit_op1(p, OPCODE_ABS, ut, WRITEMASK_Y, swizzle1(eye, Z)); /* p1 + dist * (p2 + dist * p3); */ emit_op3(p, OPCODE_MAD, ut, WRITEMASK_X, swizzle1(ut, Y), swizzle1(state_attenuation, Z), swizzle1(state_attenuation, Y)); emit_op3(p, OPCODE_MAD, ut, WRITEMASK_X, swizzle1(ut, Y), ut, swizzle1(state_attenuation, X)); /* 1 / sqrt(factor) */ emit_op1(p, OPCODE_RSQ, ut, WRITEMASK_X, ut ); #if 0 /* out = pointSize / sqrt(factor) */ emit_op2(p, OPCODE_MUL, out, WRITEMASK_X, ut, state_size); #else /* this is a good place to clamp the point size since there's likely * no hardware registers to clamp point size at rasterization time. */ emit_op2(p, OPCODE_MUL, ut, WRITEMASK_X, ut, state_size); emit_op2(p, OPCODE_MAX, ut, WRITEMASK_X, ut, swizzle1(state_size, Y)); emit_op2(p, OPCODE_MIN, out, WRITEMASK_X, ut, swizzle1(state_size, Z)); #endif release_temp(p, ut); }
static void build_pointsize( struct tnl_program *p ) { struct ureg eye = get_eye_position(p); struct ureg state_size = register_param1(p, STATE_POINT_SIZE); struct ureg state_attenuation = register_param1(p, STATE_POINT_ATTENUATION); struct ureg out = register_output(p, VERT_RESULT_PSIZ); struct ureg ut = get_temp(p); /* dist = |eyez| */ emit_op1(p, OPCODE_ABS, ut, WRITEMASK_Y, swizzle1(eye, Z)); /* p1 + dist * (p2 + dist * p3); */ emit_op3(p, OPCODE_MAD, ut, WRITEMASK_X, swizzle1(ut, Y), swizzle1(state_attenuation, Z), swizzle1(state_attenuation, Y)); emit_op3(p, OPCODE_MAD, ut, WRITEMASK_X, swizzle1(ut, Y), ut, swizzle1(state_attenuation, X)); /* 1 / sqrt(factor) */ emit_op1(p, OPCODE_RSQ, ut, WRITEMASK_X, ut ); #if 1 /* out = pointSize / sqrt(factor) */ emit_op2(p, OPCODE_MUL, out, WRITEMASK_X, ut, state_size); #else /* not sure, might make sense to do clamping here, but it's not done in t_vb_points neither */ emit_op2(p, OPCODE_MUL, ut, WRITEMASK_X, ut, state_size); emit_op2(p, OPCODE_MAX, ut, WRITEMASK_X, ut, swizzle1(state_size, Y)); emit_op2(p, OPCODE_MIN, out, WRITEMASK_X, ut, swizzle1(state_size, Z)); #endif release_temp(p, ut); }
/** * 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 ); }