3

I'm using glsl 2.0 for some GPGPU purposes (I know, not the best for GPGPU).

I have a reduction phase for matrix multiplication in which I have to constantly reduce the texture size (I'm using glTexImage2D). The pseudocode is something like this:

// Start reduction
for (int i = 1; i <= it; i++)
{
    glViewport(0, 0, x, y);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    x = resize(it);
    if (i % 2 != 0)
    {
        glUniform1i(tex2_multiply_initialstep, 4);
        glBindFramebuffer(GL_FRAMEBUFFER, framebuffer3);
        // Resize output texture
        glActiveTexture(GL_TEXTURE5);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, x, y, 0, GL_RGBA, GL_FLOAT, NULL);
    }
    else
    {
        glUniform1i(tex2_multiply_initialstep, 5);
        glBindFramebuffer(GL_FRAMEBUFFER, framebuffer2);
        // Resize output texture
        glActiveTexture(GL_TEXTURE4);
                    // A LOT OF TIME!!!!!!!
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, x, y, 0, GL_RGBA, GL_FLOAT, NULL);
                    // A LOT OF TIME!!!!!!!
    }
}

In some iterations the glTexImage2D of the else branch takes 800 times more time that in other ones. I make a test hardcoding x and y but surprisingly takes similar high times in the same iterations, so have nothing to do with x value.

What's wrong here? Alternatives to resizing without glTexImage2D?

Thanks.

EDIT:

I know that glsl 2.0 is a bad choice for GPGPU but its mandatory for my project. So that I'm not able to use functions like glTexStorage2D because they are not included in 2.0 subset.

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Keles
  • 369
  • 1
  • 2
  • 14
  • This is not the best idea to use texture when you need the GL buffer. Texture binding is something really expensive. Strongly suggesting to switch onto OpenCL from OpenGL for GPGPU operations. OpenGL designed for graphic, and have a lot of legacy functions for the code backward compatibility, using those deprecated functions may degrade performance dramatically. – Victor Gubin Apr 19 '18 at 15:01

1 Answers1

0

I'm not sure if I understand exactly what you're trying to achieve, but glTexImage2D is reallocating memory each time you call it. You may want to call glTexStorage2D, and then call glTexSubImage2D.

You can check Khronos's Common Mistakes page about that. Relevant part is :

Better code would be to use texture storage functions (if you have OpenGL 4.2 or ARB_texture_storage) to allocate the texture's storage, then upload with glTexSubImage2D:

glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
glTexSubImage2D(GL_TEXTURE_2D, 0​, 0, 0, width​, height​, GL_BGRA, GL_UNSIGNED_BYTE, pixels);

This creates a texture with a single mipmap level, and sets all of the parameters appropriately. If you wanted to have multiple mipmaps, then you should change the 1 to the number of mipmaps you want. You will also need separate glTexSubImage2D calls to upload each mipmap.

If that is unavailable, you can get a similar effect from this code:

glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels);

Again, if you use more than one mipmaps, you should change the GL_TEXTURE_MAX_LEVEL to state how many you will use (minus 1. The base/max level is a closed range), then perform a glTexImage2D (note the lack of "Sub") for each mipmap.

MartinVeronneau
  • 1,296
  • 7
  • 24
  • I know that glsl 2.0 is a bad choice for GPGPU but its mandatory for my project. So that Im not able to use functions like glTexStorage2D because they are not included in 2.0 subset. – Keles Apr 19 '18 at 15:25
  • Have you tried the second option from the link? I'll add it to my answer. – MartinVeronneau Apr 19 '18 at 15:32
  • Yes...and Im having the same bad behavior. – Keles Apr 20 '18 at 05:54
  • Well, that's weird. Slow downs after some iteration usually means memory allocation, reallocation, freeing. I'll leave my answer in case it helps someone else down the road, but I'm bummed I couldn't help you. – MartinVeronneau Apr 20 '18 at 12:58