Graphics 模拟一个简单的图形卡

Graphics 模拟一个简单的图形卡,graphics,simulation,low-level,computer-architecture,instruction-set,Graphics,Simulation,Low Level,Computer Architecture,Instruction Set,好的。我可以找到简单架构的模拟设计。(Edit:肯定不喜欢x86)例如,使用int作为程序计数器,使用字节数组作为内存等等。但是我如何模拟图形卡(可以想象的最简单的图形卡)功能? 例如,使用数组表示每个像素,并逐个“绘制”每个像素。 但是什么时候绘制-与CPU同步还是异步?谁在该数组中存储图形数据?是否有存储像素和绘制像素的说明? 请考虑所有的问号(“?”)并不意味着“你问了很多问题”而是解释问题本身——如何模拟一张图形卡? 编辑:到CPU+内存模拟的基本实现设计图形卡通常带有若干KBs或MBs

好的。我可以找到简单架构的模拟设计。(Edit:肯定不喜欢x86)


例如,使用
int
作为程序计数器,使用
字节数组
作为内存等等。

但是我如何模拟图形卡(可以想象的最简单的图形卡)功能?

例如,使用
数组
表示每个像素,并逐个“绘制”每个像素。
但是什么时候绘制-与CPU同步还是异步?谁在该数组中存储
图形数据
?是否有存储像素和绘制像素的说明?

请考虑所有的问号(“?”)并不意味着“你问了很多问题”而是解释问题本身——如何模拟一张图形卡?


编辑:到CPU+内存模拟的基本实现设计

图形卡通常带有若干KBs或MBs的内存,存储单个像素的颜色,然后显示在屏幕上。该卡每秒扫描该内存若干次,将像素颜色的数字表示转换为视频信号(模拟或数字),以便显示器理解和可视化

CPU可以访问该内存,每当它更改它时,卡最终将新的颜色数据转换为适当的视频信号,显示屏显示更新的图片。该卡以异步方式完成所有处理,不需要CPU提供太多帮助。从CPU的角度来看,这就像将新的像素颜色写入图形卡内存中对应于像素坐标的位置,然后忘记它。它在现实中可能更复杂一些(由于同步效果差,例如
撕裂
等等),但这就是它的要点

当您模拟图形卡时,您需要以某种方式将模拟卡的内存镜像到物理图形卡的内存中。如果在操作系统中,您可以直接访问物理图形卡的内存,这是一项简单的任务。只需实现对模拟计算机内存的写入,如下所示:

void MemoryWrite(unsigned long Address, unsigned char Value)
{
  if ((Address >= SimulatedCardVideoMemoryStart) &&
      (Address - SimulatedCardVideoMemoryStart < SimulatedCardVideoMemorySize))
  {
    PhysicalCard[Address - SimulatedCardVideoMemoryStart] = Value;
  }

  EmulatedComputerMemory[Address] = Value;
}
void MemoryWrite(无符号长地址,无符号字符值)
{
如果((地址>=模拟卡VideoMemoryStart)&&
(地址-模拟卡VideoMemoryStart<模拟卡VideoMemorySize))
{
PhysicalCard[地址-模拟卡VideoMemoryStart]=值;
}
模拟计算机内存[地址]=值;
}
当然,以上假设模拟卡与物理卡具有完全相同的分辨率(例如,1024x768)和像素表示(例如,每像素3个字节,第一个字节表示红色,第二个字节表示绿色,第三个字节表示蓝色)。在现实生活中,事情可能会稍微复杂一些,但这也是一般的想法

如果您使代码可由PC BIOS引导,并将其限制为仅使用BIOS服务功能(中断)和所有其他PC设备的直接硬件访问,则您可以直接在
MSDOS
中或在没有任何操作系统的裸x86 PC上访问物理卡的内存

顺便说一句,将仿真器实现为DOS程序并直接在
Windows XP
中运行可能非常容易(Vista和7在32位版本中对DOS应用程序的支持非常有限,在64位版本中则没有;但是,您可以在VM 7中安装XP)或者更好的类似,它似乎可用于多个操作系统

如果您将其作为Windows程序实现,则必须使用
GDI
DirectX
在屏幕上绘制一些内容。除非我弄错了,否则这两个选项都不允许您直接访问物理卡的内存,从而自动显示其中的更改


如果需要大量渲染,使用GDI或DirectX在屏幕上绘制单个像素可能会很昂贵。每次更改一个模拟卡的像素时,重新绘制所有模拟卡的像素都会导致相同的性能问题。最好的解决方案可能是每秒更新屏幕25-50次,并且只更新自上次重画以来已更改的部分。将模拟卡的缓冲区细分为较小的缓冲区,表示64x64像素的矩形区域,在模拟器写入时将这些缓冲区标记为“脏”,在屏幕上绘制时将其标记为“干净”。您可以设置一个定期定时器驱动屏幕重画,并在单独的线程中进行重画。您应该能够在Linux中执行类似的操作,但我对图形编程了解不多。

您想从编写提供已知API(可能是OpenGL)的驱动程序开始。在这之后,你可以做任何你想做的事情(还有一些软件OGL实现可供参考)。我要问的只是数据结构来表示图形卡和算法以获得功能。不,不是真正的家庭作业。我只是跟着书:)