GPU segments
GPU 通过DDI访问物理内存的过程被抽象成了段模型Segmentation model(PS: Segment都是从GPU怎么访问物理内存的角度来进行讨论的)。KMD通过给出一系列的Segment给GPU,以便GPU能够通过Segment使用对应的物理内存资源。Segment受到VMM的管理。
WDDM v2一共有三种段类型:
-
内存段 Memory Segment
一个内存段代表了指定给GPU的一段内存。内存段可以是独立显卡上的VRAM(Video RAM),也可以是固件或者是驱动在集成GPU上保留的内存。可以同时存在多个内存段。
新的WDDM v2中,内存段被当作一个物理内存页池(a pool of physical pages)来管理,每一页可以为4KB或者64KB。Surface的数据被Fill/Transfer/Discard/FillVirtuall/TransferVirtual这几个页操作拷贝进出内存段。
CPU可以有两种方法访问内存段中的内容。第一种方法,内存段可以在CPU的物理地址空间可见(PS:这里可以理解为CPU可以访问的物理地址空间中的一部分实际上是被映射到了内存段所代表那一段内存),这样VMM就能够简单的将CPU VA直接映射到Allocation所在的内存段中。而第二种方法,也是WDDM v2中新加入的,VMM支持CPU通过与一个内存段相关联的可编程CPU host aperture来访问被关联的那个内存段。
- Aperture段 Aperture Segment
Aperture段是一个全局页表。通过Aperture段的映射,从GPU引擎的角度来看,一些不连续的系统内存页(System Memory Page)表现呈一段连续的内存。
在WDDM v2中,KMD至少需要上报一个Aperture段。
- 系统内存段 System Memory Segment
系统内存段是一个隐含的段,表现为对系统内存的引用(i.e. a guest physical address PS: 不知道这个Guest物理地址到底指的是什么)。系统内存段不能直接被KMD访问到,但是能够被VMM隐式访问到,并且系统内存段的段ID永远是0,'SegmentId=0'。为了能够将Allocation放置在系统内存段中, KMD驱动需要使用Aperture段ID来访问系统内存段(PS:前面也说了,也就是通过指定SegmentId=0的 aperture段)。
物理内存引用 Physical memory reference
DDI中,物理内存引用都是采用段ID-段偏移对的形式(segment ID-Segment offset pair)。
用物理地址访问Allocation Accessing Allocations by physical address
对于不支持GPU VA的那些GPU引擎,就需要通过allocation的物理地址来访问allocation。这就意味着怎样从Segment分配资源给Allocation.物理引用意味着一个Allocation必须定位到一个连续的内存段中,或者在aperture段中一段连续的范围。
为了避免不必要并且开销大的连续的Allocation。KMD必须显式的确定Allocation.这些Allocation需要被渲染引擎物理的访问到,并且在这种Allocation创建的时候需要设置DXGK_ALLOCATIONFOFLAGS2::AccessedPhysically标志。
这种allocation在resident进系统内存的时候会被映射到aperture段中。并且在resident进内存段中时这些Allocation会是连续的。按照这种方式创建的Allocation会通过引擎上的Allocation List被引用。并且在物理地址模式下被访问操作。
没有被设置AccessPhysically标志的Allocation会被分配到内存段中的一些页中或者是系统内存的一些页中。两种方式都能通过GPU VA访问到。而这些Allocation不能够被GPU引擎的Allocation List所引用。以AllocationList方式引用这种Allocation的CB会在提交的时候被拒绝。
Primary Surfaces被理解为是Display controller物理访问资源,并且在实际显示的时候被连续的分配在了内存段中或被映射到aperture段中。当一个渲染引擎要物理访问Allocation的时候KMD只应该设置AccessedPhysically标记。隐式物理访问Primary surface和显式设置标志方式的不同之处在于当Allocation被映射到aperture的时候。当AccessedPhysically标志被设置之后Allocation都将被映射到aperture而不论何时resident。而没有设置AccessedPhysical标记的Primary surface只有当被实际显示的时候才会被映射到aperture中。这个特性减轻了aperture段的压力,通常情况下只有很少一些Primary surface会被显示,同时会有很大数量的surface存在并且被渲染(i.e. 在dFlip/iFlip场景中,所有FlipEx交换链都被为一个primary surface和其他的潜在的可显示的surface)。
AccessedPhysically==0 | AccessedPhysically==1 | Primary && AccessedPhysically==0 | |
Memory Segment | 内存页集合 只有GPUVA能访问 | 连续的 GPU物理地址能访问 | 连续的 只有GPUVA能够被渲染引擎访问 |
Aperture Segment | 未映射 系统内存页或只能被GPU页表映射 只能被GPUVA访问 不能通过Allocation List引用 | resident时映射 GPU物理内存能访问 | 显示时被映射 能被渲染引擎通过GPU VA访问 |