static void init_src_reg(struct asm_src_register *r);
+static void asm_instruction_set_operands(struct asm_instruction *inst,
+ const struct prog_dst_register *dst, const struct asm_src_register *src0,
+ const struct asm_src_register *src1, const struct asm_src_register *src2);
+
static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
const struct prog_dst_register *dst, const struct asm_src_register *src0,
const struct asm_src_register *src1, const struct asm_src_register *src2);
+static struct asm_instruction *asm_instruction_copy_ctor(
+ const struct prog_instruction *base, const struct prog_dst_register *dst,
+ const struct asm_src_register *src0, const struct asm_src_register *src1,
+ const struct asm_src_register *src2);
+
#ifndef FALSE
#define FALSE 0
#define TRUE (!FALSE)
unsigned attrib;
int integer;
float real;
- unsigned state[5];
+ gl_state_index state[STATE_LENGTH];
int negate;
struct asm_vector vector;
gl_inst_opcode opcode;
+
+ struct {
+ unsigned swz;
+ unsigned rgba_valid:1;
+ unsigned xyzw_valid:1;
+ unsigned negate:1;
+ } ext_swizzle;
}
%token ARBvp_10 ARBfp_10
/* Tokens for instructions */
%token <temp_inst> BIN_OP BINSC_OP SAMPLE_OP SCALAR_OP TRI_OP VECTOR_OP
-%token <temp_inst> ARL KIL SWZ
+%token <temp_inst> ARL KIL SWZ TXD_OP
%token <integer> INTEGER
%token <real> REAL
%token MATERIAL MAT_PROGRAM MATRIX MATRIXINDEX MODELVIEW MVP
%token NORMAL
%token OBJECT
-%token PALETTE PARAMS PLANE POINT POINTSIZE POSITION PRIMARY PROGRAM PROJECTION
+%token PALETTE PARAMS PLANE POINT_TOK POINTSIZE POSITION PRIMARY PROGRAM PROJECTION
%token RANGE RESULT ROW
-%token SCENECOLOR SECONDARY SHININESS SIZE SPECULAR SPOT STATE
+%token SCENECOLOR SECONDARY SHININESS SIZE_TOK SPECULAR SPOT STATE
%token TEXCOORD TEXENV TEXGEN TEXGEN_Q TEXGEN_R TEXGEN_S TEXGEN_T TEXTURE TRANSPOSE
%token TEXTURE_UNIT TEX_1D TEX_2D TEX_3D TEX_CUBE TEX_RECT
%token TEX_SHADOW1D TEX_SHADOW2D TEX_SHADOWRECT
%token VERTEX VTXATTRIB
%token WEIGHT
-%token <string> IDENTIFIER
+%token <string> IDENTIFIER USED_IDENTIFIER
+%type <string> string
%token <swiz_mask> MASK4 MASK3 MASK2 MASK1 SWIZZLE
%token DOT_DOT
%token DOT
%type <inst> instruction ALU_instruction TexInstruction
%type <inst> ARL_instruction VECTORop_instruction
%type <inst> SCALARop_instruction BINSCop_instruction BINop_instruction
-%type <inst> TRIop_instruction SWZ_instruction SAMPLE_instruction
+%type <inst> TRIop_instruction TXD_instruction SWZ_instruction SAMPLE_instruction
%type <inst> KIL_instruction
%type <dst_reg> dstReg maskedDstReg maskedAddrReg
-%type <src_reg> srcReg scalarSrcReg swizzleSrcReg
-%type <swiz_mask> scalarSuffix swizzleSuffix extendedSwizzle extSwizComp
+%type <src_reg> srcReg scalarUse scalarSrcReg swizzleSrcReg
+%type <swiz_mask> scalarSuffix swizzleSuffix extendedSwizzle
+%type <ext_swizzle> extSwizComp extSwizSel
%type <swiz_mask> optionalMask
-%type <integer> extSwizSel
%type <sym> progParamArray
%type <integer> addrRegRelOffset addrRegPosOffset addrRegNegOffset
%type <sym> addrReg
%type <swiz_mask> addrComponent addrWriteMask
+%type <dst_reg> ccMaskRule ccTest ccMaskRule2 ccTest2 optionalCcMask
+
%type <result> resultBinding resultColBinding
%type <integer> optFaceType optColorType
%type <integer> optResultFaceType optResultColorType
|
;
-option: OPTION IDENTIFIER ';'
+option: OPTION string ';'
{
int valid = 0;
TexInstruction: SAMPLE_instruction
| KIL_instruction
+ | TXD_instruction
;
ARL_instruction: ARL maskedAddrReg ',' scalarSrcReg
VECTORop_instruction: VECTOR_OP maskedDstReg ',' swizzleSrcReg
{
- $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, NULL, NULL);
- $$->Base.SaturateMode = $1.SaturateMode;
+ $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
}
;
SCALARop_instruction: SCALAR_OP maskedDstReg ',' scalarSrcReg
{
- $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, NULL, NULL);
- $$->Base.SaturateMode = $1.SaturateMode;
+ $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
}
;
BINSCop_instruction: BINSC_OP maskedDstReg ',' scalarSrcReg ',' scalarSrcReg
{
- $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, & $6, NULL);
- $$->Base.SaturateMode = $1.SaturateMode;
+ $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL);
}
;
BINop_instruction: BIN_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg
{
- $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, & $6, NULL);
- $$->Base.SaturateMode = $1.SaturateMode;
+ $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL);
}
;
TRIop_instruction: TRI_OP maskedDstReg ','
swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg
{
- $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, & $6, & $8);
- $$->Base.SaturateMode = $1.SaturateMode;
+ $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8);
}
;
SAMPLE_instruction: SAMPLE_OP maskedDstReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
{
- $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, NULL, NULL);
+ $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
if ($$ != NULL) {
const GLbitfield tex_mask = (1U << $6);
GLbitfield shadow_tex = 0;
GLbitfield target_mask = 0;
- $$->Base.SaturateMode = $1.SaturateMode;
$$->Base.TexSrcUnit = $6;
if ($8 < 0) {
$$ = asm_instruction_ctor(OPCODE_KIL, NULL, & $2, NULL, NULL);
state->fragment.UsesKill = 1;
}
+ | KIL ccTest
+ {
+ $$ = asm_instruction_ctor(OPCODE_KIL_NV, NULL, NULL, NULL, NULL);
+ $$->Base.DstReg.CondMask = $2.CondMask;
+ $$->Base.DstReg.CondSwizzle = $2.CondSwizzle;
+ $$->Base.DstReg.CondSrc = $2.CondSrc;
+ state->fragment.UsesKill = 1;
+ }
+ ;
+
+TXD_instruction: TXD_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
+ {
+ $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8);
+ if ($$ != NULL) {
+ const GLbitfield tex_mask = (1U << $10);
+ GLbitfield shadow_tex = 0;
+ GLbitfield target_mask = 0;
+
+
+ $$->Base.TexSrcUnit = $10;
+
+ if ($12 < 0) {
+ shadow_tex = tex_mask;
+
+ $$->Base.TexSrcTarget = -$12;
+ $$->Base.TexShadow = 1;
+ } else {
+ $$->Base.TexSrcTarget = $12;
+ }
+
+ target_mask = (1U << $$->Base.TexSrcTarget);
+
+ /* If this texture unit was previously accessed and that access
+ * had a different texture target, generate an error.
+ *
+ * If this texture unit was previously accessed and that access
+ * had a different shadow mode, generate an error.
+ */
+ if ((state->prog->TexturesUsed[$10] != 0)
+ && ((state->prog->TexturesUsed[$10] != target_mask)
+ || ((state->prog->ShadowSamplers & tex_mask)
+ != shadow_tex))) {
+ yyerror(& @12, state,
+ "multiple targets used on one texture image unit");
+ YYERROR;
+ }
+
+
+ state->prog->TexturesUsed[$10] |= target_mask;
+ state->prog->ShadowSamplers |= shadow_tex;
+ }
+ }
;
texImageUnit: TEXTURE_UNIT optTexImageUnitNum
$4.Base.Swizzle = $6.swizzle;
$4.Base.Negate = $6.mask;
- $$ = asm_instruction_ctor(OPCODE_SWZ, & $2, & $4, NULL, NULL);
- $$->Base.SaturateMode = $1.SaturateMode;
+ $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
}
;
-scalarSrcReg: optionalSign srcReg scalarSuffix
+scalarSrcReg: optionalSign scalarUse
{
$$ = $2;
if ($1) {
$$.Base.Negate = ~$$.Base.Negate;
}
+ }
+ | optionalSign '|' scalarUse '|'
+ {
+ $$ = $3;
+
+ if (!state->option.NV_fragment) {
+ yyerror(& @2, state, "unexpected character '|'");
+ YYERROR;
+ }
+
+ if ($1) {
+ $$.Base.Negate = ~$$.Base.Negate;
+ }
+
+ $$.Base.Abs = 1;
+ }
+ ;
+
+scalarUse: srcReg scalarSuffix
+ {
+ $$ = $1;
$$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
- $3.swizzle);
+ $2.swizzle);
+ }
+ | paramConstScalarUse
+ {
+ struct asm_symbol temp_sym;
+
+ if (!state->option.NV_fragment) {
+ yyerror(& @1, state, "expected scalar suffix");
+ YYERROR;
+ }
+
+ memset(& temp_sym, 0, sizeof(temp_sym));
+ temp_sym.param_binding_begin = ~0;
+ initialize_symbol_from_const(state->prog, & temp_sym, & $1);
+
+ init_src_reg(& $$);
+ $$.Base.File = PROGRAM_CONSTANT;
+ $$.Base.Index = temp_sym.param_binding_begin;
}
;
$$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
$3.swizzle);
}
+ | optionalSign '|' srcReg swizzleSuffix '|'
+ {
+ $$ = $3;
+
+ if (!state->option.NV_fragment) {
+ yyerror(& @2, state, "unexpected character '|'");
+ YYERROR;
+ }
+
+ if ($1) {
+ $$.Base.Negate = ~$$.Base.Negate;
+ }
+
+ $$.Base.Abs = 1;
+ $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
+ $4.swizzle);
+ }
+
;
-maskedDstReg: dstReg optionalMask
+maskedDstReg: dstReg optionalMask optionalCcMask
{
$$ = $1;
$$.WriteMask = $2.mask;
+ $$.CondMask = $3.CondMask;
+ $$.CondSwizzle = $3.CondSwizzle;
+ $$.CondSrc = $3.CondSrc;
if ($$.File == PROGRAM_OUTPUT) {
/* Technically speaking, this should check that it is in
extendedSwizzle: extSwizComp ',' extSwizComp ',' extSwizComp ',' extSwizComp
{
- $$.swizzle = MAKE_SWIZZLE4($1.swizzle, $3.swizzle,
- $5.swizzle, $7.swizzle);
- $$.mask = ($1.mask) | ($3.mask << 1) | ($5.mask << 2)
- | ($7.mask << 3);
+ const unsigned xyzw_valid =
+ ($1.xyzw_valid << 0)
+ | ($3.xyzw_valid << 1)
+ | ($5.xyzw_valid << 2)
+ | ($7.xyzw_valid << 3);
+ const unsigned rgba_valid =
+ ($1.rgba_valid << 0)
+ | ($3.rgba_valid << 1)
+ | ($5.rgba_valid << 2)
+ | ($7.rgba_valid << 3);
+
+ /* All of the swizzle components have to be valid in either RGBA
+ * or XYZW. Note that 0 and 1 are valid in both, so both masks
+ * can have some bits set.
+ *
+ * We somewhat deviate from the spec here. It would be really hard
+ * to figure out which component is the error, and there probably
+ * isn't a lot of benefit.
+ */
+ if ((rgba_valid != 0x0f) && (xyzw_valid != 0x0f)) {
+ yyerror(& @1, state, "cannot combine RGBA and XYZW swizzle "
+ "components");
+ YYERROR;
+ }
+
+ $$.swizzle = MAKE_SWIZZLE4($1.swz, $3.swz, $5.swz, $7.swz);
+ $$.mask = ($1.negate) | ($3.negate << 1) | ($5.negate << 2)
+ | ($7.negate << 3);
}
;
extSwizComp: optionalSign extSwizSel
{
- $$.swizzle = $2;
- $$.mask = ($1) ? 1 : 0;
+ $$ = $2;
+ $$.negate = ($1) ? 1 : 0;
}
;
YYERROR;
}
- $$ = ($1 == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE;
+ $$.swz = ($1 == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE;
+
+ /* 0 and 1 are valid for both RGBA swizzle names and XYZW
+ * swizzle names.
+ */
+ $$.xyzw_valid = 1;
+ $$.rgba_valid = 1;
}
- | IDENTIFIER
+ | string
{
if (strlen($1) > 1) {
yyerror(& @1, state, "invalid extended swizzle selector");
switch ($1[0]) {
case 'x':
- $$ = SWIZZLE_X;
+ $$.swz = SWIZZLE_X;
+ $$.xyzw_valid = 1;
break;
case 'y':
- $$ = SWIZZLE_Y;
+ $$.swz = SWIZZLE_Y;
+ $$.xyzw_valid = 1;
break;
case 'z':
- $$ = SWIZZLE_Z;
+ $$.swz = SWIZZLE_Z;
+ $$.xyzw_valid = 1;
break;
case 'w':
- $$ = SWIZZLE_W;
+ $$.swz = SWIZZLE_W;
+ $$.xyzw_valid = 1;
break;
+
+ case 'r':
+ $$.swz = SWIZZLE_X;
+ $$.rgba_valid = 1;
+ break;
+ case 'g':
+ $$.swz = SWIZZLE_Y;
+ $$.rgba_valid = 1;
+ break;
+ case 'b':
+ $$.swz = SWIZZLE_Z;
+ $$.rgba_valid = 1;
+ break;
+ case 'a':
+ $$.swz = SWIZZLE_W;
+ $$.rgba_valid = 1;
+ break;
+
default:
yyerror(& @1, state, "invalid extended swizzle selector");
YYERROR;
}
;
-srcReg: IDENTIFIER /* temporaryReg | progParamSingle */
+srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */
{
struct asm_symbol *const s = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $1);
$$.File = PROGRAM_OUTPUT;
$$.Index = $1;
}
- | IDENTIFIER /* temporaryReg | vertexResultReg */
+ | USED_IDENTIFIER /* temporaryReg | vertexResultReg */
{
struct asm_symbol *const s = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $1);
}
;
-progParamArray: IDENTIFIER
+progParamArray: USED_IDENTIFIER
{
struct asm_symbol *const s = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $1);
addrRegPosOffset: INTEGER
{
if (($1 < 0) || ($1 > 63)) {
- yyerror(& @1, state,
- "relative address offset too large (positive)");
+ char s[100];
+ _mesa_snprintf(s, sizeof(s),
+ "relative address offset too large (%d)", $1);
+ yyerror(& @1, state, s);
YYERROR;
} else {
$$ = $1;
addrRegNegOffset: INTEGER
{
if (($1 < 0) || ($1 > 64)) {
- yyerror(& @1, state,
- "relative address offset too large (negative)");
+ char s[100];
+ _mesa_snprintf(s, sizeof(s),
+ "relative address offset too large (%d)", $1);
+ yyerror(& @1, state, s);
YYERROR;
} else {
$$ = $1;
}
;
-addrReg: IDENTIFIER
+addrReg: USED_IDENTIFIER
{
struct asm_symbol *const s = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $1);
| { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
;
+optionalCcMask: '(' ccTest ')'
+ {
+ $$ = $2;
+ }
+ | '(' ccTest2 ')'
+ {
+ $$ = $2;
+ }
+ |
+ {
+ $$.CondMask = COND_TR;
+ $$.CondSwizzle = SWIZZLE_NOOP;
+ $$.CondSrc = 0;
+ }
+ ;
+
+ccTest: ccMaskRule swizzleSuffix
+ {
+ $$ = $1;
+ $$.CondSwizzle = $2.swizzle;
+ }
+ ;
+
+ccTest2: ccMaskRule2 swizzleSuffix
+ {
+ $$ = $1;
+ $$.CondSwizzle = $2.swizzle;
+ }
+ ;
+
+ccMaskRule: IDENTIFIER
+ {
+ const int cond = _mesa_parse_cc($1);
+ if ((cond == 0) || ($1[2] != '\0')) {
+ char *const err_str =
+ make_error_string("invalid condition code \"%s\"", $1);
+
+ yyerror(& @1, state, (err_str != NULL)
+ ? err_str : "invalid condition code");
+
+ if (err_str != NULL) {
+ _mesa_free(err_str);
+ }
+
+ YYERROR;
+ }
+
+ $$.CondMask = cond;
+ $$.CondSwizzle = SWIZZLE_NOOP;
+ $$.CondSrc = 0;
+ }
+ ;
+
+ccMaskRule2: USED_IDENTIFIER
+ {
+ const int cond = _mesa_parse_cc($1);
+ if ((cond == 0) || ($1[2] != '\0')) {
+ char *const err_str =
+ make_error_string("invalid condition code \"%s\"", $1);
+
+ yyerror(& @1, state, (err_str != NULL)
+ ? err_str : "invalid condition code");
+
+ if (err_str != NULL) {
+ _mesa_free(err_str);
+ }
+
+ YYERROR;
+ }
+
+ $$.CondMask = cond;
+ $$.CondSwizzle = SWIZZLE_NOOP;
+ $$.CondSrc = 0;
+ }
+ ;
+
namingStatement: ATTRIB_statement
| PARAM_statement
| TEMP_statement
}
| INTEGER
{
- if (($1 < 1) || ((unsigned) $1 >= state->limits->MaxParameters)) {
+ if (($1 < 1) || ((unsigned) $1 > state->limits->MaxParameters)) {
yyerror(& @1, state, "invalid parameter array size");
YYERROR;
} else {
}
;
-statePointItem: POINT statePointProperty
+statePointItem: POINT_TOK statePointProperty
{
memset($$, 0, sizeof($$));
$$[0] = $2;
}
;
-statePointProperty: SIZE
+statePointProperty: SIZE_TOK
{
$$ = STATE_POINT_SIZE;
}
{
$$ = 0;
}
- | stateModMatNum
+ | '[' stateModMatNum ']'
{
- $$ = $1;
+ $$ = $2;
}
;
stateModMatNum: INTEGER
paramConstScalarUse: REAL
{
- $$.count = 4;
+ $$.count = 1;
$$.data[0] = $1;
- $$.data[1] = 0.0f;
- $$.data[2] = 0.0f;
- $$.data[3] = 1.0f;
+ $$.data[1] = $1;
+ $$.data[2] = $1;
+ $$.data[3] = $1;
}
| INTEGER
{
- $$.count = 4;
+ $$.count = 1;
$$.data[0] = (float) $1;
- $$.data[1] = 0.0f;
- $$.data[2] = 0.0f;
- $$.data[3] = 1.0f;
+ $$.data[1] = (float) $1;
+ $$.data[2] = (float) $1;
+ $$.data[3] = (float) $1;
}
;
| { $$ = FALSE; }
;
-TEMP_statement: TEMP { $<integer>$ = $1; } varNameList
+TEMP_statement: optVarSize TEMP { $<integer>$ = $2; } varNameList
+ ;
+
+optVarSize: string
+ {
+ /* NV_fragment_program_option defines the size qualifiers in a
+ * fairly broken way. "SHORT" or "LONG" can optionally be used
+ * before TEMP or OUTPUT. However, neither is a reserved word!
+ * This means that we have to parse it as an identifier, then check
+ * to make sure it's one of the valid values. *sigh*
+ *
+ * In addition, the grammar in the extension spec does *not* allow
+ * the size specifier to be optional, but all known implementations
+ * do.
+ */
+ if (!state->option.NV_fragment) {
+ yyerror(& @1, state, "unexpected IDENTIFIER");
+ YYERROR;
+ }
+
+ if (strcmp("SHORT", $1) == 0) {
+ } else if (strcmp("LONG", $1) == 0) {
+ } else {
+ char *const err_str =
+ make_error_string("invalid storage size specifier \"%s\"",
+ $1);
+
+ yyerror(& @1, state, (err_str != NULL)
+ ? err_str : "invalid storage size specifier");
+
+ if (err_str != NULL) {
+ _mesa_free(err_str);
+ }
+
+ YYERROR;
+ }
+ }
+ |
+ {
+ }
;
ADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList
}
;
-OUTPUT_statement: OUTPUT IDENTIFIER '=' resultBinding
+OUTPUT_statement: optVarSize OUTPUT IDENTIFIER '=' resultBinding
{
struct asm_symbol *const s =
- declare_variable(state, $2, at_output, & @2);
+ declare_variable(state, $3, at_output, & @3);
if (s == NULL) {
YYERROR;
} else {
- s->output_binding = $4;
+ s->output_binding = $5;
}
}
;
}
;
-ALIAS_statement: ALIAS IDENTIFIER '=' IDENTIFIER
+ALIAS_statement: ALIAS IDENTIFIER '=' USED_IDENTIFIER
{
struct asm_symbol *exist = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $2);
"undefined variable binding in ALIAS statement");
YYERROR;
} else {
- _mesa_symbol_table_add_symbol(state->st, 0, $2, target);
+ _mesa_symbol_table_add_symbol(state->st, 0, strdup($2), target);
}
}
;
+string: IDENTIFIER
+ | USED_IDENTIFIER
+ ;
+
%%
+void
+asm_instruction_set_operands(struct asm_instruction *inst,
+ const struct prog_dst_register *dst,
+ const struct asm_src_register *src0,
+ const struct asm_src_register *src1,
+ const struct asm_src_register *src2)
+{
+ /* In the core ARB extensions only the KIL instruction doesn't have a
+ * destination register.
+ */
+ if (dst == NULL) {
+ init_dst_reg(& inst->Base.DstReg);
+ } else {
+ inst->Base.DstReg = *dst;
+ }
+
+ /* The only instruction that doesn't have any source registers is the
+ * condition-code based KIL instruction added by NV_fragment_program_option.
+ */
+ if (src0 != NULL) {
+ inst->Base.SrcReg[0] = src0->Base;
+ inst->SrcReg[0] = *src0;
+ } else {
+ init_src_reg(& inst->SrcReg[0]);
+ }
+
+ if (src1 != NULL) {
+ inst->Base.SrcReg[1] = src1->Base;
+ inst->SrcReg[1] = *src1;
+ } else {
+ init_src_reg(& inst->SrcReg[1]);
+ }
+
+ if (src2 != NULL) {
+ inst->Base.SrcReg[2] = src2->Base;
+ inst->SrcReg[2] = *src2;
+ } else {
+ init_src_reg(& inst->SrcReg[2]);
+ }
+}
+
+
struct asm_instruction *
asm_instruction_ctor(gl_inst_opcode op,
const struct prog_dst_register *dst,
const struct asm_src_register *src1,
const struct asm_src_register *src2)
{
- struct asm_instruction *inst = calloc(1, sizeof(struct asm_instruction));
+ struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
if (inst) {
_mesa_init_instructions(& inst->Base, 1);
inst->Base.Opcode = op;
- inst->Base.DstReg = *dst;
- inst->Base.SrcReg[0] = src0->Base;
- inst->SrcReg[0] = *src0;
+ asm_instruction_set_operands(inst, dst, src0, src1, src2);
+ }
- if (src1 != NULL) {
- inst->Base.SrcReg[1] = src1->Base;
- inst->SrcReg[1] = *src1;
- } else {
- init_src_reg(& inst->SrcReg[1]);
- }
+ return inst;
+}
- if (src2 != NULL) {
- inst->Base.SrcReg[2] = src2->Base;
- inst->SrcReg[2] = *src2;
- } else {
- init_src_reg(& inst->SrcReg[2]);
- }
+
+struct asm_instruction *
+asm_instruction_copy_ctor(const struct prog_instruction *base,
+ const struct prog_dst_register *dst,
+ const struct asm_src_register *src0,
+ const struct asm_src_register *src1,
+ const struct asm_src_register *src2)
+{
+ struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
+
+ if (inst) {
+ _mesa_init_instructions(& inst->Base, 1);
+ inst->Base.Opcode = base->Opcode;
+ inst->Base.CondUpdate = base->CondUpdate;
+ inst->Base.CondDst = base->CondDst;
+ inst->Base.SaturateMode = base->SaturateMode;
+ inst->Base.Precision = base->Precision;
+
+ asm_instruction_set_operands(inst, dst, src0, src1, src2);
}
return inst;
if (exist != NULL) {
yyerror(locp, state, "redeclared identifier");
} else {
- s = calloc(1, sizeof(struct asm_symbol));
- s->name = name;
+ const size_t name_len = strlen(name);
+
+ s = calloc(1, sizeof(struct asm_symbol) + name_len + 1);
+ s->name = (char *)(s + 1);
s->type = t;
+ memcpy((char *) s->name, name, name_len + 1);
+
switch (t) {
case at_temp:
if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
name = _mesa_program_state_string(tokens);
index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name,
- size, GL_NONE,
- NULL, (gl_state_index *) tokens, 0x0);
+ size, GL_NONE, NULL, tokens, 0x0);
param_list->StateFlags |= _mesa_program_state_flags(tokens);
/* free name string here since we duplicated it in add_parameter() */
_mesa_memcpy (strz, str, len);
strz[len] = '\0';
+ if (state->prog->String != NULL) {
+ _mesa_free(state->prog->String);
+ state->prog->String = NULL;
+ }
+
state->prog->String = strz;
state->st = _mesa_symbol_table_ctor();
? & ctx->Const.VertexProgram
: & ctx->Const.FragmentProgram;
- state->MaxTextureImageUnits = 16;
- state->MaxTextureCoordUnits = 8;
- state->MaxTextureUnits = 8;
- state->MaxClipPlanes = 6;
- state->MaxLights = 8;
- state->MaxProgramMatrices = 8;
+ state->MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
+ state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits;
+ state->MaxTextureUnits = ctx->Const.MaxTextureUnits;
+ state->MaxClipPlanes = ctx->Const.MaxClipPlanes;
+ state->MaxLights = ctx->Const.MaxLights;
+ state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices;
state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB)
? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM;
for (sym = state->sym; sym != NULL; sym = temp) {
temp = sym->next;
- _mesa_free((void *) sym->name);
_mesa_free(sym);
}
state->sym = NULL;
_mesa_symbol_table_dtor(state->st);
state->st = NULL;
+ if (state->string_dumpster != NULL) {
+ _mesa_free(state->string_dumpster);
+ state->dumpster_size = 0;
+ }
+
return result;
}