Skip to main content
GameDev.net gamedev.net
🔒 Locked

FBO + multisampling = SLOW

Started by IrYoKu1 Oct 16, 2007 at 6:54 PM 6 replies 10.2k views
Original Post
IrYoKu1
IrYoKu1
Hi, I am going to implement bloom effect as a postprocess shader. In order to do that I need to render the scene into a texture, and then do a second pass to perform a gaussian blur (rendering a quad that fills the screen with the texture rendered in first pass). I have measured FPS under various conditions (with no bloom effect yet but a dummy shader that just renders the image created in the first pass): No multisampling = 510 FPS Multisampling 4x = 510 FPS Multisampling 8x = 285 FPS FBO (not using glRenderbufferStorageMultisampleEXT) = 292 FPS FBO (using glRenderbufferStorageMultisampleEXT with 1 sample) = 230 FPS FBO + Multisampling 4x = 195 FPS What I do for FBO + multisampling is rendering into a renderbuffer with multisample support and then blit this into a texture:

// Multi sample colorbuffer
glGenRenderbuffersEXT(1, &colorBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorBuffer);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_RGBA8, width, height);

// Multi sample depth buffer
glGenRenderbuffersEXT(1, &depthBuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_DEPTH_COMPONENT, width, height);

// Attach them
glGenFramebuffersEXT(1, &mfbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mfbo);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, colorBuffer);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer);

// Final framebuffer color buffer
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, format, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

// Attach it
glGenFramebuffersEXT(1, &fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texture, 0);



// Drawing code
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mfbo);
// Draw
//...
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, mfbo);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fbo);
glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);


So various questions arise from those results: 1. This FPS drop is normal? 2. The blitting between buffers eat 292-230=62 FPS. There is some way to use a framebuffer directly as a texture? 3. What pixel format has the multisample framebuffer? It will be floating point format? I need floating point because HDR is needed for bloom effect. If someone is so kind to help me with some of them I will really appreciate it =] Thanks!
StealthNinja
StealthNinja
First of all, frames per second is not a linear scale, and can not be used as such. A ratio of two FPS measurements has meaning, but a difference of two has none. Use seconds per frame instead.

Secondly, I don't know if it's "normal" to see a performance difference or not, but I do know off-hand that a multisampled buffer with just one sample has different semantics than a non-multisampled buffer.

Third, if you want floating-point, you have to replace GL_RGBA8 with GL_RGBA32F_ARB. Note that GeForce 6 and 7 series cards don't support multisampled floating-point buffers.
Yann L
Yann L
Quote:
Original post by IrYoKu1
1. This FPS drop is normal?

Yep.

Quote:

2. The blitting between buffers eat 292-230=62 FPS. There is some way to use a framebuffer directly as a texture?

Nope, not yet.

Quote:

3. What pixel format has the multisample framebuffer? It will be floating point format? I need floating point because HDR is needed for bloom effect.

It has the format you specified for it. If you need floating point, specify GL_RGB(A)16F_ARB (don't use 32bit per component, unless you want a slideshow). And as StealthNinja mentioned, you need at least a GF8 to use mulisampling with floating point buffers.
IrYoKu1
IrYoKu1
Quote:
Original post by StealthNinja
First of all, frames per second is not a linear scale, and can not be used as such. A ratio of two FPS measurements has meaning, but a difference of two has none. Use seconds per frame instead.

I think I don't understand why FPS is not a linear scale.
Quote:
Original post by StealthNinja
Secondly, I don't know if it's "normal" to see a performance difference or not, but I do know off-hand that a multisampled buffer with just one sample has different semantics than a non-multisampled buffer.

You have reason, even if I specify one sample in a multisampled buffer it's performing 2x multisampling. That explains the frame drop even when specifing 1 sample.
Quote:
Original post by StealthNinja
Note that GeForce 6 and 7 series cards don't support multisampled floating-point buffers.

I am "lucky" as I have a GeForce 8600GS =]

Thanks a lot to both, you helped me a lot!
ccbrianf
ccbrianf
Quote:
Original post by IrYoKu1
2. There is some way to use a framebuffer directly as a texture?


glCopyTexImage2D
Pzc
Pzc
Quote:
Original post by IrYoKu1
Quote:
Original post by StealthNinja
First of all, frames per second is not a linear scale, and can not be used as such. A ratio of two FPS measurements has meaning, but a difference of two has none. Use seconds per frame instead.

I think I don't understand why FPS is not a linear scale.


The show what he means you can look at the numbers you provided yourself.

292 fps = 3.4ms per frame
230 fps = 4.3ms per frame

So, an increase of about 0.9ms for one frame results in 62 less fps.
If one increase the time with another 0.9ms (same increase as before) you get

4.3ms + 0.9ms = 5.2ms = 192fps

This time it's only a drop of 42fps (230 - 192 = 42)
Yann L
Yann L
Quote:
Original post by ccbrianf
Quote:
Original post by IrYoKu1
2. There is some way to use a framebuffer directly as a texture?


glCopyTexImage2D

With 'directly' he implied that he wants to use the texture without a copy. Furthermore, glCopyTexImage2D does not work on multisampled FBOs, as it doesn't trigger a resolve operation.
ignotion
ignotion
So does that mean we cannot use deferred shading with multisampling yet?
Great :(

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.