显存架构,虚拟与物理内存

发布时间 2023-11-21 04:05:47作者: 吴建明wujianming

显存架构,虚拟与物理内存

一款显卡的结构见下图,包含了GPU(执行所有计算)、视频输出(连接到屏幕)、显存(存储纹理或通用数据)、电源管理(降低电压,调节电流)、主机交互总线(与CPU的通信)等部件:

 

如今,所有计算机的结构都是类似的:一个中央处理器和许多外围设备。为了交换数据,这些外围设备通过总线互连,所有通信都通过总线进行。下图概述了标准计算机中外围设备的布局。

 

典型计算机中的外围互连。

总线的第一个用户是CPU。CPU使用总线访问系统内存和其他外围设备。然而,CPU并不是唯一能够向外围设备写入和读取数据的设备,外围设备本身也具有直接交换信息的能力。具体地说,能够在没有CPU干预的情况下读取和写入存储器的外围设备被称为具有DMA(直接存储器访问)能力,并且存储器事务通常被称为DMA。这种类型的事务很有趣,因为它允许驱动程序使用GPU而不是CPU来进行内存传输。由于CPU不再需要主动工作来实现这些传输,并且由于它允许CPU和GPU之间更好的异步性,因此可以获得更好的性能。DMA的常见用途包括提高纹理上传或流视频的性能。如今,所有图形处理器都具有这种能力(称为DMA总线主控),这种能力包括视频卡请求并随后控制总线几微秒。

如果外设能够在不连续的内存页列表中实现DMA(当数据在内存中不连续时非常方便),则称其具有DMA分散-收集(scatter-gather)功能(因为它可以将数据分散到不同的内存页,或从不同的内存页收集数据)。

请注意,DMA功能在某些情况下可能是一个缺点。例如,在实时系统上,意味着当DMA事务正在进行时,CPU无法访问总线,并且由于DMA事务是异步发生的,可能导致错过实时调度截止时间。另一个例子是小型DMA内存传输,其中设置DMA的CPU开销大于异步增益,导致传输速度变慢。因此,虽然DMA从性能角度来看有很多优势,但在某些情况下应该避免。

另外,GPU需要主机:

  • 设置屏幕模式/分辨率(模式设置)。
  • 配置引擎和通信总线。
  • 处理电源管理。热量管理(风扇,对过热/功率作出反应),更改GPU的频率/电压以节省电源。
  • 处理数据。分配处理上下文(GPU VM+上下文ID),上传纹理或场景数据,发送要在上下文中执行的命令。

16.2.2 总线类型

总线将机器外围设备连接在一起,不同外设之间的每一次通信都通过(至少)一条总线进行。特别是,总线是大多数图形卡连接到计算机其余部分的方式(一个显著的例外是某些嵌入式系统,其中GPU直接连接到CPU)。如下表所示,有许多适用于图形的总线类型:PCI、AGP、PCI-X、PCI express等等。本小节将详细介绍的所有总线类型都是PCI总线类型的变体,但其中一些总线在原始PCI设计上有独特的改进。

 

PCI (Peripheral Component Interconnect,外设部件互连标准):PCI是目前允许连接图形外围设备的最基本的总线。它的一个关键特性叫做总线控制,此功能允许给定的外围设备在给定的周期数内占用总线并执行完整的事务(称为DMA,直接内存访问)。PCI总线是一致的,意味着无需显式刷新即可使内存在设备间保持一致。

AGP (Accelerated Graphics Port,图形加速端口):AGP本质上是一种经过改进的PCI总线,与它的祖先相比,具有许多额外的功能。最重要的是,它的速度更快,主要得益于更高的时钟速度以及在每个时钟tick中每个通道发送2、4或8位的能力(分别适用于AGP 2x、4x和8x)。AGP还有三个显著特点:

  • 第1个特性是AGP GART(图形光圈重映射表),是IOMMU的一种简单形式。它允许从系统内存中取出一组(非连续的)物理内存页,并将其暴露给GPU作为连续区域使用,以很低的成本增加了GPU可用的内存量,并为CPU和GPU之间共享数据创建了一个方便的区域(AGP图形卡可以在该区域进行快速DMA,并且由于GART区域是一块系统RAM,因此CPU访问比VRAM快得多)。一个显著的缺点是,GART区域不一致,因此在另一方开始传输之前,需要刷新对GART的写入(无论是从GPU还是CPU)。另一个缺点是,硬件只处理一个GART区域,它必须由驱动程序分配。
  • 第2个特性是AGP边带寻址(SBA)。边带寻址由用作地址总线的8个额外总线位组成,与多路复用地址和数据之间的总线带宽不同,标准AGP带宽只能用于数据。此功能对驱动程序开发人员是透明的。
  • 第3个特性是AGP快速写入(FW)。快速写入允许直接向图形卡发送数据,而无需图形卡启动DMA。此功能对驱动程序开发人员也是透明的。

注意,后两个功能在各种硬件上都不稳定,通常需要特定于芯片组的hack才能正常工作,因此建议不启用它们。事实上,它们是AGP卡上出现奇怪硬件错误的极为常见的原因。

PCI-X:PCI-X是为服务器板开发的一种更快的PCI,这种格式的图形外围设备很少(一些Matrox G550卡)。不要将其与PCI-Express混淆,后者的使用非常广泛。

PCI-Express (PCI-E):PCI Express是新一代PCI设备,比简单的改进PCI有更多的优点。最后,需要注意的是,根据体系结构,CPU-GPU通信并不总是依赖于总线,在GPU和CPU位于单个芯片上的嵌入式系统上尤其常见。在这种情况下,CPU可以直接访问GPU寄存器。

16.2.3 显存架构

虽然DRAM通常被视为一个扁平的字节数组,但其内部结构要复杂得多。对于像GPU这样的高性能应用程序,非常有必要深入地理解它。从下往上大致看,VRAM由以下部分组成:

R行乘以C列的内存平面(memory plane,每个单元为一位。

 

由32、64或128个并行使用的内存平面组成的内存组(memory bank——这些平面通常分布在多个芯片上,其中一个芯片包含16或32个内存平面。bank中的所有页面都连接到行寻址系统(列也是如此),并且这些页面由命令信号和每行/列的地址控制。bank中的行和列越多,地址中需要使用的位就越多。

由若干个[2、4或8]个memory bank连接在一起并由地址位选择的内存排(memory rank——给定内存平面的所有memory bank位于同一芯片中。

由一个或两个连接在一起并由芯片选择线选择的memory rank组成的内存子分区(memory subpartition——rank的行为类似于bank,但不必具有统一的几何结构,而是在单独的芯片中。

由一个或两个稍微独立的memory subpartition组成了内存分区(memory partition

整个VRAM由几个[1-8]个memory partition组成。

以上数量会因不同的GPU架构和家族而不同。

DRAM最基本的单元是内存平面,它是按所谓的列和行组织的二维位数组:

column

row  0  1  2  3  4  5  6  7

0    X  X  X  X  X  X  X  X

1    X  X  X  X  X  X  X  X

2    X  X  X  X  X  X  X  X

3    X  X  X  X  X  X  X  X

4    X  X  X  X  X  X  X  X

5    X  X  X  X  X  X  X  X

6    X  X  X  X  X  X  X  X

7    X  X  X  X  X  X  X  X

buf  X  X  X  X  X  X  X  X

内存平面包含一个缓冲区,该缓冲区可容纳整个行。在内部,DRAM通过缓冲区以行为单位进行读/写。因此有几个后果:

  • 在对某个位进行操作之前,必须将其行加载到缓冲区中,会很慢。
  • 处理完一行后,需要将其写回内存数组,也很慢。
  • 因此,访问新行的速度很慢,如果已经有一个活动行,访问速度甚至更慢。
  • 在一段不活动时间后,抢先关闭一行通常很有用——这种操作称为precharging(预充电?)一个bank。
  • 但是,可以快速访问同一行中的不同列。

由于加载列地址本身比实际访问活动缓冲区中的位花费更多的时间,所以DRAM是以突发方式访问的,即对活动行中1-8个相邻位的一系列访问。通常,突发中的所有位都必须位于单个对齐的8位组中。内存平面中的行和列的数量始终是2的幂,并通过行选择和列选择位的计数来衡量[即行/列计数的log2],通常有8-10列位和10-14行位。内存平面被组织在bank中,bank由两个内存平面的幂组成。内存平面是并行连接的,共享地址和控制线,只有数据/数据启用线是分开的。这有效地使内存bank类似于由32位/64位/128位内存单元组成的内存平面,而不是单个位——适用于平面的所有规则仍然适用于bank,但操作的单元比位大。单个存储芯片通常包含16或32个存储平面,用于单个bank,因此多个芯片通常连接在一起以形成更宽的bank。

一个内存芯片包含多个[2、4或8]个bank,使用相同的数据线,并通过bank选择线进行多路复用。虽然在bank之间切换比在一行中的列之间切换要慢一些,但要比在同一bank中的行之间切换快得多。因此,一个内存bank由(MEMORY_CELL_SIZE / MEMORY_CELL_SIZE_PER_CHIP)存储器芯片组成。一个或两个通过公共线(包括数据)连接的内存列,芯片选择线除外,构成内存子分区。在rank之间切换与在bank中的列组之间切换具有基本相同的性能后果,唯一的区别是物理实现和为每个rank使用不同数量行选择位的可能性(尽管列计数和列计数必须匹配)。存在多个bank/rank的后果:

  • 确保一起访问的数据要么属于同一行,要么属于不同的bank,这一点很重要(以避免行切换)。
  • 分块内存布局的设计使分块大致对应于一行,相邻的分块从不共享一个bank

内存子分区在GPU上有自己的DRAM控制器。1或2个子分区构成一个内存分区,它是一个相当独立的实体,具有自己的内存访问队列、自己的ZROP和CROP单元,以及更高版本卡上的二级缓存。所有内存分区与crossbar逻辑一起构成了GPU的整个VRAM逻辑,分区中的所有子分区必须进行相同的配置,GPU中的分区通常配置相同,但在较新的卡上则不是必需的。子分区/分区存在的后果:

  • bank一样,可以使用不同的分区来避免相关数据的行冲突。
  • bank不同,如果(子)分区没有得到同等利用,带宽就会受到影响。因此,负载平衡非常重要。

虽然内存寻址高度依赖于GPU系列,但这里概述了基本方法。内存地址的位按顺序分配给:

  • 识别内存单元中的字节,因为无论如何都必须访问整个单元。
  • 多个列选择位,以允许突发(burst)。
  • 分区/子分区选择-以低位进行,以确保良好的负载平衡,但不能太低,以便在单个分区中保留相对较大的tile,以利于ROP。
  • 剩余列选择位。
  • 所有/大部分bank选择位,有时是排名选择位,以便相邻地址不会导致行冲突。
  • 行位。
  • 剩余的bank位或rank位,有效地允许将VRAM拆分为两个区域,在其中一个区域放置颜色缓冲区,在另一个区域放置zeta缓冲区,这样它们之间就不会有行冲突。

此外,可以不同倍数的数据速率同步动态随机存取内存,正是我们所熟知的DDR-SDRAM或DDR:

 

ank和双rank对比。

 

单速率、双速率、四速率对比图。

下图是CPU和GPU内存请求路线:

 

GTT/GART作为CPU-GPU共享缓冲区用于通信:

 

16.2.4 虚拟和物理内存

内存有两种主要的不同含义:

物理内存。物理内存是真实的硬件内存,存储在内存芯片中。

虚拟内存。虚拟内存是物理内存地址的转换,允许用户空间应用程序查看其分配的块,就好像它们是连续的,而它们在芯片上是碎片化和分散的。

 

虚拟地址空间的一些关键功能,以及虚拟内存和物理内存的关系。

一些操作系统(如Windows)还存在分页缓冲池(paged pool非分页缓冲池(nonpaged pool的机制。在用户空间中,所有物理内存页面都可以根据需要调出到磁盘文件。 在系统空间中,某些物理页面可以调出,而其他物理页面则不能。 系统空间具有用于动态分配内存的两个区域:分页缓冲池和非分页缓冲池。分页缓冲池中分配的内存可以根据需要调出到磁盘文件,非分页缓冲池中分配的内存永远无法调出到磁盘文件。

 

为了简化编程,更容易处理连续的内存区域。分配一个小的连续区域很容易,但分配一个更大的内存块将需要同样多的连续物理内存,在启动后由于内存碎片化导致难以实现。因此,需要一种机制来保持应用程序的连续内存块外观,同时使用分散的内存块。

为了实现这一点,内存被拆分为多个页。就本文的范围而言,可以说内存页是物理内存中连续字节的集合,以便使分散的物理页列表在虚拟空间中看起来是连续的,一个称为MMU(内存映射单元)的硬件使用页表将虚拟地址(用于应用程序)转换为物理地址(用于实际访问内存),如下图所示。如果页面不存在于虚拟空间中(因此不在MMU表中),MMU可以向其发送信号,为报告对不存在内存区域的访问提供了基本机制。反过来又被系统用来实现高级内存编程,如交换或动态页面实例化。由于MMU仅对CPU访问内存有效,虚拟地址与硬件无关,因为无法将它们与物理地址匹配。

 

MMUIOMMU

虽然MMU只适用于CPU访问,但它对外围设备有一个等价物:IOMMU。如上图所示,IOMMU与MMU相同,只是它虚拟化了外围设备的地址空间。IOMMU可以在主板芯片组(在这种情况下,它在所有外围设备之间共享)或图形卡本身(在图形卡本身上,它将被称为AGP GART、PCI GART)上看到各种化身。IOMMU的工作是将外围设备的内存地址转换为物理地址。特别是,它允许“欺骗”设备将其DMA限制在给定的内存范围内,是更好的安全性和硬件虚拟化所必需的。

IOMMU的一个特例是Linux swiotlb,它在引导时分配一段连续的物理内存(使得有一个大的连续物理分配是可行的,因为还没有碎片),并将其用于DMA。由于内存在物理上是连续的,不需要页转换,因此可以在该内存范围内进行DMA。但是,意味着该内存(默认为64MB)是预先分配的,不会用于其他任何用途。

AGP GART是IOMMU的另一个特例,它与AGP图形卡一起使用,向图形卡显示一个线性区域。在这种情况下,IOMMU被嵌入主板上的AGP芯片组中。AGP GART区域作为虚拟内存的线性区域向系统公开。

IOMMU的另一个特例是某些GPU上的PCI GART,它允许向卡公开一块系统内存。在这种情况下,IOMMU表嵌入到图形卡中,通常使用的物理内存不需要是连续的。

显然,有这么多不同的内存类型,性能是不均匀的,并非所有的访问组合都是快速的,主要取决于它们是否涉及CPU、GPU或总线传输。另一个问题是内存一致性:如何确保跨设备的内存一致,尤其是CPU写入的数据可供GPU使用(或相反)。这两个问题是相关的,因为较高的性能通常意味着较低水平的内存连贯性,反之亦然。

就设置内存缓存参数而言,有两种方法可以在内存范围上设置缓存属性:

  • MTRR。MTRR(内存类型范围寄存器)是描述给定物理内存范围属性的寄存器。每个MTRR包含一个起始物理地址、一个大小和一个缓存类型。MTRR的数量取决于系统,但非常有限。虽然适用于物理内存范围,但效果会作用于相应的虚拟内存页。例如,可以使用特定的缓存类型映射页面。
  • PAT(页面属性表)允许设置每页内存属性。与MTRR一样依赖有限数量的内存范围不同,可以在每页的基础上指定缓存属性。但是,它是仅在最新x86处理器上可用的扩展。

除此之外,可以在某些体系结构上使用显式缓存指令,例如在x86上,movntq是一条未缓存的mov指令,clflush可以选择性地刷新缓存行。

有三种缓存模式,可通过MTRR和PAT系统内存使用:

  • UC(UnCached)内存未缓存。CPU对此区域的读/写是未缓存的,每个内存写入指令都会触发实际的即时内存写入。有助于确保信息已实际写入,以避免CPU/GPU争用的情况。
  • WC(Write Combine)内存未缓存,但CPU写入被组合在一起以提高性能。在需要未缓存内存但将写操作组合在一起不会产生不利影响的情况下,非常有利于提高性能。
  • WB(Write Back)内存已被缓存。是默认模式,可以获得CPU访问的最佳性能。然而,并不能确保内存写入在有限时间后传播到中央内存。

请注意,以上缓存模式仅适用于CPU,GPU访问不受当前缓存模式的直接影响。然而,当GPU必须访问之前由CPU填充的内存区域时,未缓存模式可确保实际完成内存写入,并且不会挂起在CPU缓存中。实现相同效果的另一种方法是使用某些x86处理器(如cflush)上的缓存刷新指令,但比使用缓存模式的可移植性差。另一种(可移植的)方法是使用内存屏障,它可以确保在继续之前将挂起的内存写入提交到主内存。

显然,有这么多不同的缓存模式,并非所有访问都具有相同的性能:

  • 在CPU访问系统内存时,未缓存模式提供最差的性能,回写提供最好的性能,写入组合介于两者之间。
  • 当CPU从离散卡访问视频内存时,所有访问都非常慢,无论是读还是写,因为每次访问都需要总线上的一个周期。因此,不建议使用CPU访问大面积的VRAM。此外,在某些GPU上需要同步,否则可能会导致GPU挂起。
  • 显然,GPU访问VRAM的速度非常快。
  • GPU对系统RAM的访问不受缓存模式的影响,但仍须通过总线,DMA事务就是这种情况。由于都是异步发生的,从CPU的角度来看,它们可以被视为“免费”,但是每个DMA事务都涉及到不可忽略的设置成本。这就是为什么在传输少量内存时,DMA事务并不总是优于直接CPU访问。

最后,关于内存的最后一个重要观点是内存屏障和写入账本(write posting)的概念。对于缓存(写合并或写回)内存区域,内存屏障可确保挂起的写操作实际上已提交到内存。例如,在要求GPU读取给定的内存区域之前,会使用此选项。对于I/O区域,存在一种类似的称为写入账本的技术:包括在I/O区域内进行虚拟读取,作为一种副作用,它会等到挂起的写入生效后再完成。

经典的桌面计算机体系结构,在PCI Express上具有独特的图形卡。给定内存技术的典型带宽缺少内存延迟,GPUCPU之间不可能实现零拷贝,因为两者都有各自不同的物理内存,数据必须从一个复制到另一个才能共享。

 

 带分区主内存的集成图形:系统内存的一部分专门分配给GPU,零拷贝不可能实现,数据必须通过系统内存总线从一个分区复制到另一个分区。

 

具有统一主存储器的集成图形,可在AMD KaveriPlayStation 4HSA)中找到。

16.2.5 PFIFO

大多数引擎的命令都是通过一个名为PFIFO的特殊引擎发送的,PFIFO维护多个完全独立的命令队列,称为通道(channelFIFO,每个通道通过“通道控制区”进行控制,该区域是MMIO[GF100之前]或VRAM[GF100+]的区域,PFIFO拦截所有进入该区域的通道并对其采取行动。

PFIFO内部在通道之间进行分时(time-sharing),但对应用程序是透明的,PFIFO控制的引擎也知道通道,并为每个通道维护单独的上下文。

PFIFO的上下文切换能力取决于卡的次代。在NV40,PFIFO基本上可以随时在通道之间切换。在旧卡上,由于缺少缓存的后备存储,只有在缓存为空时才能切换。然而,PFIFO控制的引擎在切换方面要差得多:它们只能在命令之间切换。虽然这种方式在旧卡上不是一个大问题(因为命令保证在有限的时间内执行),但引入具有循环功能的可编程着色器,可以通过启动长时间运行的着色器来有效地挂起整个GPU。

PFIFO大致可分为4个部分:

  • PFIFO pusher:收集用户命令并将其注入。
  • PFIFO cache:等待执行的大量命令。
  • PFIFO puller:执行命令,将其传递给适当的引擎或驱动。
  • PFIFO switcher:标出通道的时间片,并在PFIFO寄存器和RAMFC内存之间保存/恢复通道的状态。

通道由以下部分组成:

  • 通道模式:PIO[NV1:GF100]、DMA[NV4:GF100]或IB[G80-]。
  • PFIFO DMA pusher状态[仅限DMA和IB通道]。
  • PFIFO缓存状态:已接受但尚未执行的命令。
  • PFIFO puller状态。
  • RAMFC:当PFIFO上的通道当前未激活时,存储上述信息的VRAM区域[用户不可见]。
  • RAMHT[仅限GF100之前版本]:通道可以使用的“对象”表,对象由任意32位句柄标识,可以是DMA对象[参见NV3 DMA对象、NV4:G80 DMA对象、DMA对象]或引擎对象。在G80之前的卡上,可以在通道之间共享单个对象。
  • vspace(仅G80+):页表的层次结构,描述引擎在执行通道命令时可见的虚拟内存空间,多个通道可以共享一个vspace。
  • 引擎特定状态。

通道模式决定向通道提交命令的方式。在GF100之前的卡上可以使用PIO模式,并且需要将这些方法直接插入通道控制区域。它的速度慢且脆弱——当多个通道同时使用时,很容易发生故障,故而不推荐使用。在NV1:NV40上,所有通道都支持PIO模式。在NV40:G80上,只有前32个通道支持PIO模式。在G80上:GF100仅通道0支持PIO模式。

16.2.6 图形卡剖析

如今,图形卡基本上是计算机中的计算机。它是一个复杂的野兽,在一个单独的卡上有一个专用处理器,具有自己的计算单元、总线和内存。本节概述图形卡,包括以下元素。

  • Graphics Memory(图形内存)

GPU的内存(视频内存),可以是真实的、专用的、卡上内存(对于离散卡),也可以是与CPU共享的内存(对于集成卡,也称为“被盗内存”或“雕刻内存”)。请注意,共享内存的情况有着有趣的含义,因为如果实现得当,系统到视频内存的拷贝实际上是免费的。在专用内存的情况下,意味着需要进行来回传输,并且它们将受到总线速度的限制。

现代GPU也有一种形式的虚拟内存,允许将不同的资源(系统内存的真实视频内存)映射到GPU地址空间,与CPU的虚拟内存非常相似,但使用完全独立的硬件实现。例如,较旧的Radeon卡(实际上是Rage 128)具有许多表面(Surface),我们可以将这些表面映射到GPU地址空间,每个表面都是连续的内存资源(视频ram、AGP、PCI)。旧的Nvidia卡(NV40之前的所有卡)有一个类似的概念,它基于描述内存区域的对象,然后可以绑定到给定的用途。稍后的图形卡(从NV50和R800开始)可以让我们逐页构建地址空间,还可以随意选择系统和专用视频内存页。这些与CPU虚拟地址空间的相似性非常惊人,事实上,未映射的页面访问可以通过中断向系统发出信号,并在视频内存页面错误处理程序中执行。然而,小心处理这些问题,因为驱动程序开发人员必须处理来自CPU和GPU的多个地址空间,它们具有本质性的不同点。

  • Surface(表面)

表面是所有渲染的基本源和目标。尽管它们的叫法有所差异(纹理、渲染目标、缓冲区…)基本思想总是一样的。下图描述了图形表面的布局。由于硬件限制(通常是某些2次方的下一个倍数),表面宽度被四舍五入到我们所称的间距,因此存在一个未使用的像素死区。

 

图形表面具有许多特征:

  • 表面的像素格式。像素颜色由其红色、绿色和蓝色分量以及用作混合不透明度的alpha分量表示。整个像素的位数通常与硬件大小相匹配(8、16或32位),但四个组件之间的位数重新分配不必与硬件大小相匹配。用于每个像素的位数被称为每像素位数或bpp。常见的像素格式包括888 RGBX、8888 RGBA、565 RGB、5551 RGBA、4444 RGBA。请注意,现在大多数图形卡都是在8888中原生工作的。
  • 宽度和高度是最明显的特征,以像素为单位。
  • 间距是以字节为单位的宽度(不是以像素为单位!)表面的,包括空白区域(dead zone)像素。pitch便于计算内存使用量,例如,表面的大小应通过高度 x pitch而不是高度 x 宽度 x bpp来计算,以便包括dead zone。

请注意,表面并非总是线性存储在视频内存中,事实上,出于性能原因,表面通常不是以线性存储,因为这样可以改善渲染时内存访问的位置。此类表面称为分块表面(tiled surface,分块表面的精确布局高度依赖于硬件,但通常是一种空间填充曲线,如Z曲线(又叫Z-order曲线、Morton曲线,下图)或Hilbert曲线(下下图)。

 

 

另外,Morton和Hilbert曲线还支持3D空间的遍历:

 

  • 2D Engine2D引擎)

2D引擎或blitter是用于2D加速的硬件,Blitter是最早的图形加速形式之一,今天仍然非常普遍。通常,2D引擎能够执行以下操作:

  • Blits。BLIT是GPU将内存矩形从一个位置复制到另一个位置的副本,源和目标可以是视频或系统内存。
  • 实心填充。实心填充包括用颜色填充矩形内存区域,也可以包括alpha通道。
  • Alpha blits。Alpha Blit使用来自表面的像素的Alpha分量来实现透明度。
  • 拉伸拷贝。

下图显示了在两个不同表面之间拼接矩形的示例。此操作由以下参数定义:源和目标坐标、源和目标节距以及blit宽度和高度。然而,仅限于2D坐标,通常不能使用blitting引擎进行透视或变换。

 

当blit发生在两个重叠的源表面和目标表面之间时,副本的语义并不是简单定义的,尤其是当人们认为blit发生的不是简单的矩形移动,而是在核心逐像素移动时。如下图所示,如果一行一行地从上到下复制,一些源像素将被修改为副作用。因此,拷贝方向的概念被引入到blitter中。在这种情况下,要获得正确的副本,需要从下到上的副本。一些卡将根据表面重叠自动确定拷贝方向(例如nvidia GPU),而其他卡则不会,在这种情况下,必须由驱动处理。这就是为什么有些GPU实际上支持负的pitch,以便告诉2D引擎后退。

 

最后,请记住,并非所有当前的图形加速器都具有2D引擎。由于3D加速在技术上是2D加速的超集,因此可以使用3D引擎实现2D加速。事实上,一些驱动程序使用3D引擎来实现2D,使得GPU制造商可以完全放弃专用于2D的晶体管。然而,其他一些卡并不专用于晶体管,而是在GPU内部的3D操作之上对2D操作进行微程序化(nv10之后的nVidia卡和nv50之前的nVidia卡都是这种情况,对于Radeon R600系列,它们具有在3D之上实现2D的可选固件)。有时会影响2D和3D操作的混合,因为它们现在共享硬件单元。

  • 3D Engine3D引擎)

3D引擎也称为光栅化引擎。它包含一系列以管线(单向)方式交换数据的阶段,如顶点->几何->片元、图形FIFO、DMA等。为了获得更好的缓存位置,纹理和表面通常会分块。分块意味着纹理不是线性存储在GPU内存中,而是存储在内存中,以便使纹理空间中接近的像素也在内存空间中接近,例如Z阶曲线和希尔伯特曲线。

  • 覆盖层和硬件精灵(Overlays and hardware sprites)。

扫描输出:图形显示的最后一个阶段是将信息显示在显示设备或屏幕上,显示设备是图形链的最后一环,负责向用户展示图片。

此外,还有数字与模拟信号、hsync、vsync、绿同步、连接器和编码器(CRTC、TMD、LVDS、DVI-I、DVI-A、DVI-D、VGA)等技术,此文忽略之。