Changeset - r27498:6d2aaf65c3e6
[Not reviewed]
master
0 4 0
Patric Stout - 11 months ago 2023-06-04 14:40:17
truebrain@openttd.org
Fix: disable hardware acceleration when GPU driver crashed the game last attempt (#10928)
4 files changed with 54 insertions and 1 deletions:
0 comments (0 inline, 0 general)
src/driver.cpp
Show inline comments
 
@@ -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;        ///
 
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
 

	
 
				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
 

	
 
				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);
 
				}
 
			}
 
@@ -178,6 +208,18 @@ bool DriverFactoryBase::SelectDriverImpl
 
}
 

	
 
/**
 
 * 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.
 
 */
src/driver.h
Show inline comments
 
@@ -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);
 

	
src/lang/english.txt
Show inline comments
 
@@ -2080,6 +2080,7 @@ STR_CONFIG_ERROR_SPRITECACHE_TOO_BIG    
 
# 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}
src/video/video_driver.cpp
Show inline comments
 
@@ -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();
 
		}
 
	}
 
}
 

	
0 comments (0 inline, 0 general)