何时将数据发送到使用openGL的GPU

Aco*_*orn 3 c++ opengl

我一直在研究使用OpenGL编写应用程序来在屏幕上呈现数据,并且有一件事情不断出现 - 将数据复制到GPU中的速度很慢.

我目前正在阅读OpenGL SuperBible第7版和在线阅读各种教程之间切换,而且当数据实际发送到GPU时我没有遇到过,我只是猜测.

  1. 当我调用glBufferStorage/ 时,是否在GPU的内存中分配了空间glCreateVertexArrays?或者这个空间是在我的应用程序的内存中分配的,然后在以后复制?
  2. 指针是从glMapBuffer*指向GPU内存的指针返回的,还是指向我的应用程序内存中分配的空间的指针,然后在以后复制?
  3. 假设数据存储在我的应用程序内存中并复制到GPU,实际复制的数据是什么时候?我打电话的时候glCrawArrays

Nic*_*las 8

1:glCreateVertexArrays与缓冲对象或GPU内存(那种)没有任何关系,所以它有点无关紧要.

至于其余的,当OpenGL决定分配实际GPU内存时,由OpenGL实现.它可以根据需要推迟实际分配.

如果您询问何时将数据上传到OpenGL,那么当该函数调用返回时,OpenGL将始终使用您传递的任何指针.因此,实现将数据复制到调用本身内的GPU可访问内存,或者它将分配一些CPU内存并将数据复制到其中,安排传输到实际的GPU存储以供日后使用.

实际上,您应该假设不会立即复制到缓冲区.这是因为DMA通常需要某些内存对齐,而您传递的指针可能没有这种对齐方式.

但通常,你不应该在乎.让实施完成它的工作.

2:与上面一样,实现可以在映射内存时执行任何操作.它可能会为您提供GPU可访问内存的真正指针.或者它可能只是分配一块CPU内存并在取消映射内存时将其DMA.

唯一的例外是持久映射.该功能要求 OpenGL为您提供指向缓冲区所在的实际GPU可访问内存的实际指针.这是因为您在完成对内存的写入/读取操作时从未实际告知实现.

这也是(部分)为什么OpenGL要求您不可分割地分配缓冲存储以便能够使用持久映射的原因.

3:只要实现感觉需要,就会复制它.

OpenGL实现是一个黑盒子.他们所做的事情或多或少取决于他们.规范的唯一要求是它们的行为"好像"它按照规范所说的方式进行操作.因此,每当实现感觉像复制它时,数据都可以被复制,只要一切仍然"好像"它立即复制它.

进行绘制调用不需要此绘制命令所依赖的任何缓冲区DMA已在此时完成.它只需要在GPU实际执行绘图命令之前发生这些DMA .实现可以通过阻塞glDraw*调用直到DMA完成来实现.但它也可以使用内部GPU同步机制将发出的绘图命令与DMA操作的完成联系起来.

唯一可以保证上传实际完成的是调用一个能让GPU访问缓冲区的函数,然后将CPU与该命令同步.仅在上传后进行同步并不能保证任何内容.上传本身不是可观察的行为,因此同步可能没有效果.

然后,它可能会.这才是重点; 你无法知道.