public static void Ipa(EmitterContext context) { InstIpa op = context.GetOp <InstIpa>(); context.FlagAttributeRead(op.Imm10); Operand res; bool isFixedFunc = false; if (op.Idx) { Operand userAttrOffset = context.ISubtract(GetSrcReg(context, op.SrcA), Const(AttributeConsts.UserAttributeBase)); Operand userAttrIndex = context.ShiftRightU32(userAttrOffset, Const(2)); res = context.LoadAttribute(Const(AttributeConsts.UserAttributeBase), userAttrIndex, Const(0)); res = context.FPMultiply(res, Attribute(AttributeConsts.PositionW)); context.Config.SetUsedFeature(FeatureFlags.IaIndexing); } else { isFixedFunc = TryFixedFuncToUserAttributeIpa(context, op.Imm10, out res); if (op.Imm10 >= AttributeConsts.UserAttributeBase && op.Imm10 < AttributeConsts.UserAttributeEnd) { int index = (op.Imm10 - AttributeConsts.UserAttributeBase) >> 4; if (context.Config.ImapTypes[index].GetFirstUsedType() == PixelImap.Perspective) { res = context.FPMultiply(res, Attribute(AttributeConsts.PositionW)); } } } if (op.IpaOp == IpaOp.Multiply && !isFixedFunc) { Operand srcB = GetSrcReg(context, op.SrcB); res = context.FPMultiply(res, srcB); } res = context.FPSaturate(res, op.Sat); context.Copy(GetDest(op.Dest), res); }
private static void SetUserAttributeUses(ShaderConfig config, InstName name, ulong opCode) { int offset; int count = 1; bool isStore = false; bool indexed = false; bool perPatch = false; if (name == InstName.Ast) { InstAst opAst = new InstAst(opCode); count = (int)opAst.AlSize + 1; offset = opAst.Imm11; indexed = opAst.Phys; perPatch = opAst.P; isStore = true; } else if (name == InstName.Ald) { InstAld opAld = new InstAld(opCode); count = (int)opAld.AlSize + 1; offset = opAld.Imm11; indexed = opAld.Phys; perPatch = opAld.P; isStore = opAld.O; } else /* if (name == InstName.Ipa) */ { InstIpa opIpa = new InstIpa(opCode); offset = opIpa.Imm10; indexed = opIpa.Idx; } if (indexed) { if (isStore) { config.SetAllOutputUserAttributes(); } else { config.SetAllInputUserAttributes(); } } else { for (int elemIndex = 0; elemIndex < count; elemIndex++) { int attr = offset + elemIndex * 4; if (attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd) { int index = (attr - AttributeConsts.UserAttributeBase) / 16; if (isStore) { config.SetOutputUserAttribute(index, perPatch); } else { config.SetInputUserAttribute(index, perPatch); } } if (!isStore && ((attr >= AttributeConsts.FrontColorDiffuseR && attr < AttributeConsts.ClipDistance0) || (attr >= AttributeConsts.TexCoordBase && attr < AttributeConsts.TexCoordEnd))) { config.SetUsedFeature(FeatureFlags.FixedFuncAttr); } } } }