mirror of https://github.com/OpenTTD/OpenTTD.git
Fix: disable hardware acceleration when GPU driver crashed the game last attempt (#10928)
This commit is contained in:
parent
556b44713e
commit
0e56a73fb8
|
@ -16,8 +16,15 @@
|
|||
#include "video/video_driver.hpp"
|
||||
#include "string_func.h"
|
||||
#include "table/strings.h"
|
||||
#include "fileio_func.h"
|
||||
#include <sstream>
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
std::string _ini_videodriver; ///< The video driver a stored in the configuration file.
|
||||
|
@ -32,6 +39,8 @@ std::string _ini_musicdriver; ///< The music driver a stored in the confi
|
|||
std::string _ini_blitter; ///< The blitter as stored in the configuration file.
|
||||
bool _blitter_autodetected; ///< Was the blitter autodetected or specified by the user?
|
||||
|
||||
static const std::string HWACCELERATION_TEST_FILE = "hwaccel.dat"; ///< Filename to test if we crashed last time we tried to use hardware acceleration.
|
||||
|
||||
/**
|
||||
* Get a string parameter the list of parameters.
|
||||
* @param parm The parameters.
|
||||
|
@ -114,6 +123,27 @@ bool DriverFactoryBase::SelectDriverImpl(const std::string &name, Driver::Type t
|
|||
|
||||
if (type == Driver::DT_VIDEO && !_video_hw_accel && d->UsesHardwareAcceleration()) continue;
|
||||
|
||||
if (type == Driver::DT_VIDEO && _video_hw_accel && d->UsesHardwareAcceleration()) {
|
||||
/* Check if we have already tried this driver in last run.
|
||||
* If it is here, it most likely means we crashed. So skip
|
||||
* hardware acceleration. */
|
||||
auto filename = FioFindFullPath(BASE_DIR, HWACCELERATION_TEST_FILE);
|
||||
if (!filename.empty()) {
|
||||
unlink(filename.c_str());
|
||||
|
||||
Debug(driver, 1, "Probing {} driver '{}' skipped due to earlier crash", GetDriverTypeName(type), d->name);
|
||||
|
||||
_video_hw_accel = false;
|
||||
ErrorMessageData msg(STR_VIDEO_DRIVER_ERROR, STR_VIDEO_DRIVER_ERROR_HARDWARE_ACCELERATION_CRASH, true);
|
||||
ScheduleErrorMessage(msg);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Write empty file to note we are attempting hardware acceleration. */
|
||||
auto f = FioFOpenFile(HWACCELERATION_TEST_FILE, "w", BASE_DIR);
|
||||
FioFCloseFile(f);
|
||||
}
|
||||
|
||||
Driver *oldd = *GetActiveDriver(type);
|
||||
Driver *newd = d->CreateInstance();
|
||||
*GetActiveDriver(type) = newd;
|
||||
|
@ -131,7 +161,7 @@ bool DriverFactoryBase::SelectDriverImpl(const std::string &name, Driver::Type t
|
|||
|
||||
if (type == Driver::DT_VIDEO && _video_hw_accel && d->UsesHardwareAcceleration()) {
|
||||
_video_hw_accel = false;
|
||||
ErrorMessageData msg(STR_VIDEO_DRIVER_ERROR, STR_VIDEO_DRIVER_ERROR_NO_HARDWARE_ACCELERATION);
|
||||
ErrorMessageData msg(STR_VIDEO_DRIVER_ERROR, STR_VIDEO_DRIVER_ERROR_NO_HARDWARE_ACCELERATION, true);
|
||||
ScheduleErrorMessage(msg);
|
||||
}
|
||||
}
|
||||
|
@ -177,6 +207,18 @@ bool DriverFactoryBase::SelectDriverImpl(const std::string &name, Driver::Type t
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the current video driver as operational.
|
||||
*/
|
||||
void DriverFactoryBase::MarkVideoDriverOperational()
|
||||
{
|
||||
/* As part of the detection whether the GPU driver crashes the game,
|
||||
* and as we are operational now, remove the hardware acceleration
|
||||
* test-file. */
|
||||
auto filename = FioFindFullPath(BASE_DIR, HWACCELERATION_TEST_FILE);
|
||||
if (!filename.empty()) unlink(filename.c_str());
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a human readable list of available drivers, grouped by type.
|
||||
* @param output_iterator The iterator to write the string to.
|
||||
|
|
|
@ -100,6 +100,8 @@ private:
|
|||
|
||||
static bool SelectDriverImpl(const std::string &name, Driver::Type type);
|
||||
|
||||
static void MarkVideoDriverOperational();
|
||||
|
||||
protected:
|
||||
DriverFactoryBase(Driver::Type type, int priority, const char *name, const char *description);
|
||||
|
||||
|
|
|
@ -2080,6 +2080,7 @@ STR_CONFIG_ERROR_SPRITECACHE_TOO_BIG :{WHITE}Allocati
|
|||
# Video initalization errors
|
||||
STR_VIDEO_DRIVER_ERROR :{WHITE}Error with video settings...
|
||||
STR_VIDEO_DRIVER_ERROR_NO_HARDWARE_ACCELERATION :{WHITE}... no compatible GPU found. Hardware acceleration disabled
|
||||
STR_VIDEO_DRIVER_ERROR_HARDWARE_ACCELERATION_CRASH :{WHITE}... GPU driver crashed the game. Hardware acceleration disabled
|
||||
|
||||
# Intro window
|
||||
STR_INTRO_CAPTION :{WHITE}OpenTTD {REV}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "../network/network.h"
|
||||
#include "../blitter/factory.hpp"
|
||||
#include "../debug.h"
|
||||
#include "../driver.h"
|
||||
#include "../fontcache.h"
|
||||
#include "../gfx_func.h"
|
||||
#include "../gfxinit.h"
|
||||
|
@ -156,6 +157,13 @@ void VideoDriver::Tick()
|
|||
this->Paint();
|
||||
|
||||
this->UnlockVideoBuffer();
|
||||
|
||||
/* Wait till the first successful drawing tick before marking the driver as operational. */
|
||||
static bool first_draw_tick = true;
|
||||
if (first_draw_tick) {
|
||||
first_draw_tick = false;
|
||||
DriverFactoryBase::MarkVideoDriverOperational();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue