/// <summary> /// Creates a new instance of the 3D engine class. /// </summary> /// <param name="context">GPU context</param> /// <param name="channel">GPU channel</param> public ThreedClass(GpuContext context, GpuChannel channel, GPFifoClass fifoClass) { _context = context; _fifoClass = fifoClass; _state = new DeviceStateWithShadow <ThreedClassState>(new Dictionary <string, RwCallback> { { nameof(ThreedClassState.LaunchDma), new RwCallback(LaunchDma, null) }, { nameof(ThreedClassState.LoadInlineData), new RwCallback(LoadInlineData, null) }, { nameof(ThreedClassState.SyncpointAction), new RwCallback(IncrementSyncpoint, null) }, { nameof(ThreedClassState.InvalidateSamplerCacheNoWfi), new RwCallback(InvalidateSamplerCacheNoWfi, null) }, { nameof(ThreedClassState.InvalidateTextureHeaderCacheNoWfi), new RwCallback(InvalidateTextureHeaderCacheNoWfi, null) }, { nameof(ThreedClassState.TextureBarrier), new RwCallback(TextureBarrier, null) }, { nameof(ThreedClassState.TextureBarrierTiled), new RwCallback(TextureBarrierTiled, null) }, { nameof(ThreedClassState.DrawTextureSrcY), new RwCallback(DrawTexture, null) }, { nameof(ThreedClassState.VbElementU8), new RwCallback(VbElementU8, null) }, { nameof(ThreedClassState.VbElementU16), new RwCallback(VbElementU16, null) }, { nameof(ThreedClassState.VbElementU32), new RwCallback(VbElementU32, null) }, { nameof(ThreedClassState.ResetCounter), new RwCallback(ResetCounter, null) }, { nameof(ThreedClassState.RenderEnableCondition), new RwCallback(null, Zero) }, { nameof(ThreedClassState.DrawEnd), new RwCallback(DrawEnd, null) }, { nameof(ThreedClassState.DrawBegin), new RwCallback(DrawBegin, null) }, { nameof(ThreedClassState.DrawIndexedSmall), new RwCallback(DrawIndexedSmall, null) }, { nameof(ThreedClassState.DrawIndexedSmall2), new RwCallback(DrawIndexedSmall2, null) }, { nameof(ThreedClassState.DrawIndexedSmallIncInstance), new RwCallback(DrawIndexedSmallIncInstance, null) }, { nameof(ThreedClassState.DrawIndexedSmallIncInstance2), new RwCallback(DrawIndexedSmallIncInstance2, null) }, { nameof(ThreedClassState.IndexBufferCount), new RwCallback(SetIndexBufferCount, null) }, { nameof(ThreedClassState.Clear), new RwCallback(Clear, null) }, { nameof(ThreedClassState.SemaphoreControl), new RwCallback(Report, null) }, { nameof(ThreedClassState.SetFalcon04), new RwCallback(SetFalcon04, null) }, { nameof(ThreedClassState.UniformBufferUpdateData), new RwCallback(ConstantBufferUpdate, null) }, { nameof(ThreedClassState.UniformBufferBindVertex), new RwCallback(ConstantBufferBindVertex, null) }, { nameof(ThreedClassState.UniformBufferBindTessControl), new RwCallback(ConstantBufferBindTessControl, null) }, { nameof(ThreedClassState.UniformBufferBindTessEvaluation), new RwCallback(ConstantBufferBindTessEvaluation, null) }, { nameof(ThreedClassState.UniformBufferBindGeometry), new RwCallback(ConstantBufferBindGeometry, null) }, { nameof(ThreedClassState.UniformBufferBindFragment), new RwCallback(ConstantBufferBindFragment, null) } }); _i2mClass = new InlineToMemoryClass(context, channel, initializeState: false); var drawState = new DrawState(); _drawManager = new DrawManager(context, channel, _state, drawState); _semaphoreUpdater = new SemaphoreUpdater(context, channel, _state); _cbUpdater = new ConstantBufferUpdater(channel, _state); _stateUpdater = new StateUpdater(context, channel, _state, drawState); // This defaults to "always", even without any register write. // Reads just return 0, regardless of what was set there. _state.State.RenderEnableCondition = Condition.Always; }