首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >超出DirectX11视频内存

超出DirectX11视频内存
EN

Stack Overflow用户
提问于 2017-02-10 08:23:41
回答 2查看 590关注 0票数 1

我有一个呈现循环,它监听手写板输入,并从顶点/索引缓冲区绘制(以及其他内容)。顶点数据可以增长,当达到特定级别时,DispatchMsg(&msg)会遇到以下情况:

代码语言:javascript
复制
Unhandled exception at 0x5DDBDEF0 (msvcr110d.dll) in App.exe: 0xC0000005: Access violation writing location 0x00000000.

场景中分配的顶点缓冲区和索引缓冲区的总大小每次都大致相同:

代码语言:javascript
复制
Total Vertices count: 10391370
Total Indices count: 41565480
Total Vertices size: 249392880 (bytes)
Total Indices size: 997571520 (bytes)

在另一个采样中:

代码语言:javascript
复制
Total Vertices count: 9969300
Total Indices count: 39877200
Total Vert size: 239263200
Total Indices size: 957052800

顶点和索引缓冲区都是D3D11_USAGE_DEFAULT。场景中分配的总大小高于上面列出的大小,但通常会释放较小的缓冲区。在结尾处的顶点/索引缓冲区也有一些填充。

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

代码语言:javascript
复制
#define WM_POINTERUPDATE                0x0245

我真的不介意场景渲染速度慢,但是如果我达到了最大内存分配(视频内存?)有没有办法让内存以速度为代价缓慢地向内存分页或从主存分页?我尝试禁用调用像素、顶点着色器和绘制调用的draw()调用,但仍然发生异常。我更喜欢速度权衡或变通而不是异常。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-04-10 17:00:30

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

GPU可以访问部分系统内存(与GPU内存相比,这相当慢,但总比根本没有内存要好)。例如,对于NVidia GPU,NVidia控制面板在“系统信息”>“共享系统内存”下显示它;这通常是系统中内存总量的一半。据我所知,这个系统内存占用了进程地址空间的一部分。

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

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

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

如果您快速释放,然后在GPU上重新创建缓冲区,那么D3D可能会将“旧”缓冲区保留一段时间(至少只要它仍然绑定到GPU流水线),因此它可能会因此而内存不足。因此,实际上解除绑定您将要释放的缓冲区(通过调用IASetVertexBuffers(NULL, 0, 0, 0, 0)IASetIndexBuffer(NULL, DXGI_FORMAT_R16_UINT, 0))可能会有所帮助。

票数 1
EN

Stack Overflow用户

发布于 2017-02-16 13:11:24

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

我仍然不能百分之百确定GPU是否应该在某个点之后将内存分页到主系统内存,或者这是否不可避免,因为在每个帧的计算期间(深度、光照等),场景数据必须保留在GPU内存中,但我认为A)分页只有在手动取消分配/重新分配缓冲区(无论如何都会很慢)的情况下才可能实现,B)分配的缓冲区的大小(顶点、索引)。是问题所在,而不是它们上的每帧计算。

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

我对缓冲区大小(需要填充的缓冲区)进行了快速更改,现在达到了至少2000万个顶点。我的GPU是相当老的,所以这是不坏的,虽然一些渲染器可以远远超过这一点,我知道。

将重点放在解决方法上,并在可能的时候减少细节。我想我可以通过镶嵌来获得15倍的细节,所以效果还不错。

如果任何人有更多的见解,可以将你的答案转换为正确的答案,但不确定我是否要在这里采取另一条道路。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42149440

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档