X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fffvertex_prog.c;h=03f42704a7d3a2719ff791ffee8fab5d6d5e446e;hb=c952b3e907ab31cd5f95157c18ce2f81626aafe4;hp=ec0a5e3896d91e1645347c395d698c81fffb7a52;hpb=5b714723895d321db753f896576de5e2c27778c3;p=mesa.git diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c index ec0a5e3896d..03f42704a7d 100644 --- a/src/mesa/main/ffvertex_prog.c +++ b/src/mesa/main/ffvertex_prog.c @@ -26,7 +26,7 @@ **************************************************************************/ /** - * \file ffvertex_prog. + * \file ffvertex_prog.c * * Create a vertex program to execute the current fixed function T&L pipeline. * \author Keith Whitwell @@ -101,6 +101,7 @@ static GLuint translate_fog_mode( GLenum mode ) } } + #define TXG_NONE 0 #define TXG_OBJ_LINEAR 1 #define TXG_EYE_LINEAR 2 @@ -145,6 +146,7 @@ tnl_get_per_vertex_materials(GLcontext *ctx) return mask; } + /** * Should fog be computed per-vertex? */ @@ -159,6 +161,7 @@ tnl_get_per_vertex_fog(GLcontext *ctx) #endif } + static GLboolean check_active_shininess( GLcontext *ctx, const struct state_key *key, GLuint side ) @@ -176,8 +179,6 @@ static GLboolean check_active_shininess( GLcontext *ctx, return GL_FALSE; } - - static void make_state_key( GLcontext *ctx, struct state_key *key ) @@ -278,7 +279,7 @@ static void make_state_key( GLcontext *ctx, struct state_key *key ) ctx->Texture._EnabledUnits) key->texture_enabled_global = 1; - for (i = 0; i < MAX_TEXTURE_UNITS; i++) { + for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; if (texUnit->_ReallyEnabled) @@ -292,16 +293,16 @@ static void make_state_key( GLcontext *ctx, struct state_key *key ) key->unit[i].texgen_mode0 = translate_texgen( texUnit->TexGenEnabled & (1<<0), - texUnit->GenModeS ); + texUnit->GenS.Mode ); key->unit[i].texgen_mode1 = translate_texgen( texUnit->TexGenEnabled & (1<<1), - texUnit->GenModeT ); + texUnit->GenT.Mode ); key->unit[i].texgen_mode2 = translate_texgen( texUnit->TexGenEnabled & (1<<2), - texUnit->GenModeR ); + texUnit->GenR.Mode ); key->unit[i].texgen_mode3 = translate_texgen( texUnit->TexGenEnabled & (1<<3), - texUnit->GenModeQ ); + texUnit->GenQ.Mode ); } } } @@ -362,7 +363,7 @@ struct tnl_program { }; -static const struct ureg undef = { +static const struct ureg undef = { PROGRAM_UNDEFINED, 0, 0, @@ -397,7 +398,7 @@ static struct ureg negate( struct ureg reg ) { reg.negate ^= 1; return reg; -} +} static struct ureg swizzle( struct ureg reg, int x, int y, int z, int w ) @@ -406,15 +407,16 @@ static struct ureg swizzle( struct ureg reg, int x, int y, int z, int w ) GET_SWZ(reg.swz, y), GET_SWZ(reg.swz, z), GET_SWZ(reg.swz, w)); - return reg; } + static struct ureg swizzle1( struct ureg reg, int x ) { return swizzle(reg, x, x, x, x); } + static struct ureg get_temp( struct tnl_program *p ) { int bit = _mesa_ffs( ~p->temp_in_use ); @@ -430,6 +432,7 @@ static struct ureg get_temp( struct tnl_program *p ) return make_ureg(PROGRAM_TEMPORARY, bit-1); } + static struct ureg reserve_temp( struct tnl_program *p ) { struct ureg temp = get_temp( p ); @@ -437,6 +440,7 @@ static struct ureg reserve_temp( struct tnl_program *p ) return temp; } + static void release_temp( struct tnl_program *p, struct ureg reg ) { if (reg.file == PROGRAM_TEMPORARY) { @@ -493,6 +497,7 @@ static struct ureg register_input( struct tnl_program *p, GLuint input ) } } + /** * \param input one of VERT_RESULT_x tokens. */ @@ -502,6 +507,7 @@ static struct ureg register_output( struct tnl_program *p, GLuint output ) return make_ureg(PROGRAM_OUTPUT, output); } + static struct ureg register_const4f( struct tnl_program *p, GLfloat s0, GLfloat s1, @@ -531,6 +537,7 @@ static GLboolean is_undef( struct ureg reg ) return reg.file == PROGRAM_UNDEFINED; } + static struct ureg get_identity_param( struct tnl_program *p ) { if (is_undef(p->identity)) @@ -571,6 +578,7 @@ static void emit_arg( struct prog_src_register *src, ASSERT(src->Index == reg.idx); } + static void emit_dst( struct prog_dst_register *dst, struct ureg reg, GLuint mask ) { @@ -586,6 +594,7 @@ static void emit_dst( struct prog_dst_register *dst, ASSERT(dst->Index == reg.idx); } + static void debug_insn( struct prog_instruction *inst, const char *fn, GLuint line ) { @@ -645,7 +654,6 @@ static void emit_op3fn(struct tnl_program *p, inst = &p->program->Base.Instructions[nr]; inst->Opcode = (enum prog_opcode) op; - inst->StringPos = 0; inst->Data = 0; emit_arg( &inst->SrcReg[0], src0 ); @@ -696,6 +704,7 @@ static void emit_matrix_transform_vec4( struct tnl_program *p, 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. @@ -721,6 +730,7 @@ static void emit_transpose_matrix_transform_vec4( struct tnl_program *p, release_temp(p, tmp); } + static void emit_matrix_transform_vec3( struct tnl_program *p, struct ureg dest, const struct ureg *mat, @@ -748,6 +758,7 @@ static void emit_normalize_vec3( struct tnl_program *p, #endif } + static void emit_passthrough( struct tnl_program *p, GLuint input, GLuint output ) @@ -756,6 +767,7 @@ static void emit_passthrough( struct tnl_program *p, 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)) { @@ -803,7 +815,6 @@ static struct ureg get_eye_position_z( struct tnl_program *p ) } - static struct ureg get_eye_position_normalized( struct tnl_program *p ) { if (is_undef(p->eye_position_normalized)) { @@ -865,7 +876,6 @@ static struct ureg get_transformed_normal( struct tnl_program *p ) } - static void build_hpos( struct tnl_program *p ) { struct ureg pos = register_input( p, VERT_ATTRIB_POS ); @@ -887,11 +897,12 @@ static void build_hpos( struct tnl_program *p ) static GLuint material_attrib( GLuint side, GLuint property ) { - return ((property - STATE_AMBIENT) * 2 + - side); + return (property - STATE_AMBIENT) * 2 + side; } -/* Get a bitmask of which material values vary on a per-vertex basis. + +/** + * Get a bitmask of which material values vary on a per-vertex basis. */ static void set_material_flags( struct tnl_program *p ) { @@ -927,7 +938,9 @@ static struct ureg get_material( struct tnl_program *p, GLuint side, MAT_BIT_FRONT_AMBIENT | \ MAT_BIT_FRONT_DIFFUSE) << (side)) -/* Either return a precalculated constant value or emit code to + +/** + * 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. * @@ -945,7 +958,7 @@ static struct ureg get_scenecolor( struct tnl_program *p, GLuint side ) 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, + emit_op3(p, OPCODE_MAD, tmp, WRITEMASK_XYZ, lm_ambient, material_ambient, material_emission); return tmp; } @@ -963,13 +976,14 @@ static struct ureg get_lightprod( struct tnl_program *p, GLuint light, 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); + 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, @@ -999,7 +1013,6 @@ static struct ureg calculate_light_attenuation( struct tnl_program *p, /* Calculate distance attenuation: */ if (p->state->unit[i].light_attenuated) { - /* 1/d,d,d,1/d */ emit_op1(p, OPCODE_RCP, dist, WRITEMASK_YZ, dist); /* 1,d,d*d,1/d */ @@ -1012,7 +1025,8 @@ static struct ureg calculate_light_attenuation( struct tnl_program *p, emit_op1(p, OPCODE_RCP, dist, 0, dist); /* spot-atten * dist-atten */ emit_op2(p, OPCODE_MUL, att, 0, dist, att); - } else { + } + else { /* dist-atten */ emit_op1(p, OPCODE_RCP, att, 0, dist); } @@ -1066,10 +1080,10 @@ static void build_lighting( struct tnl_program *p ) /* * NOTE: - * dot.x = dot(normal, VPpli) - * dot.y = dot(normal, halfAngle) - * dot.z = back.shininess - * dot.w = front.shininess + * dots.x = dot(normal, VPpli) + * dots.y = dot(normal, halfAngle) + * dots.z = back.shininess + * dots.w = front.shininess */ for (i = 0; i < MAX_LIGHTS; i++) @@ -1081,7 +1095,7 @@ static void build_lighting( struct tnl_program *p ) { if (!p->state->material_shininess_is_zero) { struct ureg shininess = get_material(p, 0, STATE_SHININESS); - emit_op1(p, OPCODE_MOV, dots, WRITEMASK_W, swizzle1(shininess,X)); + emit_op1(p, OPCODE_MOV, dots, WRITEMASK_W, swizzle1(shininess,X)); release_temp(p, shininess); } @@ -1090,11 +1104,13 @@ static void build_lighting( struct tnl_program *p ) _col1 = make_temp(p, get_identity_param(p)); else _col1 = _col0; - } if (twoside) { if (!p->state->material_shininess_is_zero) { + /* Note that we negate the back-face specular exponent here. + * The negation will be un-done later in the back-face code below. + */ struct ureg shininess = get_material(p, 1, STATE_SHININESS); emit_op1(p, OPCODE_MOV, dots, WRITEMASK_Z, negate(swizzle1(shininess,X))); @@ -1155,12 +1171,13 @@ static void build_lighting( struct tnl_program *p ) half = get_temp(p); emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat); emit_normalize_vec3(p, half, half); - } else { + } + else { half = register_param3(p, STATE_INTERNAL, STATE_LIGHT_HALF_VECTOR, i); } } - } + } else { struct ureg Ppli = register_param3(p, STATE_INTERNAL, STATE_LIGHT_POSITION, i); @@ -1226,7 +1243,6 @@ static void build_lighting( struct tnl_program *p ) struct ureg res0, res1; GLuint mask0, mask1; - if (count == nr_lights) { if (separate) { mask0 = WRITEMASK_XYZ; @@ -1240,25 +1256,25 @@ static void build_lighting( struct tnl_program *p ) res0 = _col0; res1 = register_output( p, VERT_RESULT_COL0 ); } - } else { + } + else { mask0 = 0; mask1 = 0; res0 = _col0; res1 = _col1; } - if (!is_undef(att)) { /* light is attenuated by distance */ emit_op1(p, OPCODE_LIT, lit, 0, dots); emit_op2(p, OPCODE_MUL, lit, 0, lit, att); emit_op3(p, OPCODE_MAD, _col0, 0, swizzle1(lit,X), ambient, _col0); - } + } else if (!p->state->material_shininess_is_zero) { /* there's a non-zero specular term */ emit_op1(p, OPCODE_LIT, lit, 0, dots); emit_op2(p, OPCODE_ADD, _col0, 0, ambient, _col0); - } + } else { /* no attenutation, no specular */ emit_degenerate_lit(p, lit, dots); @@ -1295,13 +1311,19 @@ static void build_lighting( struct tnl_program *p ) res0 = _bfc0; res1 = register_output( p, VERT_RESULT_BFC0 ); } - } else { + } + else { res0 = _bfc0; res1 = _bfc1; mask0 = 0; mask1 = 0; } + /* For the back face we need to negate the X and Y component + * dot products. dots.Z has the negated back-face specular + * exponent. We swizzle that into the W position. This + * negation makes the back-face specular term positive again. + */ dots = negate(swizzle(dots,X,Y,W,Z)); if (!is_undef(att)) { @@ -1311,8 +1333,8 @@ static void build_lighting( struct tnl_program *p ) } else if (!p->state->material_shininess_is_zero) { emit_op1(p, OPCODE_LIT, lit, 0, dots); - emit_op2(p, OPCODE_ADD, _bfc0, 0, ambient, _bfc0); - } + emit_op2(p, OPCODE_ADD, _bfc0, 0, ambient, _bfc0); /**/ + } else { emit_degenerate_lit(p, lit, dots); emit_op2(p, OPCODE_ADD, _bfc0, 0, ambient, _bfc0); @@ -1320,9 +1342,10 @@ static void build_lighting( struct tnl_program *p ) emit_op3(p, OPCODE_MAD, res0, mask0, swizzle1(lit,Y), diffuse, _bfc0); emit_op3(p, OPCODE_MAD, res1, mask1, swizzle1(lit,Z), specular, _bfc1); - - /* restore negate flag for next lighting */ - dots = negate(dots); + /* restore dots to its original state for subsequent lights + * by negating and swizzling again. + */ + dots = negate(swizzle(dots,X,Y,W,Z)); release_temp(p, ambient); release_temp(p, diffuse); @@ -1395,6 +1418,7 @@ static void build_fog( struct tnl_program *p ) emit_op1(p, useabs ? OPCODE_ABS : OPCODE_MOV, fog, WRITEMASK_X, input); } } + static void build_reflect_texgen( struct tnl_program *p, struct ureg dest, @@ -1414,6 +1438,7 @@ static void build_reflect_texgen( struct tnl_program *p, release_temp(p, tmp); } + static void build_sphere_texgen( struct tnl_program *p, struct ureg dest, GLuint writemask ) @@ -1461,7 +1486,7 @@ static void build_texture_transform( struct tnl_program *p ) { GLuint i, j; - for (i = 0; i < MAX_TEXTURE_UNITS; i++) { + for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { if (!(p->state->fragprog_inputs_read & FRAG_BIT_TEX(i))) continue; @@ -1524,10 +1549,8 @@ static void build_texture_transform( struct tnl_program *p ) case TXG_NONE: copy_mask |= WRITEMASK_X << j; } - } - if (sphere_mask) { build_sphere_texgen(p, out_texgen, sphere_mask); } @@ -1565,7 +1588,7 @@ static void build_texture_transform( struct tnl_program *p ) } release_temps(p); - } + } else { emit_passthrough(p, VERT_ATTRIB_TEX0+i, VERT_RESULT_TEX0+i); } @@ -1610,6 +1633,7 @@ static void build_atten_pointsize( struct tnl_program *p ) release_temp(p, ut); } + /** * Emit constant point size. */ @@ -1620,6 +1644,7 @@ static void build_constant_pointsize( struct tnl_program *p ) emit_op1(p, OPCODE_MOV, out, WRITEMASK_X, state_size); } + /** * Pass-though per-vertex point size, from user's point size array. */ @@ -1632,7 +1657,8 @@ static void build_array_pointsize( struct tnl_program *p ) static void build_tnl_program( struct tnl_program *p ) -{ /* Emit the program, starting with modelviewproject: +{ + /* Emit the program, starting with modelviewproject: */ build_hpos(p);