阅读:2863回复:16
直接写显存,请高手指点
hi,
我用directDraw 的来显示PCI卡采集的原始数据,通过lock 获取先存的虚拟地址,能否把虚拟地址传给driver,由driver把这个虚拟地址保存下来,当PCI卡把数据传给driver时直接把数据写到这个虚拟地址,而不是通过DeviceIOControl或者ReadFile之类的函数读取。 我知道driver是无法访问用户模式的地址的,能否通过转换实现呢,我用的driver开发工具是Numega studiodriver。请高手指点迷津,不胜感激 |
|
最新喜欢:beni_w |
沙发#
发布于:2003-07-30 01:52
it is possible to do that way!
there are few things you need to handle it properly: 1. lock the application memory; 2. pass this locked memory to driver;(from here, application should not access this memory.) 3. driver will get the app locked memory as a MDL, then get the physical address, may be more one section, from MDL; 4. fill up the hardware dma engine with this physical address and length; 5. start the dma; (wait for INT) 6. if there are more than one memory section, repeat step3 untill all data dma done. 7. driver release the MDL; 8. application unlock the memory; 9. display the video. Blt, for example. |
|
板凳#
发布于:2003-07-30 10:49
参考OSR的《Sharing Memory Between Drivers and Applications》
|
|
地板#
发布于:2003-07-30 13:49
你想做的是将PCI卡采集的数据直接传送的显存吧?
给你点提示,将你的采集卡驱动写成内核流驱动(Kernel Streaming driver)。这样通过DirectDraw的kernel-mode video transport可以完成采集卡到显存的直接传输。请参考DDK的DirectDrawDDI-(kernel-mode video transport)部分。 如果你有显卡驱动的源码,可以在其中提供特殊的接口来完成这些功能。至于你说的方法,也可以试,用MmGetPhysicalAddress()函数可以将虚拟地址转换成物理地址。但是也要用DeviceIOControl将虚拟地址传给设备驱动。 记得给分。 |
|
|
地下室#
发布于:2003-07-30 14:24
谢谢你的提示,不过用内核流的话是不是要消耗更多的CPU,另外你说的用mmgetphysicaladdress获取虚拟地址的物理地址,为什么在driverstudio里不能用,已经#include\"ntddk.h\"了,但是还是告诉我没有这个函数?prefer your answer.
|
|
5楼#
发布于:2003-07-30 14:40
要自己声明
extern \"C\" PHYSICAL_ADDRESS MmGetPhysicalAddress(PVOID); 连接库中还要加上 ntoskrnl.lib 。 如果你的采集卡有DMA控制器,应该可以完成卡到卡的DMA。 |
|
|
6楼#
发布于:2003-07-30 15:12
hi,
请问虚拟地址对应物理地址是连续的吗,如果不连续,怎样知道那一段虚拟地址对应的物理地址是在同一个区域?Thanks again |
|
7楼#
发布于:2003-07-30 15:43
这确实是个问题。是否连续取决显示驱动对显存的分配方式,可能连续,也可能不连续。想通用的话还是用Kernel-mode video transport。想简单的话还是用老方法,先传到内存,在用directdraw去blt。现在的显卡大多支持内存到显存的DMA,所以速度上也不会慢多少。
给点分吧。 |
|
|
8楼#
发布于:2003-07-30 16:05
hi,
我用你告诉我的方法试了一下,具体过程如下: 在驱动程序中: phyaddr = MmGetPhysicalAddress(virtualaddr ); virtualaddr = MmAllocateContiguousMemory(10,phyaddr); (unsigned char*)virtualaddr = 0x55; 结果: 应用程序的buffer值没有改变,并且物理地址高端(highPart)总是零 不知是什么原因?请回答,非常感谢。另外我刚刚加入,还不知道怎样加分,一块告诉我把,非常感谢!!!!!!!!!!! |
|
9楼#
发布于:2003-07-30 16:14
hi,leerom
我已经给你10分了,就20分,快点儿回答吧 |
|
10楼#
发布于:2003-07-30 16:27
看来是我理解错了,我以为你是想在采集驱动中直接将数据写入显卡显存(卡到卡的数据传输)
我的思路是应用程序用DirectDraw分配显卡显存缓冲区。再将这个缓冲区地址(虚拟)发送给采集卡驱动,采集卡驱动得到虚拟地址后转换成物理地址,将数据直接写入这个物理地址,然后再用DirectDraw进行翻转、或overlay。。。 你这里用的是普通的方法,先写入内存,再由DirectDraw显示。所以按照一般的写法就行了,不用将地址转来转去。如果你用的是缓I/O可以直接写I.IoctlBuffer()。按hong说的做就行了 [编辑 - 7/30/03 by leerom] |
|
|
11楼#
发布于:2003-07-30 17:33
高手请教:
我怎样在DeviceIOControl下的到应用层的buffer的虚拟地址 怎样给分??? |
|
|
12楼#
发布于:2003-07-31 10:24
哪位大侠能给点建议,我给20分,
KMemory Mem(I.Mdl()); Mem.LockPages( IoWriteAccess,KernelMode) 执行上述后第二条老是不成功.. |
|
|
13楼#
发布于:2003-07-31 11:24
如果你用的是direct I/O,那么应用层传来得内存地址已经被系统锁定了,不必再锁一次。如果你在驱动中另外分配了虚拟内存才应该调用KMemory.LockPages()来锁定内存。
|
|
|
14楼#
发布于:2003-08-01 08:58
牛
再请教一个问题怎样将内核的虚拟地址传给应用层. 怎么给分教我一下... 谢了..... |
|
|
15楼#
发布于:2003-08-01 09:24
这篇文章讲的很清楚,仔细研究必有收获http://www.driverdevelop.com/forum/viewthread.php?tid=20914
想给分要另外开一贴,我进去跟贴,你给分!:-) |
|
|
16楼#
发布于:2003-08-01 11:58
studio 支持directdraw么?
|
|
|