C++ 已超出DirectX11视频内存

C++ 已超出DirectX11视频内存,c++,memory,directx-11,direct3d,C++,Memory,Directx 11,Direct3d,我有一个渲染循环,用于侦听笔板输入并从顶点/索引缓冲区(以及其他内容)绘制。顶点数据可能会增长,当它达到某些级别时,DispatchMsg(&msg)会遇到以下情况: Unhandled exception at 0x5DDBDEF0 (msvcr110d.dll) in App.exe: 0xC0000005: Access violation writing location 0x00000000. 场景中分配的顶点和索引缓冲区的总大小每次大致相同: Total Vertices coun

我有一个渲染循环,用于侦听笔板输入并从顶点/索引缓冲区(以及其他内容)绘制。顶点数据可能会增长,当它达到某些级别时,DispatchMsg(&msg)会遇到以下情况:

Unhandled exception at 0x5DDBDEF0 (msvcr110d.dll) in App.exe: 0xC0000005: Access violation writing location 0x00000000.
场景中分配的顶点和索引缓冲区的总大小每次大致相同:

Total Vertices count: 10391370
Total Indices count: 41565480
Total Vertices size: 249392880 (bytes)
Total Indices size: 997571520 (bytes)
在另一个抽样中:

Total Vertices count: 9969300
Total Indices count: 39877200
Total Vert size: 239263200
Total Indices size: 957052800
顶点缓冲区和索引缓冲区都是D3D11\u默认值。场景中的总大小分配高于上面列出的,但较小的缓冲区经常被释放。末尾的顶点/索引缓冲区中也有一些填充

每次(当到达异常时)将要发送的消息是581,我相信可能是:

#define WM_POINTERUPDATE                0x0245

我真的不介意场景渲染速度慢,但是如果我达到某个最大内存分配(视频内存?),是否有一种方法可以让内存以牺牲速度的方式缓慢地从主内存分页到主内存?我尝试禁用调用像素、顶点着色器和绘图调用的draw()调用,但仍然出现异常。我更喜欢速度折衷或解决方法,而不是例外。

找到了答案并解决了问题。根据我的输入顶点计数,CreateBuffer失败或malloc/HeapAlloc失败

我仍然不能100%确定GPU是否应该在某一点后将内存分页到主系统内存,或者这是不可避免的,因为在每一帧的计算(深度、照明等)期间场景数据必须保留在GPU内存中,但我认为a)分页只有在我手动解除锁定/重新锁定缓冲区时才可能(无论如何都会很慢)和B)分配缓冲区(顶点、索引..)的大小是问题所在,而不是它们的每帧计算

我尝试切换到其他缓冲区使用(USAGE_DYNAMIC),但分配失败仍然发生在相同的级别上

我对缓冲区大小(需要填充的缓冲区)进行了快速更改,现在至少有2000万个顶点。我的GPU相当旧,所以这还不错,尽管我知道有些渲染器可以远远超出这个范围

将重点放在解决方法上,并尽可能减少细节。我想我可以通过tesselation获得约15倍的细节,所以状态不错


如果有人有更多的见解,可以切换到正确的答案,但不确定我是否会选择另一条路径。

从您问题中的数字来看,您似乎为顶点和索引数据分配了大量内存(约1.2GB)。如果您的应用程序是32位(x86,而不是x64),那么它只能访问2GB内存,因此很可能是您的进程内存不足

GPU可以访问部分系统内存(与GPU内存相比速度非常慢,但总比完全没有内存要好)。对于英伟达GPU,NVIDIA控制面板显示“系统信息”>“共享系统内存”;这通常是系统内存总量的一半。据我所知,这个系统内存占用了进程地址空间的一部分

如果你的“相当老”的GPU有512MB的内存,它将需要大约768MB的额外系统内存来满足你的内存请求。这将为您的应用程序留出1.2GB的空间。我猜您的应用程序试图在阵列中分配1.2GB的系统内存,这些阵列将获取您想要上传到GPU的几何数据。这正好合适,但您的应用程序代码也需要在某个地方。在这个假设的例子中,您已经耗尽了内存。当然,一旦将几何体数据上传到GPU,您就可以去掉系统内存阵列,但此时,系统没有足够的内存来创建您请求的大小的GPU内存缓冲区

将项目切换为64位(VisualStudio中的x64)将使您的进程占用大量内存(在大多数情况下,直到系统和页面文件中可用的内存),并解决您的问题。如果内存限制确实是问题所在

另一件事:我注意到——假设你的数字是正确的——你为索引缓冲区为每个索引分配24个字节,就像你为顶点缓冲区中的每个顶点分配的一样多。对吗?索引(只是顶点缓冲区的偏移量)不应大于4字节。您是否真的试图分配6倍于您实际需要的GPU内存,或者这是应用程序中的错误计算


如果您快速释放并在GPU上重新创建一个缓冲区,那么D3D可能会将“旧”缓冲区保留一段时间(至少只要它仍然绑定到GPU管道),因此它可能会因此而内存不足。因此,通过调用
iAssetVertexBuffers(NULL,0,0,0)
iAssetDexBuffer(NULL,DXGI格式,0)
,实际上解除即将释放的缓冲区的绑定可能会有所帮助?这似乎有很多数据。1000万个顶点?没错,似乎很高,所以我预计在某个时候会出现问题,只是想找出原因或者可以做些什么。这是很多顶点。我很惊讶你能在没有着火的情况下分配这么多。你是不是创造了太多的东西,比如说不知何故泄露了它们?是的,有一些是重复的,有些是插值的,所以我一直在研究一些算法来消除这些,但任何解决方法都可能是一种时间投资。这个场景反应非常灵敏(比我需要的多),有很多细节,但我不想放弃,除非我达到一个硬极限(或超过一个)。我最终会在每个帧中释放并重新分配块,但这可能会非常慢。索引占用的内存量似乎相当高(每个索引24字节;应该是4字节)。你确定没有分配太多内存吗?索引分配可能已关闭,但每个顶点都被大量重复使用以构建一个p