如何使用 Direct3D 设备管理器
How do I use the Direct3D Device Manager?
应用程序中的多个线程和对象之间共享一个 Direct3D 设备。 我遇到了 Direct3D 设备管理器,它看起来像我想要的,尽管我没有进行任何视频处理或视频加速:http://msdn.microsoft.com/en-us/library/windows/desktop/aa965267(v=vs.85).aspx
在我的代码中,我正在执行以下操作:
// Create the device manager
UINT resetToken = 0;
IDirect3DDeviceManager9* deviceManager = NULL;
if (FAILED(DXVA2CreateDirect3DDeviceManager9(&resetToken, &deviceManager)))
return false;
// Add the device to the device manager
if (FAILED(deviceManager->ResetDevice(device, resetToken)))
return false;
deviceManager->AddRef();
我的问题是,创建 Direct3D 设备管理器后,如何在不传递指向设备管理器的指针的情况下与其他对象共享 direct3d 设备管理器? Microsoft特别说要做以下事情,但我不知道以下内容的真正含义是什么:
设备所有者必须为其他对象提供获取指针的方法 到 IDirect3DDeviceManager9 界面。标准机制是 实现 IMFGetService 接口。服务 GUID 是 MR_VIDEO_ACCELERATION_SERVICE。
有人可以告诉我如何使用 IMFGetService 界面共享设备管理器吗?
如果您不进行任何视频处理,那么我认为实现和/或使用IDirect3DDeviceManager9
接口毫无意义。
只需实现自己的方法来管理 Direct3D 设备的生存期,使接口指针可用于对象/线程并执行同步。Direct3D 设备不是任何一种神奇的东西,只能通过IDirect3DDeviceManager9
在对象/线程之间共享。它就像任何其他资源一样。如果你正确地初始化它,你甚至可以从不同的线程并发调用某些方法(即几乎所有不依赖于可能被另一个线程更改的设备状态的方法)。
使接口指针可用可以像拥有一个保存指针的单一实例一样简单。或者,如果您的对象/线程已经以某种方式协作,则它们必须已经具有某种交换信息的方法。所以我想你应该能够扩展你已经拥有的东西,让对象/线程访问 Direct3D 设备。并且可以使用CRITICAL_SECTION
轻松完成同步。
如果您确实想使用 IDirect3DDeviceManager9
,那么 - 据我了解 - 您必须在要访问IDirect3DDeviceManager9
的所有对象上实现 IMFGetService
接口。实现 GetService
函数,以便在要求输入 MR_VIDEO_ACCELERATION_SERVICE
/IDirect3DDeviceManager9
时返回指向管理 Direct3D 设备的对象的接口指针。
编辑:关于代码示例:我希望这里给出的解释就足够了。在多个线程之间共享东西是我不敢尝试用简短的代码示例来解释的事情。如果你知道如何编写多线程应用程序,则使用 Direct3D 设备与使用其他资源的方式没有什么不同。如果你不知道如何编写多线程应用程序,那么这个主题对于一个单一的stackoverflow答案来说太复杂了。
关于为什么MS建议使用IDirect3DDeviceManager9
的问题...好吧,我不知道这样的一般性建议。建议在进行视频处理时(使用 DXVA、EVR 等)使用它。或者更像是授权的;我不确定您是否可以在不使用 D3D 设备管理器的情况下与增强型视频渲染器共享 D3D 设备。毕竟,这就是D3D设备管理器的目的。使用 VMR9 与渲染器共享设备只能通过两种方式实现:
记录的方式:仅从 VMR9 的"当前"回调访问设备。这是相当有限的 - 例如,您仅限于视频的帧速率。
未记录的方式:不要调用IVMRFilterConfig9::SetNumberOfStreams
,只连接一个输入流。这样,VMR9 将不会切换到"混音器模式",并且当不处于"混音器模式"时,VMR9 不会更改任何设备状态。因此,如果 D3D 设备是多线程初始化的,则可以在 VMR9 使用同一设备时自由使用 D3D 设备。
此外,对于VMR9,根本不可能在另一个DirectShow过滤器中使用D3D设备。D3D 设备管理器对此进行了改进,使筛选器和你自己的应用程序代码能够使用 D3D 设备,包括更改状态。但是,如果您自己实现将使用 D3D 设备的每个组件,那么使用 D3D 设备管理器实际上没有任何意义。即使使用需要 D3D 设备的第三方组件,也只能在这些组件支持的情况下使用 D3D 设备管理器。除非这些组件碰巧是DirectShow或MediaFoundation过滤器/组件,否则情况可能不会如此。
- 如何维护资源管理器项目视图中当前可见的项目列表
- 使用"Task"函数指针队列定义作业管理器
- 实现动态插件管理器
- 编译器资源管理器和 GCC 具有不同的输出
- Windows 资源管理器中的图标在使用 resource.rc 时显示 2 个不同的图标
- C++ 事件管理器的回调,使用 std::function 和 std:bind 以及派生类作为参数
- Linux 包管理器如何处理 C++20 个模块?
- 编译器资源管理器(godbolt)如何安全地运行代码?
- 创建跨平台 C++ 触摸管理器.在 c++ 中传递 Objective-c 对象涉及代码
- 从 GUI 文件资源管理器执行程序,并且不生成终端
- 自定义内存管理器在发布模式下工作正常,但在调试模式下则不然
- 无法删除EXE崩溃后,即使进程未显示在任务管理器中
- 任务管理器 - C/C++ 应用程序 - 分配的地址空间与已用内存
- 如何以编程方式获取任务管理器进程CPU使用率(不是PerfMon API)
- 管理器类和对象类之间的通信
- WinDBG适用于从Visual Studio 2015保存的转储,但不适用于任务管理器。显示异常代码"not found"
- 在C++中将系统与ECS(实体组件系统)管理器分离
- 是否可以检索与柯南包管理器一起打包的库的源代码,以便在其中进行调试?
- 如何使用 Direct3D 设备管理器
- 如果Windows资源管理器正在运行,Direct3D应用程序运行良好,否则速度会非常慢