14

I want to update an object's list of vertices after a VBO has been created. I've seen both glBufferSubData and glMapBuffer and they both appear to do similar things, which means I'm now unsure which one to use.

My pseudo workflow is:

Create object
Begin vertex update (calls glBufferData with data = nullptr)
Update object's vertices
End vertex update (takes the updated vertices and either calls glBufferSubData or glMapBuffer)

Mark Ingram
  • 65,792
  • 48
  • 164
  • 225

1 Answers1

22

Both work.

If you intend to update the vertices often (every frame or so), I recommend avoiding glBufferSubData, which requires one more memcpy in the driver. glMapBuffer/glMapBufferRange usually gets you more perf.

If you update only rarely, glBufferSubData will do fine.

See also chapter 28 of OpenGL Insights ( free : http://openglinsights.com/ )

Calvin1602
  • 9,021
  • 2
  • 38
  • 55
  • 4
    gl...Data does not absolutely require to make a copy of the data. A good driver will just CoW the pages and do a direct DMA transfer from the already allocated memory. In the driver I recently wrote (not graphics) it happens exactly like this. – datenwolf Sep 03 '12 at 16:52
  • @datenwolf : clever... but this also mean that delete[]ing the data just after glXData is a very bad idea, right ? – Calvin1602 Sep 04 '12 at 09:13
  • @Calvin1602: Why should it be a problem. The whole point of CoW is, that any operation the process does on the data will create in-situ copies on which those operations happen. The same goes for any changes to the data done by the driver. Whoever modifies the data first will do so on a copy. – datenwolf Sep 04 '12 at 12:23
  • @datenwolf: Precisely, so delete[]ing the data will (probably) force a memcpy (at least on the first page I guess), which ruins the advantage of the CoW. – Calvin1602 Sep 04 '12 at 12:48
  • 2
    @Calvin1602: Depending on the allocator used a delete/free will just unmap the pages. In that case one CoW reference is removed, which means that modifying the data by the driver will no longer trigger a duplication. Also duplication would happen per-page and not on the full data. However, standard malloc/new callocate from a memory pool, that's not handed back to the OS at free/delete. So this is the case where glMapBuffer is more efficient. If however your data comes from a mmap-ed file or similar, then glBufferData is the method of choice. – datenwolf Sep 04 '12 at 13:38
  • Something to add to the best answer by Cavin i.e : if your replacing entire buffer frequently you can call glBufferData with NULL before using glMapBuffer or glBufferSubData this lets driver discard what it is currently processing and take the new information. This is mainly because your GPU is usually rendering few frames behind and using glMapBuffer will result in wait condition as GPU should finish working with the buffer before returning you a pointer to it. – Gamer Dec 19 '13 at 09:52