Separate GPU engines and make state follow official docs (part 1/2) (#2422)

* Use DeviceState for compute and i2m

* Migrate 2D class, more comments

* Migrate DMA copy engine

* Remove now unused code

* Replace GpuState by GpuAccessorState on GpuAcessor, since compute no longer has a GpuState

* More comments

* Add logging (disabled)

* Add back i2m on 3D engine
This commit is contained in:
gdkchan 2021-07-07 20:56:06 -03:00 committed by GitHub
parent 31cbd09a75
commit 8b44eb1c98
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 2599 additions and 460 deletions

View file

@ -1,159 +0,0 @@
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu.Image;
using Ryujinx.Graphics.Gpu.Shader;
using Ryujinx.Graphics.Gpu.State;
using Ryujinx.Graphics.Shader;
using System;
namespace Ryujinx.Graphics.Gpu.Engine
{
partial class Methods
{
/// <summary>
/// Dispatches compute work.
/// </summary>
/// <param name="state">Current GPU state</param>
/// <param name="argument">Method call argument</param>
public void Dispatch(GpuState state, int argument)
{
var memoryManager = state.Channel.MemoryManager;
FlushUboDirty(memoryManager);
uint qmdAddress = (uint)state.Get<int>(MethodOffset.DispatchParamsAddress);
var qmd = state.Channel.MemoryManager.Read<ComputeQmd>((ulong)qmdAddress << 8);
GpuVa shaderBaseAddress = state.Get<GpuVa>(MethodOffset.ShaderBaseAddress);
ulong shaderGpuVa = shaderBaseAddress.Pack() + (uint)qmd.ProgramOffset;
int localMemorySize = qmd.ShaderLocalMemoryLowSize + qmd.ShaderLocalMemoryHighSize;
int sharedMemorySize = Math.Min(qmd.SharedMemorySize, _context.Capabilities.MaximumComputeSharedMemorySize);
for (int index = 0; index < Constants.TotalCpUniformBuffers; index++)
{
if (!qmd.ConstantBufferValid(index))
{
continue;
}
ulong gpuVa = (uint)qmd.ConstantBufferAddrLower(index) | (ulong)qmd.ConstantBufferAddrUpper(index) << 32;
ulong size = (ulong)qmd.ConstantBufferSize(index);
state.Channel.BufferManager.SetComputeUniformBuffer(index, gpuVa, size);
}
ShaderBundle cs = memoryManager.Physical.ShaderCache.GetComputeShader(
state,
shaderGpuVa,
qmd.CtaThreadDimension0,
qmd.CtaThreadDimension1,
qmd.CtaThreadDimension2,
localMemorySize,
sharedMemorySize);
_context.Renderer.Pipeline.SetProgram(cs.HostProgram);
var samplerPool = state.Get<PoolState>(MethodOffset.SamplerPoolState);
var texturePool = state.Get<PoolState>(MethodOffset.TexturePoolState);
state.Channel.TextureManager.SetComputeSamplerPool(samplerPool.Address.Pack(), samplerPool.MaximumId, qmd.SamplerIndex);
state.Channel.TextureManager.SetComputeTexturePool(texturePool.Address.Pack(), texturePool.MaximumId);
state.Channel.TextureManager.SetComputeTextureBufferIndex(state.Get<int>(MethodOffset.TextureBufferIndex));
ShaderProgramInfo info = cs.Shaders[0].Info;
for (int index = 0; index < info.CBuffers.Count; index++)
{
BufferDescriptor cb = info.CBuffers[index];
// NVN uses the "hardware" constant buffer for anything that is less than 8,
// and those are already bound above.
// Anything greater than or equal to 8 uses the emulated constant buffers.
// They are emulated using global memory loads.
if (cb.Slot < 8)
{
continue;
}
ulong cbDescAddress = state.Channel.BufferManager.GetComputeUniformBufferAddress(0);
int cbDescOffset = 0x260 + (cb.Slot - 8) * 0x10;
cbDescAddress += (ulong)cbDescOffset;
SbDescriptor cbDescriptor = state.Channel.MemoryManager.Physical.Read<SbDescriptor>(cbDescAddress);
state.Channel.BufferManager.SetComputeUniformBuffer(cb.Slot, cbDescriptor.PackAddress(), (uint)cbDescriptor.Size);
}
for (int index = 0; index < info.SBuffers.Count; index++)
{
BufferDescriptor sb = info.SBuffers[index];
ulong sbDescAddress = state.Channel.BufferManager.GetComputeUniformBufferAddress(0);
int sbDescOffset = 0x310 + sb.Slot * 0x10;
sbDescAddress += (ulong)sbDescOffset;
SbDescriptor sbDescriptor = state.Channel.MemoryManager.Physical.Read<SbDescriptor>(sbDescAddress);
state.Channel.BufferManager.SetComputeStorageBuffer(sb.Slot, sbDescriptor.PackAddress(), (uint)sbDescriptor.Size, sb.Flags);
}
state.Channel.BufferManager.SetComputeStorageBufferBindings(info.SBuffers);
state.Channel.BufferManager.SetComputeUniformBufferBindings(info.CBuffers);
var textureBindings = new TextureBindingInfo[info.Textures.Count];
for (int index = 0; index < info.Textures.Count; index++)
{
var descriptor = info.Textures[index];
Target target = ShaderTexture.GetTarget(descriptor.Type);
textureBindings[index] = new TextureBindingInfo(
target,
descriptor.Binding,
descriptor.CbufSlot,
descriptor.HandleIndex,
descriptor.Flags);
}
state.Channel.TextureManager.SetComputeTextures(textureBindings);
var imageBindings = new TextureBindingInfo[info.Images.Count];
for (int index = 0; index < info.Images.Count; index++)
{
var descriptor = info.Images[index];
Target target = ShaderTexture.GetTarget(descriptor.Type);
Format format = ShaderTexture.GetFormat(descriptor.Format);
imageBindings[index] = new TextureBindingInfo(
target,
format,
descriptor.Binding,
descriptor.CbufSlot,
descriptor.HandleIndex,
descriptor.Flags);
}
state.Channel.TextureManager.SetComputeImages(imageBindings);
state.Channel.TextureManager.CommitComputeBindings();
state.Channel.BufferManager.CommitComputeBindings();
_context.Renderer.Pipeline.DispatchCompute(
qmd.CtaRasterWidth,
qmd.CtaRasterHeight,
qmd.CtaRasterDepth);
_forceShaderUpdate = true;
}
}
}

View file

@ -0,0 +1,213 @@
using Ryujinx.Graphics.Device;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu.Engine.InlineToMemory;
using Ryujinx.Graphics.Gpu.Image;
using Ryujinx.Graphics.Gpu.Shader;
using Ryujinx.Graphics.Gpu.State;
using Ryujinx.Graphics.Shader;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace Ryujinx.Graphics.Gpu.Engine.Compute
{
/// <summary>
/// Represents a compute engine class.
/// </summary>
class ComputeClass : InlineToMemoryClass, IDeviceState
{
private readonly GpuContext _context;
private readonly GpuChannel _channel;
private readonly DeviceState<ComputeClassState> _state;
/// <summary>
/// Creates a new instance of the compute engine class.
/// </summary>
/// <param name="context">GPU context</param>
/// <param name="channel">GPU channel</param>
public ComputeClass(GpuContext context, GpuChannel channel) : base(context, channel, false)
{
_context = context;
_channel = channel;
_state = new DeviceState<ComputeClassState>(new Dictionary<string, RwCallback>
{
{ nameof(ComputeClassState.LaunchDma), new RwCallback(LaunchDma, null) },
{ nameof(ComputeClassState.LoadInlineData), new RwCallback(LoadInlineData, null) },
{ nameof(ComputeClassState.SendSignalingPcasB), new RwCallback(SendSignalingPcasB, null) }
});
}
/// <summary>
/// Reads data from the class registers.
/// </summary>
/// <param name="offset">Register byte offset</param>
/// <returns>Data at the specified offset</returns>
public override int Read(int offset) => _state.Read(offset);
/// <summary>
/// Writes data to the class registers.
/// </summary>
/// <param name="offset">Register byte offset</param>
/// <param name="data">Data to be written</param>
public override void Write(int offset, int data) => _state.Write(offset, data);
/// <summary>
/// Launches the Inline-to-Memory DMA copy operation.
/// </summary>
/// <param name="argument">Method call argument</param>
protected override void LaunchDma(int argument)
{
LaunchDma(ref Unsafe.As<ComputeClassState, InlineToMemoryClassState>(ref _state.State), argument);
}
/// <summary>
/// Performs the compute dispatch operation.
/// </summary>
/// <param name="argument">Method call argument</param>
private void SendSignalingPcasB(int argument)
{
var memoryManager = _channel.MemoryManager;
_context.Methods.FlushUboDirty(memoryManager);
uint qmdAddress = _state.State.SendPcasA;
var qmd = _channel.MemoryManager.Read<ComputeQmd>((ulong)qmdAddress << 8);
ulong shaderGpuVa = ((ulong)_state.State.SetProgramRegionAAddressUpper << 32) | _state.State.SetProgramRegionB;
shaderGpuVa += (uint)qmd.ProgramOffset;
int localMemorySize = qmd.ShaderLocalMemoryLowSize + qmd.ShaderLocalMemoryHighSize;
int sharedMemorySize = Math.Min(qmd.SharedMemorySize, _context.Capabilities.MaximumComputeSharedMemorySize);
for (int index = 0; index < Constants.TotalCpUniformBuffers; index++)
{
if (!qmd.ConstantBufferValid(index))
{
continue;
}
ulong gpuVa = (uint)qmd.ConstantBufferAddrLower(index) | (ulong)qmd.ConstantBufferAddrUpper(index) << 32;
ulong size = (ulong)qmd.ConstantBufferSize(index);
_channel.BufferManager.SetComputeUniformBuffer(index, gpuVa, size);
}
ulong samplerPoolGpuVa = ((ulong)_state.State.SetTexSamplerPoolAOffsetUpper << 32) | _state.State.SetTexSamplerPoolB;
ulong texturePoolGpuVa = ((ulong)_state.State.SetTexHeaderPoolAOffsetUpper << 32) | _state.State.SetTexHeaderPoolB;
GpuAccessorState gas = new GpuAccessorState(
texturePoolGpuVa,
_state.State.SetTexHeaderPoolCMaximumIndex,
_state.State.SetBindlessTextureConstantBufferSlotSelect,
false);
ShaderBundle cs = memoryManager.Physical.ShaderCache.GetComputeShader(
_channel,
gas,
shaderGpuVa,
qmd.CtaThreadDimension0,
qmd.CtaThreadDimension1,
qmd.CtaThreadDimension2,
localMemorySize,
sharedMemorySize);
_context.Renderer.Pipeline.SetProgram(cs.HostProgram);
_channel.TextureManager.SetComputeSamplerPool(samplerPoolGpuVa, _state.State.SetTexSamplerPoolCMaximumIndex, qmd.SamplerIndex);
_channel.TextureManager.SetComputeTexturePool(texturePoolGpuVa, _state.State.SetTexHeaderPoolCMaximumIndex);
_channel.TextureManager.SetComputeTextureBufferIndex(_state.State.SetBindlessTextureConstantBufferSlotSelect);
ShaderProgramInfo info = cs.Shaders[0].Info;
for (int index = 0; index < info.CBuffers.Count; index++)
{
BufferDescriptor cb = info.CBuffers[index];
// NVN uses the "hardware" constant buffer for anything that is less than 8,
// and those are already bound above.
// Anything greater than or equal to 8 uses the emulated constant buffers.
// They are emulated using global memory loads.
if (cb.Slot < 8)
{
continue;
}
ulong cbDescAddress = _channel.BufferManager.GetComputeUniformBufferAddress(0);
int cbDescOffset = 0x260 + (cb.Slot - 8) * 0x10;
cbDescAddress += (ulong)cbDescOffset;
SbDescriptor cbDescriptor = _channel.MemoryManager.Physical.Read<SbDescriptor>(cbDescAddress);
_channel.BufferManager.SetComputeUniformBuffer(cb.Slot, cbDescriptor.PackAddress(), (uint)cbDescriptor.Size);
}
for (int index = 0; index < info.SBuffers.Count; index++)
{
BufferDescriptor sb = info.SBuffers[index];
ulong sbDescAddress = _channel.BufferManager.GetComputeUniformBufferAddress(0);
int sbDescOffset = 0x310 + sb.Slot * 0x10;
sbDescAddress += (ulong)sbDescOffset;
SbDescriptor sbDescriptor = _channel.MemoryManager.Physical.Read<SbDescriptor>(sbDescAddress);
_channel.BufferManager.SetComputeStorageBuffer(sb.Slot, sbDescriptor.PackAddress(), (uint)sbDescriptor.Size, sb.Flags);
}
_channel.BufferManager.SetComputeStorageBufferBindings(info.SBuffers);
_channel.BufferManager.SetComputeUniformBufferBindings(info.CBuffers);
var textureBindings = new TextureBindingInfo[info.Textures.Count];
for (int index = 0; index < info.Textures.Count; index++)
{
var descriptor = info.Textures[index];
Target target = ShaderTexture.GetTarget(descriptor.Type);
textureBindings[index] = new TextureBindingInfo(
target,
descriptor.Binding,
descriptor.CbufSlot,
descriptor.HandleIndex,
descriptor.Flags);
}
_channel.TextureManager.SetComputeTextures(textureBindings);
var imageBindings = new TextureBindingInfo[info.Images.Count];
for (int index = 0; index < info.Images.Count; index++)
{
var descriptor = info.Images[index];
Target target = ShaderTexture.GetTarget(descriptor.Type);
Format format = ShaderTexture.GetFormat(descriptor.Format);
imageBindings[index] = new TextureBindingInfo(
target,
format,
descriptor.Binding,
descriptor.CbufSlot,
descriptor.HandleIndex,
descriptor.Flags);
}
_channel.TextureManager.SetComputeImages(imageBindings);
_channel.TextureManager.CommitComputeBindings();
_channel.BufferManager.CommitComputeBindings();
_context.Renderer.Pipeline.DispatchCompute(qmd.CtaRasterWidth, qmd.CtaRasterHeight, qmd.CtaRasterDepth);
_context.Methods.ForceShaderUpdate();
}
}
}

View file

@ -0,0 +1,435 @@
// This file was auto-generated from NVIDIA official Maxwell definitions.
using Ryujinx.Common.Memory;
using Ryujinx.Graphics.Gpu.Engine.InlineToMemory;
namespace Ryujinx.Graphics.Gpu.Engine.Compute
{
/// <summary>
/// Notify type.
/// </summary>
enum NotifyType
{
WriteOnly = 0,
WriteThenAwaken = 1,
}
/// <summary>
/// CWD control SM selection.
/// </summary>
enum SetCwdControlSmSelection
{
LoadBalanced = 0,
RoundRobin = 1,
}
/// <summary>
/// Cache lines to invalidate.
/// </summary>
enum InvalidateCacheLines
{
All = 0,
One = 1,
}
/// <summary>
/// GWC SCG type.
/// </summary>
enum SetGwcScgTypeScgType
{
GraphicsCompute0 = 0,
Compute1 = 1,
}
/// <summary>
/// Render enable override mode.
/// </summary>
enum SetRenderEnableOverrideMode
{
UseRenderEnable = 0,
AlwaysRender = 1,
NeverRender = 2,
}
/// <summary>
/// Semaphore report operation.
/// </summary>
enum SetReportSemaphoreDOperation
{
Release = 0,
Trap = 3,
}
/// <summary>
/// Semaphore report structure size.
/// </summary>
enum SetReportSemaphoreDStructureSize
{
FourWords = 0,
OneWord = 1,
}
/// <summary>
/// Semaphore report reduction operation.
/// </summary>
enum SetReportSemaphoreDReductionOp
{
RedAdd = 0,
RedMin = 1,
RedMax = 2,
RedInc = 3,
RedDec = 4,
RedAnd = 5,
RedOr = 6,
RedXor = 7,
}
/// <summary>
/// Semaphore report reduction format.
/// </summary>
enum SetReportSemaphoreDReductionFormat
{
Unsigned32 = 0,
Signed32 = 1,
}
/// <summary>
/// Compute class state.
/// </summary>
unsafe struct ComputeClassState
{
#pragma warning disable CS0649
public uint SetObject;
public int SetObjectClassId => (int)((SetObject >> 0) & 0xFFFF);
public int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
public fixed uint Reserved04[63];
public uint NoOperation;
public uint SetNotifyA;
public int SetNotifyAAddressUpper => (int)((SetNotifyA >> 0) & 0xFF);
public uint SetNotifyB;
public uint Notify;
public NotifyType NotifyType => (NotifyType)(Notify);
public uint WaitForIdle;
public fixed uint Reserved114[7];
public uint SetGlobalRenderEnableA;
public int SetGlobalRenderEnableAOffsetUpper => (int)((SetGlobalRenderEnableA >> 0) & 0xFF);
public uint SetGlobalRenderEnableB;
public uint SetGlobalRenderEnableC;
public int SetGlobalRenderEnableCMode => (int)((SetGlobalRenderEnableC >> 0) & 0x7);
public uint SendGoIdle;
public uint PmTrigger;
public uint PmTriggerWfi;
public fixed uint Reserved148[2];
public uint SetInstrumentationMethodHeader;
public uint SetInstrumentationMethodData;
public fixed uint Reserved158[10];
public uint LineLengthIn;
public uint LineCount;
public uint OffsetOutUpper;
public int OffsetOutUpperValue => (int)((OffsetOutUpper >> 0) & 0xFF);
public uint OffsetOut;
public uint PitchOut;
public uint SetDstBlockSize;
public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)((SetDstBlockSize >> 0) & 0xF);
public SetDstBlockSizeHeight SetDstBlockSizeHeight => (SetDstBlockSizeHeight)((SetDstBlockSize >> 4) & 0xF);
public SetDstBlockSizeDepth SetDstBlockSizeDepth => (SetDstBlockSizeDepth)((SetDstBlockSize >> 8) & 0xF);
public uint SetDstWidth;
public uint SetDstHeight;
public uint SetDstDepth;
public uint SetDstLayer;
public uint SetDstOriginBytesX;
public int SetDstOriginBytesXV => (int)((SetDstOriginBytesX >> 0) & 0xFFFFF);
public uint SetDstOriginSamplesY;
public int SetDstOriginSamplesYV => (int)((SetDstOriginSamplesY >> 0) & 0xFFFF);
public uint LaunchDma;
public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)((LaunchDma >> 0) & 0x1);
public LaunchDmaCompletionType LaunchDmaCompletionType => (LaunchDmaCompletionType)((LaunchDma >> 4) & 0x3);
public LaunchDmaInterruptType LaunchDmaInterruptType => (LaunchDmaInterruptType)((LaunchDma >> 8) & 0x3);
public LaunchDmaSemaphoreStructSize LaunchDmaSemaphoreStructSize => (LaunchDmaSemaphoreStructSize)((LaunchDma >> 12) & 0x1);
public bool LaunchDmaReductionEnable => (LaunchDma & 0x2) != 0;
public LaunchDmaReductionOp LaunchDmaReductionOp => (LaunchDmaReductionOp)((LaunchDma >> 13) & 0x7);
public LaunchDmaReductionFormat LaunchDmaReductionFormat => (LaunchDmaReductionFormat)((LaunchDma >> 2) & 0x3);
public bool LaunchDmaSysmembarDisable => (LaunchDma & 0x40) != 0;
public uint LoadInlineData;
public fixed uint Reserved1B8[9];
public uint SetI2mSemaphoreA;
public int SetI2mSemaphoreAOffsetUpper => (int)((SetI2mSemaphoreA >> 0) & 0xFF);
public uint SetI2mSemaphoreB;
public uint SetI2mSemaphoreC;
public fixed uint Reserved1E8[2];
public uint SetI2mSpareNoop00;
public uint SetI2mSpareNoop01;
public uint SetI2mSpareNoop02;
public uint SetI2mSpareNoop03;
public uint SetValidSpanOverflowAreaA;
public int SetValidSpanOverflowAreaAAddressUpper => (int)((SetValidSpanOverflowAreaA >> 0) & 0xFF);
public uint SetValidSpanOverflowAreaB;
public uint SetValidSpanOverflowAreaC;
public uint SetCoalesceWaitingPeriodUnit;
public uint PerfmonTransfer;
public uint SetShaderSharedMemoryWindow;
public uint SetSelectMaxwellTextureHeaders;
public bool SetSelectMaxwellTextureHeadersV => (SetSelectMaxwellTextureHeaders & 0x1) != 0;
public uint InvalidateShaderCaches;
public bool InvalidateShaderCachesInstruction => (InvalidateShaderCaches & 0x1) != 0;
public bool InvalidateShaderCachesData => (InvalidateShaderCaches & 0x10) != 0;
public bool InvalidateShaderCachesConstant => (InvalidateShaderCaches & 0x1000) != 0;
public bool InvalidateShaderCachesLocks => (InvalidateShaderCaches & 0x2) != 0;
public bool InvalidateShaderCachesFlushData => (InvalidateShaderCaches & 0x4) != 0;
public uint SetReservedSwMethod00;
public uint SetReservedSwMethod01;
public uint SetReservedSwMethod02;
public uint SetReservedSwMethod03;
public uint SetReservedSwMethod04;
public uint SetReservedSwMethod05;
public uint SetReservedSwMethod06;
public uint SetReservedSwMethod07;
public uint SetCwdControl;
public SetCwdControlSmSelection SetCwdControlSmSelection => (SetCwdControlSmSelection)((SetCwdControl >> 0) & 0x1);
public uint InvalidateTextureHeaderCacheNoWfi;
public InvalidateCacheLines InvalidateTextureHeaderCacheNoWfiLines => (InvalidateCacheLines)((InvalidateTextureHeaderCacheNoWfi >> 0) & 0x1);
public int InvalidateTextureHeaderCacheNoWfiTag => (int)((InvalidateTextureHeaderCacheNoWfi >> 4) & 0x3FFFFF);
public uint SetCwdRefCounter;
public int SetCwdRefCounterSelect => (int)((SetCwdRefCounter >> 0) & 0x3F);
public int SetCwdRefCounterValue => (int)((SetCwdRefCounter >> 8) & 0xFFFF);
public uint SetReservedSwMethod08;
public uint SetReservedSwMethod09;
public uint SetReservedSwMethod10;
public uint SetReservedSwMethod11;
public uint SetReservedSwMethod12;
public uint SetReservedSwMethod13;
public uint SetReservedSwMethod14;
public uint SetReservedSwMethod15;
public uint SetGwcScgType;
public SetGwcScgTypeScgType SetGwcScgTypeScgType => (SetGwcScgTypeScgType)((SetGwcScgType >> 0) & 0x1);
public uint SetScgControl;
public int SetScgControlCompute1MaxSmCount => (int)((SetScgControl >> 0) & 0x1FF);
public uint InvalidateConstantBufferCacheA;
public int InvalidateConstantBufferCacheAAddressUpper => (int)((InvalidateConstantBufferCacheA >> 0) & 0xFF);
public uint InvalidateConstantBufferCacheB;
public uint InvalidateConstantBufferCacheC;
public int InvalidateConstantBufferCacheCByteCount => (int)((InvalidateConstantBufferCacheC >> 0) & 0x1FFFF);
public bool InvalidateConstantBufferCacheCThruL2 => (InvalidateConstantBufferCacheC & 0x80000000) != 0;
public uint SetComputeClassVersion;
public int SetComputeClassVersionCurrent => (int)((SetComputeClassVersion >> 0) & 0xFFFF);
public int SetComputeClassVersionOldestSupported => (int)((SetComputeClassVersion >> 16) & 0xFFFF);
public uint CheckComputeClassVersion;
public int CheckComputeClassVersionCurrent => (int)((CheckComputeClassVersion >> 0) & 0xFFFF);
public int CheckComputeClassVersionOldestSupported => (int)((CheckComputeClassVersion >> 16) & 0xFFFF);
public uint SetQmdVersion;
public int SetQmdVersionCurrent => (int)((SetQmdVersion >> 0) & 0xFFFF);
public int SetQmdVersionOldestSupported => (int)((SetQmdVersion >> 16) & 0xFFFF);
public uint SetWfiConfig;
public bool SetWfiConfigEnableScgTypeWfi => (SetWfiConfig & 0x1) != 0;
public uint CheckQmdVersion;
public int CheckQmdVersionCurrent => (int)((CheckQmdVersion >> 0) & 0xFFFF);
public int CheckQmdVersionOldestSupported => (int)((CheckQmdVersion >> 16) & 0xFFFF);
public uint WaitForIdleScgType;
public uint InvalidateSkedCaches;
public bool InvalidateSkedCachesV => (InvalidateSkedCaches & 0x1) != 0;
public uint SetScgRenderEnableControl;
public bool SetScgRenderEnableControlCompute1UsesRenderEnable => (SetScgRenderEnableControl & 0x1) != 0;
public fixed uint Reserved2A0[4];
public uint SetCwdSlotCount;
public int SetCwdSlotCountV => (int)((SetCwdSlotCount >> 0) & 0xFF);
public uint SendPcasA;
public uint SendPcasB;
public int SendPcasBFrom => (int)((SendPcasB >> 0) & 0xFFFFFF);
public int SendPcasBDelta => (int)((SendPcasB >> 24) & 0xFF);
public uint SendSignalingPcasB;
public bool SendSignalingPcasBInvalidate => (SendSignalingPcasB & 0x1) != 0;
public bool SendSignalingPcasBSchedule => (SendSignalingPcasB & 0x2) != 0;
public fixed uint Reserved2C0[9];
public uint SetShaderLocalMemoryNonThrottledA;
public int SetShaderLocalMemoryNonThrottledASizeUpper => (int)((SetShaderLocalMemoryNonThrottledA >> 0) & 0xFF);
public uint SetShaderLocalMemoryNonThrottledB;
public uint SetShaderLocalMemoryNonThrottledC;
public int SetShaderLocalMemoryNonThrottledCMaxSmCount => (int)((SetShaderLocalMemoryNonThrottledC >> 0) & 0x1FF);
public uint SetShaderLocalMemoryThrottledA;
public int SetShaderLocalMemoryThrottledASizeUpper => (int)((SetShaderLocalMemoryThrottledA >> 0) & 0xFF);
public uint SetShaderLocalMemoryThrottledB;
public uint SetShaderLocalMemoryThrottledC;
public int SetShaderLocalMemoryThrottledCMaxSmCount => (int)((SetShaderLocalMemoryThrottledC >> 0) & 0x1FF);
public fixed uint Reserved2FC[5];
public uint SetSpaVersion;
public int SetSpaVersionMinor => (int)((SetSpaVersion >> 0) & 0xFF);
public int SetSpaVersionMajor => (int)((SetSpaVersion >> 8) & 0xFF);
public fixed uint Reserved314[123];
public uint SetFalcon00;
public uint SetFalcon01;
public uint SetFalcon02;
public uint SetFalcon03;
public uint SetFalcon04;
public uint SetFalcon05;
public uint SetFalcon06;
public uint SetFalcon07;
public uint SetFalcon08;
public uint SetFalcon09;
public uint SetFalcon10;
public uint SetFalcon11;
public uint SetFalcon12;
public uint SetFalcon13;
public uint SetFalcon14;
public uint SetFalcon15;
public uint SetFalcon16;
public uint SetFalcon17;
public uint SetFalcon18;
public uint SetFalcon19;
public uint SetFalcon20;
public uint SetFalcon21;
public uint SetFalcon22;
public uint SetFalcon23;
public uint SetFalcon24;
public uint SetFalcon25;
public uint SetFalcon26;
public uint SetFalcon27;
public uint SetFalcon28;
public uint SetFalcon29;
public uint SetFalcon30;
public uint SetFalcon31;
public fixed uint Reserved580[127];
public uint SetShaderLocalMemoryWindow;
public fixed uint Reserved780[4];
public uint SetShaderLocalMemoryA;
public int SetShaderLocalMemoryAAddressUpper => (int)((SetShaderLocalMemoryA >> 0) & 0xFF);
public uint SetShaderLocalMemoryB;
public fixed uint Reserved798[383];
public uint SetShaderCacheControl;
public bool SetShaderCacheControlIcachePrefetchEnable => (SetShaderCacheControl & 0x1) != 0;
public fixed uint ReservedD98[19];
public uint SetSmTimeoutInterval;
public int SetSmTimeoutIntervalCounterBit => (int)((SetSmTimeoutInterval >> 0) & 0x3F);
public fixed uint ReservedDE8[87];
public uint SetSpareNoop12;
public uint SetSpareNoop13;
public uint SetSpareNoop14;
public uint SetSpareNoop15;
public fixed uint ReservedF54[59];
public uint SetSpareNoop00;
public uint SetSpareNoop01;
public uint SetSpareNoop02;
public uint SetSpareNoop03;
public uint SetSpareNoop04;
public uint SetSpareNoop05;
public uint SetSpareNoop06;
public uint SetSpareNoop07;
public uint SetSpareNoop08;
public uint SetSpareNoop09;
public uint SetSpareNoop10;
public uint SetSpareNoop11;
public fixed uint Reserved1070[103];
public uint InvalidateSamplerCacheAll;
public bool InvalidateSamplerCacheAllV => (InvalidateSamplerCacheAll & 0x1) != 0;
public uint InvalidateTextureHeaderCacheAll;
public bool InvalidateTextureHeaderCacheAllV => (InvalidateTextureHeaderCacheAll & 0x1) != 0;
public fixed uint Reserved1214[29];
public uint InvalidateTextureDataCacheNoWfi;
public InvalidateCacheLines InvalidateTextureDataCacheNoWfiLines => (InvalidateCacheLines)((InvalidateTextureDataCacheNoWfi >> 0) & 0x1);
public int InvalidateTextureDataCacheNoWfiTag => (int)((InvalidateTextureDataCacheNoWfi >> 4) & 0x3FFFFF);
public fixed uint Reserved128C[7];
public uint ActivatePerfSettingsForComputeContext;
public bool ActivatePerfSettingsForComputeContextAll => (ActivatePerfSettingsForComputeContext & 0x1) != 0;
public fixed uint Reserved12AC[33];
public uint InvalidateSamplerCache;
public InvalidateCacheLines InvalidateSamplerCacheLines => (InvalidateCacheLines)((InvalidateSamplerCache >> 0) & 0x1);
public int InvalidateSamplerCacheTag => (int)((InvalidateSamplerCache >> 4) & 0x3FFFFF);
public uint InvalidateTextureHeaderCache;
public InvalidateCacheLines InvalidateTextureHeaderCacheLines => (InvalidateCacheLines)((InvalidateTextureHeaderCache >> 0) & 0x1);
public int InvalidateTextureHeaderCacheTag => (int)((InvalidateTextureHeaderCache >> 4) & 0x3FFFFF);
public uint InvalidateTextureDataCache;
public InvalidateCacheLines InvalidateTextureDataCacheLines => (InvalidateCacheLines)((InvalidateTextureDataCache >> 0) & 0x1);
public int InvalidateTextureDataCacheTag => (int)((InvalidateTextureDataCache >> 4) & 0x3FFFFF);
public fixed uint Reserved133C[58];
public uint InvalidateSamplerCacheNoWfi;
public InvalidateCacheLines InvalidateSamplerCacheNoWfiLines => (InvalidateCacheLines)((InvalidateSamplerCacheNoWfi >> 0) & 0x1);
public int InvalidateSamplerCacheNoWfiTag => (int)((InvalidateSamplerCacheNoWfi >> 4) & 0x3FFFFF);
public fixed uint Reserved1428[64];
public uint SetShaderExceptions;
public bool SetShaderExceptionsEnable => (SetShaderExceptions & 0x1) != 0;
public fixed uint Reserved152C[9];
public uint SetRenderEnableA;
public int SetRenderEnableAOffsetUpper => (int)((SetRenderEnableA >> 0) & 0xFF);
public uint SetRenderEnableB;
public uint SetRenderEnableC;
public int SetRenderEnableCMode => (int)((SetRenderEnableC >> 0) & 0x7);
public uint SetTexSamplerPoolA;
public int SetTexSamplerPoolAOffsetUpper => (int)((SetTexSamplerPoolA >> 0) & 0xFF);
public uint SetTexSamplerPoolB;
public uint SetTexSamplerPoolC;
public int SetTexSamplerPoolCMaximumIndex => (int)((SetTexSamplerPoolC >> 0) & 0xFFFFF);
public fixed uint Reserved1568[3];
public uint SetTexHeaderPoolA;
public int SetTexHeaderPoolAOffsetUpper => (int)((SetTexHeaderPoolA >> 0) & 0xFF);
public uint SetTexHeaderPoolB;
public uint SetTexHeaderPoolC;
public int SetTexHeaderPoolCMaximumIndex => (int)((SetTexHeaderPoolC >> 0) & 0x3FFFFF);
public fixed uint Reserved1580[34];
public uint SetProgramRegionA;
public int SetProgramRegionAAddressUpper => (int)((SetProgramRegionA >> 0) & 0xFF);
public uint SetProgramRegionB;
public fixed uint Reserved1610[34];
public uint InvalidateShaderCachesNoWfi;
public bool InvalidateShaderCachesNoWfiInstruction => (InvalidateShaderCachesNoWfi & 0x1) != 0;
public bool InvalidateShaderCachesNoWfiGlobalData => (InvalidateShaderCachesNoWfi & 0x10) != 0;
public bool InvalidateShaderCachesNoWfiConstant => (InvalidateShaderCachesNoWfi & 0x1000) != 0;
public fixed uint Reserved169C[170];
public uint SetRenderEnableOverride;
public SetRenderEnableOverrideMode SetRenderEnableOverrideMode => (SetRenderEnableOverrideMode)((SetRenderEnableOverride >> 0) & 0x3);
public fixed uint Reserved1948[57];
public uint PipeNop;
public uint SetSpare00;
public uint SetSpare01;
public uint SetSpare02;
public uint SetSpare03;
public fixed uint Reserved1A40[48];
public uint SetReportSemaphoreA;
public int SetReportSemaphoreAOffsetUpper => (int)((SetReportSemaphoreA >> 0) & 0xFF);
public uint SetReportSemaphoreB;
public uint SetReportSemaphoreC;
public uint SetReportSemaphoreD;
public SetReportSemaphoreDOperation SetReportSemaphoreDOperation => (SetReportSemaphoreDOperation)((SetReportSemaphoreD >> 0) & 0x3);
public bool SetReportSemaphoreDAwakenEnable => (SetReportSemaphoreD & 0x100000) != 0;
public SetReportSemaphoreDStructureSize SetReportSemaphoreDStructureSize => (SetReportSemaphoreDStructureSize)((SetReportSemaphoreD >> 28) & 0x1);
public bool SetReportSemaphoreDFlushDisable => (SetReportSemaphoreD & 0x4) != 0;
public bool SetReportSemaphoreDReductionEnable => (SetReportSemaphoreD & 0x8) != 0;
public SetReportSemaphoreDReductionOp SetReportSemaphoreDReductionOp => (SetReportSemaphoreDReductionOp)((SetReportSemaphoreD >> 9) & 0x7);
public SetReportSemaphoreDReductionFormat SetReportSemaphoreDReductionFormat => (SetReportSemaphoreDReductionFormat)((SetReportSemaphoreD >> 17) & 0x3);
public fixed uint Reserved1B10[702];
public uint SetBindlessTexture;
public int SetBindlessTextureConstantBufferSlotSelect => (int)((SetBindlessTexture >> 0) & 0x7);
public uint SetTrapHandler;
public fixed uint Reserved2610[843];
public Array8<uint> SetShaderPerformanceCounterValueUpper;
public Array8<uint> SetShaderPerformanceCounterValue;
public Array8<uint> SetShaderPerformanceCounterEvent;
public int SetShaderPerformanceCounterEventEvent(int i) => (int)((SetShaderPerformanceCounterEvent[i] >> 0) & 0xFF);
public Array8<uint> SetShaderPerformanceCounterControlA;
public int SetShaderPerformanceCounterControlAEvent0(int i) => (int)((SetShaderPerformanceCounterControlA[i] >> 0) & 0x3);
public int SetShaderPerformanceCounterControlABitSelect0(int i) => (int)((SetShaderPerformanceCounterControlA[i] >> 2) & 0x7);
public int SetShaderPerformanceCounterControlAEvent1(int i) => (int)((SetShaderPerformanceCounterControlA[i] >> 5) & 0x3);
public int SetShaderPerformanceCounterControlABitSelect1(int i) => (int)((SetShaderPerformanceCounterControlA[i] >> 7) & 0x7);
public int SetShaderPerformanceCounterControlAEvent2(int i) => (int)((SetShaderPerformanceCounterControlA[i] >> 10) & 0x3);
public int SetShaderPerformanceCounterControlABitSelect2(int i) => (int)((SetShaderPerformanceCounterControlA[i] >> 12) & 0x7);
public int SetShaderPerformanceCounterControlAEvent3(int i) => (int)((SetShaderPerformanceCounterControlA[i] >> 15) & 0x3);
public int SetShaderPerformanceCounterControlABitSelect3(int i) => (int)((SetShaderPerformanceCounterControlA[i] >> 17) & 0x7);
public int SetShaderPerformanceCounterControlAEvent4(int i) => (int)((SetShaderPerformanceCounterControlA[i] >> 20) & 0x3);
public int SetShaderPerformanceCounterControlABitSelect4(int i) => (int)((SetShaderPerformanceCounterControlA[i] >> 22) & 0x7);
public int SetShaderPerformanceCounterControlAEvent5(int i) => (int)((SetShaderPerformanceCounterControlA[i] >> 25) & 0x3);
public int SetShaderPerformanceCounterControlABitSelect5(int i) => (int)((SetShaderPerformanceCounterControlA[i] >> 27) & 0x7);
public int SetShaderPerformanceCounterControlASpare(int i) => (int)((SetShaderPerformanceCounterControlA[i] >> 30) & 0x3);
public Array8<uint> SetShaderPerformanceCounterControlB;
public bool SetShaderPerformanceCounterControlBEdge(int i) => (SetShaderPerformanceCounterControlB[i] & 0x1) != 0;
public int SetShaderPerformanceCounterControlBMode(int i) => (int)((SetShaderPerformanceCounterControlB[i] >> 1) & 0x3);
public bool SetShaderPerformanceCounterControlBWindowed(int i) => (SetShaderPerformanceCounterControlB[i] & 0x8) != 0;
public int SetShaderPerformanceCounterControlBFunc(int i) => (int)((SetShaderPerformanceCounterControlB[i] >> 4) & 0xFFFF);
public uint SetShaderPerformanceCounterTrapControl;
public int SetShaderPerformanceCounterTrapControlMask => (int)((SetShaderPerformanceCounterTrapControl >> 0) & 0xFF);
public uint StartShaderPerformanceCounter;
public int StartShaderPerformanceCounterCounterMask => (int)((StartShaderPerformanceCounter >> 0) & 0xFF);
public uint StopShaderPerformanceCounter;
public int StopShaderPerformanceCounterCounterMask => (int)((StopShaderPerformanceCounter >> 0) & 0xFF);
public fixed uint Reserved33E8[6];
public MmeShadowScratch SetMmeShadowScratch;
#pragma warning restore CS0649
}
}

View file

@ -2,7 +2,7 @@ using Ryujinx.Graphics.Gpu.State;
using System;
using System.Runtime.CompilerServices;
namespace Ryujinx.Graphics.Gpu.Engine
namespace Ryujinx.Graphics.Gpu.Engine.Compute
{
/// <summary>
/// Type of the dependent Queue Meta Data.

View file

@ -1,14 +1,28 @@
using Ryujinx.Common;
using Ryujinx.Common;
using Ryujinx.Graphics.Device;
using Ryujinx.Graphics.Gpu.State;
using Ryujinx.Graphics.Texture;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
namespace Ryujinx.Graphics.Gpu.Engine
namespace Ryujinx.Graphics.Gpu.Engine.Dma
{
partial class Methods
/// <summary>
/// Represents a DMA copy engine class.
/// </summary>
class DmaClass : IDeviceState
{
enum CopyFlags
private readonly GpuContext _context;
private readonly GpuChannel _channel;
private readonly DeviceState<DmaClassState> _state;
/// <summary>
/// Copy flags passed on DMA launch.
/// </summary>
[Flags]
private enum CopyFlags
{
SrcLinear = 1 << 7,
DstLinear = 1 << 8,
@ -16,74 +30,111 @@ namespace Ryujinx.Graphics.Gpu.Engine
RemapEnable = 1 << 10
}
/// <summary>
/// Creates a new instance of the DMA copy engine class.
/// </summary>
/// <param name="context">GPU context</param>
/// <param name="channel">GPU channel</param>
public DmaClass(GpuContext context, GpuChannel channel)
{
_context = context;
_channel = channel;
_state = new DeviceState<DmaClassState>(new Dictionary<string, RwCallback>
{
{ nameof(DmaClassState.LaunchDma), new RwCallback(LaunchDma, null) }
});
}
/// <summary>
/// Reads data from the class registers.
/// </summary>
/// <param name="offset">Register byte offset</param>
/// <returns>Data at the specified offset</returns>
public int Read(int offset) => _state.Read(offset);
/// <summary>
/// Writes data to the class registers.
/// </summary>
/// <param name="offset">Register byte offset</param>
/// <param name="data">Data to be written</param>
public void Write(int offset, int data) => _state.Write(offset, data);
/// <summary>
/// Determine if a buffer-to-texture region covers the entirety of a texture.
/// </summary>
/// <param name="cbp">Copy command parameters</param>
/// <param name="tex">Texture to compare</param>
/// <param name="linear">True if the texture is linear, false if block linear</param>
/// <param name="bpp">Texture bytes per pixel</param>
/// <param name="stride">Texture stride</param>
/// <param name="xCount">Number of pixels to be copied</param>
/// <param name="yCount">Number of lines to be copied</param>
/// <returns></returns>
private bool IsTextureCopyComplete(CopyBufferParams cbp, CopyBufferTexture tex, bool linear, int bpp, int stride)
private static bool IsTextureCopyComplete(CopyBufferTexture tex, bool linear, int bpp, int stride, int xCount, int yCount)
{
if (linear)
{
int alignWidth = Constants.StrideAlignment / bpp;
return tex.RegionX == 0 &&
tex.RegionY == 0 &&
stride / bpp == BitUtils.AlignUp(cbp.XCount, alignWidth);
stride / bpp == BitUtils.AlignUp(xCount, alignWidth);
}
else
{
int alignWidth = Constants.GobAlignment / bpp;
return tex.RegionX == 0 &&
tex.RegionY == 0 &&
tex.Width == BitUtils.AlignUp(cbp.XCount, alignWidth) &&
tex.Height == cbp.YCount;
tex.Width == BitUtils.AlignUp(xCount, alignWidth) &&
tex.Height == yCount;
}
}
/// <summary>
/// Performs a buffer to buffer, or buffer to texture copy.
/// </summary>
/// <param name="state">Current GPU state</param>
/// <param name="argument">Method call argument</param>
private void CopyBuffer(GpuState state, int argument)
private void LaunchDma(int argument)
{
var cbp = state.Get<CopyBufferParams>(MethodOffset.CopyBufferParams);
var swizzle = state.Get<CopyBufferSwizzle>(MethodOffset.CopyBufferSwizzle);
var memoryManager = _channel.MemoryManager;
CopyFlags copyFlags = (CopyFlags)argument;
bool srcLinear = copyFlags.HasFlag(CopyFlags.SrcLinear);
bool dstLinear = copyFlags.HasFlag(CopyFlags.DstLinear);
bool copy2D = copyFlags.HasFlag(CopyFlags.MultiLineEnable);
bool remap = copyFlags.HasFlag(CopyFlags.RemapEnable);
bool copy2D = copyFlags.HasFlag(CopyFlags.MultiLineEnable);
bool remap = copyFlags.HasFlag(CopyFlags.RemapEnable);
int size = cbp.XCount;
uint size = _state.State.LineLengthIn;
if (size == 0)
{
return;
}
FlushUboDirty(state.Channel.MemoryManager);
ulong srcGpuVa = ((ulong)_state.State.OffsetInUpperUpper << 32) | _state.State.OffsetInLower;
ulong dstGpuVa = ((ulong)_state.State.OffsetOutUpperUpper << 32) | _state.State.OffsetOutLower;
int xCount = (int)_state.State.LineLengthIn;
int yCount = (int)_state.State.LineCount;
_context.Methods.FlushUboDirty(memoryManager);
if (copy2D)
{
// Buffer to texture copy.
int srcBpp = remap ? swizzle.UnpackSrcComponentsCount() * swizzle.UnpackComponentSize() : 1;
int dstBpp = remap ? swizzle.UnpackDstComponentsCount() * swizzle.UnpackComponentSize() : 1;
int componentSize = (int)_state.State.SetRemapComponentsComponentSize + 1;
int srcBpp = remap ? ((int)_state.State.SetRemapComponentsNumSrcComponents + 1) * componentSize : 1;
int dstBpp = remap ? ((int)_state.State.SetRemapComponentsNumDstComponents + 1) * componentSize : 1;
var dst = state.Get<CopyBufferTexture>(MethodOffset.CopyBufferDstTexture);
var src = state.Get<CopyBufferTexture>(MethodOffset.CopyBufferSrcTexture);
var dst = Unsafe.As<uint, CopyBufferTexture>(ref _state.State.SetDstBlockSize);
var src = Unsafe.As<uint, CopyBufferTexture>(ref _state.State.SetSrcBlockSize);
int srcStride = (int)_state.State.PitchIn;
int dstStride = (int)_state.State.PitchOut;
var srcCalculator = new OffsetCalculator(
src.Width,
src.Height,
cbp.SrcStride,
srcStride,
srcLinear,
src.MemoryLayout.UnpackGobBlocksInY(),
src.MemoryLayout.UnpackGobBlocksInZ(),
@ -92,31 +143,34 @@ namespace Ryujinx.Graphics.Gpu.Engine
var dstCalculator = new OffsetCalculator(
dst.Width,
dst.Height,
cbp.DstStride,
dstStride,
dstLinear,
dst.MemoryLayout.UnpackGobBlocksInY(),
dst.MemoryLayout.UnpackGobBlocksInZ(),
dstBpp);
ulong srcBaseAddress = state.Channel.MemoryManager.Translate(cbp.SrcAddress.Pack());
ulong dstBaseAddress = state.Channel.MemoryManager.Translate(cbp.DstAddress.Pack());
ulong srcBaseAddress = memoryManager.Translate(srcGpuVa);
ulong dstBaseAddress = memoryManager.Translate(dstGpuVa);
(int srcBaseOffset, int srcSize) = srcCalculator.GetRectangleRange(src.RegionX, src.RegionY, cbp.XCount, cbp.YCount);
(int dstBaseOffset, int dstSize) = dstCalculator.GetRectangleRange(dst.RegionX, dst.RegionY, cbp.XCount, cbp.YCount);
(int srcBaseOffset, int srcSize) = srcCalculator.GetRectangleRange(src.RegionX, src.RegionY, xCount, yCount);
(int dstBaseOffset, int dstSize) = dstCalculator.GetRectangleRange(dst.RegionX, dst.RegionY, xCount, yCount);
ReadOnlySpan<byte> srcSpan = state.Channel.MemoryManager.Physical.GetSpan(srcBaseAddress + (ulong)srcBaseOffset, srcSize, true);
Span<byte> dstSpan = state.Channel.MemoryManager.Physical.GetSpan(dstBaseAddress + (ulong)dstBaseOffset, dstSize).ToArray();
ReadOnlySpan<byte> srcSpan = memoryManager.Physical.GetSpan(srcBaseAddress + (ulong)srcBaseOffset, srcSize, true);
Span<byte> dstSpan = memoryManager.Physical.GetSpan(dstBaseAddress + (ulong)dstBaseOffset, dstSize).ToArray();
bool completeSource = IsTextureCopyComplete(cbp, src, srcLinear, srcBpp, cbp.SrcStride);
bool completeDest = IsTextureCopyComplete(cbp, dst, dstLinear, dstBpp, cbp.DstStride);
bool completeSource = IsTextureCopyComplete(src, srcLinear, srcBpp, srcStride, xCount, yCount);
bool completeDest = IsTextureCopyComplete(dst, dstLinear, dstBpp, dstStride, xCount, yCount);
if (completeSource && completeDest)
{
Image.Texture target = state.Channel.MemoryManager.Physical.TextureCache.FindTexture(
state.Channel.MemoryManager,
var target = memoryManager.Physical.TextureCache.FindTexture(
memoryManager,
dst,
cbp,
swizzle,
dstGpuVa,
dstBpp,
dstStride,
xCount,
yCount,
dstLinear);
if (target != null)
@ -129,7 +183,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
target.Info.Height,
1,
1,
cbp.SrcStride,
srcStride,
target.Info.FormatInfo.BytesPerPixel,
srcSpan);
}
@ -160,7 +214,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
{
srcSpan.CopyTo(dstSpan); // No layout conversion has to be performed, just copy the data entirely.
state.Channel.MemoryManager.Physical.Write(dstBaseAddress + (ulong)dstBaseOffset, dstSpan);
memoryManager.Physical.Write(dstBaseAddress + (ulong)dstBaseOffset, dstSpan);
return;
}
@ -173,12 +227,12 @@ namespace Ryujinx.Graphics.Gpu.Engine
byte* dstBase = dstPtr - dstBaseOffset; // Layout offset is relative to the base, so we need to subtract the span's offset.
byte* srcBase = srcPtr - srcBaseOffset;
for (int y = 0; y < cbp.YCount; y++)
for (int y = 0; y < yCount; y++)
{
srcCalculator.SetY(src.RegionY + y);
dstCalculator.SetY(dst.RegionY + y);
for (int x = 0; x < cbp.XCount; x++)
for (int x = 0; x < xCount; x++)
{
int srcOffset = srcCalculator.GetOffset(src.RegionX + x);
int dstOffset = dstCalculator.GetOffset(dst.RegionX + x);
@ -201,37 +255,29 @@ namespace Ryujinx.Graphics.Gpu.Engine
_ => throw new NotSupportedException($"Unable to copy ${srcBpp} bpp pixel format.")
};
state.Channel.MemoryManager.Physical.Write(dstBaseAddress + (ulong)dstBaseOffset, dstSpan);
memoryManager.Physical.Write(dstBaseAddress + (ulong)dstBaseOffset, dstSpan);
}
else
{
if (remap &&
swizzle.UnpackDstX() == BufferSwizzleComponent.ConstA &&
swizzle.UnpackDstY() == BufferSwizzleComponent.ConstA &&
swizzle.UnpackDstZ() == BufferSwizzleComponent.ConstA &&
swizzle.UnpackDstW() == BufferSwizzleComponent.ConstA &&
swizzle.UnpackSrcComponentsCount() == 1 &&
swizzle.UnpackDstComponentsCount() == 1 &&
swizzle.UnpackComponentSize() == 4)
_state.State.SetRemapComponentsDstX == SetRemapComponentsDst.ConstA &&
_state.State.SetRemapComponentsDstY == SetRemapComponentsDst.ConstA &&
_state.State.SetRemapComponentsDstZ == SetRemapComponentsDst.ConstA &&
_state.State.SetRemapComponentsDstW == SetRemapComponentsDst.ConstA &&
_state.State.SetRemapComponentsNumSrcComponents == SetRemapComponentsNumComponents.One &&
_state.State.SetRemapComponentsNumDstComponents == SetRemapComponentsNumComponents.One &&
_state.State.SetRemapComponentsComponentSize == SetRemapComponentsComponentSize.Four)
{
// Fast path for clears when remap is enabled.
state.Channel.MemoryManager.Physical.BufferCache.ClearBuffer(
state.Channel.MemoryManager,
cbp.DstAddress,
(uint)size * 4,
state.Get<uint>(MethodOffset.CopyBufferConstA));
memoryManager.Physical.BufferCache.ClearBuffer(memoryManager, dstGpuVa, size * 4, _state.State.SetRemapConstA);
}
else
{
// TODO: Implement remap functionality.
// Buffer to buffer copy.
state.Channel.MemoryManager.Physical.BufferCache.CopyBuffer(
state.Channel.MemoryManager,
cbp.SrcAddress,
cbp.DstAddress,
(uint)size);
memoryManager.Physical.BufferCache.CopyBuffer(memoryManager, srcGpuVa, dstGpuVa, size);
}
}
}
}
}
}

View file

@ -0,0 +1,271 @@
// This file was auto-generated from NVIDIA official Maxwell definitions.
namespace Ryujinx.Graphics.Gpu.Engine.Dma
{
/// <summary>
/// Physical mode target.
/// </summary>
enum SetPhysModeTarget
{
LocalFb = 0,
CoherentSysmem = 1,
NoncoherentSysmem = 2,
}
/// <summary>
/// DMA data transfer type.
/// </summary>
enum LaunchDmaDataTransferType
{
None = 0,
Pipelined = 1,
NonPipelined = 2,
}
/// <summary>
/// DMA semaphore type.
/// </summary>
enum LaunchDmaSemaphoreType
{
None = 0,
ReleaseOneWordSemaphore = 1,
ReleaseFourWordSemaphore = 2,
}
/// <summary>
/// DMA interrupt type.
/// </summary>
enum LaunchDmaInterruptType
{
None = 0,
Blocking = 1,
NonBlocking = 2,
}
/// <summary>
/// DMA destination memory layout.
/// </summary>
enum LaunchDmaMemoryLayout
{
Blocklinear = 0,
Pitch = 1,
}
/// <summary>
/// DMA type.
/// </summary>
enum LaunchDmaType
{
Virtual = 0,
Physical = 1,
}
/// <summary>
/// DMA semaphore reduction operation.
/// </summary>
enum LaunchDmaSemaphoreReduction
{
Imin = 0,
Imax = 1,
Ixor = 2,
Iand = 3,
Ior = 4,
Iadd = 5,
Inc = 6,
Dec = 7,
Fadd = 10,
}
/// <summary>
/// DMA semaphore reduction signedness.
/// </summary>
enum LaunchDmaSemaphoreReductionSign
{
Signed = 0,
Unsigned = 1,
}
/// <summary>
/// DMA L2 cache bypass.
/// </summary>
enum LaunchDmaBypassL2
{
UsePteSetting = 0,
ForceVolatile = 1,
}
/// <summary>
/// DMA component remapping source component.
/// </summary>
enum SetRemapComponentsDst
{
SrcX = 0,
SrcY = 1,
SrcZ = 2,
SrcW = 3,
ConstA = 4,
ConstB = 5,
NoWrite = 6,
}
/// <summary>
/// DMA component remapping component size.
/// </summary>
enum SetRemapComponentsComponentSize
{
One = 0,
Two = 1,
Three = 2,
Four = 3,
}
/// <summary>
/// DMA component remapping number of components.
/// </summary>
enum SetRemapComponentsNumComponents
{
One = 0,
Two = 1,
Three = 2,
Four = 3,
}
/// <summary>
/// Width in GOBs of the destination texture.
/// </summary>
enum SetBlockSizeWidth
{
QuarterGob = 14,
OneGob = 0,
}
/// <summary>
/// Height in GOBs of the destination texture.
/// </summary>
enum SetBlockSizeHeight
{
OneGob = 0,
TwoGobs = 1,
FourGobs = 2,
EightGobs = 3,
SixteenGobs = 4,
ThirtytwoGobs = 5,
}
/// <summary>
/// Depth in GOBs of the destination texture.
/// </summary>
enum SetBlockSizeDepth
{
OneGob = 0,
TwoGobs = 1,
FourGobs = 2,
EightGobs = 3,
SixteenGobs = 4,
ThirtytwoGobs = 5,
}
/// <summary>
/// Height of a single GOB in lines.
/// </summary>
enum SetBlockSizeGobHeight
{
GobHeightTesla4 = 0,
GobHeightFermi8 = 1,
}
/// <summary>
/// DMA copy class state.
/// </summary>
unsafe struct DmaClassState
{
#pragma warning disable CS0649
public fixed uint Reserved00[64];
public uint Nop;
public fixed uint Reserved104[15];
public uint PmTrigger;
public fixed uint Reserved144[63];
public uint SetSemaphoreA;
public int SetSemaphoreAUpper => (int)((SetSemaphoreA >> 0) & 0xFF);
public uint SetSemaphoreB;
public uint SetSemaphorePayload;
public fixed uint Reserved24C[2];
public uint SetRenderEnableA;
public int SetRenderEnableAUpper => (int)((SetRenderEnableA >> 0) & 0xFF);
public uint SetRenderEnableB;
public uint SetRenderEnableC;
public int SetRenderEnableCMode => (int)((SetRenderEnableC >> 0) & 0x7);
public uint SetSrcPhysMode;
public SetPhysModeTarget SetSrcPhysModeTarget => (SetPhysModeTarget)((SetSrcPhysMode >> 0) & 0x3);
public uint SetDstPhysMode;
public SetPhysModeTarget SetDstPhysModeTarget => (SetPhysModeTarget)((SetDstPhysMode >> 0) & 0x3);
public fixed uint Reserved268[38];
public uint LaunchDma;
public LaunchDmaDataTransferType LaunchDmaDataTransferType => (LaunchDmaDataTransferType)((LaunchDma >> 0) & 0x3);
public bool LaunchDmaFlushEnable => (LaunchDma & 0x4) != 0;
public LaunchDmaSemaphoreType LaunchDmaSemaphoreType => (LaunchDmaSemaphoreType)((LaunchDma >> 3) & 0x3);
public LaunchDmaInterruptType LaunchDmaInterruptType => (LaunchDmaInterruptType)((LaunchDma >> 5) & 0x3);
public LaunchDmaMemoryLayout LaunchDmaSrcMemoryLayout => (LaunchDmaMemoryLayout)((LaunchDma >> 7) & 0x1);
public LaunchDmaMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaMemoryLayout)((LaunchDma >> 8) & 0x1);
public bool LaunchDmaMultiLineEnable => (LaunchDma & 0x200) != 0;
public bool LaunchDmaRemapEnable => (LaunchDma & 0x400) != 0;
public bool LaunchDmaForceRmwdisable => (LaunchDma & 0x800) != 0;
public LaunchDmaType LaunchDmaSrcType => (LaunchDmaType)((LaunchDma >> 12) & 0x1);
public LaunchDmaType LaunchDmaDstType => (LaunchDmaType)((LaunchDma >> 13) & 0x1);
public LaunchDmaSemaphoreReduction LaunchDmaSemaphoreReduction => (LaunchDmaSemaphoreReduction)((LaunchDma >> 14) & 0xF);
public LaunchDmaSemaphoreReductionSign LaunchDmaSemaphoreReductionSign => (LaunchDmaSemaphoreReductionSign)((LaunchDma >> 18) & 0x1);
public bool LaunchDmaSemaphoreReductionEnable => (LaunchDma & 0x80000) != 0;
public LaunchDmaBypassL2 LaunchDmaBypassL2 => (LaunchDmaBypassL2)((LaunchDma >> 20) & 0x1);
public fixed uint Reserved304[63];
public uint OffsetInUpper;
public int OffsetInUpperUpper => (int)((OffsetInUpper >> 0) & 0xFF);
public uint OffsetInLower;
public uint OffsetOutUpper;
public int OffsetOutUpperUpper => (int)((OffsetOutUpper >> 0) & 0xFF);
public uint OffsetOutLower;
public uint PitchIn;
public uint PitchOut;
public uint LineLengthIn;
public uint LineCount;
public fixed uint Reserved420[184];
public uint SetRemapConstA;
public uint SetRemapConstB;
public uint SetRemapComponents;
public SetRemapComponentsDst SetRemapComponentsDstX => (SetRemapComponentsDst)((SetRemapComponents >> 0) & 0x7);
public SetRemapComponentsDst SetRemapComponentsDstY => (SetRemapComponentsDst)((SetRemapComponents >> 4) & 0x7);
public SetRemapComponentsDst SetRemapComponentsDstZ => (SetRemapComponentsDst)((SetRemapComponents >> 8) & 0x7);
public SetRemapComponentsDst SetRemapComponentsDstW => (SetRemapComponentsDst)((SetRemapComponents >> 12) & 0x7);
public SetRemapComponentsComponentSize SetRemapComponentsComponentSize => (SetRemapComponentsComponentSize)((SetRemapComponents >> 16) & 0x3);
public SetRemapComponentsNumComponents SetRemapComponentsNumSrcComponents => (SetRemapComponentsNumComponents)((SetRemapComponents >> 20) & 0x3);
public SetRemapComponentsNumComponents SetRemapComponentsNumDstComponents => (SetRemapComponentsNumComponents)((SetRemapComponents >> 24) & 0x3);
public uint SetDstBlockSize;
public SetBlockSizeWidth SetDstBlockSizeWidth => (SetBlockSizeWidth)((SetDstBlockSize >> 0) & 0xF);
public SetBlockSizeHeight SetDstBlockSizeHeight => (SetBlockSizeHeight)((SetDstBlockSize >> 4) & 0xF);
public SetBlockSizeDepth SetDstBlockSizeDepth => (SetBlockSizeDepth)((SetDstBlockSize >> 8) & 0xF);
public SetBlockSizeGobHeight SetDstBlockSizeGobHeight => (SetBlockSizeGobHeight)((SetDstBlockSize >> 12) & 0xF);
public uint SetDstWidth;
public uint SetDstHeight;
public uint SetDstDepth;
public uint SetDstLayer;
public uint SetDstOrigin;
public int SetDstOriginX => (int)((SetDstOrigin >> 0) & 0xFFFF);
public int SetDstOriginY => (int)((SetDstOrigin >> 16) & 0xFFFF);
public uint Reserved724;
public uint SetSrcBlockSize;
public SetBlockSizeWidth SetSrcBlockSizeWidth => (SetBlockSizeWidth)((SetSrcBlockSize >> 0) & 0xF);
public SetBlockSizeHeight SetSrcBlockSizeHeight => (SetBlockSizeHeight)((SetSrcBlockSize >> 4) & 0xF);
public SetBlockSizeDepth SetSrcBlockSizeDepth => (SetBlockSizeDepth)((SetSrcBlockSize >> 8) & 0xF);
public SetBlockSizeGobHeight SetSrcBlockSizeGobHeight => (SetBlockSizeGobHeight)((SetSrcBlockSize >> 12) & 0xF);
public uint SetSrcWidth;
public uint SetSrcHeight;
public uint SetSrcDepth;
public uint SetSrcLayer;
public uint SetSrcOrigin;
public int SetSrcOriginX => (int)((SetSrcOrigin >> 0) & 0xFFFF);
public int SetSrcOriginY => (int)((SetSrcOrigin >> 16) & 0xFFFF);
public fixed uint Reserved740[629];
public uint PmTriggerEnd;
public fixed uint Reserved1118[2490];
#pragma warning restore CS0649
}
}

View file

@ -4,6 +4,9 @@ using Ryujinx.Common.Memory;
namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
{
/// <summary>
/// Semaphore operation.
/// </summary>
enum SemaphoredOperation
{
Acquire = 1,
@ -13,24 +16,36 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
Reduction = 16
}
/// <summary>
/// Semaphore acquire switch enable.
/// </summary>
enum SemaphoredAcquireSwitch
{
Disabled = 0,
Enabled = 1
}
/// <summary>
/// Semaphore release interrupt wait enable.
/// </summary>
enum SemaphoredReleaseWfi
{
En = 0,
Dis = 1
}
/// <summary>
/// Semaphore release structure size.
/// </summary>
enum SemaphoredReleaseSize
{
SixteenBytes = 0,
FourBytes = 1
}
/// <summary>
/// Semaphore reduction operation.
/// </summary>
enum SemaphoredReduction
{
Min = 0,
@ -43,24 +58,36 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
Dec = 7
}
/// <summary>
/// Semaphore format.
/// </summary>
enum SemaphoredFormat
{
Signed = 0,
Unsigned = 1
}
/// <summary>
/// Memory Translation Lookaside Buffer Page Directory Buffer invalidation.
/// </summary>
enum MemOpCTlbInvalidatePdb
{
One = 0,
All = 1
}
/// <summary>
/// Memory Translation Lookaside Buffer GPC invalidation enable.
/// </summary>
enum MemOpCTlbInvalidateGpc
{
Enable = 0,
Disable = 1
}
/// <summary>
/// Memory Translation Lookaside Buffer invalidation target.
/// </summary>
enum MemOpCTlbInvalidateTarget
{
VidMem = 0,
@ -68,6 +95,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
SysMemNoncoherent = 3
}
/// <summary>
/// Memory operation.
/// </summary>
enum MemOpDOperation
{
Membar = 5,
@ -78,24 +108,36 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
L2FlushDirty = 16
}
/// <summary>
/// Syncpoint operation.
/// </summary>
enum SyncpointbOperation
{
Wait = 0,
Incr = 1
}
/// <summary>
/// Syncpoint wait switch enable.
/// </summary>
enum SyncpointbWaitSwitch
{
Dis = 0,
En = 1
}
/// <summary>
/// Wait for interrupt scope.
/// </summary>
enum WfiScope
{
CurrentScgType = 0,
All = 1
}
/// <summary>
/// Yield operation.
/// </summary>
enum YieldOp
{
Nop = 0,
@ -104,6 +146,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
Tsg = 3
}
/// <summary>
/// General Purpose FIFO class state.
/// </summary>
struct GPFifoClassState
{
#pragma warning disable CS0649

View file

@ -1,4 +1,9 @@
using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Graphics.Device;
using Ryujinx.Graphics.Gpu.Engine.Compute;
using Ryujinx.Graphics.Gpu.Engine.Dma;
using Ryujinx.Graphics.Gpu.Engine.InlineToMemory;
using Ryujinx.Graphics.Gpu.Engine.Twod;
using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Graphics.Gpu.State;
using System;
using System.Runtime.CompilerServices;
@ -33,6 +38,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
private DmaState _state;
private readonly GpuState[] _subChannels;
private readonly IDeviceState[] _subChannels2;
private readonly GPFifoClass _fifoClass;
/// <summary>
@ -47,10 +53,21 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
_fifoClass = new GPFifoClass(context, this);
_subChannels = new GpuState[8];
_subChannels2 = new IDeviceState[8]
{
null,
new ComputeClass(context, channel),
new InlineToMemoryClass(context, channel),
new TwodClass(channel),
new DmaClass(context, channel),
null,
null,
null
};
for (int index = 0; index < _subChannels.Length; index++)
{
_subChannels[index] = new GpuState(channel);
_subChannels[index] = new GpuState(channel, _subChannels2[index]);
_context.Methods.RegisterCallbacks(_subChannels[index]);
}

View file

@ -0,0 +1,211 @@
using Ryujinx.Common;
using Ryujinx.Graphics.Device;
using Ryujinx.Graphics.Texture;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
{
/// <summary>
/// Represents a Inline-to-Memory engine class.
/// </summary>
class InlineToMemoryClass : IDeviceState
{
private readonly GpuContext _context;
private readonly GpuChannel _channel;
private readonly DeviceState<InlineToMemoryClassState> _state;
private bool _isLinear;
private int _offset;
private int _size;
private ulong _dstGpuVa;
private int _dstX;
private int _dstY;
private int _dstWidth;
private int _dstHeight;
private int _dstStride;
private int _dstGobBlocksInY;
private int _lineLengthIn;
private int _lineCount;
private bool _finished;
private int[] _buffer;
/// <summary>
/// Creates a new instance of the Inline-to-Memory engine class.
/// </summary>
/// <param name="context">GPU context</param>
/// <param name="channel">GPU channel</param>
/// <param name="initializeState">Indicates if the internal state should be initialized. Set to false if part of another engine</param>
protected InlineToMemoryClass(GpuContext context, GpuChannel channel, bool initializeState)
{
_context = context;
_channel = channel;
if (initializeState)
{
_state = new DeviceState<InlineToMemoryClassState>(new Dictionary<string, RwCallback>
{
{ nameof(InlineToMemoryClassState.LaunchDma), new RwCallback(LaunchDma, null) },
{ nameof(InlineToMemoryClassState.LoadInlineData), new RwCallback(LoadInlineData, null) }
});
}
}
/// <summary>
/// Creates a new instance of the inline-to-memory engine class.
/// </summary>
/// <param name="context">GPU context</param>
/// <param name="channel">GPU channel</param>
public InlineToMemoryClass(GpuContext context, GpuChannel channel) : this(context, channel, true)
{
}
/// <summary>
/// Reads data from the class registers.
/// </summary>
/// <param name="offset">Register byte offset</param>
/// <returns>Data at the specified offset</returns>
public virtual int Read(int offset) => _state.Read(offset);
/// <summary>
/// Writes data to the class registers.
/// </summary>
/// <param name="offset">Register byte offset</param>
/// <param name="data">Data to be written</param>
public virtual void Write(int offset, int data) => _state.Write(offset, data);
/// <summary>
/// Launches Inline-to-Memory engine DMA copy.
/// </summary>
/// <param name="argument">Method call argument</param>
protected virtual void LaunchDma(int argument)
{
LaunchDma(ref _state.State, argument);
}
/// <summary>
/// Launches Inline-to-Memory engine DMA copy.
/// </summary>
/// <param name="state">Current class state</param>
/// <param name="argument">Method call argument</param>
protected void LaunchDma(ref InlineToMemoryClassState state, int argument)
{
_isLinear = (argument & 1) != 0;
_offset = 0;
_size = (int)(state.LineLengthIn * state.LineCount);
int count = BitUtils.DivRoundUp(_size, 4);
if (_buffer == null || _buffer.Length < count)
{
_buffer = new int[count];
}
ulong dstGpuVa = ((ulong)state.OffsetOutUpperValue << 32) | state.OffsetOut;
ulong dstBaseAddress = _channel.MemoryManager.Translate(dstGpuVa);
// Trigger read tracking, to flush any managed resources in the destination region.
_channel.MemoryManager.Physical.GetSpan(dstBaseAddress, _size, true);
_dstGpuVa = dstGpuVa;
_dstX = state.SetDstOriginBytesXV;
_dstY = state.SetDstOriginSamplesYV;
_dstWidth = (int)state.SetDstWidth;
_dstHeight = (int)state.SetDstHeight;
_dstStride = (int)state.PitchOut;
_dstGobBlocksInY = 1 << (int)state.SetDstBlockSizeHeight;
_lineLengthIn = (int)state.LineLengthIn;
_lineCount = (int)state.LineCount;
_finished = false;
}
/// <summary>
/// Pushes a word of data to the Inline-to-Memory engine.
/// </summary>
/// <param name="argument">Method call argument</param>
protected void LoadInlineData(int argument)
{
if (!_finished)
{
_buffer[_offset++] = argument;
if (_offset * 4 >= _size)
{
FinishTransfer();
}
}
}
/// <summary>
/// Performs actual copy of the inline data after the transfer is finished.
/// </summary>
private void FinishTransfer()
{
Span<byte> data = MemoryMarshal.Cast<int, byte>(_buffer).Slice(0, _size);
if (_isLinear && _lineCount == 1)
{
ulong address = _channel.MemoryManager.Translate(_dstGpuVa);
_channel.MemoryManager.Physical.Write(address, data);
}
else
{
var dstCalculator = new OffsetCalculator(
_dstWidth,
_dstHeight,
_dstStride,
_isLinear,
_dstGobBlocksInY,
1);
int srcOffset = 0;
ulong dstBaseAddress = _channel.MemoryManager.Translate(_dstGpuVa);
for (int y = _dstY; y < _dstY + _lineCount; y++)
{
int x1 = _dstX;
int x2 = _dstX + _lineLengthIn;
int x2Trunc = _dstX + BitUtils.AlignDown(_lineLengthIn, 16);
int x;
for (x = x1; x < x2Trunc; x += 16, srcOffset += 16)
{
int dstOffset = dstCalculator.GetOffset(x, y);
ulong dstAddress = dstBaseAddress + (ulong)dstOffset;
Span<byte> pixel = data.Slice(srcOffset, 16);
_channel.MemoryManager.Physical.Write(dstAddress, pixel);
}
for (; x < x2; x++, srcOffset++)
{
int dstOffset = dstCalculator.GetOffset(x, y);
ulong dstAddress = dstBaseAddress + (ulong)dstOffset;
Span<byte> pixel = data.Slice(srcOffset, 1);
_channel.MemoryManager.Physical.Write(dstAddress, pixel);
}
}
}
_finished = true;
_context.AdvanceSequence();
}
}
}

View file

@ -0,0 +1,181 @@
// This file was auto-generated from NVIDIA official Maxwell definitions.
namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
{
/// <summary>
/// Notify type.
/// </summary>
enum NotifyType
{
WriteOnly = 0,
WriteThenAwaken = 1,
}
/// <summary>
/// Width in GOBs of the destination texture.
/// </summary>
enum SetDstBlockSizeWidth
{
OneGob = 0,
}
/// <summary>
/// Height in GOBs of the destination texture.
/// </summary>
enum SetDstBlockSizeHeight
{
OneGob = 0,
TwoGobs = 1,
FourGobs = 2,
EightGobs = 3,
SixteenGobs = 4,
ThirtytwoGobs = 5,
}
/// <summary>
/// Depth in GOBs of the destination texture.
/// </summary>
enum SetDstBlockSizeDepth
{
OneGob = 0,
TwoGobs = 1,
FourGobs = 2,
EightGobs = 3,
SixteenGobs = 4,
ThirtytwoGobs = 5,
}
/// <summary>
/// Memory layout of the destination texture.
/// </summary>
enum LaunchDmaDstMemoryLayout
{
Blocklinear = 0,
Pitch = 1,
}
/// <summary>
/// DMA completion type.
/// </summary>
enum LaunchDmaCompletionType
{
FlushDisable = 0,
FlushOnly = 1,
ReleaseSemaphore = 2,
}
/// <summary>
/// DMA interrupt type.
/// </summary>
enum LaunchDmaInterruptType
{
None = 0,
Interrupt = 1,
}
/// <summary>
/// DMA semaphore structure size.
/// </summary>
enum LaunchDmaSemaphoreStructSize
{
FourWords = 0,
OneWord = 1,
}
/// <summary>
/// DMA semaphore reduction operation.
/// </summary>
enum LaunchDmaReductionOp
{
RedAdd = 0,
RedMin = 1,
RedMax = 2,
RedInc = 3,
RedDec = 4,
RedAnd = 5,
RedOr = 6,
RedXor = 7,
}
/// <summary>
/// DMA semaphore reduction format.
/// </summary>
enum LaunchDmaReductionFormat
{
Unsigned32 = 0,
Signed32 = 1,
}
/// <summary>
/// Inline-to-Memory class state.
/// </summary>
unsafe struct InlineToMemoryClassState
{
#pragma warning disable CS0649
public uint SetObject;
public int SetObjectClassId => (int)((SetObject >> 0) & 0xFFFF);
public int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
public fixed uint Reserved04[63];
public uint NoOperation;
public uint SetNotifyA;
public int SetNotifyAAddressUpper => (int)((SetNotifyA >> 0) & 0xFF);
public uint SetNotifyB;
public uint Notify;
public NotifyType NotifyType => (NotifyType)(Notify);
public uint WaitForIdle;
public fixed uint Reserved114[7];
public uint SetGlobalRenderEnableA;
public int SetGlobalRenderEnableAOffsetUpper => (int)((SetGlobalRenderEnableA >> 0) & 0xFF);
public uint SetGlobalRenderEnableB;
public uint SetGlobalRenderEnableC;
public int SetGlobalRenderEnableCMode => (int)((SetGlobalRenderEnableC >> 0) & 0x7);
public uint SendGoIdle;
public uint PmTrigger;
public uint PmTriggerWfi;
public fixed uint Reserved148[2];
public uint SetInstrumentationMethodHeader;
public uint SetInstrumentationMethodData;
public fixed uint Reserved158[10];
public uint LineLengthIn;
public uint LineCount;
public uint OffsetOutUpper;
public int OffsetOutUpperValue => (int)((OffsetOutUpper >> 0) & 0xFF);
public uint OffsetOut;
public uint PitchOut;
public uint SetDstBlockSize;
public SetDstBlockSizeWidth SetDstBlockSizeWidth => (SetDstBlockSizeWidth)((SetDstBlockSize >> 0) & 0xF);
public SetDstBlockSizeHeight SetDstBlockSizeHeight => (SetDstBlockSizeHeight)((SetDstBlockSize >> 4) & 0xF);
public SetDstBlockSizeDepth SetDstBlockSizeDepth => (SetDstBlockSizeDepth)((SetDstBlockSize >> 8) & 0xF);
public uint SetDstWidth;
public uint SetDstHeight;
public uint SetDstDepth;
public uint SetDstLayer;
public uint SetDstOriginBytesX;
public int SetDstOriginBytesXV => (int)((SetDstOriginBytesX >> 0) & 0xFFFFF);
public uint SetDstOriginSamplesY;
public int SetDstOriginSamplesYV => (int)((SetDstOriginSamplesY >> 0) & 0xFFFF);
public uint LaunchDma;
public LaunchDmaDstMemoryLayout LaunchDmaDstMemoryLayout => (LaunchDmaDstMemoryLayout)((LaunchDma >> 0) & 0x1);
public LaunchDmaCompletionType LaunchDmaCompletionType => (LaunchDmaCompletionType)((LaunchDma >> 4) & 0x3);
public LaunchDmaInterruptType LaunchDmaInterruptType => (LaunchDmaInterruptType)((LaunchDma >> 8) & 0x3);
public LaunchDmaSemaphoreStructSize LaunchDmaSemaphoreStructSize => (LaunchDmaSemaphoreStructSize)((LaunchDma >> 12) & 0x1);
public bool LaunchDmaReductionEnable => (LaunchDma & 0x2) != 0;
public LaunchDmaReductionOp LaunchDmaReductionOp => (LaunchDmaReductionOp)((LaunchDma >> 13) & 0x7);
public LaunchDmaReductionFormat LaunchDmaReductionFormat => (LaunchDmaReductionFormat)((LaunchDma >> 2) & 0x3);
public bool LaunchDmaSysmembarDisable => (LaunchDma & 0x40) != 0;
public uint LoadInlineData;
public fixed uint Reserved1B8[9];
public uint SetI2mSemaphoreA;
public int SetI2mSemaphoreAOffsetUpper => (int)((SetI2mSemaphoreA >> 0) & 0xFF);
public uint SetI2mSemaphoreB;
public uint SetI2mSemaphoreC;
public fixed uint Reserved1E8[2];
public uint SetI2mSpareNoop00;
public uint SetI2mSpareNoop01;
public uint SetI2mSpareNoop02;
public uint SetI2mSpareNoop03;
public fixed uint Reserved200[3200];
public MmeShadowScratch SetMmeShadowScratch;
#pragma warning restore CS0649
}
}

View file

@ -17,7 +17,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
/// Flushes any queued ubo updates.
/// </summary>
/// <param name="memoryManager">GPU memory manager where the uniform buffer is mapped</param>
private void FlushUboDirty(MemoryManager memoryManager)
public void FlushUboDirty(MemoryManager memoryManager)
{
if (_ubFollowUpAddress != 0)
{

View file

@ -50,13 +50,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
state.RegisterCallback(MethodOffset.LaunchDma, LaunchDma);
state.RegisterCallback(MethodOffset.LoadInlineData, LoadInlineData);
state.RegisterCallback(MethodOffset.Dispatch, Dispatch);
state.RegisterCallback(MethodOffset.SyncpointAction, IncrementSyncpoint);
state.RegisterCallback(MethodOffset.CopyBuffer, CopyBuffer);
state.RegisterCallback(MethodOffset.CopyTexture, CopyTexture);
state.RegisterCallback(MethodOffset.TextureBarrier, TextureBarrier);
state.RegisterCallback(MethodOffset.TextureBarrierTiled, TextureBarrierTiled);
@ -956,24 +951,6 @@ namespace Ryujinx.Graphics.Gpu.Engine
_context.Renderer.Pipeline.SetLogicOpState(logicOpState.Enable, logicOpState.LogicalOp);
}
/// <summary>
/// Storage buffer address and size information.
/// </summary>
private struct SbDescriptor
{
#pragma warning disable CS0649
public uint AddressLow;
public uint AddressHigh;
public int Size;
public int Padding;
#pragma warning restore CS0649
public ulong PackAddress()
{
return AddressLow | ((ulong)AddressHigh << 32);
}
}
/// <summary>
/// Updates host shaders based on the guest GPU state.
/// </summary>
@ -1088,6 +1065,14 @@ namespace Ryujinx.Graphics.Gpu.Engine
_context.Renderer.Pipeline.SetProgram(gs.HostProgram);
}
/// <summary>
/// Forces the shaders to be rebound on the next draw.
/// </summary>
public void ForceShaderUpdate()
{
_forceShaderUpdate = true;
}
/// <summary>
/// Updates transform feedback buffer state based on the guest GPU state.
/// </summary>

View file

@ -0,0 +1,15 @@
using System;
using System.Runtime.InteropServices;
namespace Ryujinx.Graphics.Gpu.Engine
{
[StructLayout(LayoutKind.Sequential, Size = 1024)]
struct MmeShadowScratch
{
#pragma warning disable CS0169
private uint _e0;
#pragma warning restore CS0169
public ref uint this[int index] => ref ToSpan()[index];
public Span<uint> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 256);
}
}

View file

@ -1,35 +1,67 @@
using Ryujinx.Graphics.Device;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu.Image;
using Ryujinx.Graphics.Gpu.State;
using Ryujinx.Graphics.Texture;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace Ryujinx.Graphics.Gpu.Engine
namespace Ryujinx.Graphics.Gpu.Engine.Twod
{
using Texture = Image.Texture;
partial class Methods
/// <summary>
/// Represents a 2D engine class.
/// </summary>
class TwodClass : IDeviceState
{
private readonly GpuChannel _channel;
private readonly DeviceState<TwodClassState> _state;
/// <summary>
/// Performs a texture to texture copy.
/// Creates a new instance of the 2D engine class.
/// </summary>
/// <param name="state">Current GPU state</param>
/// <param name="argument">Method call argument</param>
private void CopyTexture(GpuState state, int argument)
/// <param name="channel">The channel that will make use of the engine</param>
public TwodClass(GpuChannel channel)
{
var memoryManager = state.Channel.MemoryManager;
_channel = channel;
_state = new DeviceState<TwodClassState>(new Dictionary<string, RwCallback>
{
{ nameof(TwodClassState.PixelsFromMemorySrcY0Int), new RwCallback(PixelsFromMemorySrcY0Int, null) }
});
}
var dstCopyTexture = state.Get<CopyTexture>(MethodOffset.CopyDstTexture);
var srcCopyTexture = state.Get<CopyTexture>(MethodOffset.CopySrcTexture);
/// <summary>
/// Reads data from the class registers.
/// </summary>
/// <param name="offset">Register byte offset</param>
/// <returns>Data at the specified offset</returns>
public int Read(int offset) => _state.Read(offset);
var region = state.Get<CopyRegion>(MethodOffset.CopyRegion);
/// <summary>
/// Writes data to the class registers.
/// </summary>
/// <param name="offset">Register byte offset</param>
/// <param name="data">Data to be written</param>
public void Write(int offset, int data) => _state.Write(offset, data);
var control = state.Get<CopyTextureControl>(MethodOffset.CopyTextureControl);
/// <summary>
/// Performs the blit operation, triggered by the register write.
/// </summary>
/// <param name="argument">Method call argument</param>
private void PixelsFromMemorySrcY0Int(int argument)
{
var memoryManager = _channel.MemoryManager;
bool originCorner = control.UnpackOriginCorner();
var dstCopyTexture = Unsafe.As<uint, CopyTexture>(ref _state.State.SetDstFormat);
var srcCopyTexture = Unsafe.As<uint, CopyTexture>(ref _state.State.SetSrcFormat);
long srcX = region.SrcXF;
long srcY = region.SrcYF;
long srcX = ((long)_state.State.SetPixelsFromMemorySrcX0Int << 32) | (long)(ulong)_state.State.SetPixelsFromMemorySrcX0Frac;
long srcY = ((long)_state.State.PixelsFromMemorySrcY0Int << 32) | (long)(ulong)_state.State.SetPixelsFromMemorySrcY0Frac;
long duDx = ((long)_state.State.SetPixelsFromMemoryDuDxInt << 32) | (long)(ulong)_state.State.SetPixelsFromMemoryDuDxFrac;
long dvDy = ((long)_state.State.SetPixelsFromMemoryDvDyInt << 32) | (long)(ulong)_state.State.SetPixelsFromMemoryDvDyFrac;
bool originCorner = _state.State.SetPixelsFromMemorySampleModeOrigin == SetPixelsFromMemorySampleModeOrigin.Corner;
if (originCorner)
{
@ -40,21 +72,21 @@ namespace Ryujinx.Graphics.Gpu.Engine
// The offset is calculated as FactorXY / 2.0, where FactorXY = SrcXY / DstXY,
// so we do the same here by dividing the fixed point value by 2, while
// throwing away the fractional part to avoid rounding errors.
srcX -= (region.SrcWidthRF >> 33) << 32;
srcY -= (region.SrcHeightRF >> 33) << 32;
srcX -= (duDx >> 33) << 32;
srcY -= (dvDy >> 33) << 32;
}
int srcX1 = (int)(srcX >> 32);
int srcY1 = (int)(srcY >> 32);
int srcX2 = srcX1 + (int)((region.SrcWidthRF * region.DstWidth + uint.MaxValue) >> 32);
int srcY2 = srcY1 + (int)((region.SrcHeightRF * region.DstHeight + uint.MaxValue) >> 32);
int srcX2 = srcX1 + (int)((duDx * _state.State.SetPixelsFromMemoryDstWidth + uint.MaxValue) >> 32);
int srcY2 = srcY1 + (int)((dvDy * _state.State.SetPixelsFromMemoryDstHeight + uint.MaxValue) >> 32);
int dstX1 = region.DstX;
int dstY1 = region.DstY;
int dstX1 = (int)_state.State.SetPixelsFromMemoryDstX0;
int dstY1 = (int)_state.State.SetPixelsFromMemoryDstY0;
int dstX2 = region.DstX + region.DstWidth;
int dstY2 = region.DstY + region.DstHeight;
int dstX2 = dstX1 + (int)_state.State.SetPixelsFromMemoryDstWidth;
int dstY2 = dstY1 + (int)_state.State.SetPixelsFromMemoryDstHeight;
// The source and destination textures should at least be as big as the region being requested.
// The hints will only resize within alignment constraints, so out of bound copies won't resize in most cases.
@ -82,7 +114,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
srcX1 = 0;
}
Texture srcTexture = memoryManager.Physical.TextureCache.FindOrCreateTexture(
var srcTexture = memoryManager.Physical.TextureCache.FindOrCreateTexture(
memoryManager,
srcCopyTexture,
offset,
@ -109,7 +141,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
dstCopyTextureFormat = dstCopyTexture.Format.Convert();
}
Texture dstTexture = memoryManager.Physical.TextureCache.FindOrCreateTexture(
var dstTexture = memoryManager.Physical.TextureCache.FindOrCreateTexture(
memoryManager,
dstCopyTexture,
0,
@ -137,11 +169,11 @@ namespace Ryujinx.Graphics.Gpu.Engine
(int)Math.Ceiling(dstScale * (dstX2 / dstTexture.Info.SamplesInX)),
(int)Math.Ceiling(dstScale * (dstY2 / dstTexture.Info.SamplesInY)));
bool linearFilter = control.UnpackLinearFilter();
bool linearFilter = _state.State.SetPixelsFromMemorySampleModeFilter == SetPixelsFromMemorySampleModeFilter.Bilinear;
srcTexture.HostTexture.CopyTo(dstTexture.HostTexture, srcRegion, dstRegion, linearFilter);
dstTexture.SignalModified();
}
}
}
}

View file

@ -0,0 +1,827 @@
// This file was auto-generated from NVIDIA official Maxwell definitions.
using Ryujinx.Common.Memory;
namespace Ryujinx.Graphics.Gpu.Engine.Twod
{
/// <summary>
/// Notify type.
/// </summary>
enum NotifyType
{
WriteOnly = 0,
WriteThenAwaken = 1,
}
/// <summary>
/// MME shadow RAM control mode.
/// </summary>
enum SetMmeShadowRamControlMode
{
MethodTrack = 0,
MethodTrackWithFilter = 1,
MethodPassthrough = 2,
MethodReplay = 3,
}
/// <summary>
/// Format of the destination texture.
/// </summary>
enum SetDstFormatV
{
A8r8g8b8 = 207,
A8rl8gl8bl8 = 208,
A2r10g10b10 = 223,
A8b8g8r8 = 213,
A8bl8gl8rl8 = 214,
A2b10g10r10 = 209,
X8r8g8b8 = 230,
X8rl8gl8bl8 = 231,
X8b8g8r8 = 249,
X8bl8gl8rl8 = 250,
R5g6b5 = 232,
A1r5g5b5 = 233,
X1r5g5b5 = 248,
Y8 = 243,
Y16 = 238,
Y32 = 255,
Z1r5g5b5 = 251,
O1r5g5b5 = 252,
Z8r8g8b8 = 253,
O8r8g8b8 = 254,
Y18x8 = 28,
Rf16 = 242,
Rf32 = 229,
Rf32Gf32 = 203,
Rf16Gf16Bf16Af16 = 202,
Rf16Gf16Bf16X16 = 206,
Rf32Gf32Bf32Af32 = 192,
Rf32Gf32Bf32X32 = 195,
R16G16B16A16 = 198,
Rn16Gn16Bn16An16 = 199,
Bf10gf11rf11 = 224,
An8bn8gn8rn8 = 215,
Rf16Gf16 = 222,
R16G16 = 218,
Rn16Gn16 = 219,
G8r8 = 234,
Gn8rn8 = 235,
Rn16 = 239,
Rn8 = 244,
A8 = 247,
}
/// <summary>
/// Memory layout of the destination texture.
/// </summary>
enum SetDstMemoryLayoutV
{
Blocklinear = 0,
Pitch = 1,
}
/// <summary>
/// Height in GOBs of the destination texture.
/// </summary>
enum SetDstBlockSizeHeight
{
OneGob = 0,
TwoGobs = 1,
FourGobs = 2,
EightGobs = 3,
SixteenGobs = 4,
ThirtytwoGobs = 5,
}
/// <summary>
/// Depth in GOBs of the destination texture.
/// </summary>
enum SetDstBlockSizeDepth
{
OneGob = 0,
TwoGobs = 1,
FourGobs = 2,
EightGobs = 3,
SixteenGobs = 4,
ThirtytwoGobs = 5,
}
/// <summary>
/// Format of the source texture.
/// </summary>
enum SetSrcFormatV
{
A8r8g8b8 = 207,
A8rl8gl8bl8 = 208,
A2r10g10b10 = 223,
A8b8g8r8 = 213,
A8bl8gl8rl8 = 214,
A2b10g10r10 = 209,
X8r8g8b8 = 230,
X8rl8gl8bl8 = 231,
X8b8g8r8 = 249,
X8bl8gl8rl8 = 250,
R5g6b5 = 232,
A1r5g5b5 = 233,
X1r5g5b5 = 248,
Y8 = 243,
Ay8 = 29,
Y16 = 238,
Y32 = 255,
Z1r5g5b5 = 251,
O1r5g5b5 = 252,
Z8r8g8b8 = 253,
O8r8g8b8 = 254,
Y18x8 = 28,
Rf16 = 242,
Rf32 = 229,
Rf32Gf32 = 203,
Rf16Gf16Bf16Af16 = 202,
Rf16Gf16Bf16X16 = 206,
Rf32Gf32Bf32Af32 = 192,
Rf32Gf32Bf32X32 = 195,
R16G16B16A16 = 198,
Rn16Gn16Bn16An16 = 199,
Bf10gf11rf11 = 224,
An8bn8gn8rn8 = 215,
Rf16Gf16 = 222,
R16G16 = 218,
Rn16Gn16 = 219,
G8r8 = 234,
Gn8rn8 = 235,
Rn16 = 239,
Rn8 = 244,
A8 = 247,
}
/// <summary>
/// Memory layout of the source texture.
/// </summary>
enum SetSrcMemoryLayoutV
{
Blocklinear = 0,
Pitch = 1,
}
/// <summary>
/// Height in GOBs of the source texture.
/// </summary>
enum SetSrcBlockSizeHeight
{
OneGob = 0,
TwoGobs = 1,
FourGobs = 2,
EightGobs = 3,
SixteenGobs = 4,
ThirtytwoGobs = 5,
}
/// <summary>
/// Depth in GOBs of the source texture.
/// </summary>
enum SetSrcBlockSizeDepth
{
OneGob = 0,
TwoGobs = 1,
FourGobs = 2,
EightGobs = 3,
SixteenGobs = 4,
ThirtytwoGobs = 5,
}
/// <summary>
/// Texture data caches to invalidate.
/// </summary>
enum TwodInvalidateTextureDataCacheV
{
L1Only = 0,
L2Only = 1,
L1AndL2 = 2,
}
/// <summary>
/// Sector promotion parameters.
/// </summary>
enum SetPixelsFromMemorySectorPromotionV
{
NoPromotion = 0,
PromoteTo2V = 1,
PromoteTo2H = 2,
PromoteTo4 = 3,
}
/// <summary>
/// Number of processing clusters.
/// </summary>
enum SetNumProcessingClustersV
{
All = 0,
One = 1,
}
/// <summary>
/// Color key format.
/// </summary>
enum SetColorKeyFormatV
{
A16r5g6b5 = 0,
A1r5g5b5 = 1,
A8r8g8b8 = 2,
A2r10g10b10 = 3,
Y8 = 4,
Y16 = 5,
Y32 = 6,
}
/// <summary>
/// Color blit operation.
/// </summary>
enum SetOperationV
{
SrccopyAnd = 0,
RopAnd = 1,
BlendAnd = 2,
Srccopy = 3,
Rop = 4,
SrccopyPremult = 5,
BlendPremult = 6,
}
/// <summary>
/// Texture pattern selection.
/// </summary>
enum SetPatternSelectV
{
Monochrome8x8 = 0,
Monochrome64x1 = 1,
Monochrome1x64 = 2,
Color = 3,
}
/// <summary>
/// Render enable override mode.
/// </summary>
enum SetRenderEnableOverrideMode
{
UseRenderEnable = 0,
AlwaysRender = 1,
NeverRender = 2,
}
/// <summary>
/// Pixels from memory horizontal direction.
/// </summary>
enum SetPixelsFromMemoryDirectionHorizontal
{
HwDecides = 0,
LeftToRight = 1,
RightToLeft = 2,
}
/// <summary>
/// Pixels from memory vertical direction.
/// </summary>
enum SetPixelsFromMemoryDirectionVertical
{
HwDecides = 0,
TopToBottom = 1,
BottomToTop = 2,
}
/// <summary>
/// Color format of the monochrome pattern.
/// </summary>
enum SetMonochromePatternColorFormatV
{
A8x8r5g6b5 = 0,
A1r5g5b5 = 1,
A8r8g8b8 = 2,
A8y8 = 3,
A8x8y16 = 4,
Y32 = 5,
ByteExpand = 6,
}
/// <summary>
/// Format of the monochrome pattern.
/// </summary>
enum SetMonochromePatternFormatV
{
Cga6M1 = 0,
LeM1 = 1,
}
/// <summary>
/// DMA semaphore reduction operation.
/// </summary>
enum MmeDmaReductionReductionOp
{
RedAdd = 0,
RedMin = 1,
RedMax = 2,
RedInc = 3,
RedDec = 4,
RedAnd = 5,
RedOr = 6,
RedXor = 7,
}
/// <summary>
/// DMA semaphore reduction format.
/// </summary>
enum MmeDmaReductionReductionFormat
{
Unsigned = 0,
Signed = 1,
}
/// <summary>
/// DMA semaphore reduction size.
/// </summary>
enum MmeDmaReductionReductionSize
{
FourBytes = 0,
EightBytes = 1,
}
/// <summary>
/// Data FIFO size.
/// </summary>
enum SetMmeDataFifoConfigFifoSize
{
Size0kb = 0,
Size4kb = 1,
Size8kb = 2,
Size12kb = 3,
Size16kb = 4,
}
/// <summary>
/// Render solid primitive mode.
/// </summary>
enum RenderSolidPrimModeV
{
Points = 0,
Lines = 1,
Polyline = 2,
Triangles = 3,
Rects = 4,
}
/// <summary>
/// Render solid primitive color format.
/// </summary>
enum SetRenderSolidPrimColorFormatV
{
Rf32Gf32Bf32Af32 = 192,
Rf16Gf16Bf16Af16 = 202,
Rf32Gf32 = 203,
A8r8g8b8 = 207,
A2r10g10b10 = 223,
A8b8g8r8 = 213,
A2b10g10r10 = 209,
X8r8g8b8 = 230,
X8b8g8r8 = 249,
R5g6b5 = 232,
A1r5g5b5 = 233,
X1r5g5b5 = 248,
Y8 = 243,
Y16 = 238,
Y32 = 255,
Z1r5g5b5 = 251,
O1r5g5b5 = 252,
Z8r8g8b8 = 253,
O8r8g8b8 = 254,
}
/// <summary>
/// Pixels from CPU data type.
/// </summary>
enum SetPixelsFromCpuDataTypeV
{
Color = 0,
Index = 1,
}
/// <summary>
/// Pixels from CPU color format.
/// </summary>
enum SetPixelsFromCpuColorFormatV
{
A8r8g8b8 = 207,
A2r10g10b10 = 223,
A8b8g8r8 = 213,
A2b10g10r10 = 209,
X8r8g8b8 = 230,
X8b8g8r8 = 249,
R5g6b5 = 232,
A1r5g5b5 = 233,
X1r5g5b5 = 248,
Y8 = 243,
Y16 = 238,
Y32 = 255,
Z1r5g5b5 = 251,
O1r5g5b5 = 252,
Z8r8g8b8 = 253,
O8r8g8b8 = 254,
}
/// <summary>
/// Pixels from CPU palette index format.
/// </summary>
enum SetPixelsFromCpuIndexFormatV
{
I1 = 0,
I4 = 1,
I8 = 2,
}
/// <summary>
/// Pixels from CPU monochrome format.
/// </summary>
enum SetPixelsFromCpuMonoFormatV
{
Cga6M1 = 0,
LeM1 = 1,
}
/// <summary>
/// Pixels from CPU wrap mode.
/// </summary>
enum SetPixelsFromCpuWrapV
{
WrapPixel = 0,
WrapByte = 1,
WrapDword = 2,
}
/// <summary>
/// Pixels from CPU monochrome opacity.
/// </summary>
enum SetPixelsFromCpuMonoOpacityV
{
Transparent = 0,
Opaque = 1,
}
/// <summary>
/// Pixels from memory block shape.
/// </summary>
enum SetPixelsFromMemoryBlockShapeV
{
Auto = 0,
Shape8x8 = 1,
Shape16x4 = 2,
}
/// <summary>
/// Pixels from memory origin.
/// </summary>
enum SetPixelsFromMemorySampleModeOrigin
{
Center = 0,
Corner = 1,
}
/// <summary>
/// Pixels from memory filter mode.
/// </summary>
enum SetPixelsFromMemorySampleModeFilter
{
Point = 0,
Bilinear = 1,
}
/// <summary>
/// Render solid primitive point coordinates.
/// </summary>
struct RenderSolidPrimPoint
{
#pragma warning disable CS0649
public uint SetX;
public uint Y;
#pragma warning restore CS0649
}
/// <summary>
/// 2D class state.
/// </summary>
unsafe struct TwodClassState
{
#pragma warning disable CS0649
public uint SetObject;
public int SetObjectClassId => (int)((SetObject >> 0) & 0xFFFF);
public int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
public fixed uint Reserved04[63];
public uint NoOperation;
public uint SetNotifyA;
public int SetNotifyAAddressUpper => (int)((SetNotifyA >> 0) & 0x1FFFFFF);
public uint SetNotifyB;
public uint Notify;
public NotifyType NotifyType => (NotifyType)(Notify);
public uint WaitForIdle;
public uint LoadMmeInstructionRamPointer;
public uint LoadMmeInstructionRam;
public uint LoadMmeStartAddressRamPointer;
public uint LoadMmeStartAddressRam;
public uint SetMmeShadowRamControl;
public SetMmeShadowRamControlMode SetMmeShadowRamControlMode => (SetMmeShadowRamControlMode)((SetMmeShadowRamControl >> 0) & 0x3);
public fixed uint Reserved128[2];
public uint SetGlobalRenderEnableA;
public int SetGlobalRenderEnableAOffsetUpper => (int)((SetGlobalRenderEnableA >> 0) & 0xFF);
public uint SetGlobalRenderEnableB;
public uint SetGlobalRenderEnableC;
public int SetGlobalRenderEnableCMode => (int)((SetGlobalRenderEnableC >> 0) & 0x7);
public uint SendGoIdle;
public uint PmTrigger;
public fixed uint Reserved144[3];
public uint SetInstrumentationMethodHeader;
public uint SetInstrumentationMethodData;
public fixed uint Reserved158[37];
public uint SetMmeSwitchState;
public bool SetMmeSwitchStateValid => (SetMmeSwitchState & 0x1) != 0;
public int SetMmeSwitchStateSaveMacro => (int)((SetMmeSwitchState >> 4) & 0xFF);
public int SetMmeSwitchStateRestoreMacro => (int)((SetMmeSwitchState >> 12) & 0xFF);
public fixed uint Reserved1F0[4];
public uint SetDstFormat;
public SetDstFormatV SetDstFormatV => (SetDstFormatV)((SetDstFormat >> 0) & 0xFF);
public uint SetDstMemoryLayout;
public SetDstMemoryLayoutV SetDstMemoryLayoutV => (SetDstMemoryLayoutV)((SetDstMemoryLayout >> 0) & 0x1);
public uint SetDstBlockSize;
public SetDstBlockSizeHeight SetDstBlockSizeHeight => (SetDstBlockSizeHeight)((SetDstBlockSize >> 4) & 0x7);
public SetDstBlockSizeDepth SetDstBlockSizeDepth => (SetDstBlockSizeDepth)((SetDstBlockSize >> 8) & 0x7);
public uint SetDstDepth;
public uint SetDstLayer;
public uint SetDstPitch;
public uint SetDstWidth;
public uint SetDstHeight;
public uint SetDstOffsetUpper;
public int SetDstOffsetUpperV => (int)((SetDstOffsetUpper >> 0) & 0xFF);
public uint SetDstOffsetLower;
public uint FlushAndInvalidateRopMiniCache;
public bool FlushAndInvalidateRopMiniCacheV => (FlushAndInvalidateRopMiniCache & 0x1) != 0;
public uint SetSpareNoop06;
public uint SetSrcFormat;
public SetSrcFormatV SetSrcFormatV => (SetSrcFormatV)((SetSrcFormat >> 0) & 0xFF);
public uint SetSrcMemoryLayout;
public SetSrcMemoryLayoutV SetSrcMemoryLayoutV => (SetSrcMemoryLayoutV)((SetSrcMemoryLayout >> 0) & 0x1);
public uint SetSrcBlockSize;
public SetSrcBlockSizeHeight SetSrcBlockSizeHeight => (SetSrcBlockSizeHeight)((SetSrcBlockSize >> 4) & 0x7);
public SetSrcBlockSizeDepth SetSrcBlockSizeDepth => (SetSrcBlockSizeDepth)((SetSrcBlockSize >> 8) & 0x7);
public uint SetSrcDepth;
public uint TwodInvalidateTextureDataCache;
public TwodInvalidateTextureDataCacheV TwodInvalidateTextureDataCacheV => (TwodInvalidateTextureDataCacheV)((TwodInvalidateTextureDataCache >> 0) & 0x3);
public uint SetSrcPitch;
public uint SetSrcWidth;
public uint SetSrcHeight;
public uint SetSrcOffsetUpper;
public int SetSrcOffsetUpperV => (int)((SetSrcOffsetUpper >> 0) & 0xFF);
public uint SetSrcOffsetLower;
public uint SetPixelsFromMemorySectorPromotion;
public SetPixelsFromMemorySectorPromotionV SetPixelsFromMemorySectorPromotionV => (SetPixelsFromMemorySectorPromotionV)((SetPixelsFromMemorySectorPromotion >> 0) & 0x3);
public uint SetSpareNoop12;
public uint SetNumProcessingClusters;
public SetNumProcessingClustersV SetNumProcessingClustersV => (SetNumProcessingClustersV)((SetNumProcessingClusters >> 0) & 0x1);
public uint SetRenderEnableA;
public int SetRenderEnableAOffsetUpper => (int)((SetRenderEnableA >> 0) & 0xFF);
public uint SetRenderEnableB;
public uint SetRenderEnableC;
public int SetRenderEnableCMode => (int)((SetRenderEnableC >> 0) & 0x7);
public uint SetSpareNoop08;
public uint SetSpareNoop01;
public uint SetSpareNoop11;
public uint SetSpareNoop07;
public uint SetClipX0;
public uint SetClipY0;
public uint SetClipWidth;
public uint SetClipHeight;
public uint SetClipEnable;
public bool SetClipEnableV => (SetClipEnable & 0x1) != 0;
public uint SetColorKeyFormat;
public SetColorKeyFormatV SetColorKeyFormatV => (SetColorKeyFormatV)((SetColorKeyFormat >> 0) & 0x7);
public uint SetColorKey;
public uint SetColorKeyEnable;
public bool SetColorKeyEnableV => (SetColorKeyEnable & 0x1) != 0;
public uint SetRop;
public int SetRopV => (int)((SetRop >> 0) & 0xFF);
public uint SetBeta1;
public uint SetBeta4;
public int SetBeta4B => (int)((SetBeta4 >> 0) & 0xFF);
public int SetBeta4G => (int)((SetBeta4 >> 8) & 0xFF);
public int SetBeta4R => (int)((SetBeta4 >> 16) & 0xFF);
public int SetBeta4A => (int)((SetBeta4 >> 24) & 0xFF);
public uint SetOperation;
public SetOperationV SetOperationV => (SetOperationV)((SetOperation >> 0) & 0x7);
public uint SetPatternOffset;
public int SetPatternOffsetX => (int)((SetPatternOffset >> 0) & 0x3F);
public int SetPatternOffsetY => (int)((SetPatternOffset >> 8) & 0x3F);
public uint SetPatternSelect;
public SetPatternSelectV SetPatternSelectV => (SetPatternSelectV)((SetPatternSelect >> 0) & 0x3);
public uint SetDstColorRenderToZetaSurface;
public bool SetDstColorRenderToZetaSurfaceV => (SetDstColorRenderToZetaSurface & 0x1) != 0;
public uint SetSpareNoop04;
public uint SetSpareNoop15;
public uint SetSpareNoop13;
public uint SetSpareNoop03;
public uint SetSpareNoop14;
public uint SetSpareNoop02;
public uint SetCompression;
public bool SetCompressionEnable => (SetCompression & 0x1) != 0;
public uint SetSpareNoop09;
public uint SetRenderEnableOverride;
public SetRenderEnableOverrideMode SetRenderEnableOverrideMode => (SetRenderEnableOverrideMode)((SetRenderEnableOverride >> 0) & 0x3);
public uint SetPixelsFromMemoryDirection;
public SetPixelsFromMemoryDirectionHorizontal SetPixelsFromMemoryDirectionHorizontal => (SetPixelsFromMemoryDirectionHorizontal)((SetPixelsFromMemoryDirection >> 0) & 0x3);
public SetPixelsFromMemoryDirectionVertical SetPixelsFromMemoryDirectionVertical => (SetPixelsFromMemoryDirectionVertical)((SetPixelsFromMemoryDirection >> 4) & 0x3);
public uint SetSpareNoop10;
public uint SetMonochromePatternColorFormat;
public SetMonochromePatternColorFormatV SetMonochromePatternColorFormatV => (SetMonochromePatternColorFormatV)((SetMonochromePatternColorFormat >> 0) & 0x7);
public uint SetMonochromePatternFormat;
public SetMonochromePatternFormatV SetMonochromePatternFormatV => (SetMonochromePatternFormatV)((SetMonochromePatternFormat >> 0) & 0x1);
public uint SetMonochromePatternColor0;
public uint SetMonochromePatternColor1;
public uint SetMonochromePattern0;
public uint SetMonochromePattern1;
public Array64<uint> ColorPatternX8r8g8b8;
public int ColorPatternX8r8g8b8B0(int i) => (int)((ColorPatternX8r8g8b8[i] >> 0) & 0xFF);
public int ColorPatternX8r8g8b8G0(int i) => (int)((ColorPatternX8r8g8b8[i] >> 8) & 0xFF);
public int ColorPatternX8r8g8b8R0(int i) => (int)((ColorPatternX8r8g8b8[i] >> 16) & 0xFF);
public int ColorPatternX8r8g8b8Ignore0(int i) => (int)((ColorPatternX8r8g8b8[i] >> 24) & 0xFF);
public Array32<uint> ColorPatternR5g6b5;
public int ColorPatternR5g6b5B0(int i) => (int)((ColorPatternR5g6b5[i] >> 0) & 0x1F);
public int ColorPatternR5g6b5G0(int i) => (int)((ColorPatternR5g6b5[i] >> 5) & 0x3F);
public int ColorPatternR5g6b5R0(int i) => (int)((ColorPatternR5g6b5[i] >> 11) & 0x1F);
public int ColorPatternR5g6b5B1(int i) => (int)((ColorPatternR5g6b5[i] >> 16) & 0x1F);
public int ColorPatternR5g6b5G1(int i) => (int)((ColorPatternR5g6b5[i] >> 21) & 0x3F);
public int ColorPatternR5g6b5R1(int i) => (int)((ColorPatternR5g6b5[i] >> 27) & 0x1F);
public Array32<uint> ColorPatternX1r5g5b5;
public int ColorPatternX1r5g5b5B0(int i) => (int)((ColorPatternX1r5g5b5[i] >> 0) & 0x1F);
public int ColorPatternX1r5g5b5G0(int i) => (int)((ColorPatternX1r5g5b5[i] >> 5) & 0x1F);
public int ColorPatternX1r5g5b5R0(int i) => (int)((ColorPatternX1r5g5b5[i] >> 10) & 0x1F);
public bool ColorPatternX1r5g5b5Ignore0(int i) => (ColorPatternX1r5g5b5[i] & 0x8000) != 0;
public int ColorPatternX1r5g5b5B1(int i) => (int)((ColorPatternX1r5g5b5[i] >> 16) & 0x1F);
public int ColorPatternX1r5g5b5G1(int i) => (int)((ColorPatternX1r5g5b5[i] >> 21) & 0x1F);
public int ColorPatternX1r5g5b5R1(int i) => (int)((ColorPatternX1r5g5b5[i] >> 26) & 0x1F);
public bool ColorPatternX1r5g5b5Ignore1(int i) => (ColorPatternX1r5g5b5[i] & 0x80000000) != 0;
public Array16<uint> ColorPatternY8;
public int ColorPatternY8Y0(int i) => (int)((ColorPatternY8[i] >> 0) & 0xFF);
public int ColorPatternY8Y1(int i) => (int)((ColorPatternY8[i] >> 8) & 0xFF);
public int ColorPatternY8Y2(int i) => (int)((ColorPatternY8[i] >> 16) & 0xFF);
public int ColorPatternY8Y3(int i) => (int)((ColorPatternY8[i] >> 24) & 0xFF);
public uint SetRenderSolidPrimColor0;
public uint SetRenderSolidPrimColor1;
public uint SetRenderSolidPrimColor2;
public uint SetRenderSolidPrimColor3;
public uint SetMmeMemAddressA;
public int SetMmeMemAddressAUpper => (int)((SetMmeMemAddressA >> 0) & 0x1FFFFFF);
public uint SetMmeMemAddressB;
public uint SetMmeDataRamAddress;
public uint MmeDmaRead;
public uint MmeDmaReadFifoed;
public uint MmeDmaWrite;
public uint MmeDmaReduction;
public MmeDmaReductionReductionOp MmeDmaReductionReductionOp => (MmeDmaReductionReductionOp)((MmeDmaReduction >> 0) & 0x7);
public MmeDmaReductionReductionFormat MmeDmaReductionReductionFormat => (MmeDmaReductionReductionFormat)((MmeDmaReduction >> 4) & 0x3);
public MmeDmaReductionReductionSize MmeDmaReductionReductionSize => (MmeDmaReductionReductionSize)((MmeDmaReduction >> 8) & 0x1);
public uint MmeDmaSysmembar;
public bool MmeDmaSysmembarV => (MmeDmaSysmembar & 0x1) != 0;
public uint MmeDmaSync;
public uint SetMmeDataFifoConfig;
public SetMmeDataFifoConfigFifoSize SetMmeDataFifoConfigFifoSize => (SetMmeDataFifoConfigFifoSize)((SetMmeDataFifoConfig >> 0) & 0x7);
public fixed uint Reserved578[2];
public uint RenderSolidPrimMode;
public RenderSolidPrimModeV RenderSolidPrimModeV => (RenderSolidPrimModeV)((RenderSolidPrimMode >> 0) & 0x7);
public uint SetRenderSolidPrimColorFormat;
public SetRenderSolidPrimColorFormatV SetRenderSolidPrimColorFormatV => (SetRenderSolidPrimColorFormatV)((SetRenderSolidPrimColorFormat >> 0) & 0xFF);
public uint SetRenderSolidPrimColor;
public uint SetRenderSolidLineTieBreakBits;
public bool SetRenderSolidLineTieBreakBitsXmajXincYinc => (SetRenderSolidLineTieBreakBits & 0x1) != 0;
public bool SetRenderSolidLineTieBreakBitsXmajXdecYinc => (SetRenderSolidLineTieBreakBits & 0x10) != 0;
public bool SetRenderSolidLineTieBreakBitsYmajXincYinc => (SetRenderSolidLineTieBreakBits & 0x100) != 0;
public bool SetRenderSolidLineTieBreakBitsYmajXdecYinc => (SetRenderSolidLineTieBreakBits & 0x1000) != 0;
public fixed uint Reserved590[20];
public uint RenderSolidPrimPointXY;
public int RenderSolidPrimPointXYX => (int)((RenderSolidPrimPointXY >> 0) & 0xFFFF);
public int RenderSolidPrimPointXYY => (int)((RenderSolidPrimPointXY >> 16) & 0xFFFF);
public fixed uint Reserved5E4[7];
public Array64<RenderSolidPrimPoint> RenderSolidPrimPoint;
public uint SetPixelsFromCpuDataType;
public SetPixelsFromCpuDataTypeV SetPixelsFromCpuDataTypeV => (SetPixelsFromCpuDataTypeV)((SetPixelsFromCpuDataType >> 0) & 0x1);
public uint SetPixelsFromCpuColorFormat;
public SetPixelsFromCpuColorFormatV SetPixelsFromCpuColorFormatV => (SetPixelsFromCpuColorFormatV)((SetPixelsFromCpuColorFormat >> 0) & 0xFF);
public uint SetPixelsFromCpuIndexFormat;
public SetPixelsFromCpuIndexFormatV SetPixelsFromCpuIndexFormatV => (SetPixelsFromCpuIndexFormatV)((SetPixelsFromCpuIndexFormat >> 0) & 0x3);
public uint SetPixelsFromCpuMonoFormat;
public SetPixelsFromCpuMonoFormatV SetPixelsFromCpuMonoFormatV => (SetPixelsFromCpuMonoFormatV)((SetPixelsFromCpuMonoFormat >> 0) & 0x1);
public uint SetPixelsFromCpuWrap;
public SetPixelsFromCpuWrapV SetPixelsFromCpuWrapV => (SetPixelsFromCpuWrapV)((SetPixelsFromCpuWrap >> 0) & 0x3);
public uint SetPixelsFromCpuColor0;
public uint SetPixelsFromCpuColor1;
public uint SetPixelsFromCpuMonoOpacity;
public SetPixelsFromCpuMonoOpacityV SetPixelsFromCpuMonoOpacityV => (SetPixelsFromCpuMonoOpacityV)((SetPixelsFromCpuMonoOpacity >> 0) & 0x1);
public fixed uint Reserved820[6];
public uint SetPixelsFromCpuSrcWidth;
public uint SetPixelsFromCpuSrcHeight;
public uint SetPixelsFromCpuDxDuFrac;
public uint SetPixelsFromCpuDxDuInt;
public uint SetPixelsFromCpuDyDvFrac;
public uint SetPixelsFromCpuDyDvInt;
public uint SetPixelsFromCpuDstX0Frac;
public uint SetPixelsFromCpuDstX0Int;
public uint SetPixelsFromCpuDstY0Frac;
public uint SetPixelsFromCpuDstY0Int;
public uint PixelsFromCpuData;
public fixed uint Reserved864[3];
public uint SetBigEndianControl;
public bool SetBigEndianControlX32Swap1 => (SetBigEndianControl & 0x1) != 0;
public bool SetBigEndianControlX32Swap4 => (SetBigEndianControl & 0x2) != 0;
public bool SetBigEndianControlX32Swap8 => (SetBigEndianControl & 0x4) != 0;
public bool SetBigEndianControlX32Swap16 => (SetBigEndianControl & 0x8) != 0;
public bool SetBigEndianControlX16Swap1 => (SetBigEndianControl & 0x10) != 0;
public bool SetBigEndianControlX16Swap4 => (SetBigEndianControl & 0x20) != 0;
public bool SetBigEndianControlX16Swap8 => (SetBigEndianControl & 0x40) != 0;
public bool SetBigEndianControlX16Swap16 => (SetBigEndianControl & 0x80) != 0;
public bool SetBigEndianControlX8Swap1 => (SetBigEndianControl & 0x100) != 0;
public bool SetBigEndianControlX8Swap4 => (SetBigEndianControl & 0x200) != 0;
public bool SetBigEndianControlX8Swap8 => (SetBigEndianControl & 0x400) != 0;
public bool SetBigEndianControlX8Swap16 => (SetBigEndianControl & 0x800) != 0;
public bool SetBigEndianControlI1X8Cga6Swap1 => (SetBigEndianControl & 0x1000) != 0;
public bool SetBigEndianControlI1X8Cga6Swap4 => (SetBigEndianControl & 0x2000) != 0;
public bool SetBigEndianControlI1X8Cga6Swap8 => (SetBigEndianControl & 0x4000) != 0;
public bool SetBigEndianControlI1X8Cga6Swap16 => (SetBigEndianControl & 0x8000) != 0;
public bool SetBigEndianControlI1X8LeSwap1 => (SetBigEndianControl & 0x10000) != 0;
public bool SetBigEndianControlI1X8LeSwap4 => (SetBigEndianControl & 0x20000) != 0;
public bool SetBigEndianControlI1X8LeSwap8 => (SetBigEndianControl & 0x40000) != 0;
public bool SetBigEndianControlI1X8LeSwap16 => (SetBigEndianControl & 0x80000) != 0;
public bool SetBigEndianControlI4Swap1 => (SetBigEndianControl & 0x100000) != 0;
public bool SetBigEndianControlI4Swap4 => (SetBigEndianControl & 0x200000) != 0;
public bool SetBigEndianControlI4Swap8 => (SetBigEndianControl & 0x400000) != 0;
public bool SetBigEndianControlI4Swap16 => (SetBigEndianControl & 0x800000) != 0;
public bool SetBigEndianControlI8Swap1 => (SetBigEndianControl & 0x1000000) != 0;
public bool SetBigEndianControlI8Swap4 => (SetBigEndianControl & 0x2000000) != 0;
public bool SetBigEndianControlI8Swap8 => (SetBigEndianControl & 0x4000000) != 0;
public bool SetBigEndianControlI8Swap16 => (SetBigEndianControl & 0x8000000) != 0;
public bool SetBigEndianControlOverride => (SetBigEndianControl & 0x10000000) != 0;
public fixed uint Reserved874[3];
public uint SetPixelsFromMemoryBlockShape;
public SetPixelsFromMemoryBlockShapeV SetPixelsFromMemoryBlockShapeV => (SetPixelsFromMemoryBlockShapeV)((SetPixelsFromMemoryBlockShape >> 0) & 0x7);
public uint SetPixelsFromMemoryCorralSize;
public int SetPixelsFromMemoryCorralSizeV => (int)((SetPixelsFromMemoryCorralSize >> 0) & 0x3FF);
public uint SetPixelsFromMemorySafeOverlap;
public bool SetPixelsFromMemorySafeOverlapV => (SetPixelsFromMemorySafeOverlap & 0x1) != 0;
public uint SetPixelsFromMemorySampleMode;
public SetPixelsFromMemorySampleModeOrigin SetPixelsFromMemorySampleModeOrigin => (SetPixelsFromMemorySampleModeOrigin)((SetPixelsFromMemorySampleMode >> 0) & 0x1);
public SetPixelsFromMemorySampleModeFilter SetPixelsFromMemorySampleModeFilter => (SetPixelsFromMemorySampleModeFilter)((SetPixelsFromMemorySampleMode >> 4) & 0x1);
public fixed uint Reserved890[8];
public uint SetPixelsFromMemoryDstX0;
public uint SetPixelsFromMemoryDstY0;
public uint SetPixelsFromMemoryDstWidth;
public uint SetPixelsFromMemoryDstHeight;
public uint SetPixelsFromMemoryDuDxFrac;
public uint SetPixelsFromMemoryDuDxInt;
public uint SetPixelsFromMemoryDvDyFrac;
public uint SetPixelsFromMemoryDvDyInt;
public uint SetPixelsFromMemorySrcX0Frac;
public uint SetPixelsFromMemorySrcX0Int;
public uint SetPixelsFromMemorySrcY0Frac;
public uint PixelsFromMemorySrcY0Int;
public uint SetFalcon00;
public uint SetFalcon01;
public uint SetFalcon02;
public uint SetFalcon03;
public uint SetFalcon04;
public uint SetFalcon05;
public uint SetFalcon06;
public uint SetFalcon07;
public uint SetFalcon08;
public uint SetFalcon09;
public uint SetFalcon10;
public uint SetFalcon11;
public uint SetFalcon12;
public uint SetFalcon13;
public uint SetFalcon14;
public uint SetFalcon15;
public uint SetFalcon16;
public uint SetFalcon17;
public uint SetFalcon18;
public uint SetFalcon19;
public uint SetFalcon20;
public uint SetFalcon21;
public uint SetFalcon22;
public uint SetFalcon23;
public uint SetFalcon24;
public uint SetFalcon25;
public uint SetFalcon26;
public uint SetFalcon27;
public uint SetFalcon28;
public uint SetFalcon29;
public uint SetFalcon30;
public uint SetFalcon31;
public fixed uint Reserved960[291];
public uint MmeDmaWriteMethodBarrier;
public bool MmeDmaWriteMethodBarrierV => (MmeDmaWriteMethodBarrier & 0x1) != 0;
public fixed uint ReservedDF0[2436];
public MmeShadowScratch SetMmeShadowScratch;
#pragma warning restore CS0649
}
}