模拟一个简单的图形卡

时间:2011-10-20 05:25:25

标签: graphics simulation low-level computer-architecture instruction-set

好的。我可以找到简单架构的模拟设计。(编辑:绝对不喜欢x86)

例如使用{{ 1}}作为程序计数器,使用int作为内存等等。

但是如何模拟图形卡(可以想象的最简单的图形卡)功能?
比如使用byte array来表示每个像素并逐个“绘制”每个像素 但什么时候与CPU同步或异步?谁将array存储在该阵列中?是否有存储像素和绘制像素的指令?

请考虑所有问号('?')并不意味着“你问了很多问题”,但解释了问题本身 - 如何模拟显卡?

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

1 个答案:

答案 0 :(得分:2)

图形卡通常带有许多KB或MB的内存,用于存储随后显示在屏幕上的各个像素的颜色。该卡每秒扫描该存储器若干次,将像素颜色的数字表示转换为显示器可理解和可视化的视频信号(模拟或数字)。

CPU可以访问此存储器,无论何时更改,存储卡最终会将新的颜色数据转换为适当的视频信号,并且显示屏会显示更新的图像。该卡以异步方式完成所有处理,并且不需要CPU提供太多帮助。从CPU的角度来看,它就像将新的像素颜色写入与图像坐标相对应的位置的图形卡存储器并忘记它。它实际上可能稍微复杂一些(由于tearingsnow之类的同步伪像很差),但这就是它的要点。

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

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

  EmulatedComputerMemory[Address] = Value;
}

当然,上面假设模拟卡具有完全相同的分辨率(例如,1024x768)和像素表示(例如,每像素3个字节,红色的第一个字节,绿色的第二个,蓝色的第三个)实体卡。在现实生活中,事情可能会稍微复杂一些,但同样,这也是一般的想法。

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

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

如果您将该项目实施为Windows程序,则必须使用GDIDirectX才能在屏幕上绘制内容。除非我弄错了,否则这两个选项都不允许您直接访问物理卡的内存,以便自动显示其中的更改。

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