Move the fp_machine struct into s_nvfragmprog.c since (except for program
debug) it's only used there.
This commit is contained in:
@@ -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;
|
||||||
|
@@ -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,
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
@@ -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.
|
||||||
|
Reference in New Issue
Block a user