From f2dd273322cc9ec0cfe80a609f9a1e5db5931e2e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sun, 17 Aug 2003 17:11:50 +0000 Subject: Re-org of register files for vertex/fragment programs. Will be easier to hook in global state references, etc. for ARB programs. --- src/mesa/main/arbprogram.c | 35 ++--- src/mesa/main/arbvertparse.h | 3 - src/mesa/main/context.c | 4 - src/mesa/main/macros.h | 9 -- src/mesa/main/mtypes.h | 71 +++++----- src/mesa/main/nvfragparse.c | 190 +++++++++---------------- src/mesa/main/nvfragprog.h | 23 +-- src/mesa/main/nvvertexec.c | 324 ++++++++++++++++++++++--------------------- src/mesa/main/nvvertexec.h | 2 +- src/mesa/main/nvvertparse.c | 215 +++++++++++++--------------- src/mesa/main/nvvertprog.h | 23 +-- 11 files changed, 397 insertions(+), 502 deletions(-) (limited to 'src/mesa/main') diff --git a/src/mesa/main/arbprogram.c b/src/mesa/main/arbprogram.c index 0b3008554c..e5febdb9fa 100644 --- a/src/mesa/main/arbprogram.c +++ b/src/mesa/main/arbprogram.c @@ -63,7 +63,7 @@ _mesa_init_program(GLcontext *ctx) ctx->VertexProgram.Current = (struct vertex_program *) ctx->Shared->DefaultVertexProgram; assert(ctx->VertexProgram.Current); ctx->VertexProgram.Current->Base.RefCount++; - for (i = 0; i < VP_NUM_PROG_REGS / 4; i++) { + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) { ctx->VertexProgram.TrackMatrix[i] = GL_NONE; ctx->VertexProgram.TrackMatrixTransform[i] = GL_IDENTITY_NV; } @@ -271,8 +271,7 @@ _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index, _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)"); return; } - index += FP_PROG_REG_START; - ASSIGN_4V(ctx->FragmentProgram.Machine.Registers[index], x, y, z, w); + ASSIGN_4V(ctx->FragmentProgram.Parameters[index], x, y, z, w); } if (target == GL_VERTEX_PROGRAM_ARB && ctx->Extensions.ARB_vertex_program) { @@ -280,8 +279,7 @@ _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index, _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)"); return; } - index += VP_PROG_REG_START; - ASSIGN_4V(ctx->VertexProgram.Machine.Registers[index], x, y, z, w); + ASSIGN_4V(ctx->VertexProgram.Parameters[index], x, y, z, w); } else { _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)"); @@ -331,8 +329,7 @@ _mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index, _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)"); return; } - index += FP_PROG_REG_START; - COPY_4V(params, ctx->FragmentProgram.Machine.Registers[index]); + COPY_4V(params, ctx->FragmentProgram.Parameters[index]); } if (target == GL_VERTEX_PROGRAM_ARB && ctx->Extensions.ARB_vertex_program) { @@ -340,8 +337,7 @@ _mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index, _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)"); return; } - index += VP_PROG_REG_START; - COPY_4V(params, ctx->VertexProgram.Machine.Registers[index]); + COPY_4V(params, ctx->VertexProgram.Parameters[index]); } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)"); @@ -830,8 +826,7 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, "glGetProgramRegisterfvMESA(registerName)"); return; } - COPY_4V(v, ctx->VertexProgram.Machine.Registers - [VP_TEMP_REG_START + i]); + COPY_4V(v, ctx->VertexProgram.Temporaries[i]); } else if (reg[0] == 'v' && reg[1] == '[') { /* Vertex Input attribute */ @@ -842,8 +837,7 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, sprintf(number, "%d", i); if (_mesa_strncmp(reg + 2, name, 4) == 0 || _mesa_strncmp(reg + 2, number, _mesa_strlen(number)) == 0) { - COPY_4V(v, ctx->VertexProgram.Machine.Registers - [VP_INPUT_REG_START + i]); + COPY_4V(v, ctx->VertexProgram.Inputs[i]); return; } } @@ -896,8 +890,7 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, "glGetProgramRegisterfvMESA(registerName)"); return; } - COPY_4V(v, - ctx->FragmentProgram.Machine.Registers[FP_TEMP_REG_START + i]); + COPY_4V(v, ctx->FragmentProgram.Machine.Temporaries[i]); } else if (reg[0] == 'f' && reg[1] == '[') { /* Fragment input attribute */ @@ -905,8 +898,7 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, for (i = 0; i < ctx->Const.MaxFragmentProgramAttribs; 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.Registers - [FP_INPUT_REG_START + i]); + COPY_4V(v, ctx->FragmentProgram.Machine.Inputs[i]); return; } } @@ -916,18 +908,15 @@ _mesa_GetProgramRegisterfvMESA(GLenum target, } else if (_mesa_strcmp(reg, "o[COLR]") == 0) { /* Fragment output color */ - COPY_4V(v, ctx->FragmentProgram.Machine.Registers - [FP_OUTPUT_REG_START + FRAG_OUTPUT_COLR]); + COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_COLR]); } else if (_mesa_strcmp(reg, "o[COLH]") == 0) { /* Fragment output color */ - COPY_4V(v, ctx->FragmentProgram.Machine.Registers - [FP_OUTPUT_REG_START + FRAG_OUTPUT_COLH]); + COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_COLH]); } else if (_mesa_strcmp(reg, "o[DEPR]") == 0) { /* Fragment output depth */ - COPY_4V(v, ctx->FragmentProgram.Machine.Registers - [FP_OUTPUT_REG_START + FRAG_OUTPUT_DEPR]); + COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_DEPR]); } else { _mesa_error(ctx, GL_INVALID_VALUE, diff --git a/src/mesa/main/arbvertparse.h b/src/mesa/main/arbvertparse.h index 4b4c3fe120..3e4490b8be 100644 --- a/src/mesa/main/arbvertparse.h +++ b/src/mesa/main/arbvertparse.h @@ -20,9 +20,6 @@ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Brian Paul */ #ifndef ARBVERTPARSE_H diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 13b4d193d1..fb802b48c2 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -113,10 +113,6 @@ #include "varray.h" #if FEATURE_NV_vertex_program #include "nvprogram.h" -#include "nvvertprog.h" -#endif -#if FEATURE_NV_fragment_program -#include "nvfragprog.h" #endif #include "vtxfmt.h" #if _HAVE_FULL_GL diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h index fcb63f53f2..f3c77ca5fc 100644 --- a/src/mesa/main/macros.h +++ b/src/mesa/main/macros.h @@ -146,15 +146,6 @@ do { \ (DST)[3] = (SRC)[3]; \ } while (0) -/** Copy a 4-element vector with cast */ -#define COPY_4V_CAST( DST, SRC, CAST ) \ -do { \ - (DST)[0] = (CAST)(SRC)[0]; \ - (DST)[1] = (CAST)(SRC)[1]; \ - (DST)[2] = (CAST)(SRC)[2]; \ - (DST)[3] = (CAST)(SRC)[3]; \ -} while (0) - /** Copy a 4-element unsigned byte vector */ #if defined(__i386__) #define COPY_4UBV(DST, SRC) \ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 5c321d0d99..3bf5acde61 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1352,7 +1352,8 @@ struct gl_selection { /** * 1-D Evaluator control points */ -struct gl_1d_map { +struct gl_1d_map +{ GLuint Order; /**< Number of control points */ GLfloat u1, u2, du; /**< u1, u2, 1.0/(u2-u1) */ GLfloat *Points; /**< Points to contiguous control points */ @@ -1362,7 +1363,8 @@ struct gl_1d_map { /** * 2-D Evaluator control points */ -struct gl_2d_map { +struct gl_2d_map +{ GLuint Uorder; /**< Number of control points in U dimension */ GLuint Vorder; /**< Number of control points in V dimension */ GLfloat u1, u2, du; @@ -1374,7 +1376,8 @@ struct gl_2d_map { /** * All evaluator control points */ -struct gl_evaluators { +struct gl_evaluators +{ /** * \name 1-D maps */ @@ -1410,35 +1413,30 @@ struct gl_evaluators { /** - * \name NV_vertex_program runtime state - */ -/*@{*/ - - -/** - * Machine state (i.e. the register file) + * NV_fragment_program runtime state */ -struct vp_machine +struct fp_machine { - GLfloat Registers[MAX_NV_VERTEX_PROGRAM_TEMPS - + MAX_NV_VERTEX_PROGRAM_PARAMS - + MAX_NV_VERTEX_PROGRAM_INPUTS - + MAX_NV_VERTEX_PROGRAM_OUTPUTS][4]; - GLint AddressReg; /* might someday be a 4-vector */ + 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]; }; /** - * NV_fragment_program runtime state + * Names of the various vertex/fragment register files */ -struct fp_machine +enum register_file { - GLfloat Registers[MAX_NV_FRAGMENT_PROGRAM_TEMPS - + MAX_NV_FRAGMENT_PROGRAM_PARAMS - + MAX_NV_FRAGMENT_PROGRAM_INPUTS - + MAX_NV_FRAGMENT_PROGRAM_OUTPUTS - + MAX_NV_FRAGMENT_PROGRAM_WRITE_ONLYS][4]; - GLuint CondCodes[4]; + PROGRAM_TEMPORARY = 10, + PROGRAM_INPUT, + PROGRAM_OUTPUT, + PROGRAM_LOCAL_PARAM, + PROGRAM_ENV_PARAM, + PROGRAM_NAMED_PARAM, + PROGRAM_STATE_VAR, + PROGRAM_WRITE_ONLY }; @@ -1446,8 +1444,9 @@ struct fp_machine struct vp_instruction; struct fp_instruction; + /** - * Program parameters + * Named program parameters */ struct program_parameter { @@ -1522,11 +1521,17 @@ struct vertex_program_state GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_NV */ GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_NV */ struct vertex_program *Current; /**< ptr to currently bound program */ - struct vp_machine Machine; /**< machine state */ GLenum TrackMatrix[MAX_NV_VERTEX_PROGRAM_PARAMS / 4]; GLenum TrackMatrixTransform[MAX_NV_VERTEX_PROGRAM_PARAMS / 4]; + GLfloat Parameters[MAX_NV_VERTEX_PROGRAM_PARAMS][4]; /* Env params */ + /* Only used during program execution (may be moved someday): */ + GLfloat Temporaries[MAX_NV_VERTEX_PROGRAM_TEMPS][4]; + GLfloat Inputs[MAX_NV_VERTEX_PROGRAM_INPUTS][4]; + GLfloat Outputs[MAX_NV_VERTEX_PROGRAM_OUTPUTS][4]; + GLint AddressReg[4]; + #if FEATURE_MESA_program_debug GLprogramcallbackMESA Callback; GLvoid *CallbackData; @@ -1544,6 +1549,7 @@ struct fragment_program_state GLboolean Enabled; /* GL_VERTEX_PROGRAM_NV */ struct fragment_program *Current; /* ptr to currently bound program */ struct fp_machine Machine; /* machine state */ + GLfloat Parameters[MAX_NV_FRAGMENT_PROGRAM_PARAMS][4]; /* Env params */ #if FEATURE_MESA_program_debug GLprogramcallbackMESA Callback; @@ -1553,7 +1559,6 @@ struct fragment_program_state #endif }; -/*@}*/ /* * State for GL_ARB_occlusion_query @@ -1570,7 +1575,8 @@ struct occlusion_state /** * State which can be shared by multiple contexts: */ -struct gl_shared_state { +struct gl_shared_state +{ _glthread_Mutex Mutex; /**< for thread safety */ GLint RefCount; /**< Reference count */ struct _mesa_HashTable *DisplayList; /**< Display lists hash table */ @@ -1613,7 +1619,8 @@ struct gl_shared_state { * In C++ terms, think of this as a base class from which device drivers * will make derived classes. */ -struct gl_frame_buffer { +struct gl_frame_buffer +{ GLvisual Visual; /**< The corresponding visual */ GLuint Width, Height; /**< size of frame buffer in pixels */ @@ -1664,7 +1671,8 @@ struct gl_frame_buffer { * Constants which may be overridden by device driver during context creation * but are never changed after that. */ -struct gl_constants { +struct gl_constants +{ GLint MaxTextureLevels; /**< Maximum number of allowed mipmap levels. */ GLint Max3DTextureLevels; /**< Maximum number of allowed mipmap levels for 3D texture targets. */ GLint MaxCubeTextureLevels; /**< Maximum number of allowed mipmap levels for GL_ARB_texture_cube_map */ @@ -1716,7 +1724,8 @@ struct gl_constants { /** * List of extensions. */ -struct gl_extensions { +struct gl_extensions +{ /** * \name Flags to quickly test if certain extensions are available. * diff --git a/src/mesa/main/nvfragparse.c b/src/mesa/main/nvfragparse.c index 4f1df534b9..37a5559789 100644 --- a/src/mesa/main/nvfragparse.c +++ b/src/mesa/main/nvfragparse.c @@ -444,59 +444,6 @@ static const char *OutputRegisters[MAX_NV_FRAGMENT_PROGRAM_OUTPUTS + 1] = { }; -static GLint -TempRegisterNumber(GLuint r) -{ - if (r >= FP_TEMP_REG_START && r <= FP_TEMP_REG_END) - return r - FP_TEMP_REG_START; - else - return -1; -} - -static GLint -HalfTempRegisterNumber(GLuint r) -{ - if (r >= FP_TEMP_REG_START + 32 && r <= FP_TEMP_REG_END) - return r - FP_TEMP_REG_START - 32; - else - return -1; -} - -static GLint -InputRegisterNumber(GLuint r) -{ - if (r >= FP_INPUT_REG_START && r <= FP_INPUT_REG_END) - return r - FP_INPUT_REG_START; - else - return -1; -} - -static GLint -OutputRegisterNumber(GLuint r) -{ - if (r >= FP_OUTPUT_REG_START && r <= FP_OUTPUT_REG_END) - return r - FP_OUTPUT_REG_START; - else - return -1; -} - -static GLint -ProgramRegisterNumber(GLuint r) -{ - if (r >= FP_PROG_REG_START && r <= FP_PROG_REG_END) - return r - FP_PROG_REG_START; - else - return -1; -} - -static GLint -DummyRegisterNumber(GLuint r) -{ - if (r >= FP_DUMMY_REG_START && r <= FP_DUMMY_REG_END) - return r - FP_DUMMY_REG_START; - else - return -1; -} /**********************************************************************/ @@ -823,7 +770,7 @@ Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum) reg += 32; if (reg >= MAX_NV_FRAGMENT_PROGRAM_TEMPS) RETURN_ERROR1("Invalid temporary register name"); - *tempRegNum = FP_TEMP_REG_START + reg; + *tempRegNum = reg; } else { RETURN_ERROR1("Invalid temporary register name"); @@ -840,10 +787,10 @@ static GLboolean Parse_DummyReg(struct parse_state *parseState, GLint *regNum) { if (Parse_String(parseState, "RC")) { - *regNum = FP_DUMMY_REG_START; + *regNum = 0; } else if (Parse_String(parseState, "HC")) { - *regNum = FP_DUMMY_REG_START + 1; + *regNum = 1; } else { RETURN_ERROR1("Invalid write-only register name"); @@ -872,7 +819,7 @@ Parse_ProgramParamReg(struct parse_state *parseState, GLint *regNum) GLint reg = _mesa_atoi((const char *) token); if (reg >= MAX_NV_FRAGMENT_PROGRAM_PARAMS) RETURN_ERROR1("Invalid constant program number"); - *regNum = FP_PROG_REG_START + reg; + *regNum = reg; } else { RETURN_ERROR; @@ -904,7 +851,7 @@ Parse_FragReg(struct parse_state *parseState, GLint *tempRegNum) } for (j = 0; InputRegisters[j]; j++) { if (_mesa_strcmp((const char *) token, InputRegisters[j]) == 0) { - *tempRegNum = FP_INPUT_REG_START + j; + *tempRegNum = j; parseState->inputsRead |= (1 << j); break; } @@ -940,7 +887,7 @@ Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum) for (j = 0; OutputRegisters[j]; j++) { if (_mesa_strcmp((const char *) token, OutputRegisters[j]) == 0) { static GLuint bothColors = (1 << FRAG_OUTPUT_COLR) | (1 << FRAG_OUTPUT_COLH); - *outputRegNum = FP_OUTPUT_REG_START + j; + *outputRegNum = j; parseState->outputsWritten |= (1 << j); if ((parseState->outputsWritten & bothColors) == bothColors) { RETURN_ERROR1("Illegal to write to both o[COLR] and o[COLH]"); @@ -972,17 +919,20 @@ Parse_MaskedDstReg(struct parse_state *parseState, if (_mesa_strcmp((const char *) token, "RC") == 0 || _mesa_strcmp((const char *) token, "HC") == 0) { /* a write-only register */ - if (!Parse_DummyReg(parseState, &dstReg->Register)) + dstReg->File = PROGRAM_WRITE_ONLY; + if (!Parse_DummyReg(parseState, &dstReg->Index)) RETURN_ERROR; } else if (token[0] == 'R' || token[0] == 'H') { /* a temporary register */ - if (!Parse_TempReg(parseState, &dstReg->Register)) + dstReg->File = PROGRAM_TEMPORARY; + if (!Parse_TempReg(parseState, &dstReg->Index)) RETURN_ERROR; } else if (token[0] == 'o') { /* an output register */ - if (!Parse_OutputReg(parseState, &dstReg->Register)) + dstReg->File = PROGRAM_OUTPUT; + if (!Parse_OutputReg(parseState, &dstReg->Index)) RETURN_ERROR; } else { @@ -1100,17 +1050,20 @@ Parse_VectorSrc(struct parse_state *parseState, * literal or vector literal. */ if (token[0] == 'R' || token[0] == 'H') { - if (!Parse_TempReg(parseState, &srcReg->Register)) + srcReg->File = PROGRAM_TEMPORARY; + if (!Parse_TempReg(parseState, &srcReg->Index)) RETURN_ERROR; } else if (token[0] == 'f') { /* XXX this might be an identier! */ - if (!Parse_FragReg(parseState, &srcReg->Register)) + srcReg->File = PROGRAM_INPUT; + if (!Parse_FragReg(parseState, &srcReg->Index)) RETURN_ERROR; } else if (token[0] == 'p') { /* XXX this might be an identier! */ - if (!Parse_ProgramParamReg(parseState, &srcReg->Register)) + srcReg->File = PROGRAM_LOCAL_PARAM; + if (!Parse_ProgramParamReg(parseState, &srcReg->Index)) RETURN_ERROR; } else if (IsLetter(token[0])){ @@ -1122,8 +1075,8 @@ Parse_VectorSrc(struct parse_state *parseState, if (paramIndex < 0) { RETURN_ERROR2("Undefined constant or parameter: ", ident); } - srcReg->IsParameter = GL_TRUE; - srcReg->Register = paramIndex; + srcReg->File = PROGRAM_NAMED_PARAM; + srcReg->Index = paramIndex; } else if (IsDigit(token[0]) || token[0] == '-' || token[0] == '+' || token[0] == '.'){ /* literal scalar constant */ @@ -1131,13 +1084,9 @@ Parse_VectorSrc(struct parse_state *parseState, GLuint paramIndex; if (!Parse_ScalarConstant(parseState, values)) RETURN_ERROR; -#if 0 - srcReg->Register = 0; /* XXX fix */ -#else paramIndex = add_unnamed_constant(parseState, values); - srcReg->IsParameter = GL_TRUE; - srcReg->Register = paramIndex; -#endif + srcReg->File = PROGRAM_NAMED_PARAM; + srcReg->Index = paramIndex; } else if (token[0] == '{'){ /* literal vector constant */ @@ -1147,8 +1096,8 @@ Parse_VectorSrc(struct parse_state *parseState, if (!Parse_VectorConstant(parseState, values)) RETURN_ERROR; paramIndex = add_unnamed_constant(parseState, values); - srcReg->IsParameter = GL_TRUE; - srcReg->Register = paramIndex; + srcReg->File = PROGRAM_NAMED_PARAM; + srcReg->Index = paramIndex; } else { RETURN_ERROR2("Invalid source register name", token); @@ -1216,11 +1165,13 @@ Parse_ScalarSrcReg(struct parse_state *parseState, /* Src reg can be R, H or a named fragment attrib */ if (token[0] == 'R' || token[0] == 'H') { - if (!Parse_TempReg(parseState, &srcReg->Register)) + srcReg->File = PROGRAM_TEMPORARY; + if (!Parse_TempReg(parseState, &srcReg->Index)) RETURN_ERROR; } else if (token[0] == 'f') { - if (!Parse_FragReg(parseState, &srcReg->Register)) + srcReg->File = PROGRAM_INPUT; + if (!Parse_FragReg(parseState, &srcReg->Index)) RETURN_ERROR; } else if (token[0] == '{') { @@ -1231,8 +1182,8 @@ Parse_ScalarSrcReg(struct parse_state *parseState, if (!Parse_VectorConstant(parseState, values)) RETURN_ERROR; paramIndex = add_unnamed_constant(parseState, values); - srcReg->IsParameter = GL_TRUE; - srcReg->Register = paramIndex; + srcReg->File = PROGRAM_NAMED_PARAM; + srcReg->Index = paramIndex; } else if (IsDigit(token[0])) { /* scalar literal */ @@ -1241,8 +1192,8 @@ Parse_ScalarSrcReg(struct parse_state *parseState, if (!Parse_ScalarConstant(parseState, values)) RETURN_ERROR; paramIndex = add_unnamed_constant(parseState, values); - srcReg->IsParameter = GL_TRUE; - srcReg->Register = paramIndex; + srcReg->Index = paramIndex; + srcReg->File = PROGRAM_NAMED_PARAM; needSuffix = GL_FALSE; } else { @@ -1298,13 +1249,10 @@ Parse_InstructionSequence(struct parse_state *parseState, GLubyte token[100]; /* Initialize the instruction */ - inst->SrcReg[0].Register = -1; - inst->SrcReg[1].Register = -1; - inst->SrcReg[2].Register = -1; - inst->SrcReg[0].IsParameter = GL_FALSE; - inst->SrcReg[1].IsParameter = GL_FALSE; - inst->SrcReg[2].IsParameter = GL_FALSE; - inst->DstReg.Register = -1; + inst->SrcReg[0].File = -1; + inst->SrcReg[1].File = -1; + inst->SrcReg[2].File = -1; + inst->DstReg.File = -1; inst->DstReg.CondSwizzle[0] = 0; inst->DstReg.CondSwizzle[1] = 1; inst->DstReg.CondSwizzle[2] = 2; @@ -1617,7 +1565,6 @@ PrintSrcReg(const struct fragment_program *program, const struct fp_src_register *src) { static const char comps[5] = "xyzw"; - GLint r; if (src->NegateAbs) { _mesa_printf("-"); @@ -1628,38 +1575,38 @@ PrintSrcReg(const struct fragment_program *program, if (src->NegateBase) { _mesa_printf("-"); } - if (src->IsParameter) { - if (program->Parameters[src->Register].Constant) { + if (src->File == PROGRAM_NAMED_PARAM) { + if (program->Parameters[src->Index].Constant) { printf("{%g, %g, %g, %g}", - program->Parameters[src->Register].Values[0], - program->Parameters[src->Register].Values[1], - program->Parameters[src->Register].Values[2], - program->Parameters[src->Register].Values[3]); + program->Parameters[src->Index].Values[0], + program->Parameters[src->Index].Values[1], + program->Parameters[src->Index].Values[2], + program->Parameters[src->Index].Values[3]); } else { - printf("%s", program->Parameters[src->Register].Name); + printf("%s", program->Parameters[src->Index].Name); } } - else if ((r = OutputRegisterNumber(src->Register)) >= 0) { - _mesa_printf("o[%s]", OutputRegisters[r]); + else if (src->File == PROGRAM_OUTPUT) { + _mesa_printf("o[%s]", OutputRegisters[src->Index]); } - else if ((r = InputRegisterNumber(src->Register)) >= 0) { - _mesa_printf("f[%s]", InputRegisters[r]); + else if (src->File == PROGRAM_INPUT) { + _mesa_printf("f[%s]", InputRegisters[src->Index]); } - else if ((r = ProgramRegisterNumber(src->Register)) >= 0) { - _mesa_printf("p[%d]", r); + else if (src->File == PROGRAM_LOCAL_PARAM) { + _mesa_printf("p[%d]", src->Index); } - else if ((r = HalfTempRegisterNumber(src->Register)) >= 0) { - _mesa_printf("H%d", r); - } - else if ((r = TempRegisterNumber(src->Register)) >= 0) { - _mesa_printf("R%d", r); + else if (src->File == PROGRAM_TEMPORARY) { + if (src->Index >= 32) + _mesa_printf("H%d", src->Index); + else + _mesa_printf("R%d", src->Index); } - else if ((r = DummyRegisterNumber(src->Register)) >= 0) { - _mesa_printf("%cC", "HR"[r]); + else if (src->File == PROGRAM_WRITE_ONLY) { + _mesa_printf("%cC", "HR"[src->Index]); } else { - _mesa_problem(NULL, "Invalid fragment register %d", src->Register); + _mesa_problem(NULL, "Invalid fragment register %d", src->Index); return; } if (src->Swizzle[0] == src->Swizzle[1] && @@ -1739,22 +1686,21 @@ PrintDstReg(const struct fp_dst_register *dst) { GLint w = dst->WriteMask[0] + dst->WriteMask[1] + dst->WriteMask[2] + dst->WriteMask[3]; - GLint r; - if ((r = OutputRegisterNumber(dst->Register)) >= 0) { - _mesa_printf("o[%s]", OutputRegisters[r]); + if (dst->File == PROGRAM_OUTPUT) { + _mesa_printf("o[%s]", OutputRegisters[dst->Index]); } - else if ((r = HalfTempRegisterNumber(dst->Register)) >= 0) { - _mesa_printf("H%d", r); - } - else if ((r = TempRegisterNumber(dst->Register)) >= 0) { - _mesa_printf("R%d", r); + else if (dst->File == PROGRAM_TEMPORARY) { + if (dst->Index >= 32) + _mesa_printf("H%d", dst->Index); + else + _mesa_printf("R%d", dst->Index); } - else if ((r = ProgramRegisterNumber(dst->Register)) >= 0) { - _mesa_printf("p[%d]", r); + else if (dst->File == PROGRAM_LOCAL_PARAM) { + _mesa_printf("p[%d]", dst->Index); } - else if ((r = DummyRegisterNumber(dst->Register)) >= 0) { - _mesa_printf("%cC", "HR"[r]); + else if (dst->File == PROGRAM_WRITE_ONLY) { + _mesa_printf("%cC", "HR"[dst->Index]); } else { _mesa_printf("???"); diff --git a/src/mesa/main/nvfragprog.h b/src/mesa/main/nvfragprog.h index 2f2434b42e..33b219c4ce 100644 --- a/src/mesa/main/nvfragprog.h +++ b/src/mesa/main/nvfragprog.h @@ -53,19 +53,6 @@ #define FRAG_OUTPUT_DEPR 2 -/* Location of register sets within the whole register file */ -#define FP_INPUT_REG_START 0 -#define FP_INPUT_REG_END (FP_INPUT_REG_START + MAX_NV_FRAGMENT_PROGRAM_INPUTS - 1) -#define FP_OUTPUT_REG_START (FP_INPUT_REG_END + 1) -#define FP_OUTPUT_REG_END (FP_OUTPUT_REG_START + MAX_NV_FRAGMENT_PROGRAM_OUTPUTS - 1) -#define FP_TEMP_REG_START (FP_OUTPUT_REG_END + 1) -#define FP_TEMP_REG_END (FP_TEMP_REG_START + MAX_NV_FRAGMENT_PROGRAM_TEMPS - 1) -#define FP_PROG_REG_START (FP_TEMP_REG_END + 1) -#define FP_PROG_REG_END (FP_PROG_REG_START + MAX_NV_FRAGMENT_PROGRAM_PARAMS - 1) -#define FP_DUMMY_REG_START (FP_PROG_REG_END + 1) -#define FP_DUMMY_REG_END (FP_DUMMY_REG_START + MAX_NV_FRAGMENT_PROGRAM_WRITE_ONLYS - 1) - - /* condition codes */ #define COND_GT 1 /* greater than zero */ #define COND_EQ 2 /* equal to zero */ @@ -84,6 +71,7 @@ #define FIXED12 0x4 +/* Fragment program instruction opcodes */ enum fp_opcode { FP_OPCODE_ADD = 1000, FP_OPCODE_COS, @@ -134,10 +122,11 @@ enum fp_opcode { }; +/* Instruction source register */ struct fp_src_register { - GLint Register; /* or the offset from the address register */ - GLboolean IsParameter; /* true if register refers to a param or constant */ + enum register_file File; + GLint Index; GLuint Swizzle[4]; GLboolean NegateBase; /* negate before absolute value? */ GLboolean Abs; /* take absolute value? */ @@ -148,13 +137,15 @@ struct fp_src_register /* Instruction destination register */ struct fp_dst_register { - GLint Register; + enum register_file File; + GLint Index; GLboolean WriteMask[4]; GLuint CondMask; GLuint CondSwizzle[4]; }; +/* Fragment program instruction */ struct fp_instruction { enum fp_opcode Opcode; diff --git a/src/mesa/main/nvvertexec.c b/src/mesa/main/nvvertexec.c index 153172df47..73d5440c79 100644 --- a/src/mesa/main/nvvertexec.c +++ b/src/mesa/main/nvvertexec.c @@ -48,29 +48,21 @@ static const GLfloat zeroVec[4] = { 0, 0, 0, 0 }; void _mesa_init_vp_registers(GLcontext *ctx) { - struct vp_machine *machine = &(ctx->VertexProgram.Machine); GLuint i; /* Input registers get initialized from the current vertex attribs */ - MEMCPY(machine->Registers[VP_INPUT_REG_START], - ctx->Current.Attrib, - 16 * 4 * sizeof(GLfloat)); + MEMCPY(ctx->VertexProgram.Inputs, ctx->Current.Attrib, + VERT_ATTRIB_MAX * 4 * sizeof(GLfloat)); /* Output and temp regs are initialized to [0,0,0,1] */ - for (i = VP_OUTPUT_REG_START; i <= VP_OUTPUT_REG_END; i++) { - machine->Registers[i][0] = 0.0F; - machine->Registers[i][1] = 0.0F; - machine->Registers[i][2] = 0.0F; - machine->Registers[i][3] = 1.0F; + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) { + ASSIGN_4V(ctx->VertexProgram.Outputs[i], 0.0F, 0.0F, 0.0F, 1.0F); } - for (i = VP_TEMP_REG_START; i <= VP_TEMP_REG_END; i++) { - machine->Registers[i][0] = 0.0F; - machine->Registers[i][1] = 0.0F; - machine->Registers[i][2] = 0.0F; - machine->Registers[i][3] = 1.0F; + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) { + ASSIGN_4V(ctx->VertexProgram.Temporaries[i], 0.0F, 0.0F, 0.0F, 1.0F); } - /* The program regs aren't touched */ + /* The program parameters aren't touched */ } @@ -83,7 +75,6 @@ static void load_matrix(GLfloat registers[][4], GLuint pos, const GLfloat mat[16]) { GLuint i; - pos += VP_PROG_REG_START; for (i = 0; i < 4; i++) { registers[pos + i][0] = mat[0 + i]; registers[pos + i][1] = mat[4 + i]; @@ -100,7 +91,6 @@ static void load_transpose_matrix(GLfloat registers[][4], GLuint pos, const GLfloat mat[16]) { - pos += VP_PROG_REG_START; MEMCPY(registers[pos], mat, 16 * sizeof(GLfloat)); } @@ -114,7 +104,7 @@ _mesa_init_tracked_matrices(GLcontext *ctx) { GLuint i; - for (i = 0; i < VP_NUM_PROG_REGS / 4; i++) { + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) { /* point 'mat' at source matrix */ GLmatrix *mat; if (ctx->VertexProgram.TrackMatrix[i] == GL_MODELVIEW) { @@ -147,23 +137,22 @@ _mesa_init_tracked_matrices(GLcontext *ctx) /* load the matrix */ if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_IDENTITY_NV) { - load_matrix(ctx->VertexProgram.Machine.Registers, i*4, mat->m); + load_matrix(ctx->VertexProgram.Parameters, i*4, mat->m); } else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_INVERSE_NV) { _math_matrix_analyse(mat); /* update the inverse */ assert((mat->flags & MAT_DIRTY_INVERSE) == 0); - load_matrix(ctx->VertexProgram.Machine.Registers, i*4, mat->inv); + load_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv); } else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_TRANSPOSE_NV) { - load_transpose_matrix(ctx->VertexProgram.Machine.Registers, i*4, mat->m); + load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->m); } else { assert(ctx->VertexProgram.TrackMatrixTransform[i] == GL_INVERSE_TRANSPOSE_NV); _math_matrix_analyse(mat); /* update the inverse */ assert((mat->flags & MAT_DIRTY_INVERSE) == 0); - load_transpose_matrix(ctx->VertexProgram.Machine.Registers, - i*4, mat->inv); + load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv); } } } @@ -174,72 +163,103 @@ _mesa_init_tracked_matrices(GLcontext *ctx) * For debugging. Dump the current vertex program machine registers. */ void -_mesa_dump_vp_machine( const struct vp_machine *machine ) +_mesa_dump_vp_state( const struct vertex_program_state *state ) { int i; _mesa_printf("VertexIn:\n"); - for (i = 0; i < VP_NUM_INPUT_REGS; i++) { + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_INPUTS; i++) { _mesa_printf("%d: %f %f %f %f ", i, - machine->Registers[i + VP_INPUT_REG_START][0], - machine->Registers[i + VP_INPUT_REG_START][1], - machine->Registers[i + VP_INPUT_REG_START][2], - machine->Registers[i + VP_INPUT_REG_START][3]); + state->Inputs[i][0], + state->Inputs[i][1], + state->Inputs[i][2], + state->Inputs[i][3]); } _mesa_printf("\n"); _mesa_printf("VertexOut:\n"); - for (i = 0; i < VP_NUM_OUTPUT_REGS; i++) { + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) { _mesa_printf("%d: %f %f %f %f ", i, - machine->Registers[i + VP_OUTPUT_REG_START][0], - machine->Registers[i + VP_OUTPUT_REG_START][1], - machine->Registers[i + VP_OUTPUT_REG_START][2], - machine->Registers[i + VP_OUTPUT_REG_START][3]); + state->Outputs[i][0], + state->Outputs[i][1], + state->Outputs[i][2], + state->Outputs[i][3]); } _mesa_printf("\n"); _mesa_printf("Registers:\n"); - for (i = 0; i < VP_NUM_TEMP_REGS; i++) { + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) { _mesa_printf("%d: %f %f %f %f ", i, - machine->Registers[i + VP_TEMP_REG_START][0], - machine->Registers[i + VP_TEMP_REG_START][1], - machine->Registers[i + VP_TEMP_REG_START][2], - machine->Registers[i + VP_TEMP_REG_START][3]); + state->Temporaries[i][0], + state->Temporaries[i][1], + state->Temporaries[i][2], + state->Temporaries[i][3]); } _mesa_printf("\n"); _mesa_printf("Parameters:\n"); - for (i = 0; i < VP_NUM_PROG_REGS; i++) { + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS; i++) { _mesa_printf("%d: %f %f %f %f ", i, - machine->Registers[i + VP_PROG_REG_START][0], - machine->Registers[i + VP_PROG_REG_START][1], - machine->Registers[i + VP_PROG_REG_START][2], - machine->Registers[i + VP_PROG_REG_START][3]); + state->Parameters[i][0], + state->Parameters[i][1], + state->Parameters[i][2], + state->Parameters[i][3]); } _mesa_printf("\n"); } + /** - * Fetch a 4-element float vector from the given source register. - * Apply swizzling and negating as needed. + * Return a pointer to the 4-element float vector specified by the given + * source register. */ -static void -fetch_vector4( const struct vp_src_register *source, - const struct vp_machine *machine, - GLfloat result[4] ) +static INLINE const GLfloat * +get_register_pointer( const struct vp_src_register *source, + const struct vertex_program_state *state ) { - const GLfloat *src; - if (source->RelAddr) { - const GLint reg = source->Register + machine->AddressReg; + const GLint reg = source->Index + state->AddressReg[0]; + ASSERT(source->File == PROGRAM_ENV_PARAM); if (reg < 0 || reg > MAX_NV_VERTEX_PROGRAM_PARAMS) - src = zeroVec; + return zeroVec; else - src = machine->Registers[VP_PROG_REG_START + reg]; + return state->Parameters[reg]; } else { - src = machine->Registers[source->Register]; + switch (source->File) { + case PROGRAM_TEMPORARY: + return state->Temporaries[source->Index]; + case PROGRAM_INPUT: + return state->Inputs[source->Index]; + case PROGRAM_LOCAL_PARAM: + /* XXX fix */ + return state->Temporaries[source->Index]; + case PROGRAM_ENV_PARAM: + return state->Parameters[source->Index]; + case PROGRAM_STATE_VAR: + /* XXX fix */ + return NULL; + break; + default: + _mesa_problem(NULL, + "Bad source register file in fetch_vector4(vp)"); + return NULL; + } } + return NULL; +} + + +/** + * Fetch a 4-element float vector from the given source register. + * Apply swizzling and negating as needed. + */ +static INLINE void +fetch_vector4( const struct vp_src_register *source, + const struct vertex_program_state *state, + GLfloat result[4] ) +{ + const GLfloat *src = get_register_pointer(source, state); if (source->Negate) { result[0] = -src[source->Swizzle[0]]; @@ -256,26 +276,16 @@ fetch_vector4( const struct vp_src_register *source, } + /** * As above, but only return result[0] element. */ -static void +static INLINE void fetch_vector1( const struct vp_src_register *source, - const struct vp_machine *machine, + const struct vertex_program_state *state, GLfloat result[4] ) { - const GLfloat *src; - - if (source->RelAddr) { - const GLint reg = source->Register + machine->AddressReg; - if (reg < 0 || reg > MAX_NV_VERTEX_PROGRAM_PARAMS) - src = zeroVec; - else - src = machine->Registers[VP_PROG_REG_START + reg]; - } - else { - src = machine->Registers[source->Register]; - } + const GLfloat *src = get_register_pointer(source, state); if (source->Negate) { result[0] = -src[source->Swizzle[0]]; @@ -290,10 +300,22 @@ fetch_vector1( const struct vp_src_register *source, * Store 4 floats into a register. */ static void -store_vector4( const struct vp_dst_register *dest, struct vp_machine *machine, +store_vector4( const struct vp_dst_register *dest, + struct vertex_program_state *state, const GLfloat value[4] ) { - GLfloat *dst = machine->Registers[dest->Register]; + GLfloat *dst; + switch (dest->File) { + case PROGRAM_TEMPORARY: + dst = state->Temporaries[dest->Index]; + break; + case PROGRAM_OUTPUT: + dst = state->Outputs[dest->Index]; + break; + default: + _mesa_problem(NULL, "Invalid register file in fetch_vector1(vp)"); + return; + } if (dest->WriteMask[0]) dst[0] = value[0]; @@ -329,7 +351,7 @@ store_vector4( const struct vp_dst_register *dest, struct vp_machine *machine, void _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program) { - struct vp_machine *machine = &ctx->VertexProgram.Machine; + struct vertex_program_state *state = &ctx->VertexProgram; const struct vp_instruction *inst; ctx->_CurrentProgram = GL_VERTEX_PROGRAM_ARB; /* or NV, doesn't matter */ @@ -347,15 +369,15 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program) case VP_OPCODE_MOV: { GLfloat t[4]; - fetch_vector4( &inst->SrcReg[0], machine, t ); - store_vector4( &inst->DstReg, machine, t ); + fetch_vector4( &inst->SrcReg[0], state, t ); + store_vector4( &inst->DstReg, state, t ); } break; case VP_OPCODE_LIT: { const GLfloat epsilon = 1.0e-5F; /* XXX fix? */ GLfloat t[4], lit[4]; - fetch_vector4( &inst->SrcReg[0], machine, t ); + fetch_vector4( &inst->SrcReg[0], state, t ); if (t[3] < -(128.0F - epsilon)) t[3] = - (128.0F - epsilon); else if (t[3] > 128.0F - epsilon) @@ -368,32 +390,32 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program) lit[1] = t[0]; lit[2] = (t[0] > 0.0) ? (GLfloat) exp(t[3] * log(t[1])) : 0.0F; lit[3] = 1.0; - store_vector4( &inst->DstReg, machine, lit ); + store_vector4( &inst->DstReg, state, lit ); } break; case VP_OPCODE_RCP: { GLfloat t[4]; - fetch_vector1( &inst->SrcReg[0], machine, t ); + fetch_vector1( &inst->SrcReg[0], state, t ); if (t[0] != 1.0F) t[0] = 1.0F / t[0]; /* div by zero is infinity! */ t[1] = t[2] = t[3] = t[0]; - store_vector4( &inst->DstReg, machine, t ); + store_vector4( &inst->DstReg, state, t ); } break; case VP_OPCODE_RSQ: { GLfloat t[4]; - fetch_vector1( &inst->SrcReg[0], machine, t ); + fetch_vector1( &inst->SrcReg[0], state, t ); t[0] = INV_SQRTF(FABSF(t[0])); t[1] = t[2] = t[3] = t[0]; - store_vector4( &inst->DstReg, machine, t ); + store_vector4( &inst->DstReg, state, t ); } break; case VP_OPCODE_EXP: { GLfloat t[4], q[4], floor_t0; - fetch_vector1( &inst->SrcReg[0], machine, t ); + fetch_vector1( &inst->SrcReg[0], state, t ); floor_t0 = (float) floor(t[0]); if (floor_t0 > FLT_MAX_EXP) { SET_POS_INFINITY(q[0]); @@ -416,13 +438,13 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program) } q[1] = t[0] - floor_t0; q[3] = 1.0F; - store_vector4( &inst->DstReg, machine, q ); + store_vector4( &inst->DstReg, state, q ); } break; case VP_OPCODE_LOG: { GLfloat t[4], q[4], abs_t0; - fetch_vector1( &inst->SrcReg[0], machine, t ); + fetch_vector1( &inst->SrcReg[0], state, t ); abs_t0 = (GLfloat) fabs(t[0]); if (abs_t0 != 0.0F) { /* Since we really can't handle infinite values on VMS @@ -453,147 +475,147 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program) SET_NEG_INFINITY(q[2]); } q[3] = 1.0; - store_vector4( &inst->DstReg, machine, q ); + store_vector4( &inst->DstReg, state, q ); } break; case VP_OPCODE_MUL: { GLfloat t[4], u[4], prod[4]; - fetch_vector4( &inst->SrcReg[0], machine, t ); - fetch_vector4( &inst->SrcReg[1], machine, u ); + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); prod[0] = t[0] * u[0]; prod[1] = t[1] * u[1]; prod[2] = t[2] * u[2]; prod[3] = t[3] * u[3]; - store_vector4( &inst->DstReg, machine, prod ); + store_vector4( &inst->DstReg, state, prod ); } break; case VP_OPCODE_ADD: { GLfloat t[4], u[4], sum[4]; - fetch_vector4( &inst->SrcReg[0], machine, t ); - fetch_vector4( &inst->SrcReg[1], machine, u ); + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); sum[0] = t[0] + u[0]; sum[1] = t[1] + u[1]; sum[2] = t[2] + u[2]; sum[3] = t[3] + u[3]; - store_vector4( &inst->DstReg, machine, sum ); + store_vector4( &inst->DstReg, state, sum ); } break; case VP_OPCODE_DP3: { GLfloat t[4], u[4], dot[4]; - fetch_vector4( &inst->SrcReg[0], machine, t ); - fetch_vector4( &inst->SrcReg[1], machine, u ); + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2]; dot[1] = dot[2] = dot[3] = dot[0]; - store_vector4( &inst->DstReg, machine, dot ); + store_vector4( &inst->DstReg, state, dot ); } break; case VP_OPCODE_DP4: { GLfloat t[4], u[4], dot[4]; - fetch_vector4( &inst->SrcReg[0], machine, t ); - fetch_vector4( &inst->SrcReg[1], machine, u ); + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + t[3] * u[3]; dot[1] = dot[2] = dot[3] = dot[0]; - store_vector4( &inst->DstReg, machine, dot ); + store_vector4( &inst->DstReg, state, dot ); } break; case VP_OPCODE_DST: { GLfloat t[4], u[4], dst[4]; - fetch_vector4( &inst->SrcReg[0], machine, t ); - fetch_vector4( &inst->SrcReg[1], machine, u ); + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); dst[0] = 1.0F; dst[1] = t[1] * u[1]; dst[2] = t[2]; dst[3] = u[3]; - store_vector4( &inst->DstReg, machine, dst ); + store_vector4( &inst->DstReg, state, dst ); } break; case VP_OPCODE_MIN: { GLfloat t[4], u[4], min[4]; - fetch_vector4( &inst->SrcReg[0], machine, t ); - fetch_vector4( &inst->SrcReg[1], machine, u ); + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); min[0] = (t[0] < u[0]) ? t[0] : u[0]; min[1] = (t[1] < u[1]) ? t[1] : u[1]; min[2] = (t[2] < u[2]) ? t[2] : u[2]; min[3] = (t[3] < u[3]) ? t[3] : u[3]; - store_vector4( &inst->DstReg, machine, min ); + store_vector4( &inst->DstReg, state, min ); } break; case VP_OPCODE_MAX: { GLfloat t[4], u[4], max[4]; - fetch_vector4( &inst->SrcReg[0], machine, t ); - fetch_vector4( &inst->SrcReg[1], machine, u ); + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); max[0] = (t[0] > u[0]) ? t[0] : u[0]; max[1] = (t[1] > u[1]) ? t[1] : u[1]; max[2] = (t[2] > u[2]) ? t[2] : u[2]; max[3] = (t[3] > u[3]) ? t[3] : u[3]; - store_vector4( &inst->DstReg, machine, max ); + store_vector4( &inst->DstReg, state, max ); } break; case VP_OPCODE_SLT: { GLfloat t[4], u[4], slt[4]; - fetch_vector4( &inst->SrcReg[0], machine, t ); - fetch_vector4( &inst->SrcReg[1], machine, u ); + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); slt[0] = (t[0] < u[0]) ? 1.0F : 0.0F; slt[1] = (t[1] < u[1]) ? 1.0F : 0.0F; slt[2] = (t[2] < u[2]) ? 1.0F : 0.0F; slt[3] = (t[3] < u[3]) ? 1.0F : 0.0F; - store_vector4( &inst->DstReg, machine, slt ); + store_vector4( &inst->DstReg, state, slt ); } break; case VP_OPCODE_SGE: { GLfloat t[4], u[4], sge[4]; - fetch_vector4( &inst->SrcReg[0], machine, t ); - fetch_vector4( &inst->SrcReg[1], machine, u ); + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); sge[0] = (t[0] >= u[0]) ? 1.0F : 0.0F; sge[1] = (t[1] >= u[1]) ? 1.0F : 0.0F; sge[2] = (t[2] >= u[2]) ? 1.0F : 0.0F; sge[3] = (t[3] >= u[3]) ? 1.0F : 0.0F; - store_vector4( &inst->DstReg, machine, sge ); + store_vector4( &inst->DstReg, state, sge ); } break; case VP_OPCODE_MAD: { GLfloat t[4], u[4], v[4], sum[4]; - fetch_vector4( &inst->SrcReg[0], machine, t ); - fetch_vector4( &inst->SrcReg[1], machine, u ); - fetch_vector4( &inst->SrcReg[2], machine, v ); + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( &inst->SrcReg[2], state, v ); sum[0] = t[0] * u[0] + v[0]; sum[1] = t[1] * u[1] + v[1]; sum[2] = t[2] * u[2] + v[2]; sum[3] = t[3] * u[3] + v[3]; - store_vector4( &inst->DstReg, machine, sum ); + store_vector4( &inst->DstReg, state, sum ); } break; case VP_OPCODE_ARL: { GLfloat t[4]; - fetch_vector4( &inst->SrcReg[0], machine, t ); - machine->AddressReg = (GLint) floor(t[0]); + fetch_vector4( &inst->SrcReg[0], state, t ); + state->AddressReg[0] = (GLint) floor(t[0]); } break; case VP_OPCODE_DPH: { GLfloat t[4], u[4], dot[4]; - fetch_vector4( &inst->SrcReg[0], machine, t ); - fetch_vector4( &inst->SrcReg[1], machine, u ); + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + u[3]; dot[1] = dot[2] = dot[3] = dot[0]; - store_vector4( &inst->DstReg, machine, dot ); + store_vector4( &inst->DstReg, state, dot ); } break; case VP_OPCODE_RCC: { GLfloat t[4], u; - fetch_vector1( &inst->SrcReg[0], machine, t ); + fetch_vector1( &inst->SrcReg[0], state, t ); if (t[0] == 1.0F) u = 1.0F; else @@ -615,110 +637,98 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program) } } t[0] = t[1] = t[2] = t[3] = u; - store_vector4( &inst->DstReg, machine, t ); + store_vector4( &inst->DstReg, state, t ); } break; case VP_OPCODE_SUB: /* GL_NV_vertex_program1_1 */ { GLfloat t[4], u[4], sum[4]; - fetch_vector4( &inst->SrcReg[0], machine, t ); - fetch_vector4( &inst->SrcReg[1], machine, u ); + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); sum[0] = t[0] - u[0]; sum[1] = t[1] - u[1]; sum[2] = t[2] - u[2]; sum[3] = t[3] - u[3]; - store_vector4( &inst->DstReg, machine, sum ); + store_vector4( &inst->DstReg, state, sum ); } break; case VP_OPCODE_ABS: /* GL_NV_vertex_program1_1 */ { GLfloat t[4]; - fetch_vector4( &inst->SrcReg[0], machine, t ); + fetch_vector4( &inst->SrcReg[0], state, t ); if (t[0] < 0.0) t[0] = -t[0]; if (t[1] < 0.0) t[1] = -t[1]; if (t[2] < 0.0) t[2] = -t[2]; if (t[3] < 0.0) t[3] = -t[3]; - store_vector4( &inst->DstReg, machine, t ); + store_vector4( &inst->DstReg, state, t ); } break; case VP_OPCODE_FLR: /* GL_ARB_vertex_program */ { GLfloat t[4]; - fetch_vector4( &inst->SrcReg[0], machine, t ); + fetch_vector4( &inst->SrcReg[0], state, t ); t[0] = FLOORF(t[0]); t[1] = FLOORF(t[1]); t[2] = FLOORF(t[2]); t[3] = FLOORF(t[3]); - store_vector4( &inst->DstReg, machine, t ); + store_vector4( &inst->DstReg, state, t ); } break; case VP_OPCODE_FRC: /* GL_ARB_vertex_program */ { GLfloat t[4]; - fetch_vector4( &inst->SrcReg[0], machine, t ); + fetch_vector4( &inst->SrcReg[0], state, t ); t[0] = t[0] - FLOORF(t[0]); t[1] = t[1] - FLOORF(t[1]); t[2] = t[2] - FLOORF(t[2]); t[3] = t[3] - FLOORF(t[3]); - store_vector4( &inst->DstReg, machine, t ); + store_vector4( &inst->DstReg, state, t ); } break; case VP_OPCODE_EX2: /* GL_ARB_vertex_program */ { GLfloat t[4]; - fetch_vector1( &inst->SrcReg[0], machine, t ); + fetch_vector1( &inst->SrcReg[0], state, t ); t[0] = t[1] = t[2] = t[3] = _mesa_pow(2.0, t[0]); - store_vector4( &inst->DstReg, machine, t ); + store_vector4( &inst->DstReg, state, t ); } break; case VP_OPCODE_LG2: /* GL_ARB_vertex_program */ { GLfloat t[4]; - fetch_vector1( &inst->SrcReg[0], machine, t ); + fetch_vector1( &inst->SrcReg[0], state, t ); t[0] = t[1] = t[2] = t[3] = LOG2(t[0]); - store_vector4( &inst->DstReg, machine, t ); + store_vector4( &inst->DstReg, state, t ); } break; case VP_OPCODE_POW: /* GL_ARB_vertex_program */ { GLfloat t[4], u[4]; - fetch_vector1( &inst->SrcReg[0], machine, t ); - fetch_vector1( &inst->SrcReg[1], machine, u ); + fetch_vector1( &inst->SrcReg[0], state, t ); + fetch_vector1( &inst->SrcReg[1], state, u ); t[0] = t[1] = t[2] = t[3] = _mesa_pow(t[0], u[0]); - store_vector4( &inst->DstReg, machine, t ); + store_vector4( &inst->DstReg, state, t ); } break; case VP_OPCODE_XPD: /* GL_ARB_vertex_program */ { GLfloat t[4], u[4], cross[4]; - fetch_vector4( &inst->SrcReg[0], machine, t ); - fetch_vector4( &inst->SrcReg[1], machine, u ); + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); cross[0] = t[1] * u[2] - t[2] * u[1]; cross[1] = t[2] * u[0] - t[0] * u[2]; cross[2] = t[0] * u[1] - t[1] * u[0]; - store_vector4( &inst->DstReg, machine, cross ); + store_vector4( &inst->DstReg, state, cross ); } break; case VP_OPCODE_SWZ: /* GL_ARB_vertex_program */ { const struct vp_src_register *source = &inst->SrcReg[0]; - const GLfloat *src; + const GLfloat *src = get_register_pointer(source, state); GLfloat result[4]; GLuint i; - /* Code similar to fetch_vector4() */ - if (source->RelAddr) { - const GLint reg = source->Register + machine->AddressReg; - if (reg < 0 || reg > MAX_NV_VERTEX_PROGRAM_PARAMS) - src = zeroVec; - else - src = machine->Registers[VP_PROG_REG_START + reg]; - } - else { - src = machine->Registers[source->Register]; - } - - /* extended swizzling here */ + /* do extended swizzling here */ for (i = 0; i < 3; i++) { if (source->Swizzle[i] == SWIZZLE_ZERO) result[i] = 0.0; @@ -729,7 +739,7 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program) if (source->Negate) result[i] = -result[i]; } - store_vector4( &inst->DstReg, machine, result ); + store_vector4( &inst->DstReg, state, result ); } break; diff --git a/src/mesa/main/nvvertexec.h b/src/mesa/main/nvvertexec.h index 0242d0ed7c..0e4b60ec9e 100644 --- a/src/mesa/main/nvvertexec.h +++ b/src/mesa/main/nvvertexec.h @@ -38,6 +38,6 @@ extern void _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program); extern void -_mesa_dump_vp_machine( const struct vp_machine *machine ); +_mesa_dump_vp_state( const struct vertex_program_state *state ); #endif diff --git a/src/mesa/main/nvvertparse.c b/src/mesa/main/nvvertparse.c index d6cf58a87e..4078fd864f 100644 --- a/src/mesa/main/nvvertparse.c +++ b/src/mesa/main/nvvertparse.c @@ -54,7 +54,7 @@ struct parse_state { GLboolean isVersion1_1; GLuint inputsRead; GLuint outputsWritten; - GLuint progRegsWritten; + GLboolean anyProgRegsWritten; GLuint numInst; /* number of instructions parsed */ }; @@ -282,33 +282,18 @@ static const char *OutputRegisters[MAX_NV_VERTEX_PROGRAM_OUTPUTS + 1] = { "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL }; +/* NOTE: the order here must match opcodes in nvvertprog.h */ static const char *Opcodes[] = { "MOV", "LIT", "RCP", "RSQ", "EXP", "LOG", "MUL", "ADD", "DP3", "DP4", "DST", "MIN", "MAX", "SLT", "SGE", "MAD", "ARL", "DPH", "RCC", "SUB", - "ABS", "END", NULL + "ABS", "END", + /* GL_ARB_vertex_program */ + "FLR", "FRC", "EX2", "LG2", "POW", "XPD", "SWZ", + NULL }; -static GLuint -IsProgRegister(GLuint r) -{ - return (GLuint) (r >= VP_PROG_REG_START && r <= VP_PROG_REG_END); -} - -static GLuint -IsInputRegister(GLuint r) -{ - return (GLuint) (r >= VP_INPUT_REG_START && r <= VP_INPUT_REG_END); -} - -static GLuint -IsOutputRegister(GLuint r) -{ - return (GLuint) (r >= VP_OUTPUT_REG_START && r <= VP_OUTPUT_REG_END); -} - - /** * Parse a temporary register: Rnn */ @@ -325,9 +310,9 @@ Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum) if (IsDigit(token[1])) { GLint reg = _mesa_atoi((char *) (token + 1)); - if (reg >= VP_NUM_TEMP_REGS) + if (reg >= MAX_NV_VERTEX_PROGRAM_TEMPS) RETURN_ERROR1("Bad temporary register name"); - *tempRegNum = VP_TEMP_REG_START + reg; + *tempRegNum = reg; } else { RETURN_ERROR1("Bad temporary register name"); @@ -379,9 +364,9 @@ Parse_AbsParamReg(struct parse_state *parseState, GLint *regNum) if (IsDigit(token[0])) { /* a numbered program parameter register */ GLint reg = _mesa_atoi((char *) token); - if (reg >= VP_NUM_PROG_REGS) - RETURN_ERROR1("Bad constant program number"); - *regNum = VP_PROG_REG_START + reg; + if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS) + RETURN_ERROR1("Bad program parameter number"); + *regNum = reg; } else { RETURN_ERROR; @@ -413,9 +398,10 @@ Parse_ParamReg(struct parse_state *parseState, struct vp_src_register *srcReg) GLint reg; (void) Parse_Token(parseState, token); reg = _mesa_atoi((char *) token); - if (reg >= VP_NUM_PROG_REGS) - RETURN_ERROR1("Bad constant program number"); - srcReg->Register = VP_PROG_REG_START + reg; + if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS) + RETURN_ERROR1("Bad program parameter number"); + srcReg->File = PROGRAM_ENV_PARAM; + srcReg->Index = reg; } else if (_mesa_strcmp((const char *) token, "A0") == 0) { /* address register "A0.x" */ @@ -423,8 +409,7 @@ Parse_ParamReg(struct parse_state *parseState, struct vp_src_register *srcReg) RETURN_ERROR; srcReg->RelAddr = GL_TRUE; - srcReg->Register = 0; - + srcReg->File = PROGRAM_ENV_PARAM; /* Look for +/-N offset */ if (!Peek_Token(parseState, token)) RETURN_ERROR; @@ -442,12 +427,12 @@ Parse_ParamReg(struct parse_state *parseState, struct vp_src_register *srcReg) if (sign == '-') { if (k > 64) RETURN_ERROR1("Bad address offset"); - srcReg->Register = -k; + srcReg->Index = -k; } else { if (k > 63) RETURN_ERROR1("Bad address offset"); - srcReg->Register = k; + srcReg->Index = k; } } else { @@ -496,14 +481,14 @@ Parse_AttribReg(struct parse_state *parseState, GLint *tempRegNum) if (IsDigit(token[0])) { GLint reg = _mesa_atoi((char *) token); - if (reg >= VP_NUM_INPUT_REGS) + if (reg >= MAX_NV_VERTEX_PROGRAM_INPUTS) RETURN_ERROR1("Bad vertex attribute register name"); - *tempRegNum = VP_INPUT_REG_START + reg; + *tempRegNum = reg; } else { for (j = 0; InputRegisters[j]; j++) { if (_mesa_strcmp((const char *) token, InputRegisters[j]) == 0) { - *tempRegNum = VP_INPUT_REG_START + j; + *tempRegNum = j; break; } } @@ -547,7 +532,7 @@ Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum) /* try to match an output register name */ for (j = start; OutputRegisters[j]; j++) { if (_mesa_strcmp((const char *) token, OutputRegisters[j]) == 0) { - *outputRegNum = VP_OUTPUT_REG_START + j; + *outputRegNum = j; break; } } @@ -573,17 +558,20 @@ Parse_MaskedDstReg(struct parse_state *parseState, struct vp_dst_register *dstRe if (token[0] == 'R') { /* a temporary register */ - if (!Parse_TempReg(parseState, &dstReg->Register)) + dstReg->File = PROGRAM_TEMPORARY; + if (!Parse_TempReg(parseState, &dstReg->Index)) RETURN_ERROR; } else if (!parseState->isStateProgram && token[0] == 'o') { /* an output register */ - if (!Parse_OutputReg(parseState, &dstReg->Register)) + dstReg->File = PROGRAM_OUTPUT; + if (!Parse_OutputReg(parseState, &dstReg->Index)) RETURN_ERROR; } else if (parseState->isStateProgram && token[0] == 'c') { /* absolute program parameter register */ - if (!Parse_AbsParamReg(parseState, &dstReg->Register)) + dstReg->File = PROGRAM_ENV_PARAM; + if (!Parse_AbsParamReg(parseState, &dstReg->Index)) RETURN_ERROR; } else { @@ -662,7 +650,8 @@ Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcR /* Src reg can be R, c[n], c[n +/- offset], or a named vertex attrib */ if (token[0] == 'R') { - if (!Parse_TempReg(parseState, &srcReg->Register)) + srcReg->File = PROGRAM_TEMPORARY; + if (!Parse_TempReg(parseState, &srcReg->Index)) RETURN_ERROR; } else if (token[0] == 'c') { @@ -670,7 +659,8 @@ Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcR RETURN_ERROR; } else if (token[0] == 'v') { - if (!Parse_AttribReg(parseState, &srcReg->Register)) + srcReg->File = PROGRAM_INPUT; + if (!Parse_AttribReg(parseState, &srcReg->Index)) RETURN_ERROR; } else { @@ -751,7 +741,8 @@ Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcRe /* Src reg can be R, c[n], c[n +/- offset], or a named vertex attrib */ if (token[0] == 'R') { - if (!Parse_TempReg(parseState, &srcReg->Register)) + srcReg->File = PROGRAM_TEMPORARY; + if (!Parse_TempReg(parseState, &srcReg->Index)) RETURN_ERROR; } else if (token[0] == 'c') { @@ -759,7 +750,8 @@ Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcRe RETURN_ERROR; } else if (token[0] == 'v') { - if (!Parse_AttribReg(parseState, &srcReg->Register)) + srcReg->File = PROGRAM_INPUT; + if (!Parse_AttribReg(parseState, &srcReg->Index)) RETURN_ERROR; } else { @@ -861,15 +853,15 @@ Parse_BiOpInstruction(struct parse_state *parseState, RETURN_ERROR; /* make sure we don't reference more than one program parameter register */ - if (IsProgRegister(inst->SrcReg[0].Register) && - IsProgRegister(inst->SrcReg[1].Register) && - inst->SrcReg[0].Register != inst->SrcReg[1].Register) + if (inst->SrcReg[0].File == PROGRAM_ENV_PARAM && + inst->SrcReg[1].File == PROGRAM_ENV_PARAM && + inst->SrcReg[0].Index != inst->SrcReg[1].Index) RETURN_ERROR1("Can't reference two program parameter registers"); /* make sure we don't reference more than one vertex attribute register */ - if (IsInputRegister(inst->SrcReg[0].Register) && - IsInputRegister(inst->SrcReg[1].Register) && - inst->SrcReg[0].Register != inst->SrcReg[1].Register) + if (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[1].File == PROGRAM_INPUT && + inst->SrcReg[0].Index != inst->SrcReg[1].Index) RETURN_ERROR1("Can't reference two vertex attribute registers"); return GL_TRUE; @@ -916,27 +908,27 @@ Parse_TriOpInstruction(struct parse_state *parseState, RETURN_ERROR; /* make sure we don't reference more than one program parameter register */ - if ((IsProgRegister(inst->SrcReg[0].Register) && - IsProgRegister(inst->SrcReg[1].Register) && - inst->SrcReg[0].Register != inst->SrcReg[1].Register) || - (IsProgRegister(inst->SrcReg[0].Register) && - IsProgRegister(inst->SrcReg[2].Register) && - inst->SrcReg[0].Register != inst->SrcReg[2].Register) || - (IsProgRegister(inst->SrcReg[1].Register) && - IsProgRegister(inst->SrcReg[2].Register) && - inst->SrcReg[1].Register != inst->SrcReg[2].Register)) + if ((inst->SrcReg[0].File == PROGRAM_ENV_PARAM && + inst->SrcReg[1].File == PROGRAM_ENV_PARAM && + inst->SrcReg[0].Index != inst->SrcReg[1].Index) || + (inst->SrcReg[0].File == PROGRAM_ENV_PARAM && + inst->SrcReg[2].File == PROGRAM_ENV_PARAM && + inst->SrcReg[0].Index != inst->SrcReg[2].Index) || + (inst->SrcReg[1].File == PROGRAM_ENV_PARAM && + inst->SrcReg[2].File == PROGRAM_ENV_PARAM && + inst->SrcReg[1].Index != inst->SrcReg[2].Index)) RETURN_ERROR1("Can only reference one program register"); /* make sure we don't reference more than one vertex attribute register */ - if ((IsInputRegister(inst->SrcReg[0].Register) && - IsInputRegister(inst->SrcReg[1].Register) && - inst->SrcReg[0].Register != inst->SrcReg[1].Register) || - (IsInputRegister(inst->SrcReg[0].Register) && - IsInputRegister(inst->SrcReg[2].Register) && - inst->SrcReg[0].Register != inst->SrcReg[2].Register) || - (IsInputRegister(inst->SrcReg[1].Register) && - IsInputRegister(inst->SrcReg[2].Register) && - inst->SrcReg[1].Register != inst->SrcReg[2].Register)) + if ((inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[1].File == PROGRAM_INPUT && + inst->SrcReg[0].Index != inst->SrcReg[1].Index) || + (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[2].File == PROGRAM_INPUT && + inst->SrcReg[0].Index != inst->SrcReg[2].Index) || + (inst->SrcReg[1].File == PROGRAM_INPUT && + inst->SrcReg[2].File == PROGRAM_INPUT && + inst->SrcReg[1].Index != inst->SrcReg[2].Index)) RETURN_ERROR1("Can only reference one input register"); return GL_TRUE; @@ -1042,10 +1034,10 @@ Parse_InstructionSequence(struct parse_state *parseState, struct vp_instruction *inst = program + parseState->numInst; /* Initialize the instruction */ - inst->SrcReg[0].Register = -1; - inst->SrcReg[1].Register = -1; - inst->SrcReg[2].Register = -1; - inst->DstReg.Register = -1; + inst->SrcReg[0].File = -1; + inst->SrcReg[1].File = -1; + inst->SrcReg[2].File = -1; + inst->DstReg.File = -1; if (Parse_String(parseState, "MOV")) { if (!Parse_UnaryOpInstruction(parseState, inst, VP_OPCODE_MOV)) @@ -1145,26 +1137,17 @@ Parse_InstructionSequence(struct parse_state *parseState, } /* examine input/output registers */ - { - const GLint srcReg0 = inst->SrcReg[0].Register; - const GLint srcReg1 = inst->SrcReg[1].Register; - const GLint srcReg2 = inst->SrcReg[2].Register; - const GLint dstReg = inst->DstReg.Register; - - if (IsOutputRegister(dstReg)) - parseState->outputsWritten |= (1 << (dstReg - VP_OUTPUT_REG_START)); - else if (IsProgRegister(dstReg)) - parseState->progRegsWritten |= (1 << (dstReg - VP_PROG_REG_START)); - - if (IsInputRegister(srcReg0) && !inst->SrcReg[0].RelAddr) - parseState->inputsRead |= (1 << (srcReg0 - VP_INPUT_REG_START)); - - if (IsInputRegister(srcReg1) && !inst->SrcReg[1].RelAddr) - parseState->inputsRead |= (1 << (srcReg1 - VP_INPUT_REG_START)); - - if (IsInputRegister(srcReg2) && !inst->SrcReg[2].RelAddr) - parseState->inputsRead |= (1 << (srcReg2 - VP_INPUT_REG_START)); - } + if (inst->DstReg.File == PROGRAM_OUTPUT) + parseState->outputsWritten |= (1 << inst->DstReg.Index); + else if (inst->DstReg.File == PROGRAM_ENV_PARAM) + parseState->anyProgRegsWritten = GL_TRUE; + + if (inst->SrcReg[0].File == PROGRAM_INPUT) + parseState->inputsRead |= (1 << inst->SrcReg[0].Index); + if (inst->SrcReg[1].File == PROGRAM_INPUT) + parseState->inputsRead |= (1 << inst->SrcReg[1].Index); + if (inst->SrcReg[2].File == PROGRAM_INPUT) + parseState->inputsRead |= (1 << inst->SrcReg[2].Index); parseState->numInst++; @@ -1222,7 +1205,7 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget, parseState.numInst = 0; parseState.inputsRead = 0; parseState.outputsWritten = 0; - parseState.progRegsWritten = 0; + parseState.anyProgRegsWritten = GL_FALSE; /* Reset error state */ _mesa_set_program_error(ctx, -1, NULL); @@ -1263,7 +1246,7 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget, /* successful parse! */ if (parseState.isStateProgram) { - if (parseState.progRegsWritten == 0) { + if (!parseState.anyProgRegsWritten) { _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(c[#] not written)"); return; @@ -1331,27 +1314,25 @@ PrintSrcReg(const struct vp_src_register *src) if (src->Negate) _mesa_printf("-"); if (src->RelAddr) { - if (src->Register > 0) - _mesa_printf("c[A0.x + %d]", src->Register); - else if (src->Register < 0) - _mesa_printf("c[A0.x - %d]", -src->Register); + if (src->Index > 0) + _mesa_printf("c[A0.x + %d]", src->Index); + else if (src->Index < 0) + _mesa_printf("c[A0.x - %d]", -src->Index); else _mesa_printf("c[A0.x]"); } - else if (src->Register >= VP_OUTPUT_REG_START - && src->Register <= VP_OUTPUT_REG_END) { - _mesa_printf("o[%s]", OutputRegisters[src->Register - VP_OUTPUT_REG_START]); + else if (src->File == PROGRAM_OUTPUT) { + _mesa_printf("o[%s]", OutputRegisters[src->Index]); } - else if (src->Register >= VP_INPUT_REG_START - && src->Register <= VP_INPUT_REG_END) { - _mesa_printf("v[%s]", InputRegisters[src->Register - VP_INPUT_REG_START]); + else if (src->File == PROGRAM_INPUT) { + _mesa_printf("v[%s]", InputRegisters[src->Index]); } - else if (src->Register >= VP_PROG_REG_START - && src->Register <= VP_PROG_REG_END) { - _mesa_printf("c[%d]", src->Register - VP_PROG_REG_START); + else if (src->File == PROGRAM_ENV_PARAM) { + _mesa_printf("c[%d]", src->Index); } else { - _mesa_printf("R%d", src->Register - VP_TEMP_REG_START); + ASSERT(src->File == PROGRAM_TEMPORARY); + _mesa_printf("R%d", src->Index); } if (src->Swizzle[0] == src->Swizzle[1] && @@ -1378,20 +1359,18 @@ PrintDstReg(const struct vp_dst_register *dst) GLint w = dst->WriteMask[0] + dst->WriteMask[1] + dst->WriteMask[2] + dst->WriteMask[3]; - if (dst->Register >= VP_OUTPUT_REG_START - && dst->Register <= VP_OUTPUT_REG_END) { - _mesa_printf("o[%s]", OutputRegisters[dst->Register - VP_OUTPUT_REG_START]); + if (dst->File == PROGRAM_OUTPUT) { + _mesa_printf("o[%s]", OutputRegisters[dst->Index]); } - else if (dst->Register >= VP_INPUT_REG_START - && dst->Register <= VP_INPUT_REG_END) { - _mesa_printf("v[%s]", InputRegisters[dst->Register - VP_INPUT_REG_START]); + else if (dst->File == PROGRAM_INPUT) { + _mesa_printf("v[%s]", InputRegisters[dst->Index]); } - else if (dst->Register >= VP_PROG_REG_START - && dst->Register <= VP_PROG_REG_END) { - _mesa_printf("c[%d]", dst->Register - VP_PROG_REG_START); + else if (dst->File == PROGRAM_ENV_PARAM) { + _mesa_printf("c[%d]", dst->Index); } else { - _mesa_printf("R%d", dst->Register - VP_TEMP_REG_START); + ASSERT(dst->File == PROGRAM_TEMPORARY); + _mesa_printf("R%d", dst->Index); } if (w != 0 && w != 4) { diff --git a/src/mesa/main/nvvertprog.h b/src/mesa/main/nvvertprog.h index 6ccb0c4efb..1011fc5ad2 100644 --- a/src/mesa/main/nvvertprog.h +++ b/src/mesa/main/nvvertprog.h @@ -32,22 +32,6 @@ #define NVVERTPROG_H -#define VP_NUM_INPUT_REGS MAX_NV_VERTEX_PROGRAM_INPUTS -#define VP_NUM_OUTPUT_REGS MAX_NV_VERTEX_PROGRAM_OUTPUTS -#define VP_NUM_TEMP_REGS MAX_NV_VERTEX_PROGRAM_TEMPS -#define VP_NUM_PROG_REGS MAX_NV_VERTEX_PROGRAM_PARAMS - -/* Location of register groups within the whole register file */ -#define VP_INPUT_REG_START 0 -#define VP_INPUT_REG_END (VP_INPUT_REG_START + VP_NUM_INPUT_REGS - 1) -#define VP_OUTPUT_REG_START (VP_INPUT_REG_END + 1) -#define VP_OUTPUT_REG_END (VP_OUTPUT_REG_START + VP_NUM_OUTPUT_REGS - 1) -#define VP_TEMP_REG_START (VP_OUTPUT_REG_END + 1) -#define VP_TEMP_REG_END (VP_TEMP_REG_START + VP_NUM_TEMP_REGS - 1) -#define VP_PROG_REG_START (VP_TEMP_REG_END + 1) -#define VP_PROG_REG_END (VP_PROG_REG_START + VP_NUM_PROG_REGS - 1) - - /* for GL_ARB_v_p SWZ instruction */ #define SWIZZLE_ZERO 100 #define SWIZZLE_ONE 101 @@ -89,10 +73,12 @@ enum vp_opcode }; + /* Instruction source register */ struct vp_src_register { - GLint Register; /* or the offset from the address register */ + enum register_file File; /* which register file */ + GLint Index; /* index into register file */ GLubyte Swizzle[4]; /* Each value is 0,1,2,3 for x,y,z,w or */ /* SWIZZLE_ZERO or SWIZZLE_ONE for VP_OPCODE_SWZ. */ GLboolean Negate; @@ -103,7 +89,8 @@ struct vp_src_register /* Instruction destination register */ struct vp_dst_register { - GLint Register; + enum register_file File; /* which register file */ + GLint Index; /* index into register file */ GLboolean WriteMask[4]; }; -- cgit v1.2.3