summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/common/driverfuncs.c3
-rw-r--r--src/mesa/main/dd.h5
-rw-r--r--src/mesa/main/mtypes.h25
-rw-r--r--src/mesa/shader/program.c16
-rw-r--r--src/mesa/swrast/s_nvfragprog.c104
-rw-r--r--src/mesa/swrast/swrast.h7
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.