/// <summary> /// Sends a uncompressed method for processing by the graphics pipeline. /// </summary> /// <param name="meth">Method to be processed</param> private void Send(MethodParams meth) { if ((MethodOffset)meth.Method == MethodOffset.BindChannel) { _subChannels[meth.SubChannel] = new GpuState(); _context.Methods.RegisterCallbacks(_subChannels[meth.SubChannel]); } else if (meth.Method < 0x60) { // TODO: check if macros are shared between subchannels or not. For now let's assume they are. _fifoClass.Write(meth.Method * 4, meth.Argument); } else if (meth.Method < 0xe00) { _subChannels[meth.SubChannel].CallMethod(meth, _fifoClass.ShadowCtrl); } else { int macroIndex = (meth.Method >> 1) & MacroIndexMask; if ((meth.Method & 1) != 0) { _fifoClass.MmePushArgument(macroIndex, meth.Argument); } else { _fifoClass.MmeStart(macroIndex, meth.Argument); } if (meth.IsLastCall) { _fifoClass.CallMme(macroIndex, _subChannels[meth.SubChannel]); _context.Methods.PerformDeferredDraws(); } } }
/// <summary> /// Sends a uncompressed method for processing by the graphics pipeline. /// </summary> /// <param name="gpuVa">GPU virtual address where the command word is located</param> /// <param name="meth">Method to be processed</param> private void Send(ulong gpuVa, int offset, int argument, int subChannel, bool isLastCall) { if (offset < 0x60) { _fifoClass.Write(offset * 4, argument); } else if (offset < 0xe00) { offset *= 4; switch (subChannel) { case 0: _3dClass.Write(offset, argument); break; case 1: _computeClass.Write(offset, argument); break; case 2: _i2mClass.Write(offset, argument); break; case 3: _2dClass.Write(offset, argument); break; case 4: _dmaClass.Write(offset, argument); break; } } else { IDeviceState state = subChannel switch { 0 => _3dClass, 3 => _2dClass, _ => null }; if (state != null) { int macroIndex = (offset >> 1) & MacroIndexMask; if ((offset & 1) != 0) { _fifoClass.MmePushArgument(macroIndex, gpuVa, argument); } else { _fifoClass.MmeStart(macroIndex, argument); } if (isLastCall) { _fifoClass.CallMme(macroIndex, state); _3dClass.PerformDeferredDraws(); } } } }