NV fp parser: Add support for condition codes

Conditional write masks and the condition-code based KIL instruction
are all supported.  The specific behavior of KIL in the following
shader may or may not match the behavior of other implementations:

!!ARBfp1.0
	TEMP	GT;
	MOVC	GT, fragment.texcoord[0];
	KIL	GT.x;
	END

Should be it interpreted as 'KIL srcReg' or as 'KIL ccTest'?  The
current parser will interpret it as 'KIL srcReg'.
This commit is contained in:
Ian Romanick
2009-09-10 15:04:24 -07:00
parent cdb7193994
commit 81722c5d7e
4 changed files with 1427 additions and 1125 deletions

View File

@@ -202,6 +202,8 @@ static struct asm_instruction *asm_instruction_copy_ctor(
%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
@@ -447,6 +449,14 @@ KIL_instruction: KIL swizzleSrcReg
$$ = 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
@@ -607,10 +617,13 @@ swizzleSrcReg: optionalSign srcReg swizzleSuffix
;
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
@@ -984,6 +997,82 @@ optionalMask: MASK4 | MASK3 | MASK2 | MASK1
| { $$.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
@@ -2089,8 +2178,15 @@ asm_instruction_set_operands(struct asm_instruction *inst,
inst->Base.DstReg = *dst;
}
inst->Base.SrcReg[0] = src0->Base;
inst->SrcReg[0] = *src0;
/* 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;