[ZZ]gdi显卡驱动节选

作者: JIURL
邮箱: thejiurl@gmail.com
主页: http://jiurl.blogsome.com/
http://jiurl.yeah.net/

[前言]

这篇文章是以前写给自己备忘的一个研究文档的节选。

[gdi 显卡驱动]

显卡驱动将讨论,显卡驱动中支持 gdi 实现的部分。

如果是一个纯 frame buffer 的话,显卡不作任何加速,所有 gdi 的实现都是 win32k 中的代码软件实现,gdi 把 frame buffer 当作一个位图,直接访问,进行相应的绘制。当然,这种情况除非特意设计,否则的话,是不会出现的。

不是纯 frame buffer 的情况,gdi 不直接访问 frame buffer,
显卡硬件实现了某些硬件加速,可能实现了某些 gdi 需要的硬件加速。gdi 中,有硬件加速的,就交给显卡驱动来完成,没有硬件加速的,gdi 软件实现,然后把结果交给显卡驱动来完成显示。

显卡驱动至少需要实现,DrvCopyBits, DrvTextOut 和 DrvStrokePath,其他 gdi 函数可以软件实现,最终调用这几个驱动实现的函数,来把结果写入 frame buffer。

显卡驱动可以实现的 gdi 的功能:
DrvBitBlt
DrvPlgBlt
DrvStretchBlt
DrvStretchBltROP
DrvTextOut
DrvStrokePath
DrvFillPath
DrvStrokeAndFillPath
DrvLineTo
DrvCopyBits
DrvAlphaBlend
DrvGradientFill
DrvTransparentBlt

更多细节可以参考关于 SURFACE, HDC 等的讨论。

[显卡驱动]

显卡驱动(支持gdi部分)相关内容主要在下面的4个文件中:

win32k.sys
VideoPort.sys

disp 驱动 (.dll) (如 vga.dll)
mini port 驱动 (.sys) (如 vga.sys)

win32k.sys 和 VideoPort.sys 是系统文件。
disp 驱动 (.dll) 和 mini port 驱动 (.sys) 是显卡驱动。

[win32k.sys]
gdi 就是在 win32k.sys 中实现的。EngXxx 是在 win32k.sys 中实现的。

[VideoPort.sys]

mini port 驱动 将会调用 VideoPort.sys 导出的函数。
VideoPort.sys 导出的函数,例如:

VideoPortWritePortUlong
VideoPortZeroMemory
VideoPortInitialize

只是做了个简单封装,这样逻辑性更好一些,也使得 mini port 驱动的代码和 平台(体系结构)无关。
比如 VideoPortWritePortUlong,对x86,基本上也就是一条 out 指令。

[mini port 驱动 (.sys)]

查询显卡支持的所有可用的模式,查询和设置当前的显示模式(比如,1280*1024 16位色 刷新率60hz)。
大致也就是完成,对显卡初始化,对显卡的状态进行查询和设置,将寄存器映射到虚拟地址空间,等工作。

也就是一些对应 IOCTL_VIDEO_XXX 的实现的工作。

在 DriverEntry 中,调用 VideoPortInitiaze,设置 DRIVER_OBJECT 的 MajorFunction[],IoCreateDevice 创建 DEVICE_OBJECT。

[disp 驱动 (.dll)]

显卡驱动中最重要的部分。显卡驱动的主要工作在 “disp 驱动 (.dll)” 中完成。

它知道显卡硬件的细节,知道如何向显卡发命令,来让显卡硬件完成某个工作。

它将直接访问显卡的寄存器,来向显卡发命令,或者读取显卡的情况。可能显卡的一块寄存器最终映射到虚拟地址空间的话,那么驱动中就直接访问这部分虚拟地址空间。也可能还需要访问 io 端口。

DrvXxx 函数就是由 “disp 驱动 (.dll)” 提供的。

“disp 驱动 (.dll)” 中会调用 EngXxx。比如 EngCreateDeviceSurface,EngDeviceIoControl。也可能调用 EngXxx 来帮助完成某项绘制功能。

注意:disp 驱动 (.dll) 的入口点为 DrvEnableDriver。它将被载入系统地址空间。

原文地址:https://www.cnblogs.com/coltor/p/2133989.html