예제 #1
0
        /// <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();
                }
            }
        }
예제 #2
0
        /// <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();
                    }
                }
            }
        }