#include "program/prog_parameter.h"
#include "program/prog_print.h"
#include "program/prog_statevars.h"
+#include "util/bitscan.h"
/** Max of number of lights and texture coord units */
static void make_state_key( struct gl_context *ctx, struct state_key *key )
{
- const struct gl_fragment_program *fp;
- GLuint i;
+ const struct gl_program *fp = ctx->FragmentProgram._Current;
+ GLbitfield mask;
memset(key, 0, sizeof(struct state_key));
- fp = ctx->FragmentProgram._Current;
/* This now relies on texenvprogram.c being active:
*/
key->need_eye_coords = ctx->_NeedEyeCoords;
- key->fragprog_inputs_read = fp->Base.InputsRead;
+ key->fragprog_inputs_read = fp->info.inputs_read;
key->varying_vp_inputs = ctx->varying_vp_inputs;
if (ctx->RenderMode == GL_FEEDBACK) {
key->light_color_material_mask = ctx->Light._ColorMaterialBitmask;
}
- for (i = 0; i < MAX_LIGHTS; i++) {
- struct gl_light *light = &ctx->Light.Light[i];
+ mask = ctx->Light._EnabledLights;
+ while (mask) {
+ const int i = u_bit_scan(&mask);
+ struct gl_light *light = &ctx->Light.Light[i];
- if (light->Enabled) {
- key->unit[i].light_enabled = 1;
+ key->unit[i].light_enabled = 1;
- if (light->EyePosition[3] == 0.0F)
- key->unit[i].light_eyepos3_is_zero = 1;
+ if (light->EyePosition[3] == 0.0F)
+ key->unit[i].light_eyepos3_is_zero = 1;
- if (light->SpotCutoff == 180.0F)
- key->unit[i].light_spotcutoff_is_180 = 1;
+ if (light->SpotCutoff == 180.0F)
+ key->unit[i].light_spotcutoff_is_180 = 1;
- if (light->ConstantAttenuation != 1.0F ||
- light->LinearAttenuation != 0.0F ||
- light->QuadraticAttenuation != 0.0F)
- key->unit[i].light_attenuated = 1;
- }
+ if (light->ConstantAttenuation != 1.0F ||
+ light->LinearAttenuation != 0.0F ||
+ light->QuadraticAttenuation != 0.0F)
+ key->unit[i].light_attenuated = 1;
}
if (check_active_shininess(ctx, key, 0)) {
ctx->Texture._MaxEnabledTexImageUnit != -1)
key->texture_enabled_global = 1;
- for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
+ mask = ctx->Texture._EnabledCoordUnits | ctx->Texture._TexGenEnabled
+ | ctx->Texture._TexMatEnabled | ctx->Point.CoordReplace;
+ while (mask) {
+ const int i = u_bit_scan(&mask);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
if (texUnit->_Current)
key->unit[i].texunit_really_enabled = 1;
if (ctx->Point.PointSprite)
- if (ctx->Point.CoordReplaceBits & (1u << i))
+ if (ctx->Point.CoordReplace & (1u << i))
key->unit[i].coord_replace = 1;
if (ctx->Texture._TexMatEnabled & ENABLE_TEXMAT(i))
GLuint file:4;
GLint idx:9; /* relative addressing may be negative */
/* sizeof(idx) should == sizeof(prog_src_reg::Index) */
- GLuint abs:1;
GLuint negate:1;
GLuint swz:12;
- GLuint pad:5;
+ GLuint pad:6;
};
struct tnl_program {
const struct state_key *state;
- struct gl_vertex_program *program;
+ struct gl_program *program;
GLuint max_inst; /** number of instructions allocated for program */
GLboolean mvp_with_dp4;
0,
0,
0,
- 0,
0
};
struct ureg reg;
reg.file = file;
reg.idx = idx;
- reg.abs = 0;
reg.negate = 0;
reg.swz = SWIZZLE_NOOP;
reg.pad = 0;
}
-
-static struct ureg absolute( struct ureg reg )
-{
- reg.abs = 1;
- reg.negate = 0;
- return reg;
-}
-
-
static struct ureg negate( struct ureg reg )
{
reg.negate ^= 1;
exit(1);
}
- if ((GLuint) bit > p->program->Base.NumTemporaries)
- p->program->Base.NumTemporaries = bit;
+ if ((GLuint) bit > p->program->arb.NumTemporaries)
+ p->program->arb.NumTemporaries = bit;
p->temp_in_use |= 1<<(bit-1);
return make_ureg(PROGRAM_TEMPORARY, bit-1);
tokens[2] = s2;
tokens[3] = s3;
tokens[4] = s4;
- idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens );
+ idx = _mesa_add_state_reference(p->program->Parameters, tokens );
return make_ureg(PROGRAM_STATE_VAR, idx);
}
assert(input < VERT_ATTRIB_MAX);
if (p->state->varying_vp_inputs & VERT_BIT(input)) {
- p->program->Base.InputsRead |= VERT_BIT(input);
+ p->program->info.inputs_read |= VERT_BIT(input);
return make_ureg(PROGRAM_INPUT, input);
}
else {
*/
static struct ureg register_output( struct tnl_program *p, GLuint output )
{
- p->program->Base.OutputsWritten |= BITFIELD64_BIT(output);
+ p->program->info.outputs_written |= BITFIELD64_BIT(output);
return make_ureg(PROGRAM_OUTPUT, output);
}
values[1].f = s1;
values[2].f = s2;
values[3].f = s3;
- idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4,
- &swizzle );
+ idx = _mesa_add_unnamed_constant(p->program->Parameters, values, 4,
+ &swizzle );
assert(swizzle == SWIZZLE_NOOP);
return make_ureg(PROGRAM_CONSTANT, idx);
}
GLuint nr;
struct prog_instruction *inst;
- assert(p->program->Base.NumInstructions <= p->max_inst);
+ assert(p->program->arb.NumInstructions <= p->max_inst);
- if (p->program->Base.NumInstructions == p->max_inst) {
+ if (p->program->arb.NumInstructions == p->max_inst) {
/* need to extend the program's instruction array */
struct prog_instruction *newInst;
/* double the size */
p->max_inst *= 2;
- newInst = _mesa_alloc_instructions(p->max_inst);
+ newInst =
+ rzalloc_array(p->program, struct prog_instruction, p->max_inst);
if (!newInst) {
_mesa_error(NULL, GL_OUT_OF_MEMORY, "vertex program build");
return;
}
- _mesa_copy_instructions(newInst,
- p->program->Base.Instructions,
- p->program->Base.NumInstructions);
+ _mesa_copy_instructions(newInst, p->program->arb.Instructions,
+ p->program->arb.NumInstructions);
- _mesa_free_instructions(p->program->Base.Instructions,
- p->program->Base.NumInstructions);
+ ralloc_free(p->program->arb.Instructions);
- p->program->Base.Instructions = newInst;
+ p->program->arb.Instructions = newInst;
}
- nr = p->program->Base.NumInstructions++;
+ nr = p->program->arb.NumInstructions++;
- inst = &p->program->Base.Instructions[nr];
+ inst = &p->program->arb.Instructions[nr];
inst->Opcode = (enum prog_opcode) op;
emit_arg( &inst->SrcReg[0], src0 );
emit_op2(p, OPCODE_DP3, spot, 0, negate(VPpli), spot_dir_norm);
emit_op2(p, OPCODE_SLT, slt, 0, swizzle1(spot_dir_norm,W), spot);
- emit_op2(p, OPCODE_POW, spot, 0, absolute(spot), swizzle1(attenuation, W));
+ emit_op1(p, OPCODE_ABS, spot, 0, spot);
+ emit_op2(p, OPCODE_POW, spot, 0, spot, swizzle1(attenuation, W));
emit_op2(p, OPCODE_MUL, att, 0, slt, spot);
release_temp(p, spot);
static void
create_new_program( const struct state_key *key,
- struct gl_vertex_program *program,
+ struct gl_program *program,
GLboolean mvp_with_dp4,
GLuint max_temps)
{
* If we need more, we'll grow the instruction array as needed.
*/
p.max_inst = 32;
- p.program->Base.Instructions = _mesa_alloc_instructions(p.max_inst);
- p.program->Base.String = NULL;
- p.program->Base.NumInstructions =
- p.program->Base.NumTemporaries =
- p.program->Base.NumParameters =
- p.program->Base.NumAttributes = p.program->Base.NumAddressRegs = 0;
- p.program->Base.Parameters = _mesa_new_parameter_list();
- p.program->Base.InputsRead = 0;
- p.program->Base.OutputsWritten = 0;
+ p.program->arb.Instructions =
+ rzalloc_array(program, struct prog_instruction, p.max_inst);
+ p.program->String = NULL;
+ p.program->arb.NumInstructions =
+ p.program->arb.NumTemporaries =
+ p.program->arb.NumParameters =
+ p.program->arb.NumAttributes = p.program->arb.NumAddressRegs = 0;
+ p.program->Parameters = _mesa_new_parameter_list();
+ p.program->info.inputs_read = 0;
+ p.program->info.outputs_written = 0;
build_tnl_program( &p );
}
* Return a vertex program which implements the current fixed-function
* transform/lighting/texgen operations.
*/
-struct gl_vertex_program *
+struct gl_program *
_mesa_get_fixed_func_vertex_program(struct gl_context *ctx)
{
- struct gl_vertex_program *prog;
+ struct gl_program *prog;
struct state_key key;
/* Grab all the relevant state and put it in a single structure:
/* Look for an already-prepared program for this state:
*/
- prog = gl_vertex_program(
- _mesa_search_program_cache(ctx->VertexProgram.Cache, &key, sizeof(key)));
+ prog = _mesa_search_program_cache(ctx->VertexProgram.Cache, &key,
+ sizeof(key));
if (!prog) {
/* OK, we'll have to build a new one */
if (0)
printf("Build new TNL program\n");
- prog = gl_vertex_program(ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0));
+ prog = ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0, true);
if (!prog)
return NULL;
ctx->Const.Program[MESA_SHADER_VERTEX].MaxTemps );
if (ctx->Driver.ProgramStringNotify)
- ctx->Driver.ProgramStringNotify( ctx, GL_VERTEX_PROGRAM_ARB,
- &prog->Base );
+ ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB, prog);
- _mesa_program_cache_insert(ctx, ctx->VertexProgram.Cache,
- &key, sizeof(key), &prog->Base);
+ _mesa_program_cache_insert(ctx, ctx->VertexProgram.Cache, &key,
+ sizeof(key), prog);
}
return prog;