summaryrefslogtreecommitdiff
path: root/src/mesa/main
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2003-08-17 17:11:50 +0000
committerBrian Paul <brian.paul@tungstengraphics.com>2003-08-17 17:11:50 +0000
commitf2dd273322cc9ec0cfe80a609f9a1e5db5931e2e (patch)
treeedc2da6b3b703c474fc12003e4c38505cb8ef2a5 /src/mesa/main
parent4f12be02491713d6998fa43e3efc19daf2faffeb (diff)
Re-org of register files for vertex/fragment programs. Will be easier to
hook in global state references, etc. for ARB programs.
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/arbprogram.c35
-rw-r--r--src/mesa/main/arbvertparse.h3
-rw-r--r--src/mesa/main/context.c4
-rw-r--r--src/mesa/main/macros.h9
-rw-r--r--src/mesa/main/mtypes.h71
-rw-r--r--src/mesa/main/nvfragparse.c190
-rw-r--r--src/mesa/main/nvfragprog.h23
-rw-r--r--src/mesa/main/nvvertexec.c324
-rw-r--r--src/mesa/main/nvvertexec.h2
-rw-r--r--src/mesa/main/nvvertparse.c215
-rw-r--r--src/mesa/main/nvvertprog.h23
11 files changed, 397 insertions, 502 deletions
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<n>, H<n> 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<n>, 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<n>, 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];
};