Move the fp_machine struct into s_nvfragmprog.c since (except for program

debug) it's only used there.
This commit is contained in:
Brian Paul
2006-10-10 21:43:31 +00:00
parent 97a659337e
commit 39c4daa6bc
6 changed files with 114 additions and 46 deletions

View File

@@ -126,6 +126,9 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
driver->BindProgram = NULL; driver->BindProgram = NULL;
driver->NewProgram = _mesa_new_program; driver->NewProgram = _mesa_new_program;
driver->DeleteProgram = _mesa_delete_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 */ /* simple state commands */
driver->AlphaFunc = NULL; driver->AlphaFunc = NULL;

View File

@@ -591,8 +591,9 @@ struct dd_function_table {
/** Notify driver that a program string has been specified. */ /** Notify driver that a program string has been specified. */
void (*ProgramStringNotify)(GLcontext *ctx, GLenum target, void (*ProgramStringNotify)(GLcontext *ctx, GLenum target,
struct gl_program *prog); 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 */ /** Query if program can be loaded onto hardware */
GLboolean (*IsProgramNative)(GLcontext *ctx, GLenum target, GLboolean (*IsProgramNative)(GLcontext *ctx, GLenum target,

View File

@@ -1808,18 +1808,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. * Names of the various vertex/fragment program register files, etc.
* NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c) * NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c)
@@ -1963,14 +1951,13 @@ struct gl_vertex_program_state
*/ */
struct gl_fragment_program_state struct gl_fragment_program_state
{ {
GLboolean Enabled; /* GL_VERTEX_PROGRAM_NV */ GLboolean Enabled; /**< User-set fragment program enable flag */
GLboolean _Enabled; /* Enabled and valid program? */ GLboolean _Enabled; /**< Fragment program enabled and valid? */
GLboolean _Active; GLboolean _Active; /**< Is a user program or internal program active? */
struct gl_fragment_program *Current; /* ptr to currently bound program */ struct gl_fragment_program *Current; /**< User-bound program */
const struct gl_fragment_program *_Current; /* ptr to currently active program const struct gl_fragment_program *_Current; /**< currently active program
(including internal programs) */ (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 #if FEATURE_MESA_program_debug
GLprogramcallbackMESA Callback; GLprogramcallbackMESA Callback;

View File

@@ -2163,7 +2163,8 @@ _mesa_GetProgramRegisterfvMESA(GLenum target,
"glGetProgramRegisterfvMESA(registerName)"); "glGetProgramRegisterfvMESA(registerName)");
return; return;
} }
COPY_4V(v, ctx->FragmentProgram.Machine.Temporaries[i]); ctx->Driver.GetFragmentProgramRegister(ctx, PROGRAM_TEMPORARY,
i, v);
} }
else if (reg[0] == 'f' && reg[1] == '[') { else if (reg[0] == 'f' && reg[1] == '[') {
/* Fragment input attribute */ /* Fragment input attribute */
@@ -2171,7 +2172,8 @@ _mesa_GetProgramRegisterfvMESA(GLenum target,
for (i = 0; i < ctx->Const.FragmentProgram.MaxAttribs; i++) { for (i = 0; i < ctx->Const.FragmentProgram.MaxAttribs; i++) {
const char *name = _mesa_nv_fragment_input_register_name(i); const char *name = _mesa_nv_fragment_input_register_name(i);
if (_mesa_strncmp(reg + 2, name, 4) == 0) { 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; return;
} }
} }
@@ -2181,15 +2183,18 @@ _mesa_GetProgramRegisterfvMESA(GLenum target,
} }
else if (_mesa_strcmp(reg, "o[COLR]") == 0) { else if (_mesa_strcmp(reg, "o[COLR]") == 0) {
/* Fragment output color */ /* 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) { else if (_mesa_strcmp(reg, "o[COLH]") == 0) {
/* Fragment output color */ /* 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) { else if (_mesa_strcmp(reg, "o[DEPR]") == 0) {
/* Fragment output depth */ /* Fragment output depth */
COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_RESULT_DEPR]); ctx->Driver.GetFragmentProgramRegister(ctx, PROGRAM_OUTPUT,
FRAG_RESULT_DEPR, v);
} }
else { else {
/* try user-defined identifiers */ /* try user-defined identifiers */
@@ -2210,5 +2215,4 @@ _mesa_GetProgramRegisterfvMESA(GLenum target,
"glGetProgramRegisterfvMESA(target)"); "glGetProgramRegisterfvMESA(target)");
return; return;
} }
} }

View File

@@ -1,6 +1,6 @@
/* /*
* Mesa 3-D graphics library * Mesa 3-D graphics library
* Version: 6.5.1 * Version: 6.5.2
* *
* Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
* *
@@ -44,6 +44,51 @@
/* if 1, print some debugging info */ /* if 1, print some debugging info */
#define DEBUG_FRAG 0 #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. * 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 static void
init_machine( GLcontext *ctx, struct fp_machine *machine, init_machine( GLcontext *ctx, struct fp_machine *machine,
const struct gl_fragment_program *program, 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 static void
_swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ) run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end)
{ {
const struct gl_fragment_program *program = ctx->FragmentProgram._Current; const struct gl_fragment_program *program = ctx->FragmentProgram._Current;
struct fp_machine machine;
GLuint i; GLuint i;
ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */ CurrentMachine = &machine;
if (program->Base.Parameters) { for (i = start; i < end; i++) {
_mesa_load_state_parameters(ctx, program->Base.Parameters);
}
for (i = 0; i < span->end; i++) {
if (span->array->mask[i]) { if (span->array->mask[i]) {
init_machine(ctx, &ctx->FragmentProgram.Machine, init_machine(ctx, &machine, program, span, i);
ctx->FragmentProgram._Current, span, i);
if (!execute_program(ctx, program, ~0, if (!execute_program(ctx, program, ~0, &machine, span, i)) {
&ctx->FragmentProgram.Machine, span, i)) {
span->array->mask[i] = GL_FALSE; /* killed fragment */ span->array->mask[i] = GL_FALSE; /* killed fragment */
span->writeAll = GL_FALSE; span->writeAll = GL_FALSE;
} }
/* Store output registers */ /* Store output registers */
{ {
const GLfloat *colOut const GLfloat *colOut = machine.Outputs[FRAG_RESULT_COLR];
= ctx->FragmentProgram.Machine.Outputs[FRAG_RESULT_COLR];
UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][RCOMP], colOut[0]); 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][GCOMP], colOut[1]);
UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][BCOMP], colOut[2]); 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 */ /* depth value */
if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) {
const GLfloat depth const GLfloat depth = machine.Outputs[FRAG_RESULT_DEPR][2];
= ctx->FragmentProgram.Machine.Outputs[FRAG_RESULT_DEPR][2];
if (depth <= 0.0) if (depth <= 0.0)
span->array->z[i] = 0; span->array->z[i] = 0;
else if (depth >= 1.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)) { if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) {
span->interpMask &= ~SPAN_Z; span->interpMask &= ~SPAN_Z;

View File

@@ -255,6 +255,13 @@ extern void
_swrast_eject_texture_images(GLcontext *ctx); _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. * The driver interface for the software rasterizer.
* XXX this may go away. * XXX this may go away.