Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (120)
games submitted by our members
Games in WIP (577)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  VBOs Very Slow  (Read 2863 times)
0 Members and 1 Guest are viewing this topic.
Offline chris0

Senior Newbie




Java games rock!


« Posted 2006-05-31 09:11:03 »

I'm not happy because I've just spent a few days converting all my vertex array stuff to use VBOs because apparently they're much faster. However, a quick test shows that on my Mobility Radeon X600 VBOs are infact massively slower than vertex arrays, to the tune of something like x10!! The same test on an nVidia GeForce 6800 GT shows approximately the same frame rate, possibly slightly faster when using vertex arrays.

This seems ridiculous to me. It's faster to stream hundreds of gigabytes of data from RAM over the PCI Express bus than it is to read it of the memory on the card!

It seems to me as though ATI and nVidia have implemented VBOs as an afterthought just to claim that they have OpenGL compatibility. It's also very annoying because VBOs are clearly (logically speaking) the best way to implement vertex array-type structures.

Has anyone else found this to be a problem?



Online Riven
« League of Dukes »

JGO Overlord


Medals: 817
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #1 - Posted 2006-05-31 10:14:10 »

Nope, 99.99% chance it is a design mistake or a bug in your code. VBOs really increase performance, if you keep data static in vRAM. If you update the data every frame (worst case scenario) you get the performance of normal vertex-arrays.

You might want to post some sourcecode (keep it small) that shows what you're doing.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #2 - Posted 2006-05-31 10:35:29 »

VBOs really increase performance
Only if you're vertex-bound already though. If your bottleneck is somewhere else then VBOs aren't going to change anything.

You did benchmark first, didn't you?

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Online Riven
« League of Dukes »

JGO Overlord


Medals: 817
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #3 - Posted 2006-05-31 11:17:50 »

Indeed, but it should really not decrease performance by factor 10. So in this case it's not so much an issue of finding the bottleneck, but finding the bug.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline endolf

JGO Coder


Medals: 7
Exp: 15 years


Current project release date: sometime in 3003


« Reply #4 - Posted 2006-05-31 11:21:26 »

Hi

I found the same problem, VBOs were much slower than plain on gl triangles. I'd be interested to see what the issue is and if mine is the same.

Endolf

Offline chris0

Senior Newbie




Java games rock!


« Reply #5 - Posted 2006-05-31 11:50:56 »

I hope it's a design problem! Here's a couple of code snippets...
I'm rendering some terrain. I set up the vertex/colour/normal arrays (which I can render without VBOs at quite high speed), then I bind these to VBOs. The render method renders portions of the arrays simply using glDrawArrays().
I've included some of the actual numbers. Essentially I have a terrain grid that's 400x400 (stored in vertex arrays or VBOs) and I'm rendering a 200x200 section. Vertices are stored as ints, colours as ubytes and normals as floats.
 
This is the setup (done once only).


int[] vboIds = new int[3];
gl.glGenBuffers(3,vboIds,0);
      
_vertexBufferIndex = vboIds[0];
gl.glBindBuffer(GL.GL_ARRAY_BUFFER,_vertexBufferIndex);
gl.glBufferData(GL.GL_ARRAY_BUFFER,
                _vertexByteSize, // 3849600
                _vertexArray,
                GL.GL_STATIC_DRAW);
gl.glVertexPointer(3,GL.GL_INT,0,0);

_colourBufferIndex = vboIds[1];
gl.glBindBuffer(GL.GL_ARRAY_BUFFER,_colourBufferIndex);
gl.glBufferData(GL.GL_ARRAY_BUFFER,
                _colourByteSize, // 962400
                _colourArray,
                GL.GL_STATIC_DRAW);
gl.glColorPointer(3,GL.GL_UNSIGNED_BYTE,0,0);

_normalBufferIndex = vboIds[2];
gl.glBindBuffer(GL.GL_ARRAY_BUFFER,_normalBufferIndex);
gl.glBufferData(GL.GL_ARRAY_BUFFER,
                _normalByteSize, // 3849600
                _normalArray,
                GL.GL_STATIC_DRAW);
gl.glNormalPointer(GL.GL_FLOAT,0,0);
      
gl.glBindBuffer(GL.GL_ARRAY_BUFFER,0);



If I just want to use vertex arrays, this is the setup I use instead.


gl.glVertexPointer(3,GL.GL_INT,0,_vertexArray);
gl.glColorPointer(3,GL.GL_UNSIGNED_BYTE,0,_colourArray);
gl.glNormalPointer(GL.GL_FLOAT,0,_normalArray);



This is the rendering section (called once per frame).
The same code works with vertex arrays and VBOs.


for(int j=0;j<h;j++) // h=200
{
   gl.glDrawArrays(GL.GL_TRIANGLE_STRIP,
              (802*(y+j))+(x*2), // y=0, x=0
              (w+1)*2); // w=200
}



I can't test on the RX600 at this moment in time, but I just tested on a GF6800 GT. With vertex arrays I get a frame rate of about 32 fps, with VBOs it is about 29 fps. The problem is much more pronounced on the RX600, I'll post some figures for this later.

Any input greatly appreciated!
Offline chris0

Senior Newbie




Java games rock!


« Reply #6 - Posted 2006-05-31 12:06:37 »

I just tested with the Mobility Radeon X600:
Without VBO: 65 fps
With VBO: 1 fps

Something is obviously going very wrong! But what?

(Incidentally, I have the latest drivers, but this is a laptop and so the drivers are provided by a 3rd party, ASUS in this case)
Online Riven
« League of Dukes »

JGO Overlord


Medals: 817
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #7 - Posted 2006-05-31 12:14:53 »

The correct way to bind the VBOs before rendering is:

(copy and paste from my own code - replace whatever should be replaced)
1  
2  
3  
4  
5  
6  
7  
8  
      glBindBufferARB(GL_ARRAY_BUFFER_ARB, vHandle.pointer);
      glVertexPointer(vDim, GL_FLOAT, 0, 0);

      glBindBufferARB(GL_ARRAY_BUFFER_ARB, cHandle.pointer);
      glColorPointer(cDim, GL_FLOAT, 0, 0);

      glBindBufferARB(GL_ARRAY_BUFFER_ARB, nHandle.pointer);
      glNormalPointer(GL_FLOAT, 0, 0);

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline chris0

Senior Newbie




Java games rock!


« Reply #8 - Posted 2006-05-31 12:28:46 »

Ok, I changed my code to this (below), ie. essentially just adding the "ARB" bit. However it appears to make no difference. Could you explain what the significance of ARB is?


gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB,_vertexBufferIndex);
gl.glBufferDataARB(GL.GL_ARRAY_BUFFER_ARB,
                   _vertexByteSize, // 3849600
                   _vertexArray,
                   GL.GL_STATIC_DRAW);
gl.glVertexPointer(3,GL.GL_INT,0,0);
Online Riven
« League of Dukes »

JGO Overlord


Medals: 817
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #9 - Posted 2006-05-31 12:34:20 »

It is NOT essentially adding ARB !

Look at the method-parameters

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline chris0

Senior Newbie




Java games rock!


« Reply #10 - Posted 2006-05-31 12:40:14 »

True, so are you saying I should use:

gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB,_vertexArray);

Which would compare to your:

glBindBufferARB(GL_ARRAY_BUFFER_ARB, vHandle.pointer);

?

Because this method does not exist for these parameters (in my version of jogl, the latest beta release).
The only method is: glBindBufferARB(int target, int id)
Online Riven
« League of Dukes »

JGO Overlord


Medals: 817
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #11 - Posted 2006-05-31 12:49:36 »

It was about:


gl.glVertexPointer(3,GL.GL_INT,0, vbo_handle);

that needed to be changed to

gl.glVertexPointer(3,GL.GL_INT,0,0);


if that doesn't work, it turns out to be a non-trival bug

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline chris0

Senior Newbie




Java games rock!


« Reply #12 - Posted 2006-05-31 13:13:29 »

I think that's what I had in the first place:


gl.glVertexPointer(3,GL.GL_INT,0,0);


So I guess it's not trivial!
Online Riven
« League of Dukes »

JGO Overlord


Medals: 817
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #13 - Posted 2006-05-31 13:21:23 »

Check back on your 'blue post':

...
gl.glNormalPointer(GL.GL_FLOAT,0,_normalArray);
...

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline chris0

Senior Newbie




Java games rock!


« Reply #14 - Posted 2006-05-31 13:29:08 »

You mean this bit?:

...
If I just want to use vertex arrays, this is the setup I use instead.


gl.glVertexPointer(3,GL.GL_INT,0,_vertexArray);
gl.glColorPointer(3,GL.GL_UNSIGNED_BYTE,0,_colourArray);
gl.glNormalPointer(GL.GL_FLOAT,0,_normalArray);
...

As it says above, that's the setup I'm using when I'm not using VBOs, but using vertex arrays instead (I can easily switch between either method).
Offline Spasi
« Reply #15 - Posted 2006-05-31 13:39:10 »

Hi chris0,

Just change GL_INT to GL_FLOAT for your vertex positions (you may need to change the actual geometry data too). GL_INT is not a hardware accelerated format, that's why you see a slowdown. The most propable reason for the slowdown you see is that the data is being read back to memory, converted to floats and then send back to the GPU.
Online Riven
« League of Dukes »

JGO Overlord


Medals: 817
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #16 - Posted 2006-05-31 13:40:21 »

Could you try to bind the VBOs in the rendering-loop?

Or could you provide sourceode of a working example (tiny), so that I can run it on my own machine. Remote-debugging == slow


@Spasi
Thought about it too, but then it's hard to explain the difference between VAs and VBOs

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Spasi
« Reply #17 - Posted 2006-05-31 14:03:44 »

@Spasi
Thought about it too, but then it's hard to explain the difference between VAs and VBOs

No readback is necessary with plain vertex arrays.
Online Riven
« League of Dukes »

JGO Overlord


Medals: 817
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #18 - Posted 2006-05-31 14:13:28 »

That seems like a one-time effort, when uploading the data to the VBO. Not something you should notice in the main-loop

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline chris0

Senior Newbie




Java games rock!


« Reply #19 - Posted 2006-05-31 14:40:16 »

Ok, I tried converting to floats...

The GF6800 VBO frame rate has gone through the roof! It has now increased well beyond the monitor refresh rate. I had to up the LOD to get a frame rate less than 60, I estimate about 240fps compared with about 30fps for non-VBO! Excellent!

On the RX600 it has improved things, but only very slightly. The VBO implementation now runs at 3fps (originally 1fps) and the non-VBO implementation has remained about the same at around 65fps.
Online Riven
« League of Dukes »

JGO Overlord


Medals: 817
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #20 - Posted 2006-05-31 14:45:30 »

Quote
Or could you provide sourceode of a working example (tiny), so that I can run it on my own machine. Remote-debugging == slow

I have an ATi so I might be able to debug it.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline chris0

Senior Newbie




Java games rock!


« Reply #21 - Posted 2006-05-31 14:49:30 »

I can try to extract a small test application for you. It will take a few days for me to get around to doing this though!
Offline Spasi
« Reply #22 - Posted 2006-05-31 14:54:00 »

Riven, maybe that's true for a clever driver, but usually at data upload time the buffer object is just a bunch of bytes for the driver. The actual data type is made known to the driver after a call to a glXXXPointer function.

chris0, another thing you could try is using 4 instead of 3 bytes for the color array (better data alignment). If that doesn't work, could you post any unusual GL state you have enabled during rendering (line/point rendering, depth offset, etc)?
Offline chris0

Senior Newbie




Java games rock!


« Reply #23 - Posted 2006-05-31 15:53:17 »

Yes, I was thinking that too. What I've just tried is to use floats for colours instead of bytes (as I remember reading somewhere that floats are the native format for colours too). This has completely solved the problem. The RX600 now runs at well over 200fps (originally 3fps!!). I guess I was making similar assumptions to Riven with regard to "automatic optimisations" that were infact never made. I will also try using bytes aligned on 4-byte boundaries later, and I'll post back with the results just for interest.

Thanks to both of you for your help.

Chris.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Longarmx (52 views)
2014-10-17 03:59:02

Norakomi (45 views)
2014-10-16 15:22:06

Norakomi (34 views)
2014-10-16 15:20:20

lcass (38 views)
2014-10-15 16:18:58

TehJavaDev (68 views)
2014-10-14 00:39:48

TehJavaDev (68 views)
2014-10-14 00:35:47

TehJavaDev (60 views)
2014-10-14 00:32:37

BurntPizza (73 views)
2014-10-11 23:24:42

BurntPizza (45 views)
2014-10-11 23:10:45

BurntPizza (87 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!