在调试版本中调用OpenGL之后检查OpenGL错误状态可以成为查找OpenGL代码中的错误的宝贵工具。但是在分配纹理或其他OpenGL资源时会出现内存不足等错误呢?处理或避免这些错误的最佳做法是什么?
在大多数情况下,OpenGL资源分配失败可能会致命,那么一个程序是否应该尝试分配合理数量的资源并希望最好?在不同平台上的实际项目中使用了哪种方法,例如在PC和移动平台上?
答案 0 :(得分:6)
对此没有“一刀切”的方法。这一切都取决于应用程序及其重要性。一般规则是:在可能的情况下优先安全地失败。
在游戏的情况下,最好的行动方案是保存当前游戏状态的快照(在关键点之前和之后添加自动保存点是个好主意)终止游戏过程并向用户显示失败的可理解的原因;如果有一个保存游戏向他保证他的进步不会丢失。
在医疗诊断系统的情况下,通知用户图形显示已损坏,并且他不得使用屏幕上当前可见的内容进行任何进一步的诊断。
对于飞行控制器显示器,医疗系统或类似应用程序,其中完全失败不是一种选择,您的系统必须以某种方式构建,以便将故障部件隔离并且有足够的冗余部分失败和备份,操作可以正常开始。
例如,飞行控制器显示器不是由单台计算机供电,而是每台显示器都有(IIRC)三台独立运行的计算机,产生相同的输出,其编程不同,因此其中一台计算机的编程故障将导致与其他2.每台计算机将其内部状态提供给仲裁器,以确保所有计算机都同意其数据。显示信号本身通过另一个独立的比较仲裁器进行馈送,该仲裁器比较显示输出,并在发生故障时禁用有问题的系统输出。答案 1 :(得分:6)
在为纹理和顶点缓冲区分配资源时,内存不足是最近罕见的一面。如果遇到这种情况,您应该已经知道自己正在接近系统要求的限制,并且拥有足够智能的资源管理器来处理它。
在PC频谱中,可用内存量变得越来越不相关,难以定义。纹理正在成为虚拟化资源,其中当在着色器中引用特定子区域时(Sparse Textures在OpenGL 4.4术语中,或Tiled Resources in D3D 11.2条款)。您可能还会听到此功能称为部分常驻纹理,这是我最常使用的术语。
由于部分驻留纹理(PRT)是DX 11.2+ PC硬件的架构趋势和Xbox One / PS4的一个关键特性,可用内存量将越来越少的应用程序终止事件。当必须为页面错误提供服务时(例如,第一次引用部分纹理的内存),这将更多地是性能故障,并且必须小心谨慎以尽量减少颠簸。这与10年前的情况确实没有太大的不同,除了纹理完全驻留或完全不驻留,现在纹理图集或mipmap级别中的单个图块可能具有不同的状态。处理内存故障的方式实际上可以为更高效的程序生成内容和基于光学/网络的存储流进行打开。
话虽如此,虚拟化内存资源并不是接近实时应用程序和/或嵌入式应用程序的最有效方式。通常需要额外的硬件来处理内存映射,并且在发出非驻留资源的内存提取时引入额外的延迟。在移动领域,我怀疑PRT会发生很大的变化,在这里你仍然可以从低级内存管理和纹理分配之前的代理纹理等方面受益;不幸的是,OpenGL ES甚至不支持代理纹理。
您的资源管理器应设计为保留为所有类型的资源分配的内存的运行选项卡。它不会完全准确,因为OpenGL隐藏了很多细节,但它会给你一个大局。您将能够立即看到从RGBA16F渲染缓冲区切换到RGBA8可以节省X多个字节的内存,或者从一个顶点缓冲区中消除1个顶点属性会改变存储要求。您可以在分配资源时插入自己的检查,并在运行时将其作为断言失败等处理。最好定义和监控自己的阈值,而不是仅在OpenGL无法满足内存请求时才会抱怨。