Aros/开发者/文档/HIDD/ATI
- 2006 年 ati 从 radeon 7000 到 x600
- 2011 年 ati 添加了 r400 和 r500
- 20?? 年 ati HD r600 及以上
- 20?? 年 ati 南部群岛 r800 及以上 - 可以查看此处的 vulkan api
最初的 2d ati 驱动程序 编写的 2000 年代中期
进行了一些工作来实现 r4xx 和 r5xx 显卡的 2d 加速,功能与旧显卡几乎相同,尚未经过测试。使用 Ati x1300 切换分辨率时出现了一些问题
到目前为止,使用 2011 年更新的 igp 的运气好坏参半。有些比其他的效果更好。
- HD 芯片组之前没有 gallium
- HD 期间和之后支持 gallium
- 带 OpenGL 包装器的 SI vulkan api
https://docs.mesa3d.org/gallium/index.html
尝试移植 DRM,以使 3d 加速工作... 必须使 3d 加速工作才能使 2d 加速与 r600-evergreen 显卡一起工作。您使用 3d 输出 2d。2d 加速已从 r600 常青树和 以后 的显卡中删除。
目前,r600 r700 显卡仅提供软件渲染,某些 2d 功能也不正常工作。
下一步,移植大部分 drm/radeon/ 代码,以便我可以使用 radeon 驱动程序对其进行编译。 http://www.kernel.org/ /drivers/gpu/drm/radeon/ /drivers/gpu/drm/
现在尝试设置 GART 表以使环形缓冲区工作。函数 r600_do_init_cp(... 在文件“r600_cp.c”中。/drivers/gpu/drm/radeon/r600_cp.c
workbench/hidd/hidd.nouveau 中的代码包含 nouveau 和通用 drm 代码。您应该能够在 radeon 驱动程序中重用大部分通用内容。至于 GART,基本上需要做的是为模拟页面的 4k 边界处分配的驱动程序内存提供内存。nouveau 驱动程序已经具有将此映射到卡地址空间的必要代码。假设 radeon 驱动程序也是如此。
直接渲染基础设施的硬件锁定 Rickard E. Faith、Jens Owen、Kevin E. Martin Precision Insight, Inc. $Date: 1999/05/11 22:45:24 $,$Revision: 1.6 $
本文考察了针对直接渲染基础设施 (DRI) 目前可用于 PC 平台的典型基于 DMA 的硬件的锁定要求。描述了一种锁定算法。此算法通过以下单一优化增强了典型的基于内核调用的阻塞锁:最近持有锁的实体可以在不使用内核调用的情况下请求锁。该算法依赖于原子指令,并且在时间和空间上都是常数。假设熟悉 DRI 设计文档 [OM98,MFOA99]。
1. 前言
1.1 版权
版权所有 © 1999 Precision Insight, Inc.,德克萨斯州雪松公园。版权所有。
允许制作和分发此文档的逐字副本,前提是在所有副本上保留版权声明和本许可声明。
1.2 商标
OpenGL 是 Silicon Graphics, Inc. 的注册商标。Unix 是 The Open Group 的注册商标。“X”设备和 X Window System 是 The Open Group 的商标。XFree86 是 XFree86 项目的商标。Linux 是 Linus Torvalds 的注册商标。Intel 是英特尔公司的注册商标。提到的所有其他商标均为其各自所有者的财产。
2. 锁定要求
尽管某些卡可能支持某些同时访问的子集,但典型的基于英特尔的 PC 图形硬件(1998 年价格低于 2000 美元)不允许同时交错访问帧缓冲区内存、基于 MMIO 的命令 FIFO 和基于 DMA 的命令 FIFO。例如,典型的卡在处理控制硬件光标位置的 MMIO 寄存器的更新时,将允许帧缓冲区和命令 FIFO 活动。某些卡将通过 DMA 发送的命令原子地添加到命令 FIFO 中,从而允许某些类型的同时 MMIO 和 DMA。但是,其他卡将在命令 FIFO 中逐字混合 MMIO 和 DMA 命令,从而完全破坏命令 FIFO。其他卡不够健壮,无法在执行其他操作时允许帧缓冲区访问。
由于这些限制,典型的硬件将需要一个单一的(每个设备)锁,该锁协作地限制 X 服务器、内核和 3D 直接渲染客户端对硬件的访问。本节简要概述了三种类型的 DRI 实体通常如何使用硬件锁。某些硬件可能不需要在本文档中列出的所有实例中进行锁定。
2.1 内核
DMA 缓冲区调度
当硬件准备好从内核的 DMA 缓冲区队列进行另一次 DMA 调度时,内核将获取硬件锁。如果有关另一次 DMA 调度可能性的通知是通过硬件中断发出的,则内核可能必须重置硬件上的中断。如果当前 GLXContext 与下一个要调度的 DMA 缓冲区所需的 GLXContext 不同,则内核必须更新硬件图形上下文,可能通过回调到 X 服务器(见下文)。
图形上下文保存和恢复
如果 X 服务器代表内核执行硬件图形上下文切换,则内核将在上下文切换期间代表 X 服务器持有硬件锁。X 服务器可以通过执行 MMIO 或发出立即调度 DMA 的请求(无需获取另一个锁)来执行上下文切换,然后发出 ioctl 以告诉内核上下文已切换,现在可以安全地继续进行 DMA 调度。
垂直同步
当操作(例如,DMA 缓冲区调度)必须与下一个垂直同步同步时,内核将获取锁并在执行操作之前轮询或等待中断。
2.2 3D 客户端库:软件回退
3D 客户端库在执行需要直接硬件访问(例如,访问帧缓冲区)的软件回退时将获取硬件锁。在此期间,客户端可能会发出绕过正常内核 DMA 缓冲区队列(并且不需要内核获取锁)的高优先级阻塞 DMA 请求。
3D 客户端库假设当前 GLXContext 的内核 DMA 缓冲区队列已刷新,其他内核 DMA 缓冲区队列已停止(通过获取锁隐含),硬件处于静止状态,并且当前完整图形上下文可用(包括纹理和显示列表)。初始 DRI 实现将假设此上下文存储在硬件上,而不是在 SAREA 中。
2.3 X 服务器
硬件光标
根据图形硬件的要求,可能需要锁来移动硬件光标。(在撰写本文时,我们还没有发现任何需要锁定硬件光标移动的硬件,但我们注意到了这种可能性,以便未来的驱动程序实现者可以检查它。)在不更改窗口偏移量的情况下进行 2D 渲染
X 服务器的 2D 渲染将需要锁,并且可能需要硬件处于静止状态(取决于正在执行的操作和使用的硬件)。
区域修改
区域修改(例如,移动窗口)需要锁和硬件处于静止状态。此外,所有内核 DMA 缓冲区队列都必须刷新(可以根据要移动的窗口和该窗口触发的 GLXContexts 计算出一组优化的 DMA 队列,以进行刷新)。区域修改后,将更新窗口更改 ID(此更新可能不需要加锁)。
DGA
当应用程序使用 XFree86-DGA 协议扩展时,X 服务器将代表 DGA 客户端持有锁。对于直接访问硬件但不知道 DRI 的客户端,必须支持 XFree86-DGA。
OpenGL/全屏
将提供一个新的协议扩展,允许在 DRI 框架内进行全屏 OpenGL 访问。服务器将发出一个 ioctl 来停止所有现有 GLXContexts 的内核 DMA 缓冲区队列。从那时起,所有新创建的 GLXContexts 将拥有可操作的(即未停止的)内核 DMA 缓冲区队列。这意味着客户端必须在创建任何 GLXContexts 之前发出 OpenGL/全屏请求。
3. 优化机会
3.1 分析
X 服务器、3D 客户端和内核将协作共享锁。由于客户端进程在持有锁时可能会死亡,因此某些进程必须检测客户端死亡并回收锁。当用于 X 协议的连接失败时,X 服务器可以检测到客户端死亡。但是,在 UNIX 域套接字(即命名管道)的情况下,及时通知需要在连接上进行主动 I/O。然而,内核级设备驱动程序在客户端关闭与内核设备驱动程序的连接时就会知道客户端死亡。客户端死亡的及时通知,以及其他内核级问题(例如,SIGSTOP 的处理 [FM99]),使得使用内核作为最终的锁仲裁者变得很有必要。
但是,通过 ioctl 获取硬件锁是一个重量级操作。如果某个实体正在执行多个短操作,则为了提供用户感知的交互性,必须为每个操作获取和释放锁。下一节将探讨通过引入两级锁来避免每次锁定操作都执行 ioctl 的方法。本节通过探索常见实体状态之间的转换并根据以下一般标准识别性能关键的转换,概述了两级锁设计的需求
Interaction is optimized for a single GLXContext. User-perceived responsiveness of the X server is maintained.
为了分析的目的,系统具有以下状态
DA: The kernel dispatching DMA buffers for GLXContext A. DB: The kernel dispatching DMA buffers for GLXContext B. SA: A 3D client doing software fallbacks for GLXContext A. Software fallbacks are assumed to be slow operations, such that the overhead of obtaining the hardware lock, regardless of implementation, is negligible. SB: A 3D client doing a software fallbacks for GLXContext B. 2D: The X server performing 2D rendering. HC: The X server moving the hardware cursor. This operation is lightweight, but a human is involved, so responsiveness is more important than overall speed. RM: The X server performing region modifications.
优化的重要性将按以下等级进行排序
Optimization is critical to meet performance goals. Optimization will help meet performance goals, but is not critical. Optimization may help meet performance goals, but may not have a large performance impact.
以下是任意两个状态之间转换的排名
DA DB SA SB 2D HC RM DA 1 2 3 3 2 2 3 DB 2 1 3 3 2 2 3 SA 3 3 3 3 2 2 3 SB 3 3 3 3 2 2 3 2D 2 2 2 2 1 2 3 HC 2 2 2 2 2 2 3 RM 3 3 3 3 3 3 3
3.2 讨论
由于我们的目标是优化单个 GLXContext 的吞吐量以及 X 服务器的响应能力,因此最重要的是优化 DMA 分派和 2D 渲染的锁定。如果内核长时间持有锁,则响应能力会受到影响。如果 X 服务器长时间持有锁,则渲染吞吐量会受到影响。因此,内核和 X 服务器不得持有锁超过最少必要的时间。但是,由于 DMA 分派和 2D 渲染操作都相对较短,因此锁将被频繁地获取和释放:重量级基于 ioctl 的锁定可能会占执行操作所用时间的很大一部分。在高级基于 MMIO 的图形硬件(即与可用的基于 DMA 的硬件相比)的情况下,基于 ioctl 的锁的开销将是禁止的。
由于这些需求和观察结果,我们进行了两级锁的设计。我们采用操作系统术语,将两种获取锁的方法称为“重量级”和“轻量级”。上述讨论中的关键观察结果是,必须针对单个 GLXContext 连续多次获取和释放锁来优化锁定(对于此讨论,X 服务器将被视为一个特殊的 GLXContext)。特别是,轻量级锁的设计并非用于在 GLXContexts 之间共享,因为这样的设计可能会以牺牲更关键的情况为代价来使算法复杂化(例如,通过要求轻量级例程中进行额外的工作来设置标志或检查重要的状态,但在单个 GLXContext 的情况下很少或从未使用这些状态)。
4. 锁设计
4.1 简介
以下假设将简化锁设计
Locking will be performed using the GLXContext ID to determine which entity last had the lock (or a hash of this ID that makes at least two bits (e.g., the high bits) and one ID (e.g., zero) available as flags. The heavyweight lock will use the ioctl interface to the kernel (an ioctl has the approximate overhead of a system call). The heavyweight lock will be used to resolve all cases of contention. The lightweight lock will be stored in a user-space shared memory segment that is available to all locking entities. A pointer-sized compare-and-set (CAS) atomic primitive is available. This is true for most modern processors, including Intel processors starting with the Intel486 (a double-wide CAS instruction is available starting with the Pentium). Similar lightweight algorithms can be designed using other atomic primitives. (For older hardware, such as the Intel386, which will have extremely poor 3D graphics throughput, the lightweight lock may simply fallback to the heavyweight lock.)
4.2 之前的工作
[MCS91] 讨论了利用繁忙等待和原子操作(由 fetch-and-phi 原语抽象)的同步算法,但没有讨论两级锁定机制。
[BKMS98] 描述了一种“细锁”,可以“膨胀”为“粗锁”。但是,粗锁不能“收缩”为细锁,因此这些方法不适用于我们的工作。
[L87] 描述了一种方法,在没有竞争的情况下,使用 7 次内存访问来提供互斥。如果修改 Lamport 的算法以在发生竞争时提供内核级回退,则可能可以使用更少读取和写入次数的算法。但是,由于所有现代架构都提供原子 fetch-and-phi 原语,因此探索仅依赖于原子读取和写入的算法的价值有限。
[LA93] 探索了结合繁忙等待和阻塞的“两阶段”算法。本文中描述的两级锁是 Lim 和 Agarwal 的两阶段锁,轮询值设置为 1。但是,目前我们施加了限制,即只有最后一个拥有锁的进程可以通过检查同步变量来获取锁——所有其他锁获取都必须阻塞。将来,在我们获得更多关于 DRI 竞争的经验后,我们可能会扩展我们的锁定算法以成为一个完全通用的两阶段锁。
Lim 和 Agarwal 指出,结合轮询和信号的好处的想法最初由 Ousterhout 在 [O82] 中提出。不幸的是,我们无法获得本文的副本。
4.3 锁定算法
算法和结构以类似 C 的编程语言表示。
锁结构
锁结构是一个简单的缓存行对齐整数。为了避免在多处理器系统上发生处理器总线竞争,不应该在同一缓存行中存储任何其他数据。
typedef struct lock_s { unsigned int context; unsigned int padding[3]; } lock_t;
标志
锁字中的位将用于声明锁,并通知客户端内核必须参与竞争解决。
#define LOCK_HELD 0x80000000 #define LOCK_CONT 0x40000000
比较并交换 (CAS)
这是一个标准的 32 位比较并交换 (CAS) 例程。它可以使用单个 Intel486 指令以原子方式实现。在 RISC 处理器上,CAS 通常使用指令对 load-linked/store-conditional 实现。
int CAS(int *address, int compare_value, int update_value) { if (*address == compare-value) { *address = update-value; return SUCCEED; } else return FAIL; }
获取轻量级锁
void get_lightweight_lock(lock_t *L, int my_context) { if (CAS(&L->context, my_context, LOCK_HELD|my_context) == FAIL) { // Contention, so we use the kernel to arbitrate get_heavyweight_lock(L, my_context); } }
释放轻量级锁
void release_lightweight_lock(lock_t *L, int my_context) { if (CAS(&L->context, LOCK_HELD|my_context, my_context) == FAIL) { // Kernel is requesting the lock release_heavyweight_lock(L, my_context); } }
获取重量级锁
void get_heavyweight_lock(lock_t *L, int my_context) { for (;;) { do { // If lock held, mark it as contended // Otherwise, try to get it current_context = L->context; if (current_context & LOCK_HELD) new = LOCK_CONT | current_context; else new = LOCK_HELD | my_context; } while (CAS(&L->context, current_context, new)); if (new == LOCK_HELD|my_context) break; // Have lock // Didn't get lock // Suspend process until lock available place_current_process_on_queue(); schedule(); // blocks until wake_up_queued_processes() called // Loop and try to obtain lock again } }
释放重量级锁
void release_heavyweight_lock(lock_t *L, int my_context) { L->context = 0; // CAS can be used to detect multiple unlocks wake_up_queued_processes(); }
讨论
获取和释放轻量级锁都需要 CAS 指令,这可能会导致处理器总线 LOCK 循环。如果缓存行驻留在当前处理器的缓存中,则在 Pentium Pro 及更高版本的处理器上会避免总线 LOCK。由于这通常是使用此锁的情况,因此在处理器数量上的可扩展性应该很好。在 RISC 处理器上,使用指令对 load-linked/store-conditional 来实现 CAS。此指令对不会导致总线锁定,并且在处理器数量上具有良好的可扩展性。
如果锁释放使用简单的写操作而不是 CAS,则在进程确定内核需要锁的时间和锁被释放的时间之间会存在竞争条件。在此期间,内核可能会设置请求的位。如果进程没有意识到内核正在等待锁,那么内核将无法获得锁,直到同一个进程或另一个进程再次请求锁。由于这可能永远不会发生,因此可能会导致死锁。
5. 致谢
感谢 James H. Anderson 讨论锁实现问题。
6. 参考文献
[AM97] James H. Anderson 和 Mark Moir。大型对象的通用构造。提交给 IEEE 并行与分布式系统汇刊,1997 年 6 月。可从 http://www.cs.pitt.edu/~moir/Papers/anderson-moir-tpds97.ps 获取。(本文的早期版本发表在第九届国际分布式算法研讨会的论文集中,计算机科学讲义 972,施普林格出版社,第 168-182 页,1995 年 9 月。)
[BKMS98] David F. Bacon、Ravi Konuru、Chet Murthy 和 Mauricio Serrano。细锁:Java 的轻量级同步。ACM SIGPLAN '98 编程语言设计与实现会议论文集(加拿大蒙特利尔,1998 年 6 月 17-19 日)。发表在 SIGPLAN 通告 33,5(1998 年 5 月),258-268 页。
[FM99] Rickard E. Faith 和 Kevin E. Martin。直接渲染基础设施的安全分析。德克萨斯州雪松公园:Precision Insight, Inc.,1999 年。
[L87 Leslie Lamport。一种快速的互斥算法。ACM 计算机系统汇刊 5,1(1987 年 2 月),1-11 页。
[LA93] Beng-Hong Lim 和 Anat Agarwal。大型多处理器同步的等待算法。ACM 计算机系统汇刊 11,3(1993 年 8 月),253-294 页。
[M92] Henry Massalin。合成:操作系统基本服务的有效实现。博士学位论文,发表为技术报告 CUCS-039-92。哥伦比亚大学文理研究生院,1992 年,71-91 页。可从 ftp://ftp.cs.columbia.edu/reports/reports-1992/cucs-039-92.ps.gz 获取。
[MCS91] John M. Mellor-Crummey 和 Michael L. Scott。共享内存多处理器上可扩展同步的算法。ACM 计算机系统汇刊 9,1(1991 年 2 月),21-65 页。
[MFOA99] Kevin E. Martin、Rickard E. Faith、Jens Owen、Allen Akin。直接渲染基础设施,低级设计文档。德克萨斯州雪松公园:Precision Insight, Inc.,1999 年。
[O82] J. K. Ousterhout。并发系统的调度技术。在第三届国际分布式计算系统会议论文集中。IEEE,纽约,1982 年,第 22-30 页。
[OM98] Jens Owen 和 Kevin E. Martin。3D 的多管道直接渲染架构。德克萨斯州雪松公园:Precision Insight, Inc.,1998 年 9 月 15 日。可从 http://www.precisioninsight.com/dr/dr.html 获取。10°
Vulkan
[edit | edit source]从南岛(GCN 1.0)及更高版本的图形核心下一代 (GCN) 架构支持 Vulkan(Radeon 7000 系列为 Vulkan 1.0,而 8000 系列 Sea Islands 为 GCN 2 并支持 Vulkan 1.1)。较早的非 GCN 架构不应该原生支持 Vulkan。
Vulkan 可能是驱动程序级别唯一需要的 API。OpenGL 和 Direct3D 可以通过包装器使用。
Radeon 视频内存结构,GPU 拥有自己的虚拟内存和类似 CPU 的页表。
需要渲染循环和其他主要部分
- 初始化和获取信息。
- 图形内存分配 (AMDGPU_GEM_CREATE)。
- GPU 虚拟内存映射 (AMDGPU_GEM_VA)。
- 将命令缓冲区发送到 GPU 环形缓冲区 (AMDGPU_CS)。
- 处理中断以了解命令执行何时完成 (AMDGPU_WAIT_CS)
Radeon GPU 拥有自己的 MMU 单元,因此每个使用 3D 加速的过程都有其自己的 GPU 虚拟地址空间。GPU 使用两级页表将虚拟地址映射到 GPU 物理地址。
在 Southern Islands Radeon GPU 上,物理内存布局为
0…VRAM size: VRAM (video RAM) VRAM size…GTT end: GTT (CPU memory mapped to GPU)
环形缓冲区需要管理从系统 RAM MMU 到 GPU MMU 的读写操作,并将编译后的着色器和绘图命令发送到 GPU 管道。
引用计数的 GPU 缓冲区类和 GPU 内存管理器。内存管理器可以分配三种类型的内存
- 可映射到 CPU 的 VRAM,
- 不可映射到 CPU 的 VRAM,
- 映射到 GPU 的 CPU 内存 (GTT)。GTT 缓冲区
一个 GART 页表,将 CPU 内存映射到 GPU GTT 内存范围。因此,CPU 内存映射在用户空间中进行,无需特殊的内核驱动程序。确保 GPU DMA 引擎可以写入 GTT 内存
间接缓冲区允许在环形缓冲区上执行命令,而无需将其复制到环形缓冲区。而是将执行间接缓冲区命令写入环形缓冲区,并将间接缓冲区地址和大小作为参数。Vulkan 驱动程序准备并发送间接缓冲区中的命令。
GTT 缓冲区测试。bufAdr 是由 GART 映射到 GPU 并由 GPU DMA 引擎写入的操作系统区域地址。
我理解的“驱动程序”在你的术语中是指位于此模块之上并仅允许与单个输出交互的东西吗?
驱动程序就是驱动程序。它是一个软件模块(如当前的 nvidia.hidd、radeon.hidd 等)。它们几乎不会改变。它们是 HIDD 类,并将保持不变。还有一个驱动程序的实例,即驱动程序类的对象。这些东西将真正控制不同的显示器。因此,例如,如果您有一个带有两个显示器的 ATI 显卡和一个带有另一个显示器的 NVidia 显卡,您将有两个驱动程序和三个实例。目前我们始终只有一个驱动程序的一个实例。
因此,驱动程序的一个实例将表示一个可控输出。客户端(graphics.library?)如何创建这样的实例。通过 OOP_NewObject 作为通常方式。
目前通过 OOP_NewObject 创建驱动程序的实例很容易,因为您只需要执行一次,并且创建后您就知道自己控制了正确的输出。使用新方法,创建驱动程序的实例将返回一个控制输出的对象 - 但客户端如何知道它是哪个输出?客户端如何知道可以有多少个输出 - 或者换句话说,客户端如何知道为所有输出创建驱动程序对象?(除非我错了,客户端在此阶段唯一可以使用的是 OOP_NewObject 调用)
这个模型对我来说没有多大意义。“驱动程序”的一个实例应该表示一个单个显示适配器,并公开单独的对象来表示 ldp - IMHO
不同的输出(或不同的卡 - 这无关紧要)是不同的 OOP 对象。每个驱动程序对象(实例)都使用 AddDisplayDriverA() 在显示模式数据库中注册。这些驱动程序被分配了不同的显示模式 ID
0x0010xxyy - 第一个显示器 0x0011xxyy - 第二个显示器 0x0012xxyy - 第三个显示器
等等。
xxyy 是驱动程序相关的 ID 部分,它编码同步和像素格式索引,与以前相同。为什么从 0x0010 开始?因为 Amiga(tm) 芯片组使用占用从 0x0000xxyy 到 0x000Axxyy 范围的固定定义。并决定将 0x000B - 0x000F 作为保留,以防万一。无论如何,系统中最多 65519 个显示器就足够了。:)
每个显示驱动程序都已为其显示模式提供名称。只是驱动程序必须为用户传递不同的名称(“Radeon 模拟”,“Radeon DVI”,“Radeon N2 模拟”,“Radeon N2 DVI”等)。
客户端如何知道可以有多少个输出 - 或者换句话说,客户端如何知道为所有输出创建驱动程序对象?(除非错了,客户端在此阶段唯一可以使用的是 OOP_NewObject 调用)
客户端不会执行 OOP_NewObject() 调用。驱动程序模块将有一个启动代码来执行此操作。新模型非常接近于目前所做的。只有一件事不同
当前模型:当执行 OOP_NewObject() 时,会找到第一个兼容的 PCI 设备并为其创建一个对象。
新模型:驱动程序启动代码枚举所有 PCI 设备并为每个设备调用 OOP_NewObject()。它使用私有属性来传递设备基地址等。驱动程序类甚至不必具有公共名称。是的,驱动程序不必是库。它可以是位于 DEVS:Monitors 中的普通可执行文件,就像在其他系统上一样。这样,它可以在任何时候启动,并且其显示模式将立即添加到系统中。
请参阅 arch/all-mingw32/hidd/wingdi/startup.c 作为示例。目前它只创建了一个对象,将来可以修改它以创建多个对象来模拟多个显示器(每个显示器将有一个单独的主机窗口)。这种方法甚至允许使用旧驱动程序,直到它们被重写。它们需要一个非常小的加载程序。到那时,我将继续进行转换,创建 DEVS:Monitors,并编写这样的加载程序。
启动序列中将没有 LoadMonDrvs。IMHO,加载显示驱动程序的更好位置是 dosboot 常驻程序,在 inithidds.c 中
- R100 Radeon 7000
- R200 Radeon 8000
- RS400/RS480 Radeon XPRESS 200(M)/1100 IGP
R300 Radeon 9700PRO/9700/9500PRO/9500/9600TX,FireGL X1/Z1 R350 Radeon 9800PRO/9800SE/9800,FireGL X2 R360 Radeon 9800XT RV350 Radeon 9600PRO/9600SE/9600/9550,M10/M11,FireGL T2 RV360 Radeon 9600XT RV370 Radeon X300,M22 RV380 Radeon X600,M24 RV410 Radeon X700,M26 PCIE R420 Radeon X800 AGP R423/R430 Radeon X800,M28 PCIE R480/R481 Radeon X850 PCIE/AGP
RV505/RV515/RV516/RV550 Radeon X1300/X1400/X1500/X1550/X2300 R520 Radeon X1800 RV530/RV560 Radeon X1600/X1650/X1700 RV570/R580 Radeon X1900/X1950
- RS600/RS690/RS740 Radeon X1200/X1250/X2100
- R600 Radeon HD 2900
RV610/RV630 Radeon HD 2400/2600/2700/4200/4225/4250 RV620/RV635 Radeon HD 3410/3430/3450/3470/3650/3670 RV670 Radeon HD 3690/3850/3870 RS780/RS880 Radeon HD 3100/3200/3300/4100/4200/4250/4290 RV710/RV730 Radeon HD 4330/4350/4550/4650/4670/5145/5165/530v/545v/560v/565v RV740/RV770/RV790 Radeon HD 4770/4730/4830/4850/4860/4870/4890 CEDAR Radeon HD 5430/5450/6330/6350/6370 REDWOOD Radeon HD 5550/5570/5650/5670/5730/5750/5770/6530/6550/6570 JUNIPER Radeon HD 5750/5770/5830/5850/5870/6750/6770/6830/6850/6870 CYPRESS Radeon HD 5830/5850/5870 HEMLOCK Radeon HD 5970
PALM Radeon HD 6310/6250 SUMO/SUMO2 Radeon HD 6370/6380/6410/6480/6520/6530/6550/6620 BARTS Radeon HD 6790/6850/6870/6950/6970/6990 TURKS Radeon HD 6570/6630/6650/6670/6730/6750/6770 CAICOS Radeon HD 6430/6450/6470/6490 CAYMAN Radeon HD 6950/6970/6990 ARUBA Radeon HD 7000 系列
- TAHITI Radeon HD 7900 系列
Radeon R9 280/280X PITCAIRN Radeon HD 7800 系列 Radeon R7 265/370 Radeon R9 270/270X/M290X VERDE Radeon HD 7700 系列 Radeon R7 250X/350 Radeon R9 M265X/M270X/M275X OLAND Radeon HD 8000 系列 Radeon R7 240/250/350 HAINAN Radeon HD 8800 系列 BONAIRE Radeon HD 7790 系列 Radeon R7 260/260X/360 KAVERI KAVERI APU KABINI KABINI APU HAWAII Radeon R9 290/290X/390/390X MULLINS (Puma/Puma+ 内核,GCN GPU) MULLINS/BEEMA/CARRIZO-L APU
- radeon/R600_rlc.bin radeon/R600_uvd.bin
- radeon/R600_rlc.bin radeon/RS780_uvd.bin radeon/RS780_pfp.bin radeon/RS780_me.bin
- radeon/PALM_me.bin radeon/PALM_pfp.bin
- radeon/SUMO_rlc.bin radeon/SUMO_uvd.bin SUMO radeon/SUMO_me.bin radeon/SUMO_pfp.bin
- radeon/BTC_rlc.bin radeon/CAICOS_mc.bin radeon/CAICOS_me.bin radeon/CAICOS_pfp.bin radeon/CAICOS_smc.bin radeon/SUMO_uvd.bin
- radeon/BTC_rlc.bin radeon/TURKS_mc.bin radeon/TURKS_me.bin radeon/TURKS_pfp.bin radeon/TURKS_smc.bin radeon/SUMO_uvd.bin
- radeon/BONAIRE_ce.bin radeon/BONAIRE_mc.bin radeon/BONAIRE_mc2.bin radeon/BONAIRE_me.bin radeon/BONAIRE_mec.bin radeon/BONAIRE_pfp.bin radeon/BONAIRE_rlc.bin radeon/BONAIRE_sdma.bin radeon/BONAIRE_smc.bin radeon/BONAIRE_uvd.bin radeon/BONAIRE_vce.bin