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

Author Topic: SFML Context Management  (Read 9158 times)

0 Members and 1 Guest are viewing this topic.

dk123

  • Newbie
  • *
  • Posts: 49
    • View Profile
SFML Context Management
« on: June 26, 2014, 02:00:23 pm »
Hi, I'm currently working on a small game engine using sfml.

I've recently had users with intel graphics cards building reporting that they were getting corrupt images when loading image files. Sadly, I couldn't reproduce the problems with my graphics card.

In the end, I had to place a

pRenderWindow->setActive( true );

before each and every texture and view manipulation function
and a glFlush() right afterwards.

Users have been telling me since that they aren't getting the problems,
but I feel like this is a terrible ad-hoc hack just waiting to hit me in the face again any time.

Are there any plans to improve context management in sfml,
or is this the only way to prevent these weird bugs?

The attached image is a screenshot sent to me by one of my users -
there's this weird mixing of textures going on despite having loaded single image files.

I am not running the executable in a multithreaded fashion and all images loaded are done through
the normal .loadFromFile() function.


binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: SFML Context Management
« Reply #1 on: June 26, 2014, 02:19:50 pm »
It would help to know what kind of hardware your users are running and most importantly whether they are using current drivers. Many similar problems that have popped up in the past were solved by updating drivers, especially for Intel chips since not everything is 100% hardware accelerated. Most users who use the integrated graphics more often than not don't bother updating their graphics driver because 1. drivers are released less frequently than those for discrete GPUs and 2. they are more of a hassle to get hold of because there are multiple obscure sources to get them from.

Also, SFML is trying to cut down on the number of workarounds needed for things that are broken that aren't really SFML's fault and work for the majority of others. Often these workarounds have a negative impact on those who don't experience the problem, so the reliable solution is to fix the problem upstream (i.e. driver maintainer). If you can reproduce this in a minimal example using the latest Intel drivers then it is easy to reconstruct a minimal OpenGL example to submit to Intel so they can reproduce the problem and hopefully fix it in their next release. If nobody cares to file bug reports you really can't expect anything to get fixed.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

dk123

  • Newbie
  • *
  • Posts: 49
    • View Profile
Re: SFML Context Management
« Reply #2 on: June 27, 2014, 04:37:24 pm »
Hi, I've asked for some additional info from my users previously reporting bugs. It seems they're using:

Intel HD Graphics 4400
Intel HD Graphics 4000

They've replied back to me saying that they'd all updated to the latest drivers they could get.

I can understand wanting to reduce the number of workarounds to serve the minority with issues, but is there no underlying method to address or improve them all?

I've had roughly 20 people during the last month email me with the problem (back before the fix)
- while they may be a minority in terms of a larger group, I definitely don't feel that they should be considered lightly;
especially if something as simple as adding a 'pRenderWindow->setActive(true)' before all texture/view/window manipulation functions cleaned out most issues.

I'm not sure how effective this would be, but would it be possible to add something along the lines of a 'normal' mode and 'safe' mode trigger for context management? 'normal' mode would run without the workarounds pertaining to minority drivers, while 'safe' mode would be as cautious as possible to suit as many drivers as possible.

« Last Edit: June 27, 2014, 04:55:32 pm by dk123 »

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: SFML Context Management
« Reply #3 on: June 27, 2014, 05:07:19 pm »
What about... come up with a simple (100-200 lines) self contained example using SFML exclusively (without any built-in workarounds or modifications) that breaks on said chips? It can't be too hard from what you describe. I can build a simple executable using win32 and GL and if that breaks as well on your users' systems, you can file a report at Intel. If they can reproduce it using the latest drivers, then I'm sure they will acknowledge the bug and fix it for the next driver release.

If you can't reproduce it in a minimal example, then you must understand that we have to assume that the error is specific to your code and making any changes to SFML to alleviate problems caused exclusively by your code isn't such a good idea.

Also, judging by your description of the fix, it sounds like either the problem is really an easily reproducible bug (context related) or that something else is messing with the context that makes it look like it is context related but actually not. Intel is notorious for not being as nice to work with as Nvidia or AMD, but I've never heard of a case that was this bad...

Don't get me wrong, I want to help you, but it is better if we find clean thought-out solutions rather than just "hackish workarounds" that are the result of trial and error. The first step is to reproduce the problem in an isolated environment so we can rule out anything that really isn't related to the problem, and that step is up to you. Just throw a few SFML objects together to make it look like what your application does and see what happens. Even if the example doesn't turn out to be that short, we'll help you shorten it.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

dk123

  • Newbie
  • *
  • Posts: 49
    • View Profile
Re: SFML Context Management
« Reply #4 on: June 28, 2014, 02:24:10 am »
Thanks for the reply,
I managed to get a hold of a laptop pc with an intel hd graphics 4000 graphic card.

Quote
#include <SFML\Graphics.hpp>
#include <memory>
#include <array>

std::unique_ptr<sf::RenderWindow> pRenderWindow;

using ImageVec = std::array<std::shared_ptr<sf::Texture>, 3>;

int main()
{
   using namespace std;
   pRenderWindow.reset( new sf::RenderWindow( sf::VideoMode( 800, 600 ), "sfml test", sf::Style::Titlebar | sf::Style::Close ) );

   ImageVec imageVec;

   while ( pRenderWindow->isOpen() )
   {
      // check all the window's events that were triggered since the last iteration of the loop
      sf::Event event;
      while ( pRenderWindow->pollEvent( event ) )
      {
         switch ( event.type )
         {
         case sf::Event::Closed:
            imageVec.empty();
            pRenderWindow->close();
            pRenderWindow.reset();
            return 0;

         case sf::Event::KeyPressed:
            switch ( event.key.code )
            {
            case sf::Keyboard::Num4:
            {
               ImageVec imageVec_ = { make_shared<sf::Texture>(), make_shared<sf::Texture>(), make_shared<sf::Texture>() };
               imageVec = imageVec_;

               for ( auto& pBtnImage : imageVec )
               {
                  pBtnImage = make_shared<sf::Texture>();
                  pBtnImage->create( 100, 100 );
               }
            }
            }

         }
         
         pRenderWindow->clear( sf::Color( 255, 255, 255, 255 ) );
         pRenderWindow->display();
      }
   }

   return 0;
}

Running the code and hitting on the keyboard 4 key a couple of times and then closing the window will produce the following error: (with just different memory addresses)

Quote
First-chance exception at 0x7797E3BE (ntdll.dll) in sfml_test.exe: 0xC0000005: Access violation reading location 0x95159966.
First-chance exception at 0x7797E3BE (ntdll.dll) in sfml_test.exe: 0xC0000005: Access violation reading location 0x95159966.
First-chance exception at 0x7797E3BE (ntdll.dll) in sfml_test.exe: 0xC0000005: Access violation reading location 0x95159966.

Tell me if there is anything wrong with the code itself - it works completely fine on my pc with the ATI graphics card; the problem only occurs on the one with the Intel card.

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: SFML Context Management
« Reply #5 on: June 28, 2014, 02:52:04 am »
That example still seems unnecessarily complex. Are the unique_ptr and shared_ptrs really necessary to reproduce the problem? The way you use the unique_ptr, you might as well just create an instance of the RenderWindow directly. Also, why create a temporary ImageVec only to assign it to another in the following line? Is that required to reproduce the problem?

Try to get rid of the <memory> related objects and see if the problem is still reproducible. Also, does this have to do with the original problem you mentioned? Or is it just a crash you ran into while trying to reproduce the original problem?

Also, just in case you forgot, make sure the driver is up to date ;). The latest one (15.​33.​22.​3621) was released on 5/21/2014.

P.S. You might want to use code=cpp tags instead of a quote the next time you post code.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

dk123

  • Newbie
  • *
  • Posts: 49
    • View Profile
Re: SFML Context Management
« Reply #6 on: June 28, 2014, 03:44:28 am »
Thanks for the feedback  :)

#include <SFML\Graphics.hpp>
#include <array>

using ImageVec2 = std::array<sf::Texture, 3>;

int main()
{
        using namespace std;
        sf::RenderWindow renderWindow( sf::VideoMode( 800, 600 ), "sfml test", sf::Style::Titlebar | sf::Style::Close );

        ImageVec2 imageVec;

        while ( renderWindow.isOpen() )
        {
                // check all the window's events that were triggered since the last iteration of the loop
                sf::Event event;
                while ( renderWindow.pollEvent( event ) )
                {
                        switch ( event.type )
                        {
                        case sf::Event::Closed:
                                imageVec.empty();
                                renderWindow.close();
                                return 0;

                        case sf::Event::KeyPressed:
                                switch ( event.key.code )
                                {
                                case sf::Keyboard::Num4:
                                {
                                        for ( auto& pBtnImage : imageVec )
                                        {
                                                pBtnImage.create( 100, 100 );
                                        }
                                }
                                }

                        }
                       
                        renderWindow.clear( sf::Color( 255, 255, 255, 255 ) );
                        renderWindow.display();
                }
        }

        return 0;
}
 

The same memory address errors occur after pressing on the 4 key a few times and closing the window.

The crash is something I noticed while trying to reproduce the original issue.
The code that loads the textures in the original issue and the above code are closely related in my engine code - fixing this might fix the texture corruption issue that users have reported to me about.

I notice visual studio breaking me at times on
`pBtnImage.create( 100, 100 );` in the original engine code (the same ntdll.dll issue), this might be the source of trouble in the minimized code here as well.

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: SFML Context Management
« Reply #7 on: June 28, 2014, 04:43:54 am »
So does the following code also (immediately) crash?
#include <SFML\Graphics.hpp>

int main()
{
        sf::RenderWindow renderWindow( sf::VideoMode( 800, 600 ), "sfml test", sf::Style::Titlebar | sf::Style::Close );

        renderWindow.clear( sf::Color( 255, 255, 255, 255 ) );
        renderWindow.display();

        sf::Texture imageVec[3];

        for ( int i = 0; i < 3; ++i )
        {
                imageVec[i].create( 100, 100 );
        }

        renderWindow.clear( sf::Color( 255, 255, 255, 255 ) );
        renderWindow.display();

        renderWindow.close();
}
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

dk123

  • Newbie
  • *
  • Posts: 49
    • View Profile
Re: SFML Context Management
« Reply #8 on: June 28, 2014, 04:56:53 am »
So does the following code also (immediately) crash?
#include <SFML\Graphics.hpp>

int main()
{
        sf::RenderWindow renderWindow( sf::VideoMode( 800, 600 ), "sfml test", sf::Style::Titlebar | sf::Style::Close );

        renderWindow.clear( sf::Color( 255, 255, 255, 255 ) );
        renderWindow.display();

        sf::Texture imageVec[3];

        for ( int i = 0; i < 3; ++i )
        {
                imageVec[i].create( 100, 100 );
        }

        renderWindow.clear( sf::Color( 255, 255, 255, 255 ) );
        renderWindow.display();

        renderWindow.close();
}

I've just checked the code - it crashes right away.

dk123

  • Newbie
  • *
  • Posts: 49
    • View Profile
Re: SFML Context Management
« Reply #9 on: June 28, 2014, 05:31:47 am »
I've found something interesting.

The following code crashes: (the same ntdll.dll access violation errors)

#include <SFML\Graphics.hpp>

int main()
{
        sf::RenderWindow renderWindow( sf::VideoMode( 800, 600 ), "sfml test", sf::Style::Titlebar | sf::Style::Close );

        renderWindow.clear( sf::Color( 255, 255, 255, 255 ) );
        renderWindow.display();

        sf::Texture texture;
        texture.loadFromFile( "btn_sel.png" );

        sf::Sprite sprite;
        sprite.setTexture( texture );

        renderWindow.clear( sf::Color( 255, 255, 255, 255 ) );
        renderWindow.display();

        renderWindow.close();

        return 0;
}
 

while the following code doesn't:

#include <SFML\Graphics.hpp>

int main()
{
        sf::RenderWindow renderWindow( sf::VideoMode( 800, 600 ), "sfml test", sf::Style::Titlebar | sf::Style::Close );

        renderWindow.clear( sf::Color( 255, 255, 255, 255 ) );
        renderWindow.display();

        sf::Texture texture;
        texture.loadFromFile( "btn_sel.png" );

        sf::Sprite sprite;
        sprite.setTexture( texture );

        renderWindow.clear( sf::Color( 255, 255, 255, 255 ) );
        renderWindow.draw( sprite );
        renderWindow.display();

        renderWindow.close();

        return 0;
}
 

The only difference is one `renderWindow.draw( sprite );` call.
(the same occurs if I replace the texture.loadFromFile function with texture.create( 100, 100 ); )

I don't know if this helps track down something.
« Last Edit: June 28, 2014, 05:34:14 am by dk123 »

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: SFML Context Management
« Reply #10 on: June 28, 2014, 10:33:57 am »
Does this code crash?
#include <SFML\Graphics.hpp>
 
int main()
{
    sf::RenderWindow renderWindow( sf::VideoMode( 800, 600 ), "sfml test", sf::Style::Titlebar | sf::Style::Close );
 
    sf::Texture texture;
    texture.create( 100, 100 );

    renderWindow.display();
 
    return 0;
}

Also, what driver version is installed on the machine? Maybe this is a known bug.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

dk123

  • Newbie
  • *
  • Posts: 49
    • View Profile
Re: SFML Context Management
« Reply #11 on: June 28, 2014, 11:54:03 am »
Does this code crash?
#include <SFML\Graphics.hpp>
 
int main()
{
    sf::RenderWindow renderWindow( sf::VideoMode( 800, 600 ), "sfml test", sf::Style::Titlebar | sf::Style::Close );
 
    sf::Texture texture;
    texture.create( 100, 100 );

    renderWindow.display();
 
    return 0;
}

Also, what driver version is installed on the machine? Maybe this is a known bug.

The code doesn't crash - it doesn't crash if I change 'texture.create( 100, 100 );' to a 'texture.loadFromFile()' either.

The driver version on this laptop is 8.771.1.0

This code also works:

#include <SFML\Graphics.hpp>

int main()
{
        sf::RenderWindow renderWindow( sf::VideoMode( 800, 600 ), "sfml test", sf::Style::Titlebar | sf::Style::Close );

        renderWindow.clear( sf::Color( 255, 255, 255, 255 ) );
        renderWindow.display();

        sf::Texture texture;
        texture.create( 100, 100 );

        renderWindow.clear( sf::Color( 255, 255, 255, 255 ) );
        renderWindow.display();

        //renderWindow.close();

        return 0;
}
 

It seems the moment I uncomment the 'renderWindow.close()', the code crashes again.
The same happens if I add a 'renderWindow.close()' to the last part of the code you gave.

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: SFML Context Management
« Reply #12 on: June 28, 2014, 02:56:52 pm »
From what I've seen, 8.771.1.0 means you have a HP notebook with dual AMD/Intel graphics? That driver package is 4 years old and I'm sure Intel has fixed a ton of bugs since then. Is there no way to update the drivers? HP is known to not release driver updates for their products as soon as a couple of years after release. You could try heading to the Intel download site and installing the "appropriate" driver and hope it doesn't break your AMD graphics.

From the code that has been posted so far, this looks more and more like a driver bug. There is no systematic way to explain why renderWindow.close() prevents the crash since it is called when the RenderWindow goes out of scope at the end of main() as well. So whether renderWindow.close() is present or not, the code that is executed is almost identical and really shouldn't be able to have an effect on the crash and yet it does...
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

AlexAUT

  • Sr. Member
  • ****
  • Posts: 396
    • View Profile
Re: SFML Context Management
« Reply #13 on: June 28, 2014, 07:42:02 pm »
For me with an i5 4200u (Intel HD 4400) with the latest driver (10.18.10.3621) I have no problems with the code, also with the "GPU" Geforce gt740m I get no error.

Btw I have also an HP laptop and I does always use the "normal" drivers from the intel site and the Nividia site. So from my experience it's not a problem.



AlexAUT

dk123

  • Newbie
  • *
  • Posts: 49
    • View Profile
Re: SFML Context Management
« Reply #14 on: July 03, 2014, 01:46:11 pm »
From what I've seen, 8.771.1.0 means you have a HP notebook with dual AMD/Intel graphics? That driver package is 4 years old and I'm sure Intel has fixed a ton of bugs since then. Is there no way to update the drivers? HP is known to not release driver updates for their products as soon as a couple of years after release. You could try heading to the Intel download site and installing the "appropriate" driver and hope it doesn't break your AMD graphics.

From the code that has been posted so far, this looks more and more like a driver bug. There is no systematic way to explain why renderWindow.close() prevents the crash since it is called when the RenderWindow goes out of scope at the end of main() as well. So whether renderWindow.close() is present or not, the code that is executed is almost identical and really shouldn't be able to have an effect on the crash and yet it does...

You're right- the test machine I'm using is a HP notebook with dual AMD/Intel graphics. This is the only machine I have that seems to model the problems that my users are getting though - hence updating the drivers currently isn't an option. Telling my users with laptops to update their drivers hoping that it doesn't break something on theirs, isn't really an option either..;

For me with an i5 4200u (Intel HD 4400) with the latest driver (10.18.10.3621) I have no problems with the code, also with the "GPU" Geforce gt740m I get no error.

Great to know you're here to help AlexAUT - it's good to know there are other people to help check the issue.

I've noticed that the following code works without any access violation issues - any thoughts?
'renderWindow.close();' doesn't seem to cause an issue here.
The only real thing I've changed here is in using a pointer to a texture instead.

#include <SFML\Graphics.hpp>

sf::Texture* texture;

int main()
{
        sf::RenderWindow renderWindow( sf::VideoMode( 800, 600 ), "sfml test", sf::Style::Titlebar | sf::Style::Close );

        texture = new sf::Texture();
        texture->create( 100, 100 );

        renderWindow.display();

        renderWindow.close();

        return 0;
}