24位像素格式在银行切换显存下的处理方式How did code handle 24-bit-per-pixel formats when using video cards with bank-switched memory?
该文探讨了在早期使用银行切换内存的视频卡上如何处理24位每像素(24bpp)图像格式的技术挑战。尽管像素数据可能未对齐,开发者仍需坚持使用对齐访问以确保正确性和性能。文章回顾了历史代码的实现策略,强调即使在非对齐情况下,内存访问的边界检查仍是关键。这种设计决策影响了早期图形编程的实践,并为现代GPU驱动开发提供了历史参考。
Raymond Chen
关于访问违规跨越多个页面的问题,Gil-Ad Ben Or 好奇当使用具有银行切换内存的视频卡时,代码如何处理每像素24位格式。“问题在于,64KB 字节数不能被3整除,而如果不使用某种缓冲机制,通常需要以像素为粒度进行操作。”
这里指的是关于 Windows 95 VFLATD 视频驱动助手程序的一篇旧文章,该程序通过将当前激活的银行映射到与模拟的平坦地址空间对应的地址位置,来模拟平坦的视频地址空间,即使底层视频卡使用的是银行切换内存;同时通过切换银行并将映射移动到新银行的模拟平坦地址来响应页面错误。
但如果有人进行跨越两个银行的内存访问,这种技巧就会失效,因为这会导致无限次的银行切换循环:CPU 在第一个银行上触发访问违规,驱动程序将该银行映射进来并无效化第二个银行。但由于内存访问跨越了两个银行,CPU 又在第二个银行上触发访问违规,而重新映射该银行的行为又导致第一个银行被解除映射,如此循环往复。
那么代码是如何处理跨越两个银行的像素呢?
基本规则是:所有对内存的访问必须正确对齐。任何正确对齐的内存访问都不会跨越页边界。
满足这一要求只是业务成本的一部分。编写访问视频内存的代码的人知道他们不能使用“读取一个32位值并忽略高8位”这类小技巧。如果一个像素跨越了边界,就必须将其拆分为三次字节访问,或者至少一次字节访问和一次字访问(其中字访问需正确对齐)。实际上,决定是否按字节+字或字+字节的方式拆分像素并不值得投入精力,因此大家统一采用三次字节访问的方式。
现在,如果你要对一整行像素进行操作,可以使用对齐的32位读写来访问整行:先复制字节直到地址对齐到32位,然后对行的主体部分使用32位读取,最后再复制末尾剩余的字节。32位读取会跨越像素边界,但这没关系,因为它们不会跨越页边界。
换句话说,答案就是——他们通过正确处理来解决这个问题。
分类
主题
作者
Raymond 参与 Windows 系统演进已超过30年。2003年,他创办了一个名为 The Old New Thing 的网站,其受欢迎程度远超他的想象,这一发展至今仍让他感到些许不安。该网站催生了一本同名书籍《The Old New Thing》(Addison Wesley, 2007)。他偶尔会在 Windows Dev Docs 的 Twitter 账号上出现,讲述一些毫无实用价值的故事。
需要完整排版与评论请前往来源站点阅读。