aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu/GpuContext.cs
blob: f2a0d5e51381dd2166ee127baf8f7099d1e94539 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu.Engine;
using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Graphics.Gpu.Synchronization;
using System;

namespace Ryujinx.Graphics.Gpu
{
    /// <summary>
    /// GPU emulation context.
    /// </summary>
    public sealed class GpuContext : IDisposable
    {
        /// <summary>
        /// Host renderer.
        /// </summary>
        public IRenderer Renderer { get; }

        /// <summary>
        /// Physical memory access (it actually accesses the process memory, not actual physical memory).
        /// </summary>
        internal PhysicalMemory PhysicalMemory { get; private set; }

        /// <summary>
        /// GPU memory manager.
        /// </summary>
        public MemoryManager MemoryManager { get; }

        /// <summary>
        /// GPU memory accessor.
        /// </summary>
        public MemoryAccessor MemoryAccessor { get; }

        /// <summary>
        /// GPU engine methods processing.
        /// </summary>
        internal Methods Methods { get; }

        /// <summary>
        /// GPU commands FIFO.
        /// </summary>
        internal NvGpuFifo Fifo { get; }

        /// <summary>
        /// DMA pusher.
        /// </summary>
        public DmaPusher DmaPusher { get; }

        /// <summary>
        /// GPU synchronization manager.
        /// </summary>
        public SynchronizationManager Synchronization { get; }

        /// <summary>
        /// Presentation window.
        /// </summary>
        public Window Window { get; }

        /// <summary>
        /// Internal sequence number, used to avoid needless resource data updates
        /// in the middle of a command buffer before synchronizations.
        /// </summary>
        internal int SequenceNumber { get; private set; }

        private readonly Lazy<Capabilities> _caps;

        /// <summary>
        /// Host hardware capabilities.
        /// </summary>
        internal Capabilities Capabilities => _caps.Value;

        /// <summary>
        /// Creates a new instance of the GPU emulation context.
        /// </summary>
        /// <param name="renderer">Host renderer</param>
        public GpuContext(IRenderer renderer)
        {
            Renderer = renderer;

            MemoryManager = new MemoryManager();

            MemoryAccessor = new MemoryAccessor(this);

            Methods = new Methods(this);

            Fifo = new NvGpuFifo(this);

            DmaPusher = new DmaPusher(this);

            Synchronization = new SynchronizationManager();

            Window = new Window(this);

            _caps = new Lazy<Capabilities>(Renderer.GetCapabilities);
        }

        /// <summary>
        /// Advances internal sequence number.
        /// This forces the update of any modified GPU resource.
        /// </summary>
        internal void AdvanceSequence()
        {
            SequenceNumber++;
        }

        /// <summary>
        /// Sets the process memory manager, after the application process is initialized.
        /// This is required for any GPU memory access.
        /// </summary>
        /// <param name="cpuMemory">CPU memory manager</param>
        public void SetVmm(ARMeilleure.Memory.MemoryManager cpuMemory)
        {
            PhysicalMemory = new PhysicalMemory(cpuMemory);
        }

        /// <summary>
        /// Disposes all GPU resources currently cached.
        /// It's an error to push any GPU commands after disposal.
        /// Additionally, the GPU commands FIFO must be empty for disposal,
        /// and processing of all commands must have finished.
        /// </summary>
        public void Dispose()
        {
            Methods.ShaderCache.Dispose();
            Methods.BufferManager.Dispose();
            Methods.TextureManager.Dispose();
            Renderer.Dispose();
        }
    }
}