diff options
-rw-r--r-- | src/mesa/drivers/common/driverfuncs.c | 3 | ||||
-rw-r--r-- | src/mesa/main/dd.h | 5 | ||||
-rw-r--r-- | src/mesa/main/mtypes.h | 25 | ||||
-rw-r--r-- | src/mesa/shader/program.c | 16 | ||||
-rw-r--r-- | src/mesa/swrast/s_nvfragprog.c | 104 | ||||
-rw-r--r-- | src/mesa/swrast/swrast.h | 7 |
6 files changed, 114 insertions, 46 deletions
diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c index 3ccbe54817a..1e44904b930 100644 --- a/src/mesa/drivers/common/driverfuncs.c +++ b/src/mesa/drivers/common/driverfuncs.c @@ -126,6 +126,9 @@ _mesa_init_driver_functions(struct dd_function_table *driver) driver->BindProgram = NULL; driver->NewProgram = _mesa_new_program; driver->DeleteProgram = _mesa_delete_program; +#if FEATURE_MESA_program_debug + driver->GetFragmentProgramRegister = _swrast_get_program_register; +#endif /* FEATURE_MESA_program_debug */ /* simple state commands */ driver->AlphaFunc = NULL; diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 1b8cf6304e5..26cabc90963 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -591,8 +591,9 @@ struct dd_function_table { /** Notify driver that a program string has been specified. */ void (*ProgramStringNotify)(GLcontext *ctx, GLenum target, struct gl_program *prog); - - + /** Get value of a fragment program register during program execution. */ + void (*GetFragmentProgramRegister)(GLcontext *ctx, enum register_file file, + GLuint index, GLfloat val[4]); /** Query if program can be loaded onto hardware */ GLboolean (*IsProgramNative)(GLcontext *ctx, GLenum target, diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 2bb6d93c390..ff6b053c230 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1809,18 +1809,6 @@ struct gl_evaluators /** - * State used during execution of fragment programs. - */ -struct fp_machine -{ - GLfloat Temporaries[MAX_NV_FRAGMENT_PROGRAM_TEMPS][4]; - GLfloat Inputs[MAX_NV_FRAGMENT_PROGRAM_INPUTS][4]; - GLfloat Outputs[MAX_NV_FRAGMENT_PROGRAM_OUTPUTS][4]; - GLuint CondCodes[4]; -}; - - -/** * Names of the various vertex/fragment program register files, etc. * NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c) * All values should fit in a 4-bit field. @@ -1963,14 +1951,13 @@ struct gl_vertex_program_state */ struct gl_fragment_program_state { - GLboolean Enabled; /* GL_VERTEX_PROGRAM_NV */ - GLboolean _Enabled; /* Enabled and valid program? */ - GLboolean _Active; - struct gl_fragment_program *Current; /* ptr to currently bound program */ - const struct gl_fragment_program *_Current; /* ptr to currently active program + GLboolean Enabled; /**< User-set fragment program enable flag */ + GLboolean _Enabled; /**< Fragment program enabled and valid? */ + GLboolean _Active; /**< Is a user program or internal program active? */ + struct gl_fragment_program *Current; /**< User-bound program */ + const struct gl_fragment_program *_Current; /**< currently active program (including internal programs) */ - struct fp_machine Machine; /* machine state */ - GLfloat Parameters[MAX_NV_FRAGMENT_PROGRAM_PARAMS][4]; /* Env params */ + GLfloat Parameters[MAX_NV_FRAGMENT_PROGRAM_PARAMS][4]; /**< Env params */ #if FEATURE_MESA_program_debug GLprogramcallbackMESA Callback; diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index f999e0695ba..8aed74110c0 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -2163,7 +2163,8 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, "glGetProgramRegisterfvMESA(registerName)"); return; } - COPY_4V(v, ctx->FragmentProgram.Machine.Temporaries[i]); + ctx->Driver.GetFragmentProgramRegister(ctx, PROGRAM_TEMPORARY, + i, v); } else if (reg[0] == 'f' && reg[1] == '[') { /* Fragment input attribute */ @@ -2171,7 +2172,8 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, for (i = 0; i < ctx->Const.FragmentProgram.MaxAttribs; i++) { const char *name = _mesa_nv_fragment_input_register_name(i); if (_mesa_strncmp(reg + 2, name, 4) == 0) { - COPY_4V(v, ctx->FragmentProgram.Machine.Inputs[i]); + ctx->Driver.GetFragmentProgramRegister(ctx, + PROGRAM_INPUT, i, v); return; } } @@ -2181,15 +2183,18 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, } else if (_mesa_strcmp(reg, "o[COLR]") == 0) { /* Fragment output color */ - COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_RESULT_COLR]); + ctx->Driver.GetFragmentProgramRegister(ctx, PROGRAM_OUTPUT, + FRAG_RESULT_COLR, v); } else if (_mesa_strcmp(reg, "o[COLH]") == 0) { /* Fragment output color */ - COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_RESULT_COLH]); + ctx->Driver.GetFragmentProgramRegister(ctx, PROGRAM_OUTPUT, + FRAG_RESULT_COLH, v); } else if (_mesa_strcmp(reg, "o[DEPR]") == 0) { /* Fragment output depth */ - COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_RESULT_DEPR]); + ctx->Driver.GetFragmentProgramRegister(ctx, PROGRAM_OUTPUT, + FRAG_RESULT_DEPR, v); } else { /* try user-defined identifiers */ @@ -2210,5 +2215,4 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, "glGetProgramRegisterfvMESA(target)"); return; } - } diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c index 658b6efe32d..d3525320764 100644 --- a/src/mesa/swrast/s_nvfragprog.c +++ b/src/mesa/swrast/s_nvfragprog.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * Version: 6.5.2 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -44,6 +44,51 @@ /* if 1, print some debugging info */ #define DEBUG_FRAG 0 + +/** + * Virtual machine state used during execution of a fragment programs. + */ +struct fp_machine +{ + GLfloat Temporaries[MAX_NV_FRAGMENT_PROGRAM_TEMPS][4]; + GLfloat Inputs[MAX_NV_FRAGMENT_PROGRAM_INPUTS][4]; + GLfloat Outputs[MAX_NV_FRAGMENT_PROGRAM_OUTPUTS][4]; + GLuint CondCodes[4]; +}; + + +#if FEATURE_MESA_program_debug +static struct fp_machine *CurrentMachine = NULL; + +/** + * For GL_MESA_program_debug. + * Return current value (4*GLfloat) of a fragment program register. + * Called via ctx->Driver.GetFragmentProgramRegister(). + */ +void +_swrast_get_program_register(GLcontext *ctx, enum register_file file, + GLuint index, GLfloat val[4]) +{ + if (CurrentMachine) { + switch (file) { + case PROGRAM_INPUT: + COPY_4V(val, CurrentMachine->Inputs[index]); + break; + case PROGRAM_OUTPUT: + COPY_4V(val, CurrentMachine->Outputs[index]); + break; + case PROGRAM_TEMPORARY: + COPY_4V(val, CurrentMachine->Temporaries[index]); + break; + default: + _mesa_problem(NULL, + "bad register file in _swrast_get_program_register"); + } + } +} +#endif /* FEATURE_MESA_program_debug */ + + /** * Fetch a texel. */ @@ -1379,6 +1424,15 @@ execute_program( GLcontext *ctx, } +/** + * Initialize the virtual fragment program machine state prior to running + * fragment program on a fragment. This involves initializing the input + * registers, condition codes, etc. + * \param machine the virtual machine state to init + * \param program the fragment program we're about to run + * \param span the span of pixels we'll operate on + * \param col which element (column) of the span we'll operate on + */ static void init_machine( GLcontext *ctx, struct fp_machine *machine, const struct gl_fragment_program *program, @@ -1451,37 +1505,30 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, } - /** - * Execute the current fragment program, operating on the given span. + * Run fragment program on the pixels in span from 'start' to 'end' - 1. */ -void -_swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ) +static void +run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end) { const struct gl_fragment_program *program = ctx->FragmentProgram._Current; + struct fp_machine machine; GLuint i; - ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */ + CurrentMachine = &machine; - if (program->Base.Parameters) { - _mesa_load_state_parameters(ctx, program->Base.Parameters); - } - - for (i = 0; i < span->end; i++) { + for (i = start; i < end; i++) { if (span->array->mask[i]) { - init_machine(ctx, &ctx->FragmentProgram.Machine, - ctx->FragmentProgram._Current, span, i); + init_machine(ctx, &machine, program, span, i); - if (!execute_program(ctx, program, ~0, - &ctx->FragmentProgram.Machine, span, i)) { + if (!execute_program(ctx, program, ~0, &machine, span, i)) { span->array->mask[i] = GL_FALSE; /* killed fragment */ span->writeAll = GL_FALSE; } /* Store output registers */ { - const GLfloat *colOut - = ctx->FragmentProgram.Machine.Outputs[FRAG_RESULT_COLR]; + const GLfloat *colOut = machine.Outputs[FRAG_RESULT_COLR]; UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][RCOMP], colOut[0]); UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][GCOMP], colOut[1]); UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][BCOMP], colOut[2]); @@ -1489,8 +1536,7 @@ _swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ) } /* depth value */ if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { - const GLfloat depth - = ctx->FragmentProgram.Machine.Outputs[FRAG_RESULT_DEPR][2]; + const GLfloat depth = machine.Outputs[FRAG_RESULT_DEPR][2]; if (depth <= 0.0) span->array->z[i] = 0; else if (depth >= 1.0) @@ -1500,6 +1546,26 @@ _swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ) } } } + CurrentMachine = NULL; +} + + +/** + * Execute the current fragment program for all the fragments + * in the given span. + */ +void +_swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ) +{ + const struct gl_fragment_program *program = ctx->FragmentProgram._Current; + + ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */ + + if (program->Base.Parameters) { + _mesa_load_state_parameters(ctx, program->Base.Parameters); + } + + run_program(ctx, span, 0, span->end); if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { span->interpMask &= ~SPAN_Z; diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h index 2a212342539..6d384fbec26 100644 --- a/src/mesa/swrast/swrast.h +++ b/src/mesa/swrast/swrast.h @@ -255,6 +255,13 @@ extern void _swrast_eject_texture_images(GLcontext *ctx); +#if FEATURE_MESA_program_debug +extern void +_swrast_get_program_register(GLcontext *, enum register_file file, + GLuint index, GLfloat val[4]); +#endif /* FEATURE_MESA_program_debug */ + + /** * The driver interface for the software rasterizer. * XXX this may go away. |