public static void Ast(EmitterContext context) { InstAst op = context.GetOp <InstAst>(); for (int index = 0; index < (int)op.AlSize + 1; index++) { if (op.SrcB + index > RegisterConsts.RegisterZeroIndex) { break; } Register rd = new Register(op.SrcB + index, RegisterType.Gpr); if (op.Phys) { Operand userAttrOffset = context.ISubtract(GetSrcReg(context, op.SrcA), Const(AttributeConsts.UserAttributeBase)); Operand userAttrIndex = context.ShiftRightU32(userAttrOffset, Const(2)); context.StoreAttribute(Const(AttributeConsts.UserAttributeBase), userAttrIndex, Register(rd)); context.Config.SetUsedFeature(FeatureFlags.OaIndexing); } else { // TODO: Support indirect stores using Ra. int offset = op.Imm11 + index * 4; if (!context.Config.IsUsedOutputAttribute(offset)) { return; } offset = FixedFuncToUserAttribute(context.Config, offset, isOutput: true); context.FlagAttributeWritten(offset); Operand dest = op.P ? AttributePerPatch(offset) : Attribute(offset); context.Copy(dest, Register(rd)); } } }
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); } } } }