Example #1
0
 /// <summary>
 /// Bind a macro index to a position for the MME
 /// </summary>
 /// <param name="index">The macro index</param>
 /// <param name="data">The position of the macro</param>
 public void BindMacro(int index, int position)
 {
     _macros[index] = new CachedMacro(position);
 }
Example #2
0
        private void Call3dMethod(NvGpuVmm Vmm, GpuMethodCall MethCall)
        {
            if (MethCall.Method < 0x80)
            {
                switch ((NvGpuFifoMeth)MethCall.Method)
                {
                case NvGpuFifoMeth.SetMacroUploadAddress:
                {
                    CurrMacroPosition = MethCall.Argument;

                    break;
                }

                case NvGpuFifoMeth.SendMacroCodeData:
                {
                    Mme[CurrMacroPosition++] = MethCall.Argument;

                    break;
                }

                case NvGpuFifoMeth.SetMacroBindingIndex:
                {
                    CurrMacroBindIndex = MethCall.Argument;

                    break;
                }

                case NvGpuFifoMeth.BindMacro:
                {
                    int Position = MethCall.Argument;

                    Macros[CurrMacroBindIndex] = new CachedMacro(this, Gpu.Engine3d, Position);

                    break;
                }

                default: CallP2mfMethod(Vmm, MethCall); break;
                }
            }
            else if (MethCall.Method < 0xe00)
            {
                Gpu.Engine3d.CallMethod(Vmm, MethCall);
            }
            else
            {
                int MacroIndex = (MethCall.Method >> 1) & MacroIndexMask;

                if ((MethCall.Method & 1) != 0)
                {
                    Macros[MacroIndex].PushArgument(MethCall.Argument);
                }
                else
                {
                    Macros[MacroIndex].StartExecution(MethCall.Argument);
                }

                if (MethCall.IsLastCall)
                {
                    Macros[MacroIndex].Execute(Vmm, Mme);
                }
            }
        }
Example #3
0
        private void Call3dMethod(NvGpuVmm vmm, GpuMethodCall methCall)
        {
            if (methCall.Method < 0x80)
            {
                switch ((NvGpuFifoMeth)methCall.Method)
                {
                case NvGpuFifoMeth.SetMacroUploadAddress:
                {
                    _currMacroPosition = methCall.Argument;

                    break;
                }

                case NvGpuFifoMeth.SendMacroCodeData:
                {
                    _mme[_currMacroPosition++] = methCall.Argument;

                    break;
                }

                case NvGpuFifoMeth.SetMacroBindingIndex:
                {
                    _currMacroBindIndex = methCall.Argument;

                    break;
                }

                case NvGpuFifoMeth.BindMacro:
                {
                    int position = methCall.Argument;

                    _macros[_currMacroBindIndex++] = new CachedMacro(this, _gpu.Engine3d, position);

                    break;
                }

                default: CallP2mfMethod(vmm, methCall); break;
                }
            }
            else if (methCall.Method < 0xe00)
            {
                _gpu.Engine3d.CallMethod(vmm, methCall);
            }
            else
            {
                int macroIndex = (methCall.Method >> 1) & MacroIndexMask;

                if ((methCall.Method & 1) != 0)
                {
                    _macros[macroIndex].PushArgument(methCall.Argument);
                }
                else
                {
                    _macros[macroIndex].StartExecution(methCall.Argument);
                }

                if (methCall.IsLastCall)
                {
                    _macros[macroIndex].Execute(vmm, _mme);
                }
            }
        }
Example #4
0
        /// <summary>
        /// Calls a GPU method.
        /// </summary>
        /// <param name="meth">GPU method call parameters</param>
        public void CallMethod(MethodParams meth)
        {
            if ((NvGpuFifoMeth)meth.Method == NvGpuFifoMeth.BindChannel)
            {
                _subChannels[meth.SubChannel].Class = (ClassId)meth.Argument;
            }
            else if (meth.Method < 0x60)
            {
                switch ((NvGpuFifoMeth)meth.Method)
                {
                    case NvGpuFifoMeth.WaitForIdle:
                    {
                        _context.Methods.PerformDeferredDraws();

                        _context.Renderer.Pipeline.Barrier();

                        break;
                    }

                    case NvGpuFifoMeth.SetMacroUploadAddress:
                    {
                        _currMacroPosition = meth.Argument;

                        break;
                    }

                    case NvGpuFifoMeth.SendMacroCodeData:
                    {
                        _mme[_currMacroPosition++] = meth.Argument;

                        break;
                    }

                    case NvGpuFifoMeth.SetMacroBindingIndex:
                    {
                        _currMacroBindIndex = meth.Argument;

                        break;
                    }

                    case NvGpuFifoMeth.BindMacro:
                    {
                        int position = meth.Argument;

                        _macros[_currMacroBindIndex++] = new CachedMacro(position);

                        break;
                    }
                }
            }
            else if (meth.Method < 0xe00)
            {
                _subChannels[meth.SubChannel].State.CallMethod(meth);
            }
            else
            {
                int macroIndex = (meth.Method >> 1) & MacroIndexMask;

                if ((meth.Method & 1) != 0)
                {
                    _macros[macroIndex].PushArgument(meth.Argument);
                }
                else
                {
                    _macros[macroIndex].StartExecution(meth.Argument);
                }

                if (meth.IsLastCall)
                {
                    _macros[macroIndex].Execute(_mme, _subChannels[meth.SubChannel].State);

                    _context.Methods.PerformDeferredDraws();
                }
            }
        }
Example #5
0
		/// <summary>
        /// This method invokes the macros. It's very tolerant about calls
        /// it can't make, meaning that it absorbs the exceptions
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="expression"></param>
        /// <returns></returns>
		private object InvokeMacro( object obj, string expression )
		{
			int subexStartIndex = 0;
			int subexEndIndex = 0;
			object subexObject = obj;
    			
			try
			{
				do
				{
					subexEndIndex = expression.IndexOfAny(new char[]{'.','(','['}, subexStartIndex);
			
					if ( subexEndIndex == -1 ) subexEndIndex=expression.Length;
					string subex = expression.Substring(subexStartIndex,subexEndIndex-subexStartIndex);


					int subexWithArgsEndIndex = expression.IndexOfAny(new char[]{'(','['}, subexStartIndex);
			
					string subexWithArgs;
					if ( subexWithArgsEndIndex != -1 ) 
						subexWithArgs = expression.Substring(subexStartIndex);
					else
						subexWithArgs = subex;

					// build the cacheKey used for caching the macros: typename.macroname
					// obj can be null, so we should check for that
					// we use obj instead of subexObject to short-cut the loop
					string cacheKey = ( obj != null ? obj.GetType().FullName + "." : "" ) + subexWithArgs;

					CachedMacro subCached;
					if (!macros.TryGetValue(cacheKey, out subCached) || subCached == null)
					{
						lock(macrosLock)
						{
							subexStartIndex = subexEndIndex+1;
							MemberInfo memberToInvoke;
							MemberInfo[] members = subexObject.GetType().FindMembers(
								MemberTypes.Field|MemberTypes.Method|MemberTypes.Property,
								BindingFlags.IgnoreCase|BindingFlags.Instance|BindingFlags.Public,
								new MemberFilter(this.IsMemberEligibleForMacroCall), subex.Trim() );
							string[] arglist=null;

							if ( members.Length == 0 )
							{
								throw new MissingMemberException(subexObject.GetType().FullName,subex.Trim());
							}
							if ( subexEndIndex<expression.Length && (expression[subexEndIndex] == '[' || expression[subexEndIndex] == '(') )
							{
								arglist = SplitArgs(expression,subexEndIndex, ref subexStartIndex);
							}

							//SDH: We REALLY need to refactor this whole Clemens thing - it's getting hairy.
							memberToInvoke = null;
							if ( members.Length > 1 )
							{
								foreach(MemberInfo potentialMember in members)
								{
									MethodInfo potentialMethod = potentialMember as MethodInfo;
									if(potentialMethod != null)
									{
										ParameterInfo[] parameters = potentialMethod.GetParameters();
										if(parameters != null && parameters.Length > 0)
										{
											if(parameters.Length == arglist.Length)
											{
												memberToInvoke = potentialMember;
												break;
											}
										}
									}
								}
							}

							if(memberToInvoke == null)//Previous behavior, use the first one.
							{
								memberToInvoke = members[0];
							}


							if ( memberToInvoke.MemberType == MemberTypes.Property &&
								(subexEndIndex==expression.Length ||
								expression[subexEndIndex] == '.' ||
								expression[subexEndIndex] == '[' ))
							{
								PropertyInfo propInfo = memberToInvoke as PropertyInfo;
								if ( subexEndIndex<expression.Length && expression[subexEndIndex] == '[' )
								{
									System.Reflection.ParameterInfo[] paramInfo = propInfo.GetIndexParameters();
									if ( arglist.Length > paramInfo.Length )
									{
										throw new InvalidOperationException(String.Format("Parameter list length mismatch {0}",memberToInvoke.Name));
									}
									object[] oarglist = new object[paramInfo.Length];
									for( int n=0;n<arglist.Length;n++)
									{
										oarglist[n] = Convert.ChangeType(arglist[n],paramInfo[n].ParameterType);
									}
									CachedMacro macro = new CachedMacro(propInfo,oarglist);
									macros[cacheKey] = macro;
									subexObject = macro.Invoke(subexObject);
									//subexObject = propInfo.GetValue(subexObject,oarglist);
								}
								else
								{
									CachedMacro macro = new CachedMacro(propInfo,null);
									macros[cacheKey] = macro;
									subexObject = macro.Invoke(subexObject);
									//subexObject = propInfo.GetValue(subexObject,null);
								}
							}
							else if ( memberToInvoke.MemberType == MemberTypes.Field &&
								(subexEndIndex==expression.Length ||
								expression[subexEndIndex] == '.'))
							{
								FieldInfo fieldInfo = memberToInvoke as FieldInfo;
			
								CachedMacro macro = new CachedMacro(fieldInfo);
								macros[cacheKey] = macro;
								subexObject = macro.Invoke(subexObject);
								//subexObject = fieldInfo.GetValue(subexObject);
							}
							else if ( memberToInvoke.MemberType == MemberTypes.Method &&
								subexEndIndex<expression.Length && expression[subexEndIndex] == '(' )
							{
								MethodInfo methInfo = memberToInvoke as MethodInfo;
								System.Reflection.ParameterInfo[] paramInfo = methInfo.GetParameters();
								if ( arglist.Length > paramInfo.Length && 
									!(paramInfo.Length>0 && paramInfo[paramInfo.Length-1].ParameterType == typeof(string[])))
								{
									throw new InvalidOperationException(String.Format("Parameter list length mismatch {0}",memberToInvoke.Name));
								}
								object[] oarglist = new object[paramInfo.Length];
								for( int n=0;n<arglist.Length;n++)
								{
									if ( n == paramInfo.Length-1 && 
										arglist.Length>paramInfo.Length)
									{
										string[] paramsArg = new string[arglist.Length-paramInfo.Length+1];
										for( int m=n;m<arglist.Length;m++)
										{
											paramsArg[m-n] = Convert.ChangeType(arglist[n],typeof(string)) as string;
										}
										oarglist[n] = paramsArg;
										break;
									}
									else
									{
										oarglist[n] = Convert.ChangeType(arglist[n],paramInfo[n].ParameterType);
									}
								}

								CachedMacro macro = new CachedMacro(methInfo,oarglist);
								macros[cacheKey] = macro;
								subexObject = macro.Invoke(subexObject);
								//subexObject = methInfo.Invoke(subexObject,oarglist);
							}
						}
					}
					else
					{
						subexStartIndex = subexEndIndex+1;
						subexObject = subCached.Invoke(subexObject);
						if (subexObject is Control) 
						{
							return subexObject;
						}
					}
				}
				while(subexEndIndex<expression.Length && subexStartIndex < expression.Length);
				
				return subexObject==null?new LiteralControl(""):subexObject;
			}
			catch( Exception exc )
			{
				ErrorTrace.Trace(System.Diagnostics.TraceLevel.Error,exc);
				throw;
			}
		}
        /// <summary>
        /// This method invokes the macros. It's very tolerant about calls
        /// it can't make, meaning that it absorbs the exceptions
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="expression"></param>
        /// <returns></returns>
        private object InvokeMacro(object obj, string expression)
        {
            int    subexStartIndex = 0;
            int    subexEndIndex   = 0;
            object subexObject     = obj;

            try
            {
                do
                {
                    subexEndIndex = expression.IndexOfAny(new char[] { '.', '(', '[' }, subexStartIndex);

                    if (subexEndIndex == -1)
                    {
                        subexEndIndex = expression.Length;
                    }
                    string subex = expression.Substring(subexStartIndex, subexEndIndex - subexStartIndex);


                    int subexWithArgsEndIndex = expression.IndexOfAny(new char[] { '(', '[' }, subexStartIndex);

                    string subexWithArgs;
                    if (subexWithArgsEndIndex != -1)
                    {
                        subexWithArgs = expression.Substring(subexStartIndex);
                    }
                    else
                    {
                        subexWithArgs = subex;
                    }

                    // build the cacheKey used for caching the macros: typename.macroname
                    // obj can be null, so we should check for that
                    // we use obj instead of subexObject to short-cut the loop
                    string cacheKey = (obj != null ? obj.GetType().FullName + "." : "") + subexWithArgs;

                    CachedMacro subCached;
                    if (!macros.TryGetValue(cacheKey, out subCached) || subCached == null)
                    {
                        lock (macrosLock)
                        {
                            subexStartIndex = subexEndIndex + 1;
                            MemberInfo   memberToInvoke;
                            MemberInfo[] members = subexObject.GetType().FindMembers(
                                MemberTypes.Field | MemberTypes.Method | MemberTypes.Property,
                                BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public,
                                new MemberFilter(this.IsMemberEligibleForMacroCall), subex.Trim());
                            string[] arglist = null;

                            if (members.Length == 0)
                            {
                                throw new MissingMemberException(subexObject.GetType().FullName, subex.Trim());
                            }
                            if (subexEndIndex < expression.Length && (expression[subexEndIndex] == '[' || expression[subexEndIndex] == '('))
                            {
                                arglist = SplitArgs(expression, subexEndIndex, ref subexStartIndex);
                            }

                            //SDH: We REALLY need to refactor this whole Clemens thing - it's getting hairy.
                            memberToInvoke = null;
                            if (members.Length > 1)
                            {
                                foreach (MemberInfo potentialMember in members)
                                {
                                    MethodInfo potentialMethod = potentialMember as MethodInfo;
                                    if (potentialMethod != null)
                                    {
                                        ParameterInfo[] parameters = potentialMethod.GetParameters();
                                        if (parameters != null && parameters.Length > 0)
                                        {
                                            if (parameters.Length == arglist.Length)
                                            {
                                                memberToInvoke = potentialMember;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }

                            if (memberToInvoke == null)                           //Previous behavior, use the first one.
                            {
                                memberToInvoke = members[0];
                            }


                            if (memberToInvoke.MemberType == MemberTypes.Property &&
                                (subexEndIndex == expression.Length ||
                                 expression[subexEndIndex] == '.' ||
                                 expression[subexEndIndex] == '['))
                            {
                                PropertyInfo propInfo = memberToInvoke as PropertyInfo;
                                if (subexEndIndex < expression.Length && expression[subexEndIndex] == '[')
                                {
                                    System.Reflection.ParameterInfo[] paramInfo = propInfo.GetIndexParameters();
                                    if (arglist.Length > paramInfo.Length)
                                    {
                                        throw new InvalidOperationException(String.Format("Parameter list length mismatch {0}", memberToInvoke.Name));
                                    }
                                    object[] oarglist = new object[paramInfo.Length];
                                    for (int n = 0; n < arglist.Length; n++)
                                    {
                                        oarglist[n] = Convert.ChangeType(arglist[n], paramInfo[n].ParameterType);
                                    }
                                    CachedMacro macro = new CachedMacro(propInfo, oarglist);
                                    macros[cacheKey] = macro;
                                    subexObject      = macro.Invoke(subexObject);
                                    //subexObject = propInfo.GetValue(subexObject,oarglist);
                                }
                                else
                                {
                                    CachedMacro macro = new CachedMacro(propInfo, null);
                                    macros[cacheKey] = macro;
                                    subexObject      = macro.Invoke(subexObject);
                                    //subexObject = propInfo.GetValue(subexObject,null);
                                }
                            }
                            else if (memberToInvoke.MemberType == MemberTypes.Field &&
                                     (subexEndIndex == expression.Length ||
                                      expression[subexEndIndex] == '.'))
                            {
                                FieldInfo fieldInfo = memberToInvoke as FieldInfo;

                                CachedMacro macro = new CachedMacro(fieldInfo);
                                macros[cacheKey] = macro;
                                subexObject      = macro.Invoke(subexObject);
                                //subexObject = fieldInfo.GetValue(subexObject);
                            }
                            else if (memberToInvoke.MemberType == MemberTypes.Method &&
                                     subexEndIndex < expression.Length && expression[subexEndIndex] == '(')
                            {
                                MethodInfo methInfo = memberToInvoke as MethodInfo;
                                System.Reflection.ParameterInfo[] paramInfo = methInfo.GetParameters();
                                if (arglist.Length > paramInfo.Length &&
                                    !(paramInfo.Length > 0 && paramInfo[paramInfo.Length - 1].ParameterType == typeof(string[])))
                                {
                                    throw new InvalidOperationException(String.Format("Parameter list length mismatch {0}", memberToInvoke.Name));
                                }
                                object[] oarglist = new object[paramInfo.Length];
                                for (int n = 0; n < arglist.Length; n++)
                                {
                                    if (n == paramInfo.Length - 1 &&
                                        arglist.Length > paramInfo.Length)
                                    {
                                        string[] paramsArg = new string[arglist.Length - paramInfo.Length + 1];
                                        for (int m = n; m < arglist.Length; m++)
                                        {
                                            paramsArg[m - n] = Convert.ChangeType(arglist[n], typeof(string)) as string;
                                        }
                                        oarglist[n] = paramsArg;
                                        break;
                                    }
                                    else
                                    {
                                        oarglist[n] = Convert.ChangeType(arglist[n], paramInfo[n].ParameterType);
                                    }
                                }

                                CachedMacro macro = new CachedMacro(methInfo, oarglist);
                                macros[cacheKey] = macro;
                                subexObject      = macro.Invoke(subexObject);
                                //subexObject = methInfo.Invoke(subexObject,oarglist);
                            }
                        }
                    }
                    else
                    {
                        subexStartIndex = subexEndIndex + 1;
                        subexObject     = subCached.Invoke(subexObject);
                        if (subexObject is Control)
                        {
                            return(subexObject);
                        }
                    }
                }while(subexEndIndex < expression.Length && subexStartIndex < expression.Length);

                return(subexObject == null?new LiteralControl(""):subexObject);
            }
            catch (Exception exc)
            {
                ErrorTrace.Trace(System.Diagnostics.TraceLevel.Error, exc);
                throw;
            }
        }