Original Post
Hi there,
I do some calculations on the GPU by rendering a quad into a FBO. The result is subsequently submitted back to GPU for further processing.
The result looks fine but due to some strange mistake I seem to make, it runs very slow (below 1 fps). But when I include a "glReadPixels" call after rendering the quad, the performance goes up to 20 fps (the result of the calculation stays absolutely the same!). But since I don't want to access the data on CPU between the two shader calls, I don't need to acces the pixels and therefore there should be no need for a glReadPixels call. The result of the glReadPixels call is not even read by the program and I only need to read a one-pixel-region to get this effect (see comments below). I have no Idea how this strange behaviour could be explained.
The relevant code is posted below. I used an FBO without an attached depth buffer, only a rgba-texture. The functions "renderToFBO" and "submitToGPU" are called subsequently. If you are interested in initialzation code or something, please let me know. I figured out, that the performance issue is not related to the glsl-shader code.
Thanks for your answers.
[source lang="cpp"]// RenderTarget - Type:
typedef struct {
bool isAllocated;
bool hasDepthBuffer;
GLuint color_tex;
GLuint fb; // FBO
GLuint depthBuffer;
GLsizei width;
GLsizei height;
TextureType textureType;
} RenderTarget;
// ------------------ render to FBO ---------------------
void RenderTargetContainer :: renderToFBO(RenderTarget *rt) {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, rt->fb);
glViewport(0,0, rt->width, rt->height);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, rt->width, 0.0, rt->height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_QUADS);
glVertex2f(0.0, 0.0);
glVertex2f(static_cast (rt->width), 0.0);
glVertex2f(static_cast (rt->width),static_cast (rt->height));
glVertex2f(0.0, static_cast (rt->height));
glEnd();
// -- these two lines make it run fast
// -- although the visible result statys the same.
// -- "foo" will never be read.
// -- region needs to be at least 1 to get the speed up effect.
static float foo[4];
glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, foo);
}
// ------------------ submit result to GPU ---------------------
void RenderTargetContainer :: submitToGPU(GLint shaderVarLocation, int textureUnit, RenderTarget *rt) {
glActiveTexture(GL_TEXTURE0 + textureUnit);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, rt->color_tex);
glUniform1i(shaderVarLocation, textureUnit);
}[/source]
I do some calculations on the GPU by rendering a quad into a FBO. The result is subsequently submitted back to GPU for further processing.
The result looks fine but due to some strange mistake I seem to make, it runs very slow (below 1 fps). But when I include a "glReadPixels" call after rendering the quad, the performance goes up to 20 fps (the result of the calculation stays absolutely the same!). But since I don't want to access the data on CPU between the two shader calls, I don't need to acces the pixels and therefore there should be no need for a glReadPixels call. The result of the glReadPixels call is not even read by the program and I only need to read a one-pixel-region to get this effect (see comments below). I have no Idea how this strange behaviour could be explained.
The relevant code is posted below. I used an FBO without an attached depth buffer, only a rgba-texture. The functions "renderToFBO" and "submitToGPU" are called subsequently. If you are interested in initialzation code or something, please let me know. I figured out, that the performance issue is not related to the glsl-shader code.
Thanks for your answers.
[source lang="cpp"]// RenderTarget - Type:
typedef struct {
bool isAllocated;
bool hasDepthBuffer;
GLuint color_tex;
GLuint fb; // FBO
GLuint depthBuffer;
GLsizei width;
GLsizei height;
TextureType textureType;
} RenderTarget;
// ------------------ render to FBO ---------------------
void RenderTargetContainer :: renderToFBO(RenderTarget *rt) {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, rt->fb);
glViewport(0,0, rt->width, rt->height);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, rt->width, 0.0, rt->height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_QUADS);
glVertex2f(0.0, 0.0);
glVertex2f(static_cast
glVertex2f(static_cast
glVertex2f(0.0, static_cast
glEnd();
// -- these two lines make it run fast
// -- although the visible result statys the same.
// -- "foo" will never be read.
// -- region needs to be at least 1 to get the speed up effect.
static float foo[4];
glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, foo);
}
// ------------------ submit result to GPU ---------------------
void RenderTargetContainer :: submitToGPU(GLint shaderVarLocation, int textureUnit, RenderTarget *rt) {
glActiveTexture(GL_TEXTURE0 + textureUnit);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, rt->color_tex);
glUniform1i(shaderVarLocation, textureUnit);
}[/source]