public static void Ald(EmitterContext context) { InstAld op = context.GetOp <InstAld>(); Operand primVertex = context.Copy(GetSrcReg(context, op.SrcB)); for (int index = 0; index < (int)op.AlSize + 1; index++) { Register rd = new Register(op.Dest + index, RegisterType.Gpr); if (rd.IsRZ) { break; } if (op.Phys) { Operand userAttrOffset = context.ISubtract(GetSrcReg(context, op.SrcA), Const(AttributeConsts.UserAttributeBase)); Operand userAttrIndex = context.ShiftRightU32(userAttrOffset, Const(2)); context.Copy(Register(rd), context.LoadAttribute(Const(AttributeConsts.UserAttributeBase), userAttrIndex, primVertex)); context.Config.SetUsedFeature(FeatureFlags.IaIndexing); } else if (op.SrcB == RegisterConsts.RegisterZeroIndex || op.P) { int offset = FixedFuncToUserAttribute(context.Config, op.Imm11 + index * 4, op.O); context.FlagAttributeRead(offset); if (op.O) { offset |= AttributeConsts.LoadOutputMask; } Operand src = op.P ? AttributePerPatch(offset) : Attribute(offset); context.Copy(Register(rd), src); } else { int offset = FixedFuncToUserAttribute(context.Config, op.Imm11 + index * 4, op.O); context.FlagAttributeRead(offset); if (op.O) { offset |= AttributeConsts.LoadOutputMask; } Operand src = Const(offset); context.Copy(Register(rd), context.LoadAttribute(src, Const(0), primVertex)); } } }
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); } } } }