📄 arbprogparse.c
字号:
#define REGISTER_ESTABLISHED_NAME 0x04
/* param binding */
#define PARAM_NULL 0x00
#define PARAM_ARRAY_ELEMENT 0x01
#define PARAM_STATE_ELEMENT 0x02
#define PARAM_PROGRAM_ELEMENT 0x03
#define PARAM_PROGRAM_ELEMENTS 0x04
#define PARAM_CONSTANT 0x05
/* param state property */
#define STATE_MATERIAL_PARSER 0x01
#define STATE_LIGHT_PARSER 0x02
#define STATE_LIGHT_MODEL 0x03
#define STATE_LIGHT_PROD 0x04
#define STATE_FOG 0x05
#define STATE_MATRIX_ROWS 0x06
/* GL_ARB_fragment_program */
#define STATE_TEX_ENV 0x07
#define STATE_DEPTH 0x08
/* GL_ARB_vertex_program */
#define STATE_TEX_GEN 0x09
#define STATE_CLIP_PLANE 0x0A
#define STATE_POINT 0x0B
/* state material property */
#define MATERIAL_AMBIENT 0x01
#define MATERIAL_DIFFUSE 0x02
#define MATERIAL_SPECULAR 0x03
#define MATERIAL_EMISSION 0x04
#define MATERIAL_SHININESS 0x05
/* state light property */
#define LIGHT_AMBIENT 0x01
#define LIGHT_DIFFUSE 0x02
#define LIGHT_SPECULAR 0x03
#define LIGHT_POSITION 0x04
#define LIGHT_ATTENUATION 0x05
#define LIGHT_HALF 0x06
#define LIGHT_SPOT_DIRECTION 0x07
/* state light model property */
#define LIGHT_MODEL_AMBIENT 0x01
#define LIGHT_MODEL_SCENECOLOR 0x02
/* state light product property */
#define LIGHT_PROD_AMBIENT 0x01
#define LIGHT_PROD_DIFFUSE 0x02
#define LIGHT_PROD_SPECULAR 0x03
/* state texture environment property */
#define TEX_ENV_COLOR 0x01
/* state texture generation coord property */
#define TEX_GEN_EYE 0x01
#define TEX_GEN_OBJECT 0x02
/* state fog property */
#define FOG_COLOR 0x01
#define FOG_PARAMS 0x02
/* state depth property */
#define DEPTH_RANGE 0x01
/* state point parameters property */
#define POINT_SIZE 0x01
#define POINT_ATTENUATION 0x02
/* declaration */
#define ATTRIB 0x01
#define PARAM 0x02
#define TEMP 0x03
#define OUTPUT 0x04
#define ALIAS 0x05
/* GL_ARB_vertex_program */
#define ADDRESS 0x06
/*-----------------------------------------------------------------------
* From here on down is the semantic checking portion
*
*/
/**
* Variable Table Handling functions
*/
typedef enum
{
vt_none,
vt_address,
vt_attrib,
vt_param,
vt_temp,
vt_output,
vt_alias
} var_type;
/*
* Setting an explicit field for each of the binding properties is a bit wasteful
* of space, but it should be much more clear when reading later on..
*/
struct var_cache
{
GLubyte *name;
var_type type;
GLuint address_binding; /* The index of the address register we should
* be using */
GLuint attrib_binding; /* For type vt_attrib, see nvfragprog.h for values */
GLuint attrib_binding_idx; /* The index into the attrib register file corresponding
* to the state in attrib_binding */
GLuint attrib_is_generic; /* If the attrib was specified through a generic
* vertex attrib */
GLuint temp_binding; /* The index of the temp register we are to use */
GLuint output_binding; /* For type vt_output, see nvfragprog.h for values */
GLuint output_binding_idx; /* This is the index into the result register file
* corresponding to the bound result state */
struct var_cache *alias_binding; /* For type vt_alias, points to the var_cache entry
* that this is aliased to */
GLuint param_binding_type; /* {PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM,
* PROGRAM_ENV_PARAM} */
GLuint param_binding_begin; /* This is the offset into the program_parameter_list where
* the tokens representing our bound state (or constants)
* start */
GLuint param_binding_length; /* This is how many entries in the the program_parameter_list
* we take up with our state tokens or constants. Note that
* this is _not_ the same as the number of param registers
* we eventually use */
struct var_cache *next;
};
static GLvoid
var_cache_create (struct var_cache **va)
{
*va = (struct var_cache *) _mesa_malloc (sizeof (struct var_cache));
if (*va) {
(**va).name = NULL;
(**va).type = vt_none;
(**va).attrib_binding = ~0;
(**va).attrib_is_generic = 0;
(**va).temp_binding = ~0;
(**va).output_binding = ~0;
(**va).output_binding_idx = ~0;
(**va).param_binding_type = ~0;
(**va).param_binding_begin = ~0;
(**va).param_binding_length = ~0;
(**va).alias_binding = NULL;
(**va).next = NULL;
}
}
static GLvoid
var_cache_destroy (struct var_cache **va)
{
if (*va) {
var_cache_destroy (&(**va).next);
_mesa_free (*va);
*va = NULL;
}
}
static GLvoid
var_cache_append (struct var_cache **va, struct var_cache *nv)
{
if (*va)
var_cache_append (&(**va).next, nv);
else
*va = nv;
}
static struct var_cache *
var_cache_find (struct var_cache *va, GLubyte * name)
{
/*struct var_cache *first = va;*/
while (va) {
if (!strcmp ( (const char*) name, (const char*) va->name)) {
if (va->type == vt_alias)
return va->alias_binding;
return va;
}
va = va->next;
}
return NULL;
}
/**
* constructs an integer from 4 GLubytes in LE format
*/
static GLuint
parse_position (GLubyte ** inst)
{
GLuint value;
value = (GLuint) (*(*inst)++);
value += (GLuint) (*(*inst)++) * 0x100;
value += (GLuint) (*(*inst)++) * 0x10000;
value += (GLuint) (*(*inst)++) * 0x1000000;
return value;
}
/**
* This will, given a string, lookup the string as a variable name in the
* var cache. If the name is found, the var cache node corresponding to the
* var name is returned. If it is not found, a new entry is allocated
*
* \param I Points into the binary array where the string identifier begins
* \param found 1 if the string was found in the var_cache, 0 if it was allocated
* \return The location on the var_cache corresponding the the string starting at I
*/
static struct var_cache *
parse_string (GLubyte ** inst, struct var_cache **vc_head,
struct arb_program *Program, GLuint * found)
{
GLubyte *i = *inst;
struct var_cache *va = NULL;
(void) Program;
*inst += _mesa_strlen ((char *) i) + 1;
va = var_cache_find (*vc_head, i);
if (va) {
*found = 1;
return va;
}
*found = 0;
var_cache_create (&va);
va->name = i;
var_cache_append (vc_head, va);
return va;
}
static char *
parse_string_without_adding (GLubyte ** inst, struct arb_program *Program)
{
GLubyte *i = *inst;
(void) Program;
*inst += _mesa_strlen ((char *) i) + 1;
return (char *) i;
}
/**
* \return -1 if we parse '-', return 1 otherwise
*/
static GLint
parse_sign (GLubyte ** inst)
{
/*return *(*inst)++ != '+'; */
if (**inst == '-') {
(*inst)++;
return -1;
}
else if (**inst == '+') {
(*inst)++;
return 1;
}
return 1;
}
/**
* parses and returns signed integer
*/
static GLint
parse_integer (GLubyte ** inst, struct arb_program *Program)
{
GLint sign;
GLint value;
/* check if *inst points to '+' or '-'
* if yes, grab the sign and increment *inst
*/
sign = parse_sign (inst);
/* now check if *inst points to 0
* if yes, increment the *inst and return the default value
*/
if (**inst == 0) {
(*inst)++;
return 0;
}
/* parse the integer as you normally would do it */
value = _mesa_atoi (parse_string_without_adding (inst, Program));
/* now, after terminating 0 there is a position
* to parse it - parse_position()
*/
Program->Position = parse_position (inst);
return value * sign;
}
/**
Accumulate this string of digits, and return them as
a large integer represented in floating point (for range).
If scale is not NULL, also accumulates a power-of-ten
integer scale factor that represents the number of digits
in the string.
*/
static GLdouble
parse_float_string(GLubyte ** inst, struct arb_program *Program, GLdouble *scale)
{
GLdouble value = 0.0;
GLdouble oscale = 1.0;
if (**inst == 0) { /* this string of digits is empty-- do nothing */
(*inst)++;
}
else { /* nonempty string-- parse out the digits */
while (**inst >= '0' && **inst <= '9') {
GLubyte digit = *((*inst)++);
value = value * 10.0 + (GLint) (digit - '0');
oscale *= 10.0;
}
assert(**inst == 0); /* integer string should end with 0 */
(*inst)++; /* skip over terminating 0 */
Program->Position = parse_position(inst); /* skip position (from integer) */
}
if (scale)
*scale = oscale;
return value;
}
/**
Parse an unsigned floating-point number from this stream of tokenized
characters. Example floating-point formats supported:
12.34
12
0.34
.34
12.34e-4
*/
static GLfloat
parse_float (GLubyte ** inst, struct arb_program *Program)
{
GLint exponent;
GLdouble whole, fraction, fracScale = 1.0;
whole = parse_float_string(inst, Program, 0);
fraction = parse_float_string(inst, Program, &fracScale);
/* Parse signed exponent */
exponent = parse_integer(inst, Program); /* This is the exponent */
/* Assemble parts of floating-point number: */
return (GLfloat) ((whole + fraction / fracScale) *
_mesa_pow(10.0, (GLfloat) exponent));
}
/**
*/
static GLfloat
parse_signed_float (GLubyte ** inst, struct arb_program *Program)
{
GLint sign = parse_sign (inst);
GLfloat value = parse_float (inst, Program);
return value * sign;
}
/**
* This picks out a constant value from the parsed array. The constant vector is r
* returned in the *values array, which should be of length 4.
*
* \param values - The 4 component vector with the constant value in it
*/
static GLvoid
parse_constant (GLubyte ** inst, GLfloat *values, struct arb_program *Program,
GLboolean use)
{
GLuint components, i;
switch (*(*inst)++) {
case CONSTANT_SCALAR:
if (use == GL_TRUE) {
values[0] =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -