首页 > 解决方案 > 使 GL 纹理异步上传并确定何时完成上传

问题描述

我遇到了一个问题,我的应用程序需要在运行时动态加载图像。这最终成为一个问题,因为无法预先加载它们,因为我不知道将使用哪些......否则我必须上传所有内容。问题是有些人没有好的 PC,并且一直抱怨由于硬件不好,将所有图像加载到 GPU 需要很长时间。

我为后一组的工作是根据需要上传纹理,这在很大程度上是有效的。问题是在申请过程中,有时需要上传一系列图片时会出现延迟,并且由于上传而出现延迟。

我正在研究如何解决这个问题,我有一个想法:用户希望获得流畅的体验,并且如果纹理没有立即加载而是不存在则可以。这很容易,因为我可以在后台上传,然后不为对象应该在的位置绘制任何内容,然后在完成后将其变为存在。这是可以接受的,因为无论如何上传通常都非常快,但是它们足够慢,以至于对于某些人来说它会下降到 60 fps 以下,这会导致一些口吃。平均而言,它会导致 1-3 帧的卡顿,因此上传确实可以快速解决,平均不到 50 毫秒。

我的解决方案是尝试使用 PBO 进行一些类似异步的上传。问题是我无法在网上找到如何知道上传何时完成。有没有办法做到这一点?

我认为有四种选择:

  1. 从 OpenGL 3.1 开始,有一种方法可以做我想做的事,那就是
  2. 这是不可能的(1),但我可以放置一个栅栏,然后检查栅栏是否已经完成,但是我以前从来没有这样做过,所以我不确定它在这种情况下是否有效
  3. 这是不可能的,但我可以假设所有内容都将在 < 50 毫秒内上传,并使用某种时间戳来判断它是否可以绘制,并希望是这样(如果时间是自发出上传,然后什么都不画)
  4. 对于纹理上传,这是不可能的,我被卡住了

这引出了我的问题:我可以知道何时将像素异步上传到纹理完成了吗?

标签: opengl

解决方案


Fence 同步对象告诉所有以前发出的命令何时完成执行。这包括异步像素传输操作。因此,您可以在传输后发出栅栏,并使用同步对象工具检查何时完成。

您在这里遇到的烦人问题是它的粒度非常粗。测试栅栏还包括测试是否也完成了任何非传输命令,尽管这两个操作可能由独立的硬件处理。因此,如果在开始传输之前渲染的帧完成渲染之前传输完成,则仍然不会设置栅栏。但是,如果您一次启动大量纹理上传,则传输操作将主导结果。


推荐阅读