WPF 应用程序和 DirectX 光栅器中的访问冲突异常
Posted
技术标签:
【中文标题】WPF 应用程序和 DirectX 光栅器中的访问冲突异常【英文标题】:Access Violation exception in WPF application and DirectX rasterizer 【发布时间】:2014-09-12 03:12:19 【问题描述】:我有一个 WPF 应用程序,经过一些琐碎的操作(打开和关闭一些应用程序控件)后崩溃了。当我打开故障转储文件时,我看到异常是
FAULTING_IP:
rgb9rast!D3D8RGBRast::CRGBContext::PackGenVertex+b4
000007fe`f7625b88 428b0c10 mov ecx,dword ptr [rax+r10]
EXCEPTION_RECORD: ffffffffffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 000007fef7625b88 (rgb9rast!D3D8RGBRast::CRGBContext::PackGenVertex+0x00000000000000b4)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 0000000000000000
Parameter[1]: 000000009f011620
Attempt to read from address 000000009f011620
这表明directx光栅化中的访问冲突错误,并且错误的线程堆栈跟踪是(我省略了调用地址)
rgb9rast!D3D8RGBRast::CRGBContext::PackGenVertex+0xb4
rgb9rast!D3D8RGBRast::CRGBContext::DoDrawOneGenIndexedPrimitive+0x72b
rgb9rast!D3D8RGBRast::CRGBContext::DP2DrawIndexedPrimitive2+0x1d4
rgb9rast!DX8SDDIFW::SDP2MFnParser::ParseDP2<DX8SDDIFW::CStdDrawPrimitives2<D3D8RGBRast::CRGBContext,D3D8RGBRast::CRGBStateSet,D3D8RGBRast::static_hash_map<unsigned long,D3D8RGBRast::CRGBStateSet,32,D3D8RGBRast::hash<unsigned long>,std::equal_to<unsigned long>,D3D8RGBRast::allocator<std::pair<unsigned long const ,D3D8RGBRast::CRGBStateSet> > >,DX8SDDIFW::CDP2DataWrap<D3D8RGBRast::SDP2NextCmdExt>,D3D8RGBRast::block<long (__cdecl D3D8RGBRast::CRGBContext::*)(DX8SDDIFW::CDP2DataWrap<D3D8RGBRast::SDP2NextCmdExt> & __ptr64,_D3DHAL_DP2COMMAND const * __ptr64,void const * __ptr64) __ptr64,89>,D3D8RGBRast::block<long (__cdecl D3D8RGBRast::CRGBContext::*)(_D3DHAL_DP2COMMAND const * __ptr64,void * __ptr64) __ptr64,89> >::TMFnCaller,D3D8RGBRast::block<long (__cdecl D3D8RGBRast::CRGBContext::*)(DX8SDDIFW::CDP2DataWrap<D3D8RGBRast::SDP2NextCmdExt> & __ptr64,_D3DHAL_DP2COMMAND const * __ptr64,void const * __ptr64) __ptr64,89>,DX8SDDIFW::CConstDP2CmdIterator<D3D8RGBRast::SDP2NextCmdExt> >+0x69
rgb9rast!DX8SDDIFW::CStdDrawPrimitives2<D3D8RGBRast::CRGBContext,D3D8RGBRast::CRGBStateSet,D3D8RGBRast::static_hash_map<unsigned long,D3D8RGBRast::CRGBStateSet,32,D3D8RGBRast::hash<unsigned long>,std::equal_to<unsigned long>,D3D8RGBRast::allocator<std::pair<unsigned long const ,D3D8RGBRast::CRGBStateSet> > >,DX8SDDIFW::CDP2DataWrap<D3D8RGBRast::SDP2NextCmdExt>,D3D8RGBRast::block<long (__cdecl D3D8RGBRast::CRGBContext::*)(DX8SDDIFW::CDP2DataWrap<D3D8RGBRast::SDP2NextCmdExt> & __ptr64,_D3DHAL_DP2COMMAND const * __ptr64,void const * __ptr64) __ptr64,89>,D3D8RGBRast::block<long (__cdecl D3D8RGBRast::CRGBContext::*)(_D3DHAL_DP2COMMAND const * __ptr64,void * __ptr64) __ptr64,89> >::DrawPrimitives2+0x345
rgb9rast!DX8SDDIFW::CSubDriver<D3D8RGBRast::CRGBDriver,D3D8RGBRast::CRGBContext,D3D8RGBRast::CRGBSurfAllocator,D3D8RGBRast::CRGBPerDDrawData,D3D8RGBRast::set<D3D8RGBRast::CRGBContext * __ptr64,std::less<D3D8RGBRast::CRGBContext * __ptr64>,D3D8RGBRast::allocator<D3D8RGBRast::CRGBContext * __ptr64> >,D3D8RGBRast::map<_DDRAWI_DIRECTDRAW_LCL * __ptr64,D3D8RGBRast::CRGBPerDDrawData,std::less<_DDRAWI_DIRECTDRAW_LCL * __ptr64>,D3D8RGBRast::allocator<std::pair<_DDRAWI_DIRECTDRAW_LCL * __ptr64 const,D3D8RGBRast::CRGBPerDDrawData> > >,D3D8RGBRast::set<D3D8RGBRast::IRGBSurface * __ptr64,std::less<D3D8RGBRast::IRGBSurface * __ptr64>,D3D8RGBRast::allocator<D3D8RGBRast::IRGBSurface * __ptr64> >,DX8SDDIFW::SFakeEntryPointHook<D3D8RGBRast::CRGBDriver> >::DrawPrimitives2+0x26
d3d9!SwDrawPrimitives2+0x7c
d3d9!CD3DDDIDX8::FlushStates+0x161
d3d9!CD3DBase::FlushStatesNoThrow+0x22
d3d9!CVertexBuffer::Lock+0xce
d3d9!CVertexBufferMT::Lock+0x7e
d3d9!CTLStream::Lock+0x6d
d3d9!CD3DDDIDX8::StartPrimTL+0x3b
d3d9!CD3DDDIDX8::ProcessIndexedPrimitiveC+0xa0
d3d9!CD3DBase::DrawIndexedPrimitive+0x489
wpfgfx_v0400!CD3DDeviceLevel1::DrawIndexedTriangleList+0x49
wpfgfx_v0400!CHw3DGeometryRenderer<unsigned long>::Render+0x152
wpfgfx_v0400!CHwShader::FixedFunctionDrawMesh3D+0x158
wpfgfx_v0400!CHwShader::DrawMesh3D+0x88
wpfgfx_v0400!CHwSurfaceRenderTarget::DrawMesh3D+0x1fb
wpfgfx_v0400!CHw3DSoftwareSurface::DrawMesh3D+0x38
wpfgfx_v0400!CSwRenderTargetSurface::DrawMesh3D+0x49
wpfgfx_v0400!CMetaRenderTarget::DrawMesh3D+0xee
wpfgfx_v0400!CModelRenderWalker::RealizeMaterialAndRender+0x17a
wpfgfx_v0400!CModelRenderWalker::ProcessMaterialAndRender+0x160
wpfgfx_v0400!CModelRenderWalker::RenderGeometryModel3D+0x11b
wpfgfx_v0400!CModelRenderWalker::PreSubgraph+0x19
wpfgfx_v0400!CModelIterator::Walk+0x64
wpfgfx_v0400!CModelRenderWalker::RenderModels+0x70
wpfgfx_v0400!CRender3DContext::PreSubgraph+0xd3
wpfgfx_v0400!CGraphIterator::Walk+0x4b
wpfgfx_v0400!CRender3DContext::Render+0xd9
wpfgfx_v0400!CDrawingContext::Render3D+0x277
wpfgfx_v0400!CMilViewport3DVisual::RenderContent+0x50
wpfgfx_v0400!CDrawingContext::PreSubgraph+0x766
wpfgfx_v0400!CGraphIterator::Walk+0x4b
wpfgfx_v0400!CDrawingContext::DrawVisualTree+0x23d
wpfgfx_v0400!CDrawingContext::Render+0x393
wpfgfx_v0400!CSlaveHWndRenderTarget::Render+0x206
wpfgfx_v0400!CRenderTargetManager::Render+0x4d
wpfgfx_v0400!CComposition::Render+0x28
wpfgfx_v0400!CComposition::ProcessComposition+0x13a
wpfgfx_v0400!CComposition::Compose+0x51
wpfgfx_v0400!CPartitionThread::RenderPartition+0x28
wpfgfx_v0400!CPartitionThread::Run+0x61
wpfgfx_v0400!CPartitionThread::ThreadMain+0x1c
kernel32!BaseThreadInitThunk+0xd
ntdll!RtlUserThreadStart+0x1d
这只发生在我检查应用程序的某些 PC 上。都有 .Net 4.5 和 Directx 11。 这可能是什么原因?在调试/调查转储文件时,我看不到任何可能导致该问题的托管代码。我唯一的提示是我的应用程序中有一些 3D 内容,这可能与某些 3D 渲染有关错误线程堆栈跟踪中的方法。
【问题讨论】:
你能理解发生了什么吗?这是固定的吗?我认为我们的转储文件中有相同的堆栈跟踪。任何帮助将不胜感激(即使您不记得了:)) @ChuckNorris 作为部分解决方案/测试,尝试关闭软件渲染,看看您是否仍然遇到崩溃。另外,如果是我,我会尝试创建一个 minimal reproducible example 来重现这一点。我意识到这将花费您大量时间来慢慢删除代码以将其缩小到较小的程度,但可能会让您朝着目标前进。 有一个相关的(但现在被删除为“已放弃”)的问题没有得到回答:***.com/questions/57219993/… 也许有些信息是相关或有用的。 @LynnCrumbling 好主意!谢谢 这是提到的半相关已删除问题的文本:pastebin.com/cWtDB0D7 【参考方案1】:DirectX Rasterize(如果我没记错的话,9 及以上)决定了三角形的绘制方式。给定三角形的三个点 - 您可以顺时针或逆时针绘制它们,还可以确定三角形的表面是朝内还是朝外 - 这提供了交点。
它还提供了设置 Multisample 和 AntialiasedLine 的功能 - 这些功能(高处理)允许渲染更平滑的线条。请记住,2D 屏幕中并不真正存在直线 - 您可能熟悉计算机图形或锯齿形中的楼梯效果。
现在,当我们使用 DirectX 时,我们实际上是在对计算机显卡的 GPU 进行编程。因此显卡必须支持 DirectX - 取决于版本。
检查您电脑的硬件并确定 onbard 或 PCI 显卡是否兼容 DirectX11。
您还可以调整您的 WPF 应用程序渲染设置 - 如果您愿意,可以将其调低或在 here 将其全部关闭
更多信息:
来自 MSDN documentation:
注意 ProcessRenderMode 指定一个首选项,并不一定会改变实际的渲染模式。系统的其他部分可能会覆盖此首选项并强制系统进行软件渲染。
您可以在窗口搜索框中使用 dxdiag 检查系统 DirectX 信息(我认为是 Window 7 及更高版本)。
【讨论】:
感谢您的回答。正如我在我的一个 cmets 中提到的,我们正在使用 SoftwareOnly 渲染,所以我根本不知道 GPU 可以如何参与其中。另一方面,我们的应用程序中不使用任何绘图等。当它在 SoftwareOnly 模式下使用时,这听起来像是一个内部 WPF 错误。我们想了解是什么部分导致了这种情况以及我们如何解决它。 我看到了你的更新。但我看不出我们该如何解决这个错误。 你能分享应用程序 - 或应用程序的演示吗? 企业级应用挺大的,我不觉得可以分享一下。 我完全理解 - 我唯一可以建议的是在每个渲染的窗口中设置 SoftwareOnly - 或者可能添加一些日志记录以查看在流程中触发异常的位置 -以上是关于WPF 应用程序和 DirectX 光栅器中的访问冲突异常的主要内容,如果未能解决你的问题,请参考以下文章
在 C# WPF 或 Windows 窗体应用程序中使用 DirectX c++ DLL
DirectX OMSetRenderTargets 中的访问冲突