Electronic Joint Business

Solution for E-Business

Linux环境下的图形系统和AMD R600显卡编程(7)——AMD显卡的软件中断

CPU上处理的中断可以分成“硬件中断”和“软件中断”两类,比如网卡产生的中断称为硬件中断,而如果是软件使用诸如”int 0x10″(X86平台上)这样的指令产生中断称为软件中断,硬件中断是异步的,其发生的时机是不可知的,但是软件中断是同步的,CPU是“确切”知道其发生的时机的。   同样的,在GPU看来,中断也可以分成“硬件中断”和“软件中断”两类,比如热插拔事件或者vblank事件都会产生“硬件中断”,这些事件在GPU看来是异步的,GPU不知道这些事情何时发生。GPU也可以使用类似CPU的int指令那样产生中断,考虑这样一种情形:驱动向硬件发送了绘图命令后必须等到硬件执行完了这些命令后才能进行后续的操作,否则硬件的上一次命令没有执行完就继续执行下一次命令会导致错误。前面介绍scratch寄存器的时候提及过可以在命令末尾添加一条写scratch寄存器的命令,发送命令之后驱动使用轮询的方式轮询scratch寄存器,当然这种场合使用轮询肯定是不合适的,实际上显卡可以采用软中断机制,在完成绘图命令后执行一个类似“int xx”的命令产生中断,这里GPU是“确切”知道中断发生的时机的—-即在绘图命令完成的时候。   前面提到的fence就是这种“软件中断”的具体应用。   在上一篇blog中看到,fence是按照下面的步骤使用的:   radeon_fence_create->radeon_fence_emit->radeon_fence_wait   radeon驱动中的fence机制用于同步GPU和CPU,Fence机制的实现依赖GPU产生的软中断和scratch寄存器。CP完成一个绘图操作后执行产生中断的命令,向CPU发送一次中断信号,这里的“产生中断的命令”其实就是写CP_INT_STAT寄存器。   在radeon驱动代码中,完成向ring buffer中填充绘图命令后,会调用radeon_fence_emit函数(参考GPU命令包章节的代码),在r600显卡上最终调用r600_fence_ring_emit函数,该函数中有如下代码: 2327 void r600_fence_ring_emit(struct radeon_device *rdev, 2328 struct radeon_fence *fence) …… 2347 /* Emit fence sequence & fire IRQ */ 2348 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); 2349 radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg – PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); 2350 radeon_ring_write(rdev, fence->seq); 2351 /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */ […]

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.