Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: RenderTexture.clear() is very slow for a large texture  (Read 4390 times)

0 Members and 1 Guest are viewing this topic.

kevinsshaffer

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
RenderTexture.clear() is very slow for a large texture
« on: September 12, 2015, 08:39:46 am »
I implemented fog of war recently by having a solid black RenderTexture and a semi-transparent RenderTexture. 

The player's FOV is drawn onto each of the layers and only the semi-transparent one clears it's self.

The textures are large, 8000, 8000 pixels but only the semi-transparent texture produces poor performance due to the "haze.clear(sf::Color::Color(0, 0, 0, 190));"

Why does the clear() take so long?

From inside my game loop:
                haze.clear(sf::Color::Color(0, 0, 0, 190)); // This is very expensive
                haze.display();
                sf::VertexArray vArray = getViewCone(player->GetView(), player->GetCenter());
                haze.draw(&vArray[0], vArray.getVertexCount(), vArray.getPrimitiveType(), sf::BlendNone);
                fogOfWar.draw(&vArray[0], vArray.getVertexCount(), vArray.getPrimitiveType(), sf::BlendNone);
               
                window.clear();

                window.draw(sBackground);
                rootNode->Draw(window);
                //joypadInfo(window);
                player->Draw(window);

                for (auto enemy : enemies)
                        enemy->Draw(window);

                window.draw(sf::Sprite(fogOfWar.getTexture()));
                window.draw(sf::Sprite(haze.getTexture()));

                window.display();
 

Link to video:

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: RenderTexture.clear() is very slow for a large texture
« Reply #1 on: September 12, 2015, 04:17:44 pm »
Try the new and shiny SFML 2.3.2 - a bug related to RenderTexture::clear() was fixed :)

kevinsshaffer

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Re: RenderTexture.clear() is very slow for a large texture
« Reply #2 on: September 12, 2015, 06:11:45 pm »
That's awesome about the update but it didn't seem to fix my problem.

In order to start using the new libraries, would I only need to change the path in my project properties to point to the new library folders for both the c++ and linker in VS?  I just want to make sure I didn't miss anything.

If the new patch didn't address my problem, I would think that my code could be optimized to improve performance.  Would a RenderTexture::clear() inside a game loop be expected to be slow for a texture size of 8000 x 8000?  I didn't think it would be a problem when I wrote the code as the texture is nothing more than a color.  I haven't been able to think of a way to reduce the size of the texture in my application.

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: RenderTexture.clear() is very slow for a large texture
« Reply #3 on: September 12, 2015, 06:34:11 pm »
I must admit I didn't check the details of the fixed bug. I just saw a rendertexture clear() bug being fixed and you having a problem related to rendertexture clear(), so it seemed logical to point you at the new release to test :)

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: RenderTexture.clear() is very slow for a large texture
« Reply #4 on: September 12, 2015, 07:41:33 pm »
Why GPU do you use? What's your driver version?
Have you actually run a CPU and GPU profiler or are you only guessing?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

kevinsshaffer

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Re: RenderTexture.clear() is very slow for a large texture
« Reply #5 on: September 12, 2015, 09:59:35 pm »
Sorry, I should have posted my specs.  I am using a laptop to test my code so the GPU is onboard and, more than likely, is not very good.

I didn't know about CPU/GPU profiling; after googling about it I will set it up on in visual studios and get back with any data I find.

The reason I made the forum post is because I didn't expect to see a drop in performance, even on this machine, this early into development.  This is basically my first gaming project and is more so a learning experience, so I was just hoping to get information on optimization on rendering textures using SFML.

*edit* Upon running the compiled application on my desktop (with a NVidia 880GTS) I noticed the same performance issue.  I figured the RenderTexture::clear() was causing slow down because, when commented out, the performance is back to normal.  I will check out the "profiling" and get back.
« Last Edit: September 12, 2015, 10:05:30 pm by kevinsshaffer »

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: RenderTexture.clear() is very slow for a large texture
« Reply #6 on: September 13, 2015, 01:41:59 am »
You are aware of what you are telling your GPU to do right?

8000 x 8000 x 4 bytes is 256 MB

Just taking into consideration a single clear operation on a single texture, you are essentially telling your GPU to update 256 MB of texture data every frame. Considering your 8800 GTS boasts a theoretical (i.e. you will probably never see this happen) maximum fillrate of 64 GB/s, assuming you expect your application to run at 30 FPS would require 7.68 GB/s just for that one clear operation. When you factor in that the GPU has other work to do as well, you shouldn't be surprised that it starts sweating.

Judging by your video, you don't even need to use such large textures. Unless you plan on displaying ultra high definition textures on an 8K monitor or rolling your own fullscreen post-processing such as AA, using a texture that large is just wasteful and kills GPU performance. Even big game developers don't use (let alone update every frame) such huge textures in their games (unless performing some filtering), and they already tend to push hardware to its limits.

Oh... and then there's that part about how your texture probably wouldn't even fit entirely into GPU memory ::). If this happens, OpenGL tries it's best not to break in your face and just keeps swapping GPU RAM contents to and from system RAM resulting in really really horrible performance.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

kevinsshaffer

  • Newbie
  • *
  • Posts: 4
    • View Profile
    • Email
Re: RenderTexture.clear() is very slow for a large texture
« Reply #7 on: September 13, 2015, 07:48:38 am »
Quote
You are aware of what you are telling your GPU to do right?

8000 x 8000 x 4 bytes is 256 MB

Just taking into consideration a single clear operation on a single texture, you are essentially telling your GPU to update 256 MB of texture data every frame. Considering your 8800 GTS boasts a theoretical (i.e. you will probably never see this happen) maximum fillrate of 64 GB/s, assuming you expect your application to run at 30 FPS would require 7.68 GB/s just for that one clear operation. When you factor in that the GPU has other work to do as well, you shouldn't be surprised that it starts sweating.

Good point.  I hadn't considered the size of the texture in terms of bits/bytes.

Quote
Judging by your video, you don't even need to use such large textures. Unless you plan on displaying ultra high definition textures on an 8K monitor or rolling your own fullscreen post-processing such as AA, using a texture that large is just wasteful and kills GPU performance. Even big game developers don't use (let alone update every frame) such huge textures in their games (unless performing some filtering), and they already tend to push hardware to its limits.

Thanks for pointing this out.  I read this on my phone at a friend's house and thought about it on the way home.  I was able to reduce the Fog of War to the size of my view and now the performance is back to normal.  Great point!

Quote
Oh... and then there's that part about how your texture probably wouldn't even fit entirely into GPU memory ::). If this happens, OpenGL tries it's best not to break in your face and just keeps swapping GPU RAM contents to and from system RAM resulting in really really horrible performance.

I did make sure that this wasn't the case.  I'm use textures that are at the limit.

Like I said, I was not surprised at the poor performance, but I wanted to know why as a learning experience.
Thanks for the guidance!