Lots of clean-up in arb program parser.

Use new _mesa_init_fp/vp_instruction() function to initialize instructions.
This commit is contained in:
Brian Paul
2005-10-30 21:23:23 +00:00
parent 094a1ddf24
commit 7aebaf3deb
5 changed files with 250 additions and 231 deletions

View File

@@ -482,9 +482,9 @@ typedef enum
} var_type; } var_type;
/* /**
* Setting an explicit field for each of the binding properties is a bit wasteful * Setting an explicit field for each of the binding properties is a bit
* of space, but it should be much more clear when reading later on.. * wasteful of space, but it should be much more clear when reading later on..
*/ */
struct var_cache struct var_cache
{ {
@@ -498,9 +498,7 @@ struct var_cache
GLuint attrib_is_generic; /* If the attrib was specified through a generic GLuint attrib_is_generic; /* If the attrib was specified through a generic
* vertex attrib */ * vertex attrib */
GLuint temp_binding; /* The index of the temp register we are to use */ 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; /* Output/result register number */
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 struct var_cache *alias_binding; /* For type vt_alias, points to the var_cache entry
* that this is aliased to */ * that this is aliased to */
GLuint param_binding_type; /* {PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM, GLuint param_binding_type; /* {PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM,
@@ -526,7 +524,6 @@ var_cache_create (struct var_cache **va)
(**va).attrib_is_generic = 0; (**va).attrib_is_generic = 0;
(**va).temp_binding = ~0; (**va).temp_binding = ~0;
(**va).output_binding = ~0; (**va).output_binding = ~0;
(**va).output_binding_idx = ~0;
(**va).param_binding_type = ~0; (**va).param_binding_type = ~0;
(**va).param_binding_begin = ~0; (**va).param_binding_begin = ~0;
(**va).param_binding_length = ~0; (**va).param_binding_length = ~0;
@@ -1580,108 +1577,98 @@ parse_attrib_binding (GLcontext * ctx, GLubyte ** inst,
return err; return err;
} }
/** /**
* This translates between a binary token for an output variable type * This translates between a binary token for an output variable type
* and the mesa token for the same thing. * and the mesa token for the same thing.
* *
* * \param inst The parsed tokens
* XXX: What is the 'name' for vertex program state? -> do we need it? * \param outputReg Returned index/number of the output register,
* I don't think we do; * one of the VERT_RESULT_* or FRAG_OUTPUT_* values.
*
* See nvfragprog.h for definitions
*
* \param inst - The parsed tokens
* \param binding - The name of the state we are binding too
* \param binding_idx - The index into the result register file that this is bound too
*
* See nvfragparse.c for the register file layout for fragment programs
* See nvvertparse.c for the register file layout for vertex programs
*/ */
static GLuint static GLuint
parse_result_binding (GLcontext * ctx, GLubyte ** inst, GLuint * binding, parse_result_binding(GLcontext *ctx, GLubyte **inst,
GLuint * binding_idx, struct arb_program *Program) GLuint *outputReg, struct arb_program *Program)
{ {
GLuint b, out_color; const GLubyte token = *(*inst)++;
switch (*(*inst)++) { switch (token) {
case FRAGMENT_RESULT_COLOR: case FRAGMENT_RESULT_COLOR:
/* for frag programs, this is FRAGMENT_RESULT_COLOR */
if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
GLuint out_color;
/* This gets result of the color buffer we're supposed to /* This gets result of the color buffer we're supposed to
* draw into * draw into. This pertains to GL_ARB_draw_buffers.
*/ */
parse_output_color_num(ctx, inst, Program, &out_color); parse_output_color_num(ctx, inst, Program, &out_color);
ASSERT(out_color < MAX_DRAW_BUFFERS);
*binding = FRAG_OUTPUT_COLR; *outputReg = FRAG_OUTPUT_COLR;
/* XXX: We're ignoring the color buffer for now. */
*binding_idx = 0;
} }
/* for vtx programs, this is VERTEX_RESULT_POSITION */
else { else {
*binding_idx = 0; /* for vtx programs, this is VERTEX_RESULT_POSITION */
*outputReg = VERT_RESULT_HPOS;
} }
break; break;
case FRAGMENT_RESULT_DEPTH: case FRAGMENT_RESULT_DEPTH:
/* for frag programs, this is FRAGMENT_RESULT_DEPTH */
if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
*binding = FRAG_OUTPUT_DEPR; /* for frag programs, this is FRAGMENT_RESULT_DEPTH */
*binding_idx = 2; *outputReg = FRAG_OUTPUT_DEPR;
} }
/* for vtx programs, this is VERTEX_RESULT_COLOR */
else { else {
/* for vtx programs, this is VERTEX_RESULT_COLOR */
GLint color_type; GLint color_type;
GLuint face_type = parse_face_type(inst); GLuint face_type = parse_face_type(inst);
GLint color_type_ret = parse_color_type(ctx, inst, Program, &color_type); GLint err = parse_color_type(ctx, inst, Program, &color_type);
if (err)
return 1;
/* back face */
if (face_type) { if (face_type) {
if (color_type_ret) return 1; /* back face */
/* secondary color */
if (color_type) { if (color_type) {
*binding_idx = 4; *outputReg = VERT_RESULT_BFC1; /* secondary color */
} }
/* primary color */
else { else {
*binding_idx = 3; *outputReg = VERT_RESULT_BFC0; /* primary color */
} }
} }
/* front face */
else { else {
/* secondary color */ /* front face */
if (color_type) { if (color_type) {
*binding_idx = 2; *outputReg = VERT_RESULT_COL1; /* secondary color */
} }
/* primary color */ /* primary color */
else { else {
*binding_idx = 1; *outputReg = VERT_RESULT_COL0; /* primary color */
} }
} }
} }
break; break;
case VERTEX_RESULT_FOGCOORD: case VERTEX_RESULT_FOGCOORD:
*binding_idx = 5; *outputReg = VERT_RESULT_FOGC;
break; break;
case VERTEX_RESULT_POINTSIZE: case VERTEX_RESULT_POINTSIZE:
*binding_idx = 6; *outputReg = VERT_RESULT_PSIZ;
break; break;
case VERTEX_RESULT_TEXCOORD: case VERTEX_RESULT_TEXCOORD:
if (parse_texcoord_num (ctx, inst, Program, &b)) {
return 1; GLuint unit;
*binding_idx = 7 + b; if (parse_texcoord_num (ctx, inst, Program, &unit))
return 1;
*outputReg = VERT_RESULT_TEX0 + unit;
}
break; break;
} }
Program->OutputsWritten |= (1 << *binding_idx); Program->OutputsWritten |= (1 << *outputReg);
return 0; return 0;
} }
/** /**
* This handles the declaration of ATTRIB variables * This handles the declaration of ATTRIB variables
* *
@@ -1715,22 +1702,19 @@ parse_attrib (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
attrib_var->type = vt_attrib; attrib_var->type = vt_attrib;
/* I think this is ok now - karl */ if (parse_attrib_binding(ctx, inst, Program, &attrib_var->attrib_binding,
/* XXX: */ &attrib_var->attrib_binding_idx,
/*if (Program->type == GL_FRAGMENT_PROGRAM_ARB) */ &attrib_var->attrib_is_generic))
{ return 1;
if (parse_attrib_binding
(ctx, inst, Program, &attrib_var->attrib_binding,
&attrib_var->attrib_binding_idx, &attrib_var->attrib_is_generic))
return 1;
if (generic_attrib_check(*vc_head)) {
_mesa_set_program_error (ctx, Program->Position,
"Cannot use both a generic vertex attribute and a specific attribute of the same type");
_mesa_error (ctx, GL_INVALID_OPERATION,
"Cannot use both a generic vertex attribute and a specific attribute of the same type");
return 1;
}
if (generic_attrib_check(*vc_head)) {
_mesa_set_program_error(ctx, Program->Position,
"Cannot use both a generic vertex attribute "
"and a specific attribute of the same type");
_mesa_error(ctx, GL_INVALID_OPERATION,
"Cannot use both a generic vertex attribute and a specific "
"attribute of the same type");
return 1;
} }
Program->Base.NumAttributes++; Program->Base.NumAttributes++;
@@ -1748,15 +1732,12 @@ parse_param_elements (GLcontext * ctx, GLubyte ** inst,
struct arb_program *Program, GLboolean use) struct arb_program *Program, GLboolean use)
{ {
GLint idx; GLint idx;
GLuint err; GLuint err = 0;
GLint state_tokens[6]; GLint state_tokens[6];
GLfloat const_values[4]; GLfloat const_values[4];
err = 0;
switch (*(*inst)++) { switch (*(*inst)++) {
case PARAM_STATE_ELEMENT: case PARAM_STATE_ELEMENT:
if (parse_state_single_item (ctx, inst, Program, state_tokens)) if (parse_state_single_item (ctx, inst, Program, state_tokens))
return 1; return 1;
@@ -1792,7 +1773,6 @@ parse_param_elements (GLcontext * ctx, GLubyte ** inst,
break; break;
case PARAM_PROGRAM_ELEMENT: case PARAM_PROGRAM_ELEMENT:
if (parse_program_single_item (ctx, inst, Program, state_tokens)) if (parse_program_single_item (ctx, inst, Program, state_tokens))
return 1; return 1;
idx = _mesa_add_state_reference (Program->Parameters, state_tokens); idx = _mesa_add_state_reference (Program->Parameters, state_tokens);
@@ -1841,10 +1821,9 @@ parse_param_elements (GLcontext * ctx, GLubyte ** inst,
Program->Base.NumParameters++; Program->Base.NumParameters++;
} }
} }
else else {
{ (*inst)++;
(*inst)++; }
}
break; break;
case PARAM_CONSTANT: case PARAM_CONSTANT:
@@ -1859,10 +1838,10 @@ parse_param_elements (GLcontext * ctx, GLubyte ** inst,
break; break;
default: default:
_mesa_set_program_error (ctx, Program->Position, _mesa_set_program_error(ctx, Program->Position,
"Unexpected token in parse_param_elements()"); "Unexpected token in parse_param_elements()");
_mesa_error (ctx, GL_INVALID_OPERATION, _mesa_error(ctx, GL_INVALID_OPERATION,
"Unexpected token in parse_param_elements()"); "Unexpected token in parse_param_elements()");
return 1; return 1;
} }
@@ -1882,6 +1861,7 @@ parse_param_elements (GLcontext * ctx, GLubyte ** inst,
return err; return err;
} }
/** /**
* This picks out PARAM program parameter bindings. * This picks out PARAM program parameter bindings.
* *
@@ -1895,7 +1875,6 @@ parse_param (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
{ {
GLuint found, err; GLuint found, err;
GLint specified_length; GLint specified_length;
char *error_msg;
struct var_cache *param_var; struct var_cache *param_var;
err = 0; err = 0;
@@ -1903,7 +1882,8 @@ parse_param (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
Program->Position = parse_position (inst); Program->Position = parse_position (inst);
if (found) { if (found) {
error_msg = (char *) _mesa_malloc (_mesa_strlen ((char *) param_var->name) + 40); char *error_msg = (char *)
_mesa_malloc (_mesa_strlen ((char *) param_var->name) + 40);
_mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
param_var->name); param_var->name);
@@ -1948,10 +1928,10 @@ parse_param (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
/* Test array length here! */ /* Test array length here! */
if (specified_length) { if (specified_length) {
if (specified_length != (int)param_var->param_binding_length) { if (specified_length != (int)param_var->param_binding_length) {
_mesa_set_program_error (ctx, Program->Position, const char *msg
"Declared parameter array length does not match parameter list"); = "Declared parameter array length does not match parameter list";
_mesa_error (ctx, GL_INVALID_OPERATION, _mesa_set_program_error(ctx, Program->Position, msg);
"Declared parameter array length does not match parameter list"); _mesa_error(ctx, GL_INVALID_OPERATION, msg);
} }
} }
@@ -2005,13 +1985,12 @@ parse_temp (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
{ {
GLuint found; GLuint found;
struct var_cache *temp_var; struct var_cache *temp_var;
char *error_msg;
while (**inst != 0) { while (**inst != 0) {
temp_var = parse_string (inst, vc_head, Program, &found); temp_var = parse_string (inst, vc_head, Program, &found);
Program->Position = parse_position (inst); Program->Position = parse_position (inst);
if (found) { if (found) {
error_msg = (char *) char *error_msg = (char *)
_mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40); _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
_mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
temp_var->name); temp_var->name);
@@ -2057,12 +2036,12 @@ parse_output (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
{ {
GLuint found; GLuint found;
struct var_cache *output_var; struct var_cache *output_var;
GLuint err;
output_var = parse_string (inst, vc_head, Program, &found); output_var = parse_string (inst, vc_head, Program, &found);
Program->Position = parse_position (inst); Program->Position = parse_position (inst);
if (found) { if (found) {
char *error_msg; char *error_msg = (char *)
error_msg = (char *)
_mesa_malloc (_mesa_strlen ((char *) output_var->name) + 40); _mesa_malloc (_mesa_strlen ((char *) output_var->name) + 40);
_mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
output_var->name); output_var->name);
@@ -2075,8 +2054,9 @@ parse_output (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
} }
output_var->type = vt_output; output_var->type = vt_output;
return parse_result_binding (ctx, inst, &output_var->output_binding,
&output_var->output_binding_idx, Program); err = parse_result_binding(ctx, inst, &output_var->output_binding, Program);
return err;
} }
/** /**
@@ -2090,14 +2070,12 @@ parse_alias (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
{ {
GLuint found; GLuint found;
struct var_cache *temp_var; struct var_cache *temp_var;
char *error_msg;
temp_var = parse_string (inst, vc_head, Program, &found); temp_var = parse_string (inst, vc_head, Program, &found);
Program->Position = parse_position (inst); Program->Position = parse_position (inst);
if (found) { if (found) {
error_msg = (char *) char *error_msg = (char *)
_mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40); _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
_mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
temp_var->name); temp_var->name);
@@ -2115,7 +2093,7 @@ parse_alias (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
if (!found) if (!found)
{ {
error_msg = (char *) char *error_msg = (char *)
_mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40); _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
_mesa_sprintf (error_msg, "Alias value %s is not defined", _mesa_sprintf (error_msg, "Alias value %s is not defined",
temp_var->alias_binding->name); temp_var->alias_binding->name);
@@ -2141,13 +2119,12 @@ parse_address (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
{ {
GLuint found; GLuint found;
struct var_cache *temp_var; struct var_cache *temp_var;
char *error_msg;
while (**inst != 0) { while (**inst != 0) {
temp_var = parse_string (inst, vc_head, Program, &found); temp_var = parse_string (inst, vc_head, Program, &found);
Program->Position = parse_position (inst); Program->Position = parse_position (inst);
if (found) { if (found) {
error_msg = (char *) char *error_msg = (char *)
_mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40); _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
_mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
temp_var->name); temp_var->name);
@@ -2163,10 +2140,10 @@ parse_address (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
if (Program->Base.NumAddressRegs >= if (Program->Base.NumAddressRegs >=
ctx->Const.MaxVertexProgramAddressRegs) { ctx->Const.MaxVertexProgramAddressRegs) {
_mesa_set_program_error (ctx, Program->Position, const char *msg = "Too many ADDRESS variables declared";
"Too many ADDRESS variables declared"); _mesa_set_program_error(ctx, Program->Position, msg);
_mesa_error (ctx, GL_INVALID_OPERATION,
"Too many ADDRESS variables declared"); _mesa_error(ctx, GL_INVALID_OPERATION, msg);
return 1; return 1;
} }
@@ -2219,10 +2196,11 @@ parse_declaration (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
} }
/** /**
* Handle the parsing out of a masked destination register * Handle the parsing out of a masked destination register, either for a
* vertex or fragment program.
* *
* If we are a vertex program, make sure we don't write to * If we are a vertex program, make sure we don't write to
* result.position of we have specified that the program is * result.position if we have specified that the program is
* position invariant * position invariant
* *
* \param File - The register file we write to * \param File - The register file we write to
@@ -2234,9 +2212,9 @@ parse_declaration (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
static GLuint static GLuint
parse_masked_dst_reg (GLcontext * ctx, GLubyte ** inst, parse_masked_dst_reg (GLcontext * ctx, GLubyte ** inst,
struct var_cache **vc_head, struct arb_program *Program, struct var_cache **vc_head, struct arb_program *Program,
GLint * File, GLint * Index, GLint *WriteMask) enum register_file *File, GLuint *Index, GLint *WriteMask)
{ {
GLuint result, tmp; GLuint tmp, result;
struct var_cache *dst; struct var_cache *dst;
/* We either have a result register specified, or a /* We either have a result register specified, or a
@@ -2244,8 +2222,7 @@ parse_masked_dst_reg (GLcontext * ctx, GLubyte ** inst,
*/ */
switch (*(*inst)++) { switch (*(*inst)++) {
case REGISTER_RESULT: case REGISTER_RESULT:
if (parse_result_binding if (parse_result_binding(ctx, inst, Index, Program))
(ctx, inst, &result, (GLuint *) Index, Program))
return 1; return 1;
*File = PROGRAM_OUTPUT; *File = PROGRAM_OUTPUT;
break; break;
@@ -2266,7 +2243,7 @@ parse_masked_dst_reg (GLcontext * ctx, GLubyte ** inst,
switch (dst->type) { switch (dst->type) {
case vt_output: case vt_output:
*File = PROGRAM_OUTPUT; *File = PROGRAM_OUTPUT;
*Index = dst->output_binding_idx; *Index = dst->output_binding;
break; break;
case vt_temp: case vt_temp:
@@ -2479,7 +2456,8 @@ parse_extended_swizzle_mask(GLubyte **inst, GLubyte swizzle[4],
static GLuint static GLuint
parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head, parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
struct arb_program *Program, GLint * File, GLint * Index, struct arb_program *Program,
enum register_file * File, GLint * Index,
GLboolean *IsRelOffset ) GLboolean *IsRelOffset )
{ {
struct var_cache *src; struct var_cache *src;
@@ -2508,10 +2486,10 @@ parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
src->attrib_is_generic = is_generic; src->attrib_is_generic = is_generic;
var_cache_append(vc_head, src); var_cache_append(vc_head, src);
if (generic_attrib_check(*vc_head)) { if (generic_attrib_check(*vc_head)) {
_mesa_set_program_error (ctx, Program->Position, const char *msg = "Cannot use both a generic vertex attribute "
"Cannot use both a generic vertex attribute and a specific attribute of the same type"); "and a specific attribute of the same type";
_mesa_error (ctx, GL_INVALID_OPERATION, _mesa_set_program_error (ctx, Program->Position, msg);
"Cannot use both a generic vertex attribute and a specific attribute of the same type"); _mesa_error (ctx, GL_INVALID_OPERATION, msg);
return 1; return 1;
} }
break; break;
@@ -2587,7 +2565,6 @@ parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
break; break;
case REGISTER_ESTABLISHED_NAME: case REGISTER_ESTABLISHED_NAME:
src = parse_string (inst, vc_head, Program, &found); src = parse_string (inst, vc_head, Program, &found);
Program->Position = parse_position (inst); Program->Position = parse_position (inst);
@@ -2647,7 +2624,7 @@ parse_fp_vector_src_reg(GLcontext * ctx, GLubyte ** inst,
struct arb_program *program, struct arb_program *program,
struct fp_src_register *reg) struct fp_src_register *reg)
{ {
GLint file; enum register_file file;
GLint index; GLint index;
GLboolean negate; GLboolean negate;
GLubyte swizzle[4]; GLubyte swizzle[4];
@@ -2678,7 +2655,9 @@ parse_fp_dst_reg(GLcontext * ctx, GLubyte ** inst,
struct var_cache **vc_head, struct arb_program *Program, struct var_cache **vc_head, struct arb_program *Program,
struct fp_dst_register *reg ) struct fp_dst_register *reg )
{ {
GLint file, idx, mask; GLint mask;
GLuint idx;
enum register_file file;
if (parse_masked_dst_reg (ctx, inst, vc_head, Program, &file, &idx, &mask)) if (parse_masked_dst_reg (ctx, inst, vc_head, Program, &file, &idx, &mask))
return 1; return 1;
@@ -2692,16 +2671,18 @@ parse_fp_dst_reg(GLcontext * ctx, GLubyte ** inst,
} }
/**
* Parse fragment program scalar src register.
*/
static GLuint static GLuint
parse_fp_scalar_src_reg (GLcontext * ctx, GLubyte ** inst, parse_fp_scalar_src_reg (GLcontext * ctx, GLubyte ** inst,
struct var_cache **vc_head, struct arb_program *Program, struct var_cache **vc_head,
struct arb_program *Program,
struct fp_src_register *reg ) struct fp_src_register *reg )
{ {
enum register_file File;
GLint File;
GLint Index; GLint Index;
GLboolean Negate; GLubyte Negate;
GLubyte Swizzle[4]; GLubyte Swizzle[4];
GLboolean IsRelOffset; GLboolean IsRelOffset;
@@ -2740,19 +2721,11 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
GLubyte instClass, type, code; GLubyte instClass, type, code;
GLboolean rel; GLboolean rel;
/* No condition codes in ARB_fp */ _mesa_init_fp_instruction(fp);
fp->UpdateCondRegister = 0;
/* Record the position in the program string for debugging */ /* Record the position in the program string for debugging */
fp->StringPos = Program->Position; fp->StringPos = Program->Position;
fp->Data = NULL;
fp->DstReg.File = 0xf; /* mark as undef */
fp->SrcReg[0].File = 0xf; /* mark as undef */
fp->SrcReg[1].File = 0xf; /* mark as undef */
fp->SrcReg[2].File = 0xf; /* mark as undef */
/* OP_ALU_INST or OP_TEX_INST */ /* OP_ALU_INST or OP_TEX_INST */
instClass = *(*inst)++; instClass = *(*inst)++;
@@ -2774,11 +2747,6 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
break; break;
} }
fp->Saturate = 0;
fp->Precision = FLOAT32;
fp->DstReg.CondMask = COND_TR;
switch (type) { switch (type) {
case OP_ALU_VECTOR: case OP_ALU_VECTOR:
switch (code) { switch (code) {
@@ -3019,7 +2987,8 @@ parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
{ {
GLubyte swizzle[4]; GLubyte swizzle[4];
GLubyte negateMask; GLubyte negateMask;
GLint file, index; enum register_file file;
GLint index;
if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index, &rel)) if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index, &rel))
return 1; return 1;
@@ -3107,7 +3076,9 @@ parse_vp_dst_reg(GLcontext * ctx, GLubyte ** inst,
struct var_cache **vc_head, struct arb_program *Program, struct var_cache **vc_head, struct arb_program *Program,
struct vp_dst_register *reg ) struct vp_dst_register *reg )
{ {
GLint file, idx, mask; GLint mask;
GLuint idx;
enum register_file file;
if (parse_masked_dst_reg(ctx, inst, vc_head, Program, &file, &idx, &mask)) if (parse_masked_dst_reg(ctx, inst, vc_head, Program, &file, &idx, &mask))
return 1; return 1;
@@ -3149,6 +3120,7 @@ parse_vp_address_reg (GLcontext * ctx, GLubyte ** inst,
} }
/** /**
* Parse vertex program vector source register.
*/ */
static GLuint static GLuint
parse_vp_vector_src_reg(GLcontext * ctx, GLubyte ** inst, parse_vp_vector_src_reg(GLcontext * ctx, GLubyte ** inst,
@@ -3156,14 +3128,14 @@ parse_vp_vector_src_reg(GLcontext * ctx, GLubyte ** inst,
struct arb_program *program, struct arb_program *program,
struct vp_src_register *reg ) struct vp_src_register *reg )
{ {
GLint file; enum register_file file;
GLint index; GLint index;
GLboolean negate; GLubyte negateMask;
GLubyte swizzle[4]; GLubyte swizzle[4];
GLboolean isRelOffset; GLboolean isRelOffset;
/* Grab the sign */ /* Grab the sign */
negate = (parse_sign (inst) == -1) ? 0xf : 0x0; negateMask = (parse_sign (inst) == -1) ? 0xf : 0x0;
/* And the src reg */ /* And the src reg */
if (parse_src_reg (ctx, inst, vc_head, program, &file, &index, &isRelOffset)) if (parse_src_reg (ctx, inst, vc_head, program, &file, &index, &isRelOffset))
@@ -3176,7 +3148,7 @@ parse_vp_vector_src_reg(GLcontext * ctx, GLubyte ** inst,
reg->Index = index; reg->Index = index;
reg->Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], reg->Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
swizzle[2], swizzle[3]); swizzle[2], swizzle[3]);
reg->Negate = negate; reg->Negate = negateMask;
reg->RelAddr = isRelOffset; reg->RelAddr = isRelOffset;
return 0; return 0;
} }
@@ -3184,13 +3156,13 @@ parse_vp_vector_src_reg(GLcontext * ctx, GLubyte ** inst,
static GLuint static GLuint
parse_vp_scalar_src_reg (GLcontext * ctx, GLubyte ** inst, parse_vp_scalar_src_reg (GLcontext * ctx, GLubyte ** inst,
struct var_cache **vc_head, struct arb_program *Program, struct var_cache **vc_head,
struct arb_program *Program,
struct vp_src_register *reg ) struct vp_src_register *reg )
{ {
enum register_file File;
GLint File;
GLint Index; GLint Index;
GLboolean Negate; GLubyte Negate;
GLubyte Swizzle[4]; GLubyte Swizzle[4];
GLboolean IsRelOffset; GLboolean IsRelOffset;
@@ -3231,15 +3203,9 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst,
/* The actual opcode name */ /* The actual opcode name */
code = *(*inst)++; code = *(*inst)++;
_mesa_init_vp_instruction(vp);
/* Record the position in the program string for debugging */ /* Record the position in the program string for debugging */
vp->StringPos = Program->Position; vp->StringPos = Program->Position;
vp->Data = NULL;
vp->SrcReg[0].RelAddr = vp->SrcReg[1].RelAddr = vp->SrcReg[2].RelAddr = 0;
vp->SrcReg[0].Swizzle = SWIZZLE_NOOP;
vp->SrcReg[1].Swizzle = SWIZZLE_NOOP;
vp->SrcReg[2].Swizzle = SWIZZLE_NOOP;
vp->SrcReg[3].Swizzle = SWIZZLE_NOOP;
vp->DstReg.WriteMask = 0xf;
switch (type) { switch (type) {
/* XXX: */ /* XXX: */
@@ -3403,7 +3369,8 @@ parse_vp_instruction (GLcontext * ctx, GLubyte ** inst,
GLubyte swizzle[4]; GLubyte swizzle[4];
GLubyte negateMask; GLubyte negateMask;
GLboolean relAddr; GLboolean relAddr;
GLint file, index; enum register_file file;
GLint index;
if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
return 1; return 1;
@@ -3678,6 +3645,33 @@ debug_variables (GLcontext * ctx, struct var_cache *vc_head,
#endif #endif
/**
* Grow an array of fragment program instructions.
*/
static struct fp_instruction *
realloc_fp_instructions(struct fp_instruction *oldArray, GLuint oldSize)
{
struct fp_instruction *array = (struct fp_instruction *)
_mesa_realloc(oldArray,
oldSize * sizeof(struct fp_instruction),
(oldSize + 1) * sizeof(struct fp_instruction));
return array;
}
/**
* Grow an array of vertex program instructions.
*/
static struct vp_instruction *
realloc_vp_instructions(struct vp_instruction *oldArray, GLuint oldSize)
{
struct vp_instruction *array = (struct vp_instruction *)
_mesa_realloc(oldArray,
oldSize * sizeof(struct vp_instruction),
(oldSize + 1) * sizeof(struct vp_instruction));
return array;
}
/** /**
* The main loop for parsing a fragment or vertex program * The main loop for parsing a fragment or vertex program
* *
@@ -3740,48 +3734,38 @@ parse_arb_program(GLcontext * ctx, GLubyte * inst, struct var_cache **vc_head,
Program->Position = parse_position (&inst); Program->Position = parse_position (&inst);
if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
/* Check instruction count. END counts as an instruction. */
/* Check the instruction count if (Program->Base.NumInstructions + 1
* XXX: Does END count as an instruction? == MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS) {
*/ const char *msg = "Max instruction count exceeded";
if (Program->Base.NumInstructions+1 == MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS) { _mesa_set_program_error(ctx, Program->Position, msg);
_mesa_set_program_error (ctx, Program->Position, _mesa_error(ctx, GL_INVALID_OPERATION, msg);
"Max instruction count exceeded!");
_mesa_error (ctx, GL_INVALID_OPERATION,
"Max instruction count exceeded!");
} }
/* Realloc Program->FPInstructions */ /* grow instruction list */
Program->FPInstructions = Program->FPInstructions
(struct fp_instruction *) _mesa_realloc (Program->FPInstructions, = realloc_fp_instructions(Program->FPInstructions,
Program->Base.NumInstructions*sizeof(struct fp_instruction), Program->Base.NumInstructions);
(Program->Base.NumInstructions+1)*sizeof (struct fp_instruction)); /* parse the current instruction */
/* parse the current instruction */
err = parse_fp_instruction (ctx, &inst, vc_head, Program, err = parse_fp_instruction (ctx, &inst, vc_head, Program,
&Program->FPInstructions[Program->Base.NumInstructions]); &Program->FPInstructions[Program->Base.NumInstructions]);
} }
else { else {
/* Check the instruction count /* Check instruction count. END counts as an instruction. */
* XXX: Does END count as an instruction? if (Program->Base.NumInstructions + 1
*/ == MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS) {
if (Program->Base.NumInstructions+1 == MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS) { const char *msg = "Max instruction count exceeded";
_mesa_set_program_error (ctx, Program->Position, _mesa_set_program_error(ctx, Program->Position, msg);
"Max instruction count exceeded!"); _mesa_error(ctx, GL_INVALID_OPERATION, msg);
_mesa_error (ctx, GL_INVALID_OPERATION,
"Max instruction count exceeded!");
} }
/* Realloc Program->VPInstructions */ /* grow instruction list */
Program->VPInstructions = Program->VPInstructions
(struct vp_instruction *) _mesa_realloc (Program->VPInstructions, = realloc_vp_instructions(Program->VPInstructions,
Program->Base.NumInstructions*sizeof(struct vp_instruction), Program->Base.NumInstructions);
(Program->Base.NumInstructions +1)*sizeof(struct vp_instruction)); /* parse the current instruction */
/* parse the current instruction */
err = parse_vp_instruction (ctx, &inst, vc_head, Program, err = parse_vp_instruction (ctx, &inst, vc_head, Program,
&Program->VPInstructions[Program->Base.NumInstructions]); &Program->VPInstructions[Program->Base.NumInstructions]);
} }
/* increment Program->Base.NumInstructions */ /* increment Program->Base.NumInstructions */
@@ -3802,48 +3786,39 @@ parse_arb_program(GLcontext * ctx, GLubyte * inst, struct var_cache **vc_head,
/* Finally, tag on an OPCODE_END instruction */ /* Finally, tag on an OPCODE_END instruction */
if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
Program->FPInstructions = const GLuint numInst = Program->Base.NumInstructions;
(struct fp_instruction *) _mesa_realloc (Program->FPInstructions, Program->FPInstructions
Program->Base.NumInstructions*sizeof(struct fp_instruction), = realloc_fp_instructions(Program->FPInstructions, numInst);
(Program->Base.NumInstructions+1)*sizeof(struct fp_instruction)); _mesa_init_fp_instruction(Program->FPInstructions + numInst);
Program->FPInstructions[numInst].Opcode = FP_OPCODE_END;
Program->FPInstructions[Program->Base.NumInstructions].Opcode = FP_OPCODE_END;
Program->FPInstructions[Program->Base.NumInstructions].Saturate = 0;
Program->FPInstructions[Program->Base.NumInstructions].DstReg.File = 0xf;
Program->FPInstructions[Program->Base.NumInstructions].SrcReg[0].File = 0xf;
Program->FPInstructions[Program->Base.NumInstructions].SrcReg[1].File = 0xf;
Program->FPInstructions[Program->Base.NumInstructions].SrcReg[2].File = 0xf;
/* YYY Wrong Position in program, whatever, at least not random -> crash /* YYY Wrong Position in program, whatever, at least not random -> crash
Program->Position = parse_position (&inst); Program->Position = parse_position (&inst);
*/ */
Program->FPInstructions[Program->Base.NumInstructions].StringPos = Program->Position; Program->FPInstructions[numInst].StringPos = Program->Position;
Program->FPInstructions[Program->Base.NumInstructions].Data = NULL;
} }
else { else {
Program->VPInstructions = const GLuint numInst = Program->Base.NumInstructions;
(struct vp_instruction *) _mesa_realloc (Program->VPInstructions, Program->VPInstructions
Program->Base.NumInstructions*sizeof(struct vp_instruction), = realloc_vp_instructions(Program->VPInstructions, numInst);
(Program->Base.NumInstructions+1)*sizeof(struct vp_instruction)); _mesa_init_vp_instruction(Program->VPInstructions + numInst);
Program->VPInstructions[numInst].Opcode = VP_OPCODE_END;
Program->VPInstructions[Program->Base.NumInstructions].Opcode = VP_OPCODE_END;
/* YYY Wrong Position in program, whatever, at least not random -> crash /* YYY Wrong Position in program, whatever, at least not random -> crash
Program->Position = parse_position (&inst); Program->Position = parse_position (&inst);
*/ */
Program->VPInstructions[Program->Base.NumInstructions].StringPos = Program->Position; Program->VPInstructions[numInst].StringPos = Program->Position;
Program->VPInstructions[Program->Base.NumInstructions].Data = NULL;
} }
/* increment Program->Base.NumInstructions */
Program->Base.NumInstructions++; Program->Base.NumInstructions++;
return err; return err;
} }
/* XXX temporary */ /* XXX temporary */
__extension__ static char core_grammar_text[] = __extension__ static char core_grammar_text[] =
#include "grammar_syn.h" #include "grammar_syn.h"
; ;
static int set_reg8 (GLcontext *ctx, grammar id, const byte *name, byte value) static int set_reg8 (GLcontext *ctx, grammar id, const byte *name, byte value)
{ {
char error_msg[300]; char error_msg[300];

View File

@@ -1259,12 +1259,7 @@ Parse_InstructionSequence(struct parse_state *parseState,
GLubyte token[100]; GLubyte token[100];
/* Initialize the instruction */ /* Initialize the instruction */
inst->SrcReg[0].File = PROGRAM_UNDEFINED; _mesa_init_fp_instruction(inst);
inst->SrcReg[1].File = PROGRAM_UNDEFINED;
inst->SrcReg[2].File = PROGRAM_UNDEFINED;
inst->DstReg.File = PROGRAM_UNDEFINED;
inst->DstReg.CondSwizzle = SWIZZLE_NOOP;
inst->Data = NULL;
/* special instructions */ /* special instructions */
if (Parse_String(parseState, "DEFINE")) { if (Parse_String(parseState, "DEFINE")) {
@@ -1823,3 +1818,24 @@ _mesa_nv_fragment_output_register_name(GLuint i)
ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_OUTPUTS); ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_OUTPUTS);
return OutputRegisters[i]; return OutputRegisters[i];
} }
/**
* Initialize fragment program instruction fields to defaults.
*/
void
_mesa_init_fp_instruction(struct fp_instruction *inst)
{
_mesa_bzero(inst, sizeof(struct fp_instruction));
inst->SrcReg[0].File = PROGRAM_UNDEFINED;
inst->SrcReg[0].Swizzle = SWIZZLE_NOOP;
inst->SrcReg[1].File = PROGRAM_UNDEFINED;
inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
inst->SrcReg[2].File = PROGRAM_UNDEFINED;
inst->SrcReg[2].Swizzle = SWIZZLE_NOOP;
inst->DstReg.File = PROGRAM_UNDEFINED;
inst->DstReg.WriteMask = 0xf;
inst->DstReg.CondSwizzle = SWIZZLE_NOOP;
inst->Precision = FLOAT32;
inst->DstReg.CondMask = COND_TR;
}

View File

@@ -1,8 +1,8 @@
/* /*
* Mesa 3-D graphics library * Mesa 3-D graphics library
* Version: 6.3 * Version: 6.5
* *
* Copyright (C) 1999-2004 Brian Paul All Rights Reserved. * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@@ -36,10 +36,15 @@
#include "config.h" #include "config.h"
#include "mtypes.h" #include "mtypes.h"
/* output registers */
#define FRAG_OUTPUT_COLR 0 /**
#define FRAG_OUTPUT_COLH 1 * Fragment program output registers.
#define FRAG_OUTPUT_DEPR 2 * Note: when we fully suppport GL_ARB_draw_buffers we'll have more than
* one output color.
*/
#define FRAG_OUTPUT_COLR 0 /* fragment color */
#define FRAG_OUTPUT_COLH 1 /* fragment color, half precision (NV) */
#define FRAG_OUTPUT_DEPR 2 /* depth/Z */
/* condition codes */ /* condition codes */
@@ -165,4 +170,8 @@ struct fp_instruction
}; };
extern void
_mesa_init_fp_instruction(struct fp_instruction *inst);
#endif #endif

View File

@@ -1142,11 +1142,7 @@ Parse_InstructionSequence(struct parse_state *parseState,
struct vp_instruction *inst = program + parseState->numInst; struct vp_instruction *inst = program + parseState->numInst;
/* Initialize the instruction */ /* Initialize the instruction */
inst->SrcReg[0].File = PROGRAM_UNDEFINED; _mesa_init_vp_instruction(inst);
inst->SrcReg[1].File = PROGRAM_UNDEFINED;
inst->SrcReg[2].File = PROGRAM_UNDEFINED;
inst->DstReg.File = PROGRAM_UNDEFINED;
inst->Data = NULL;
if (Parse_String(parseState, "MOV")) { if (Parse_String(parseState, "MOV")) {
if (!Parse_UnaryOpInstruction(parseState, inst, VP_OPCODE_MOV)) if (!Parse_UnaryOpInstruction(parseState, inst, VP_OPCODE_MOV))
@@ -1601,3 +1597,22 @@ _mesa_nv_vertex_output_register_name(GLuint i)
ASSERT(i < MAX_NV_VERTEX_PROGRAM_OUTPUTS); ASSERT(i < MAX_NV_VERTEX_PROGRAM_OUTPUTS);
return OutputRegisters[i]; return OutputRegisters[i];
} }
/**
* Initialize vertex program instruction fields to defaults.
*/
void
_mesa_init_vp_instruction(struct vp_instruction *inst)
{
_mesa_bzero(inst, sizeof(struct vp_instruction));
inst->SrcReg[0].File = PROGRAM_UNDEFINED;
inst->SrcReg[0].Swizzle = SWIZZLE_NOOP;
inst->SrcReg[1].File = PROGRAM_UNDEFINED;
inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
inst->SrcReg[2].File = PROGRAM_UNDEFINED;
inst->SrcReg[2].Swizzle = SWIZZLE_NOOP;
inst->DstReg.File = PROGRAM_UNDEFINED;
inst->DstReg.WriteMask = 0xf;
}

View File

@@ -108,4 +108,8 @@ struct vp_instruction
}; };
extern void
_mesa_init_vp_instruction(struct vp_instruction *inst);
#endif /* VERTPROG_H */ #endif /* VERTPROG_H */