Jump to content
  • Advertisement
Sign in to follow this  
sunsflower

question about data transfer between memory and graphics card memory...

This topic is 1003 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

It's about VAO, VBO, glGenBuffers, glBindBuffer and glBufferData...

As far as I know(or quess), VAO and VBO are stored in the graphics card memory.

And when I call glGenBuffers, I create some sort of a identifier on graphics card and glBindBuffer implement some current identifier.

glBufferData will upload data from cpu memory to gpu memory.

so glBufferData(glBufferSubData may be the same) is not very efficient and should be avoided in update function.


are those statement actually right?

thanks!

Share this post


Link to post
Share on other sites
Advertisement
Actually you have no direct control or information about the memory location of a buffer object. It can be in Vram or it can be in System memory. The driver guesses where the best place is, and it also may change the location during runtime. There are some general patterns what drivers will do. For example nvidia seems to always relocate buffers to system memory if you map them.

Share this post


Link to post
Share on other sites

What exactly are you trying to do.? glBufferData updates the entire buffer of data. glBufferSubData let you update a section the buffer which can be very helpful when you have a dynamic buffer and you just want to update a section of the buffer, while the gpu is working on some other section. The only reason it would not be efficient is if you are locking the entire buffer every frame and replacing the whole thing everytime then yes that will be inefficient because you will stall and you want to prevent that. But what you can do is make the buffer like twice or three times the size. That way you can map one section of it and update that while the GPU is currently drawing another section.With that there will be no stalls as long you can keep feeding data that the GPU is not currently working with, that is where glBufferSubData comes in handy, because it allows you to do exactly that.

Edited by BornToCode

Share this post


Link to post
Share on other sites
I'm just trying to understand more of those functions..and...still two more things:
can I use glVertexAtrribPointer to upload data to gpu without a buffer?
and can I call glBindBuffer very frequently during rendering?
thanks!!

Share this post


Link to post
Share on other sites


can I use glVertexAtrribPointer to upload data to gpu without a buffer?

You do not upload data with that function, this is a function with which you explain layout of data in buffer to the vertex function, against the attributes of verticies fed to vertex function.

The upload of data happens at multiple stages, so even if you use genbuffer->bindbuffer->bufferdata and do not issue actual draw call before unbinding it, it may not even then be presented to gpu. Gpu state calls do not work as straight forward as you might think at first stance. Those rather happen at first usage, in management of layer hidden behind opengl (great) logic.


and can I call glBindBuffer very frequently during rendering?

No , buffers tor render from, when changed, is quite expensive, you will benefit large if you optimize changing buffers between draw calls.

Share this post


Link to post
Share on other sites

Theres basically 3 components:

1. CPU (your program)

You call some opengl functions. Probably minor overhead.

2. CPU (driver)

All those calls are checked for validity, processed, pipelined, optimized, sent to GPU at correct order and times... Lots of work.

This is why you DONT want to call opengl functions often. Theres a lot of driver overhead.

3. GPU

All the commands sent by driver (based on your opengl calls) are actually executed.

 

So theres both CPU and GPU cost, and either can be the performance bottleneck.

 

 

You can act like all your textures/buffers data is stored on GPU, when its used for rendering. If something is on the CPU (maybe while you fill a buffer on CPU, or read some GPU originated buffer), its probably copied from GPU=>CPU first (or CPU=>GPU after). And again the driver has to manage all of that (to ensure everything is in correct order, and data is where it needs to be when it needs to be), so its not free.

Share this post


Link to post
Share on other sites
VAO and VBO are stored in the graphics card memory.

Often, but not necessarily. It is possible for the GPU to directly access data via DMA, too. The buffer usage flags give you some sort of hinting the driver about where data is to be stored, but you do not have any strict control (or knowledge).

 

glGenBuffers, I create some sort of a identifier on graphics card and glBindBuffer implement some current identifier

glGenBuffers reserves an identifier (an integer) for your application to talk with the implementation, but it does nothing on the graphics card. glBindBuffer creates the internal structures necessary for the implementation/driver to do what a buffer does the first time you call it. It otherwise marks the buffer as the currently active one, and if draw calls follow that pull data from the buffer, it may involve other actions (move around data).

 

glBufferData will upload data from cpu memory to gpu memory [...] (glBufferSubData may be the same) is not very efficient and should be avoided in update function.

glBufferData does a memory allocation (and optionally orphaning), creating the actual buffer with undefined contents (plus, it optionally copies data into that buffer). The buffer lives in main memory, but is owned by the GL, so it is not mapped in your application's address space (unless you do map it explicitly), so you need to "ask for permission" via GL's interface to access it.

The upload to the GPU usually happens at a later, unknown time.

 

glBufferSubdata does no allocations, it uses storage that already exists. Both of them may (often do) cause a partial or full sync. Orphaning (calling glBufferdata with NULL) is very easy to do and works wonders for that as the driver will silently rename in-use buffers without you knowing and reclaim them later.

 

Using glBuffer(Sub)Data is usually as efficient as it can get. Unless you consider unsynchronized persistent mappings which is rather advanced, it is indeed the fastest method on at least one major IVH's cards (almost twice as fast as mapping). If you need to update data every frame, there is no good reason no to call glBuffer(Sub)Data (of course, if you don't need to update the data, you shouldn't call it!).

 

 

does that means I can use glBindBuffer and glVertexAttribPointer as frequently as I wish when drawing things on screen?

 

No. (Well, yes... you can. But it will impact performance.)

glBindBuffer is a state change that requires the driver to do some non-trivial validation, and it's something that possibly changes state on the GPU (I say possibly because GPUs can usually switch around between a small number of state sets without much hassle). It means telling the GL: "From now on, whatever I am telling you, such as draw something, refers to this buffer".

In the worst case, that might cause the driver to throw away another buffer's content that is stored on the GPU, and have it do a DMA transfer.

 

It's no big deal to do it a few dozen times, but you don't want to do it a thousand times.

Share this post


Link to post
Share on other sites

glBufferdata data create a new store and copies the stream. For some implementations, the initialization of the stream does not occur until you call the draw method. 

glBufferSubData- initializing the new data but DOES NOT create a new store. Therefore when replacing data- you should use this. 

 

glVertexAttributePoitner and glBindBuffer are less complicated and you need not feat for their performance implications.- there are none. (If you have any information telling otherwise, please let me see the source smile.png ).

However, if you find yourself changing buffers all the time using glVertexAttributePointer, Try setting couple of VAO's instead of iterating over buffers all the time. 

The main point of having VAO's is setting them up before the drawing begins. 

Edited by WoopsASword

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!