Opengl es 转换反馈:将多个反馈批处理在一起

Opengl es 转换反馈:将多个反馈批处理在一起,opengl-es,transform-feedback,Opengl Es,Transform Feedback,目标:OpenGL ES>=3.0 以下是我的应用程序的功能: generateSeveralMeshes() setupStuff(); for (each Mesh) { glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, myBuf); glBeginTransformFeedback( GLES30.GL_POINTS); callOpenGLToGetTransformFeedback(); glMap

目标:OpenGL ES>=3.0

以下是我的应用程序的功能:

generateSeveralMeshes()
setupStuff();

for (each Mesh)
  {
  glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, myBuf);
  glBeginTransformFeedback( GLES30.GL_POINTS);
  callOpenGLToGetTransformFeedback();
  glMapBufferRange(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, ...)   // THE PROBLEM
  computeStuffDependantOnVertexAttribsGottenBack();
  glUnmapBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER);
  glEndTransformFeedback();
  glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);

  renderTheMeshAsNormal();
  }
i、 e.对于每个网格,它首先使用顶点着色器计算一些逐顶点的内容,将这些内容返回给CPU,根据CPU做出一些决定,然后才渲染网格

这是可行的,问题是速度。我们已经在几个基于OpenGL ES 3.0、3.1、3.2的设备上进行了测试,每个设备上的情况看起来都是一样的:“glMapBufferRange()”调用将FPS减少了一半左右

我怀疑,如果没有glMapBufferRange(),OpenGL可以“延迟”渲染,即将多个渲染集中在一起,并根据自己的方便进行渲染,而如果我们调用glMapBufferRange(),它确实需要立即渲染,这可能会使渲染速度变慢(我们返回的数据量非常小,我真的认为这不是问题)

因此,我也想批量处理我的转换反馈,如下所示:

generateSeveralMeshes()
setupStuff();

for (each Mesh)
  {
  glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, myLargerBuf);
  glBeginTransformFeedback( GLES30.GL_POINTS);
  setupOpenGLtoSaveTransformFeedbackToSpecificOffset();
  callOpenGLToGetTransformFeedback();
  advanceOffset();
  glEndTransformFeedback();
  glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);

  renderTheMeshAsNormal();
  }

glMapBufferRange(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, ...)
computeStuffDependantOnVertexAttribsGottenBackInOneBatch();
glUnmapBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER);
问题是,我不知道如何告诉OpenGL将变换反馈输出保存到变换反馈缓冲区中的特定偏移量,而不是保存到开始处(这样,在循环之后,我就可以一次获得所有TF数据)


有什么建议吗?

性能问题是管道问题-您基本上是在强制GPU与CPU保持同步,因为
glMapBufferRange()
必须阻塞,直到结果可用为止。这是“非常糟糕的”-所有GPU(尤其是移动设备中基于磁贴的GPU)都依赖于驱动程序建立一个工作队列,该队列与应用程序异步运行,从而保持前进压力以保持硬件繁忙。应用程序执行任何强制同步和耗尽管道的操作都会破坏性能

这里有一个很好的博客:

通常,如果您在CPU上读回数据,则在将生成数据的draw调用排入队列后,只会将数据读回一到两帧。(在GPU上消费结果没有这个问题-这将是管道)


要将缓冲区偏移量绑定到转换反馈缓冲区,请按照注释使用
glBindBufferRange()

Hmm,阅读OpenGL ES规范-这难道不只是调用“glBindBufferRange(GLES30.GL\u transform\u feedback\u buffer,0,myLargerBuf,offset,buffersizegodforcurrentmesh)”吗?