[util] Use __wine_dbg_output if available

This commit is contained in:
Philip Rebohle 2023-03-13 15:45:18 +01:00
parent 3a123222e5
commit 05fb634f91
3 changed files with 69 additions and 34 deletions

View File

@ -17,7 +17,7 @@ cp x32/*.dll $WINEPREFIX/drive_c/windows/syswow64
winecfg
```
Verify that your application uses DXVK instead of wined3d by checking for the presence of the log file `d3d9.log` or `d3d11.log` in the application's directory, or by enabling the HUD (see notes below).
Verify that your application uses DXVK instead of wined3d by by enabling the HUD (see notes below).
In order to remove DXVK from a prefix, remove the DLLs and DLL overrides, and run `wineboot -u` to restore the original DLL files.
@ -70,6 +70,11 @@ Before reporting an issue, please check the [Wiki](https://github.com/doitsujin/
### Online multi-player games
Manipulation of Direct3D libraries in multi-player games may be considered cheating and can get your account **banned**. This may also apply to single-player games with an embedded or dedicated multiplayer portion. **Use at your own risk.**
### Logs
When used with Wine, DXVK will print log messages to `stderr`. Additionally, standalone log files can optionally be generated by setting the `DXVK_LOG_PATH` variable, where log files in the given directory will be called `app_d3d11.log`, `app_dxgi.log` etc., where `app` is the name of the game executable.
On Windows, log files will be created in the game's working directory by default, which is usually next to the game executable.
### HUD
The `DXVK_HUD` environment variable controls a HUD which can display the framerate and some stat counters. It accepts a comma-separated list of the following options:
- `devinfo`: Displays the name of the GPU and the driver version.

View File

@ -1,17 +1,14 @@
#include <utility>
#include "log.h"
#include "../util_env.h"
namespace dxvk {
Logger::Logger(const std::string& file_name)
: m_minLevel(getMinLogLevel()) {
if (m_minLevel != LogLevel::None) {
auto path = getFileName(file_name);
Logger::Logger(const std::string& fileName)
: m_minLevel(getMinLogLevel()), m_fileName(fileName) {
if (!path.empty())
m_fileStream = std::ofstream(str::topath(path.c_str()).c_str());
}
}
@ -57,19 +54,61 @@ namespace dxvk {
const char* prefix = s_prefixes.at(static_cast<uint32_t>(level));
if (!std::exchange(m_initialized, true)) {
#ifdef _WIN32
HMODULE ntdll = GetModuleHandleA("ntdll.dll");
if (ntdll)
m_wineLogOutput = reinterpret_cast<PFN_wineLogOutput>(GetProcAddress(ntdll, "__wine_dbg_output"));
#endif
auto path = getFileName(m_fileName);
if (!path.empty())
m_fileStream = std::ofstream(str::topath(path.c_str()).c_str());
}
std::stringstream stream(message);
std::string line;
std::string line;
while (std::getline(stream, line, '\n')) {
std::cerr << prefix << line << std::endl;
std::stringstream outstream;
outstream << prefix << line << std::endl;
std::string adjusted = outstream.str();
if (!adjusted.empty()) {
if (m_wineLogOutput)
m_wineLogOutput(adjusted.c_str());
else
std::cerr << adjusted;
}
if (m_fileStream)
m_fileStream << prefix << line << std::endl;
m_fileStream << adjusted;
}
}
}
std::string Logger::getFileName(const std::string& base) {
std::string path = env::getEnvVar("DXVK_LOG_PATH");
if (path == "none")
return std::string();
// Don't create a log file if we're writing to wine's console output
if (path.empty() && m_wineLogOutput)
return std::string();
if (!path.empty() && *path.rbegin() != '/')
path += '/';
std::string exeName = env::getExeBaseName();
path += exeName + "_" + base;
return path;
}
LogLevel Logger::getMinLogLevel() {
const std::array<std::pair<const char*, LogLevel>, 6> logLevels = {{
{ "trace", LogLevel::Trace },
@ -90,19 +129,4 @@ namespace dxvk {
return LogLevel::Info;
}
std::string Logger::getFileName(const std::string& base) {
std::string path = env::getEnvVar("DXVK_LOG_PATH");
if (path == "none")
return "";
if (!path.empty() && *path.rbegin() != '/')
path += '/';
std::string exeName = env::getExeBaseName();
path += exeName + "_" + base;
return path;
}
}

View File

@ -18,6 +18,8 @@ namespace dxvk {
None = 5,
};
using PFN_wineLogOutput = int (STDMETHODCALLTYPE *)(const char *);
/**
* \brief Logger
*
@ -44,20 +46,24 @@ namespace dxvk {
private:
static Logger s_instance;
static Logger s_instance;
const LogLevel m_minLevel;
dxvk::mutex m_mutex;
std::ofstream m_fileStream;
const LogLevel m_minLevel;
const std::string m_fileName;
dxvk::mutex m_mutex;
std::ofstream m_fileStream;
bool m_initialized = false;
PFN_wineLogOutput m_wineLogOutput = nullptr;
void emitMsg(LogLevel level, const std::string& message);
static LogLevel getMinLogLevel();
static std::string getFileName(
std::string getFileName(
const std::string& base);
static LogLevel getMinLogLevel();
};
}