【问题标题】:SlimDX stops loading big textures after a whileSlimDX 在一段时间后停止加载大纹理
【发布时间】:2017-03-20 15:46:53
【问题描述】:

我的应用程序有时会初始化一堆 DirectX 内容并加载场景,有时会包含一些大型纹理(每个纹理最多 200–300 MB)。起初,一切正常,但一段时间后FromMemory() 停止工作,但仅适用于大纹理:

SlimDX.Direct3D11.Direct3D11Exception: E_FAIL: An undetermined error occurred (-2147467259)
  at SlimDX.Result.Throw[T](Object dataKey, Object dataValue)
  at SlimDX.Result.Record[T](Int32 hr, Boolean failed, Object dataKey, Object dataValue)
  at SlimDX.Direct3D11.ShaderResourceView.ConstructFromMemory(Device device, Byte[] memory, D3DX11_IMAGE_LOAD_INFO* loadInformation)
  at SlimDX.Direct3D11.ShaderResourceView.FromMemory(Device device, Byte[] memory)

当然,我会在加载新场景之前处理所有之前加载的ShaderResourceViews。但是FromMemory() 只有在应用重启后才能重新开始工作。你能告诉我还有什么问题吗?

UPD:

有了Texture2D.FromMemory(),我明白了:

System.Runtime.InteropServices.SEHException (0x80004005): External component has thrown an exception.
  at D3DX11CreateTextureFromMemory(ID3D11Device* , Void* , UInt32 , D3DX11_IMAGE_LOAD_INFO* , ID3DX11ThreadPump* , ID3D11Resource** , Int32* )
  at SlimDX.Direct3D11.Resource.ConstructFromMemory(Device device, Byte[] memory, D3DX11_IMAGE_LOAD_INFO* info)
  at SlimDX.Direct3D11.Texture2D.FromMemory(Device device, Byte[] memory)

并启用本机代码调试:

Exception thrown at 0x748AA882 in app.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x00AFC7C8.
Exception thrown: 'System.Runtime.InteropServices.SEHException' in SlimDX.dll

遗憾的是,我不知道D3DX11CreateTextureFromMemory() 的实际工作原理以及它为什么尝试重新分配内存。也许是时候迁移到 x64 了……

【问题讨论】:

  • 您使用的是 32 位 (x86) 还是 64 位本机?您可能正在分割视频内存或出现“内存不足”的情况,但在不寻常的地方出现错误(因此E_FAIL)。尝试从调试设备中寻找任何输出。
  • @ChuckWalbourn 32 位,但通常占用的 RAM 不超过 ≈200 MB(除了加载场景的那些时间,但每个场景通常只有一个巨大的 200 MB 纹理— 用于 360° 全景)。遗憾的是,我在调试中找不到任何有用的信息。 EnableObjectTrackingDetectDoubleDispose 都已启用,看起来一切都已妥善处理。
  • 检查设备的 max_texture 大小,它不会加载超过 192MB 的纹理。
  • 尝试使用 DeviceCreationFlags.Debug 创建您的设备,并在您的项目属性中(假设您使用的是 Visual Studio 2015),在“调试”选项卡中,勾选“启用本机代码调试”选项。这将在输出窗口中为您提供详细的错误报告(发布这些消息将帮助我们解决您的问题)
  • @catflier,谢谢,现在情况更清楚了。

标签: directx directx-11 slimdx


【解决方案1】:

发现问题。原来我所要做的就是将“LARGEADDRESSAWARE”标志添加到可执行文件中。没有它,1 GB 是极限——每个纹理 300 MB 很容易实现。

当然,由于大部分数据最终都存储在大对象堆中,GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce 也有帮助。

很抱歉浪费了您的时间。

【讨论】:

    猜你喜欢
    • 2015-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多