**************************************************************************/
/**
- * \file ffvertex_prog.
+ * \file ffvertex_prog.c
*
* Create a vertex program to execute the current fixed function T&L pipeline.
* \author Keith Whitwell
}
}
+
#define TXG_NONE 0
#define TXG_OBJ_LINEAR 1
#define TXG_EYE_LINEAR 2
return mask;
}
+
/**
* Should fog be computed per-vertex?
*/
#endif
}
+
static GLboolean check_active_shininess( GLcontext *ctx,
const struct state_key *key,
GLuint side )
return GL_FALSE;
}
-
-
static void make_state_key( GLcontext *ctx, struct state_key *key )
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 );
return make_ureg(PROGRAM_TEMPORARY, bit-1);
}
+
static struct ureg reserve_temp( struct tnl_program *p )
{
struct ureg temp = get_temp( p );
return temp;
}
+
static void release_temp( struct tnl_program *p, struct ureg reg )
{
if (reg.file == PROGRAM_TEMPORARY) {
}
}
+
static void release_temps( struct tnl_program *p )
{
p->temp_in_use = p->temp_reserved;
}
-
/**
* \param input one of VERT_ATTRIB_x tokens.
*/
return make_ureg(PROGRAM_INPUT, input);
}
+
/**
* \param input one of VERT_RESULT_x tokens.
*/
return make_ureg(PROGRAM_OUTPUT, output);
}
+
static struct ureg register_const4f( struct tnl_program *p,
GLfloat s0,
GLfloat s1,
return make_ureg(PROGRAM_CONSTANT, idx);
}
+
#define register_const1f(p, s0) register_const4f(p, s0, 0, 0, 1)
#define register_scalar_const(p, s0) register_const4f(p, s0, s0, s0, s0)
#define register_const2f(p, s0, s1) register_const4f(p, s0, s1, 0, 1)
return reg.file == PROGRAM_UNDEFINED;
}
+
static struct ureg get_identity_param( struct tnl_program *p )
{
if (is_undef(p->identity))
return p->identity;
}
+
static struct ureg register_param5(struct tnl_program *p,
GLint s0,
GLint s1,
ASSERT(src->Index == reg.idx);
}
+
static void emit_dst( struct prog_dst_register *dst,
struct ureg reg, GLuint mask )
{
ASSERT(dst->Index == reg.idx);
}
+
static void debug_insn( struct prog_instruction *inst, const char *fn,
GLuint line )
{
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.
release_temp(p, tmp);
}
+
static void emit_matrix_transform_vec3( struct tnl_program *p,
struct ureg dest,
const struct ureg *mat,
#endif
}
+
static void emit_passthrough( struct tnl_program *p,
GLuint input,
GLuint 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)) {
}
-
static struct ureg get_eye_position_normalized( struct tnl_program *p )
{
if (is_undef(p->eye_position_normalized)) {
}
-
static void build_hpos( struct tnl_program *p )
{
struct ureg pos = register_input( p, VERT_ATTRIB_POS );
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 )
{
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.
*
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 res0, res1;
GLuint mask0, mask1;
-
if (count == nr_lights) {
if (separate) {
mask0 = WRITEMASK_XYZ;
res1 = _col1;
}
-
if (!is_undef(att)) {
/* light is attenuated by distance */
emit_op1(p, OPCODE_LIT, lit, 0, dots);
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);
emit_op1(p, useabs ? OPCODE_ABS : OPCODE_MOV, fog, WRITEMASK_X, input);
}
}
+
static void build_reflect_texgen( struct tnl_program *p,
struct ureg dest,
release_temp(p, tmp);
}
+
static void build_sphere_texgen( struct tnl_program *p,
struct ureg dest,
GLuint writemask )
case TXG_NONE:
copy_mask |= WRITEMASK_X << j;
}
-
}
-
if (sphere_mask) {
build_sphere_texgen(p, out_texgen, sphere_mask);
}
release_temp(p, ut);
}
+
/**
* Emit constant point size.
*/
emit_op1(p, OPCODE_MOV, out, WRITEMASK_X, state_size);
}
+
/**
* Pass-though per-vertex point size, from user's point size array.
*/