windows虚拟显示器开发(一)

虚拟显示器概述

最近因工作需要,需要在物理显卡上虚拟出一个显示器,我用的操作系统是win7,查询了下官方文档和网络资源, 没有现成的框架,所以需要自己研究如何一步步实现。

虚拟显示器用途挺多的,我们其实在一些场景中有用到过,比如displaylink,我们网上买的一些USB转HDMI的连接线,在使用过程中我们需要安装displaylink的驱动,其实该驱动的原理是在电脑上虚拟出一个显示器,然后将显示器图片截获,通过USB再转换成HDMI信号给显示器显示。
USB转HDMI
类似的还有银行经常使用的一些手写板。

银行柜台手写板
还有一些小的场景,虚拟显示器也比较有用了,我们有时候会使用teamviewer远程软件连接电脑进行远程操作,此时连接电脑上物理显示器其实没有什么作用,耗电不说,还比较容易泄露电脑信息,但有些显卡又不得不插上显示器,不插的话teamviewer连接会黑屏,此时如果我们用软件虚拟一个显示器上去,问题就会得到完美解决。

虚拟显示器原理方案

多显卡,多显示器

至于单纯的虚拟显示器的实现,其实原理很简单,只需要编写一个虚拟的显卡驱动(需要有虚拟的显示设备),然后在虚拟显卡驱动上挂载一个显示器,但是这种方式虚拟出来的显示器并未用到实际物理GPU的渲染引擎,所以,基于性能上的考虑,改用其他方式。
多显卡多显示器

一显卡,多显示器

如果虚拟显示器需要用到物理显卡渲染,那么只能采用一显卡多显示器的方式了,我们使用的显卡有几种常用的类型:NV和AMD的独显,intel的集显,他们各自有有各自的显卡驱动,如果要实现一显卡多显示器的方式,那必须要“欺骗”各个厂商的显卡驱动,让他们认为设备上多插了一个显示器。
一显卡多显示器

由于我们不能修改厂商驱动源码,又缺少微软支持的框架,所以只能依靠一些所谓“黑客”的途径来实现,因为各个厂商都使用了微软的WDDM框架开发显卡驱动,所以从WDDM框架入手是个比较好的选择,可以通过注入WDDM框架的方式对操作系统进行“欺骗”,让操作系统误认为设备上多了个显示器。大概的原理图如下:
过滤驱动原理图
我们需要实现两个部分:
(1)内核态WDDM驱动hook;
(2)用户态WDDM驱动hook。

听听大牛怎么说

虽然虚拟显示器这块的资料极少,但是在网络上还是能发现一些蛛丝马迹的,我在OSR上发现有一位大神Marcel Ruedinger,他对WDDM框架及WDDM filter驱动特别精通,以下是他在解答别人问题时的回答:
Assuming you mean “WDDM Hook Driver”, the frame buffer of the additional monitor you are looking for is given in DxgkDdiSetVidPnSourceAddress(). This will only be called for your additional monitor after:

Prerequisite 1: A successful Video Present Network implementation including: DxgkDdiIsSupportedVidPn(), DxgkDdiEnumVidPnCofuncModality(),

DxgkDdiSetVidPnSourceAddress(), DxgkDdiSetVidPnSourceVisibility() etc. The main graphics adapter must not see the additional monitor, but dxgkrnl.sys must see it and all the existing monitors of the main graphics adapter, too. This implementation takes many months of development for all different main graphics adapters.

Prerequisite 2: A successful implementation of managing additional allocations (primary and secondary) for the additional monitor. Allocations can be taken from the main graphics adapter (thus reducing its video memory) or from system memory (must be hidden from main adapter). Performance might be crucial, too. E.g. copying from main graphics adapter video memory tends to be too slow etc. This implementation takes many months of development for all different main graphics adapters.

etc.etc.etc.

After a successful implementation of all the above (very unlikely - explaining the 100+ substantial obstacles would by far exceed the scope of this forum) the whole thing only works in NON-AERO mode with “Glass Look” turned off…

While AERO “Glass Look” is ON, everything is completely different. You need to hook the WDDM User Mode Driver DLL, too. You need to understand Direct3D in depth and you need to deal with constantly changing (flipped) framebuffers of Direct3D Swap Chains.
大致意思是做一个完整的WDDM过滤驱动,虚拟出一个显示器,需要做到如下三步:

(1)需要处理好VIDPN,包括DxgkDdiIsSupportedVidPn(), DxgkDdiEnumVidPnCofuncModality(),
DxgkDdiSetVidPnSourceAddress(), DxgkDdiSetVidPnSourceVisibility() 等函数,并且做到对于真实的显卡驱动,该虚拟显示器是透明的,他们不知道有这个显示器存在,对于dxgkrnl.sys,需要给他报一个显示器。我把这步理解为“欺上瞒下”,这步的主要作用是在系统里面能够识别出虚拟显示器。

(2)需要处理好虚拟显示器的内存分配。
这步的主要作用是如何获取虚拟显示器上显示的图像信息,这步需要对WDDM的GPU调度及内存管理要相当熟悉,如何映射GPU内存到CPU内存,如何给虚拟显示器分配显存,将显存图片拷贝到CPU内存速度是相当慢的,怎么取解决这个问题?

(3)毛玻璃效果开启后,情况就大不一样了,除了内核态的过滤驱动外,我们还需要hook用户态驱动,并且需要深入理解D3D,需要处理好Direct3D Swap Chains导致的FrameBuffer随时变化情况。我觉得这部是最为关键的,否则做出来的虚拟显示器是不完整的,不能支持毛玻璃效果,这步难度也是最大的,需要对D3D有着较为深入的理解,同时对WDDM框架甚是精通。

展望

这是我在未来几个月奋斗的目标,凭借多年的显卡驱动开发和D3D开发经验,相信不久就会出来成果,敬请期待!

微信
在这里插入图片描述

QQ:3505459047

欢迎交流!

  • 8
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Windows虚拟显示器是通过编写虚拟显卡驱动来实现的。这个驱动会创建一个虚拟的显示设备,并在其上挂载一个虚拟显示器。然而,虚拟显示器并不使用实际物理GPU的渲染引擎,因此在性能方面可能存在一些限制。为了让系统能够识别出虚拟显示器,需要处理好VIDPN(虚拟显示器路径名称),包括一些函数如DxgkDdiIsSupportedVidPn()、DxgkDdiEnumVidPnCofuncModality()、DxgkDdiSetVidPnSourceAddress()和DxgkDdiSetVidPnSourceVisibility()等。这些函数的作用是在系统中报告虚拟显示器的存在,同时对于真实的显卡驱动来说,虚拟显示器是透明的,它们并不知道有这个显示器的存在。这一步可以理解为在系统中“欺上瞒下”。虚拟显示器在一些场景中非常有用,比如在使用远程软件(如TeamViewer)进行远程操作时,连接电脑上的物理显示器可能没有实际作用,而且还会耗电和泄露电脑信息。但是有些显卡必须插上显示器才能正常使用远程软件,这时如果使用虚拟显示器软件,就可以完美解决这个问题。总结来说,Windows虚拟显示器是通过编写虚拟显卡驱动来实现的,可以在系统中识别出虚拟显示器,并在一些特定场景中提供便利。 #### 引用[.reference_title] - *1* *2* *3* [windows虚拟显示器开发(一)](https://blog.csdn.net/MagicFMan/article/details/95457763)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宸汐软件

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值