diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/compiler/radeon_program.c | 35 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_vertprog.c | 31 | ||||
-rw-r--r-- | src/mesa/shader/program.c | 1 |
4 files changed, 62 insertions, 6 deletions
diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c index 93a516105e6..dad27fc98e6 100644 --- a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c @@ -89,6 +89,7 @@ static unsigned long t_dst_index(struct r300_vertex_program_code *vp, static unsigned long t_src_class(gl_register_file file) { switch (file) { + case PROGRAM_BUILTIN: case PROGRAM_TEMPORARY: return PVS_SRC_REG_TEMPORARY; case PROGRAM_INPUT: diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program.c b/src/mesa/drivers/dri/r300/compiler/radeon_program.c index bbbf0dd7768..b636f90a968 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program.c @@ -150,14 +150,37 @@ void rc_mesa_to_rc_program(struct radeon_compiler * c, struct gl_program * progr c->Program.InputsRead = program->InputsRead; c->Program.OutputsWritten = program->OutputsWritten; - for(i = 0; i < program->Parameters->NumParameters; ++i) { - struct rc_constant constant; + int isNVProgram = 0; - constant.Type = RC_CONSTANT_EXTERNAL; - constant.Size = 4; - constant.u.External = i; + if (program->Target == GL_VERTEX_PROGRAM_ARB) { + struct gl_vertex_program * vp = (struct gl_vertex_program *) program; + isNVProgram = vp->IsNVProgram; + } + + if (isNVProgram) { + /* NV_vertex_program has a fixed-sized constant environment. + * This could be handled more efficiently for programs that + * do not use relative addressing. + */ + for(i = 0; i < 96; ++i) { + struct rc_constant constant; - rc_constants_add(&c->Program.Constants, &constant); + constant.Type = RC_CONSTANT_EXTERNAL; + constant.Size = 4; + constant.u.External = i; + + rc_constants_add(&c->Program.Constants, &constant); + } + } else { + for(i = 0; i < program->Parameters->NumParameters; ++i) { + struct rc_constant constant; + + constant.Type = RC_CONSTANT_EXTERNAL; + constant.Size = 4; + constant.u.External = i; + + rc_constants_add(&c->Program.Constants, &constant); + } } } diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c index dd0f27f9cba..0cb7dde985b 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c @@ -203,6 +203,34 @@ static void t_inputs_outputs(struct r300_vertex_program_compiler * c) } } +/** + * The NV_vertex_program spec mandates that all registers be + * initialized to zero. We do this here unconditionally. + * + * \note We rely on dead-code elimination in the compiler. + */ +static void initialize_NV_registers(struct radeon_compiler * compiler) +{ + unsigned int reg; + struct rc_instruction * inst; + + for(reg = 0; reg < 12; ++reg) { + inst = rc_insert_new_instruction(compiler, &compiler->Program.Instructions); + inst->I.Opcode = OPCODE_MOV; + inst->I.DstReg.File = PROGRAM_TEMPORARY; + inst->I.DstReg.Index = reg; + inst->I.SrcReg[0].File = PROGRAM_BUILTIN; + inst->I.SrcReg[0].Swizzle = SWIZZLE_0000; + } + + inst = rc_insert_new_instruction(compiler, &compiler->Program.Instructions); + inst->I.Opcode = OPCODE_ARL; + inst->I.DstReg.File = PROGRAM_ADDRESS; + inst->I.DstReg.Index = 0; + inst->I.DstReg.WriteMask = WRITEMASK_X; + inst->I.SrcReg[0].File = PROGRAM_BUILTIN; + inst->I.SrcReg[0].Swizzle = SWIZZLE_0000; +} static struct r300_vertex_program *build_program(GLcontext *ctx, struct r300_vertex_program_key *wanted_key, @@ -234,6 +262,9 @@ static struct r300_vertex_program *build_program(GLcontext *ctx, rc_mesa_to_rc_program(&compiler.Base, &vp->Base->Base); + if (mesa_vp->IsNVProgram) + initialize_NV_registers(&compiler.Base); + rc_move_output(&compiler.Base, VERT_RESULT_PSIZ, VERT_RESULT_PSIZ, WRITEMASK_X); if (vp->key.WPosAttr != FRAG_ATTRIB_MAX) { diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 963478fccdb..2cd6eb8a389 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -502,6 +502,7 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog) = (const struct gl_vertex_program *) prog; struct gl_vertex_program *vpc = (struct gl_vertex_program *) clone; vpc->IsPositionInvariant = vp->IsPositionInvariant; + vpc->IsNVProgram = vp->IsNVProgram; } break; case GL_FRAGMENT_PROGRAM_ARB: |