Wine 6.19环境下SlimDX调用CreateOffscreenPlainSurfaceEx返回空的解决方法问询
排查思路与解决方案
前置验证步骤
- 校验参数合法性:优先确认传入的
width/height是否符合对应格式的对齐要求,YUY2格式强制要求宽度必须为2的倍数,Wine的D3D实现对参数对齐的校验比原生Windows严格,很多Windows下可正常运行的边界值在Wine中会直接返回D3DERR_INVALIDCALL。 - 检查设备状态:调用接口前确认
_device已完成初始化且未处于丢失状态,Wine staging 6.19的D3D设备状态同步逻辑和原生Windows存在差异,设备丢失后未完成重置时调用离屏表面创建接口大概率触发错误。 - 缩小问题范围:临时固定格式为
X8R8G8B8测试是否能成功创建,确认是否为YUY2格式的兼容性问题,Wine 6.x版本对非RGB格式的离屏表面支持存在较多已知缺陷。 - 验证SlimDX封装正确性:打印所有传入参数的实际值,确认SlimDX层没有对参数做非法转换,部分旧版本SlimDX对非Windows环境的D3D接口封装有问题,会错误传递参数调用约定。
可落地解决方案
- 参数适配方案:如果确认是YUY2格式创建失败,先强制对齐宽度到2的倍数、高度到4的倍数,同时将
Usage参数改为Usage.Dynamic搭配Pool.Default,Wine staging 6.x版本对动态离屏表面的YUY2格式支持更完善。
// 调整后的示例代码 surface = Surface.CreateOffscreenPlainEx(_device, (width + 1) & ~1, // 宽度对齐到2的倍数 (height + 3) & ~3, // 高度对齐到4的倍数 useRgb ? Format.X8R8G8B8 : Format.Yuy2, Pool.Default, Usage.Dynamic); // 替换Usage.None为Usage.Dynamic
- Wine环境调整方案:升级到Wine 7.0及以上staging版本,该版本修复了大量D3D9离屏表面创建的兼容性问题;也可以在Wine配置中启用
csmt(命令流多线程)选项,关闭d3d9.dll的自定义替代,强制使用Wine原生实现。 - 接口替换方案:如果上述方案均无效,可放弃
CreateOffscreenPlainEx接口,改用CreateRenderTarget接口创建相同规格的表面,两者在离屏渲染、视频帧写入场景下功能基本一致,Wine对CreateRenderTarget的兼容性更好。
内容的提问来源于stack exchange,提问作者Ksnadr Renderon
相关产品推荐
相关产品推荐

