/** * Parse absolute program parameter register "c[##]" */ static GLboolean Parse_AbsParamReg(struct parse_state *parseState, GLint *regNum) { GLubyte token[100]; if (!Parse_String(parseState, "c")) RETURN_ERROR; if (!Parse_String(parseState, "[")) RETURN_ERROR; if (!Parse_Token(parseState, token)) RETURN_ERROR; if (IsDigit(token[0])) { /* a numbered program parameter register */ GLint reg = _mesa_atoi((char *) token); if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS) RETURN_ERROR1("Bad program parameter number"); *regNum = reg; } else { RETURN_ERROR; } if (!Parse_String(parseState, "]")) RETURN_ERROR; return GL_TRUE; }
/** * Parse a program local parameter register "p[##]" */ static GLboolean Parse_ProgramParamReg(struct parse_state *parseState, GLint *regNum) { GLubyte token[100]; if (!Parse_String(parseState, "p[")) RETURN_ERROR1("Expected p["); if (!Parse_Token(parseState, token)) RETURN_ERROR; if (IsDigit(token[0])) { /* a numbered program parameter register */ GLint reg = _mesa_atoi((const char *) token); if (reg >= MAX_NV_FRAGMENT_PROGRAM_PARAMS) RETURN_ERROR1("Invalid constant program number"); *regNum = reg; } else { RETURN_ERROR; } if (!Parse_String(parseState, "]")) RETURN_ERROR1("Expected ]"); return GL_TRUE; }
/** * Parse a temporary register: Rnn or Hnn */ static GLboolean Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum) { GLubyte token[100]; /* Should be 'R##' or 'H##' */ if (!Parse_Token(parseState, token)) RETURN_ERROR; if (token[0] != 'R' && token[0] != 'H') RETURN_ERROR1("Expected R## or H##"); if (IsDigit(token[1])) { GLint reg = _mesa_atoi((const char *) (token + 1)); if (token[0] == 'H') reg += 32; if (reg >= MAX_NV_FRAGMENT_PROGRAM_TEMPS) RETURN_ERROR1("Invalid temporary register name"); *tempRegNum = reg; } else { RETURN_ERROR1("Invalid temporary register name"); } return GL_TRUE; }
/** * Parse a texture image source: * [TEX0 | TEX1 | .. | TEX15] , [1D | 2D | 3D | CUBE | RECT] */ static GLboolean Parse_TextureImageId(struct parse_state *parseState, GLubyte *texUnit, GLubyte *texTargetBit) { GLubyte imageSrc[100]; GLint unit; if (!Parse_Token(parseState, imageSrc)) RETURN_ERROR; if (imageSrc[0] != 'T' || imageSrc[1] != 'E' || imageSrc[2] != 'X') { RETURN_ERROR1("Expected TEX# source"); } unit = _mesa_atoi((const char *) imageSrc + 3); if ((unit < 0 || unit > MAX_TEXTURE_IMAGE_UNITS) || (unit == 0 && (imageSrc[3] != '0' || imageSrc[4] != 0))) { RETURN_ERROR1("Invalied TEX# source index"); } *texUnit = unit; if (!Parse_String(parseState, ",")) RETURN_ERROR1("Expected ,"); if (Parse_String(parseState, "1D")) { *texTargetBit = TEXTURE_1D_BIT; } else if (Parse_String(parseState, "2D")) { *texTargetBit = TEXTURE_2D_BIT; } else if (Parse_String(parseState, "3D")) { *texTargetBit = TEXTURE_3D_BIT; } else if (Parse_String(parseState, "CUBE")) { *texTargetBit = TEXTURE_CUBE_BIT; } else if (Parse_String(parseState, "RECT")) { *texTargetBit = TEXTURE_RECT_BIT; } else { RETURN_ERROR1("Invalid texture target token"); } /* update record of referenced texture units */ parseState->texturesUsed[*texUnit] |= *texTargetBit; if (_mesa_bitcount(parseState->texturesUsed[*texUnit]) > 1) { RETURN_ERROR1("Only one texture target can be used per texture unit."); } return GL_TRUE; }
/** * Parse v[#] or v[<name>] */ static GLboolean Parse_AttribReg(struct parse_state *parseState, GLint *tempRegNum) { GLubyte token[100]; GLint j; /* Match 'v' */ if (!Parse_String(parseState, "v")) RETURN_ERROR; /* Match '[' */ if (!Parse_String(parseState, "[")) RETURN_ERROR; /* match number or named register */ if (!Parse_Token(parseState, token)) RETURN_ERROR; if (parseState->isStateProgram && token[0] != '0') RETURN_ERROR1("Only v[0] accessible in vertex state programs"); if (IsDigit(token[0])) { GLint reg = _mesa_atoi((char *) token); if (reg >= MAX_NV_VERTEX_PROGRAM_INPUTS) RETURN_ERROR1("Bad vertex attribute register name"); *tempRegNum = reg; } else { for (j = 0; InputRegisters[j]; j++) { if (_mesa_strcmp((const char *) token, InputRegisters[j]) == 0) { *tempRegNum = j; break; } } if (!InputRegisters[j]) { /* unknown input register label */ RETURN_ERROR2("Bad register name", token); } } /* Match '[' */ if (!Parse_String(parseState, "]")) RETURN_ERROR; return GL_TRUE; }
void _mesa_GetProgramRegisterfvMESA(GLenum target, GLsizei len, const GLubyte *registerName, GLfloat *v) { char reg[1000]; GET_CURRENT_CONTEXT(ctx); /* We _should_ be inside glBegin/glEnd */ #if 0 if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramRegisterfvMESA"); return; } #endif /* make null-terminated copy of registerName */ len = MIN2((unsigned int) len, sizeof(reg) - 1); _mesa_memcpy(reg, registerName, len); reg[len] = 0; switch (target) { case GL_VERTEX_PROGRAM_NV: if (!ctx->Extensions.ARB_vertex_program && !ctx->Extensions.NV_vertex_program) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramRegisterfvMESA(target)"); return; } if (!ctx->VertexProgram.Enabled) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramRegisterfvMESA"); return; } /* GL_NV_vertex_program */ if (reg[0] == 'R') { /* Temp register */ GLint i = _mesa_atoi(reg + 1); if (i >= (GLint)ctx->Const.MaxVertexProgramTemps) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramRegisterfvMESA(registerName)"); return; } COPY_4V(v, ctx->VertexProgram.Temporaries[i]); } else if (reg[0] == 'v' && reg[1] == '[') { /* Vertex Input attribute */ GLuint i; for (i = 0; i < ctx->Const.MaxVertexProgramAttribs; i++) { const char *name = _mesa_nv_vertex_input_register_name(i); char number[10]; 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.Inputs[i]); return; } } _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramRegisterfvMESA(registerName)"); return; } else if (reg[0] == 'o' && reg[1] == '[') { /* Vertex output attribute */ } /* GL_ARB_vertex_program */ else if (_mesa_strncmp(reg, "vertex.", 7) == 0) { } else { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramRegisterfvMESA(registerName)"); return; } break; case GL_FRAGMENT_PROGRAM_ARB: if (!ctx->Extensions.ARB_fragment_program) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramRegisterfvMESA(target)"); return; } if (!ctx->FragmentProgram.Enabled) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramRegisterfvMESA"); return; } /* XXX to do */ break; case GL_FRAGMENT_PROGRAM_NV: if (!ctx->Extensions.NV_fragment_program) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramRegisterfvMESA(target)"); return; } if (!ctx->FragmentProgram.Enabled) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramRegisterfvMESA"); return; } if (reg[0] == 'R') { /* Temp register */ GLint i = _mesa_atoi(reg + 1); if (i >= (GLint)ctx->Const.MaxFragmentProgramTemps) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramRegisterfvMESA(registerName)"); return; } COPY_4V(v, ctx->FragmentProgram.Machine.Temporaries[i]); } else if (reg[0] == 'f' && reg[1] == '[') { /* Fragment input attribute */ GLuint i; 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.Inputs[i]); return; } } _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramRegisterfvMESA(registerName)"); return; } else if (_mesa_strcmp(reg, "o[COLR]") == 0) { /* Fragment output color */ 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.Outputs[FRAG_OUTPUT_COLH]); } else if (_mesa_strcmp(reg, "o[DEPR]") == 0) { /* Fragment output depth */ COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_DEPR]); } else { /* try user-defined identifiers */ const GLfloat *value = _mesa_lookup_parameter_value( ctx->FragmentProgram.Current->Parameters, -1, reg); if (value) { COPY_4V(v, value); } else { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramRegisterfvMESA(registerName)"); return; } } break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramRegisterfvMESA(target)"); return; } }
static GLboolean Parse_ParamReg(struct parse_state *parseState, struct vp_src_register *srcReg) { GLubyte token[100]; if (!Parse_String(parseState, "c")) RETURN_ERROR; if (!Parse_String(parseState, "[")) RETURN_ERROR; if (!Peek_Token(parseState, token)) RETURN_ERROR; if (IsDigit(token[0])) { /* a numbered program parameter register */ GLint reg; (void) Parse_Token(parseState, token); reg = _mesa_atoi((char *) token); 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" */ if (!Parse_AddrReg(parseState)) RETURN_ERROR; srcReg->RelAddr = GL_TRUE; srcReg->File = PROGRAM_ENV_PARAM; /* Look for +/-N offset */ if (!Peek_Token(parseState, token)) RETURN_ERROR; if (token[0] == '-' || token[0] == '+') { const GLubyte sign = token[0]; (void) Parse_Token(parseState, token); /* consume +/- */ /* an integer should be next */ if (!Parse_Token(parseState, token)) RETURN_ERROR; if (IsDigit(token[0])) { const GLint k = _mesa_atoi((char *) token); if (sign == '-') { if (k > 64) RETURN_ERROR1("Bad address offset"); srcReg->Index = -k; } else { if (k > 63) RETURN_ERROR1("Bad address offset"); srcReg->Index = k; } } else { RETURN_ERROR; } } else { /* probably got a ']', catch it below */ } } else { RETURN_ERROR; } /* Match closing ']' */ if (!Parse_String(parseState, "]")) RETURN_ERROR; return GL_TRUE; }
static GLboolean execute_expression (slang_string *output, const byte *code, GLuint *pi, GLint *result, slang_info_log *elog) { GLuint i = *pi; GLint stack[EXECUTION_STACK_SIZE]; GLuint sp = EXECUTION_STACK_SIZE; while (code[i] != OP_END) { switch (code[i++]) { case OP_PUSHINT: i++; PUSH(_mesa_atoi ((const char *) (&code[i]))); i += _mesa_strlen ((const char *) (&code[i])) + 1; break; case OP_LOGICALOR: BINARY(||); break; case OP_LOGICALAND: BINARY(&&); break; case OP_OR: BINARY(|); break; case OP_XOR: BINARY(^); break; case OP_AND: BINARY(&); break; case OP_EQUAL: BINARY(==); break; case OP_NOTEQUAL: BINARY(!=); break; case OP_LESSEQUAL: BINARY(<=); break; case OP_GREATEREQUAL: BINARY(>=); break; case OP_LESS: BINARY(<); break; case OP_GREATER: BINARY(>); break; case OP_LEFTSHIFT: BINARY(<<); break; case OP_RIGHTSHIFT: BINARY(>>); break; case OP_ADD: BINARY(+); break; case OP_SUBTRACT: BINARY(-); break; case OP_MULTIPLY: BINARY(*); break; case OP_DIVIDE: BINARYDIV(/); break; case OP_MODULUS: BINARYDIV(%); break; case OP_PLUS: UNARY(+); break; case OP_MINUS: UNARY(-); break; case OP_NEGATE: UNARY(!); break; case OP_COMPLEMENT: UNARY(~); break; default: assert (0); } } /* Write-back the index skipping the OP_END. */ *pi = i + 1; /* There should be exactly one value left on the stack. This is our result. */ POP(*result); pp_annotate (output, "%d ", *result); assert (sp == EXECUTION_STACK_SIZE); return GL_TRUE; }