Merge pull request #1358 from jgoyvaerts/config_final
Replace GFLAGS with a config system + config file.
This commit is contained in:
commit
763274654d
|
@ -16,9 +16,6 @@
|
||||||
[submodule "third_party/catch"]
|
[submodule "third_party/catch"]
|
||||||
path = third_party/catch
|
path = third_party/catch
|
||||||
url = https://github.com/catchorg/Catch2.git
|
url = https://github.com/catchorg/Catch2.git
|
||||||
[submodule "third_party/gflags"]
|
|
||||||
path = third_party/gflags
|
|
||||||
url = https://github.com/benvanik/gflags.git
|
|
||||||
[submodule "third_party/premake-core"]
|
[submodule "third_party/premake-core"]
|
||||||
path = third_party/premake-core
|
path = third_party/premake-core
|
||||||
url = https://github.com/xenia-project/premake-core.git
|
url = https://github.com/xenia-project/premake-core.git
|
||||||
|
@ -49,3 +46,9 @@
|
||||||
[submodule "third_party/capstone"]
|
[submodule "third_party/capstone"]
|
||||||
path = third_party/capstone
|
path = third_party/capstone
|
||||||
url = https://github.com/xenia-project/capstone.git
|
url = https://github.com/xenia-project/capstone.git
|
||||||
|
[submodule "third_party/cpptoml"]
|
||||||
|
path = third_party/cpptoml
|
||||||
|
url = https://github.com/skystrife/cpptoml
|
||||||
|
[submodule "third_party/cxxopts"]
|
||||||
|
path = third_party/cxxopts
|
||||||
|
url = https://github.com/jarro2783/cxxopts
|
||||||
|
|
27
premake5.lua
27
premake5.lua
|
@ -192,30 +192,9 @@ filter("platforms:Windows")
|
||||||
"shlwapi",
|
"shlwapi",
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Create scratch/ path and dummy flags file if needed.
|
-- Create scratch/ path
|
||||||
if not os.isdir("scratch") then
|
if not os.isdir("scratch") then
|
||||||
os.mkdir("scratch")
|
os.mkdir("scratch")
|
||||||
local flags_file = io.open("scratch/flags.txt", "w")
|
|
||||||
flags_file:write("# Put flags, one on each line.\n")
|
|
||||||
flags_file:write("# Launch executables with --flags_file=scratch/flags.txt\n")
|
|
||||||
flags_file:write("\n")
|
|
||||||
flags_file:write("--cpu=x64\n")
|
|
||||||
flags_file:write("#--enable_haswell_instructions=false\n")
|
|
||||||
flags_file:write("\n")
|
|
||||||
flags_file:write("--debug\n")
|
|
||||||
flags_file:write("#--protect_zero=false\n")
|
|
||||||
flags_file:write("\n")
|
|
||||||
flags_file:write("#--mute\n")
|
|
||||||
flags_file:write("\n")
|
|
||||||
flags_file:write("--fast_stdout\n")
|
|
||||||
flags_file:write("#--flush_stdout=false\n")
|
|
||||||
flags_file:write("\n")
|
|
||||||
flags_file:write("#--vsync=false\n")
|
|
||||||
flags_file:write("#--trace_gpu_prefix=scratch/gpu/gpu_trace_\n")
|
|
||||||
flags_file:write("#--trace_gpu_stream\n")
|
|
||||||
flags_file:write("#--disable_framebuffer_readback\n")
|
|
||||||
flags_file:write("\n")
|
|
||||||
flags_file:close()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
solution("xenia")
|
solution("xenia")
|
||||||
|
@ -229,11 +208,11 @@ solution("xenia")
|
||||||
end
|
end
|
||||||
configurations({"Checked", "Debug", "Release"})
|
configurations({"Checked", "Debug", "Release"})
|
||||||
|
|
||||||
-- Include third party files first so they don't have to deal with gflags.
|
|
||||||
include("third_party/aes_128.lua")
|
include("third_party/aes_128.lua")
|
||||||
include("third_party/capstone.lua")
|
include("third_party/capstone.lua")
|
||||||
include("third_party/discord-rpc.lua")
|
include("third_party/discord-rpc.lua")
|
||||||
include("third_party/gflags.lua")
|
include("third_party/cxxopts.lua")
|
||||||
|
include("third_party/cpptoml.lua")
|
||||||
include("third_party/glew.lua")
|
include("third_party/glew.lua")
|
||||||
include("third_party/glslang-spirv.lua")
|
include("third_party/glslang-spirv.lua")
|
||||||
include("third_party/imgui.lua")
|
include("third_party/imgui.lua")
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include "xenia/app/emulator_window.h"
|
#include "xenia/app/emulator_window.h"
|
||||||
|
|
||||||
// Autogenerated by `xb premake`.
|
// Autogenerated by `xb premake`.
|
||||||
|
@ -17,6 +15,7 @@
|
||||||
#include "third_party/imgui/imgui.h"
|
#include "third_party/imgui/imgui.h"
|
||||||
#include "xenia/app/discord/discord_presence.h"
|
#include "xenia/app/discord/discord_presence.h"
|
||||||
#include "xenia/base/clock.h"
|
#include "xenia/base/clock.h"
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
#include "xenia/base/debugging.h"
|
#include "xenia/base/debugging.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/platform.h"
|
#include "xenia/base/platform.h"
|
||||||
|
@ -29,7 +28,8 @@
|
||||||
#include "xenia/ui/imgui_dialog.h"
|
#include "xenia/ui/imgui_dialog.h"
|
||||||
#include "xenia/ui/imgui_drawer.h"
|
#include "xenia/ui/imgui_drawer.h"
|
||||||
|
|
||||||
DEFINE_bool(discord, false, "Enable Discord rich presence");
|
DECLARE_bool(debug);
|
||||||
|
DEFINE_bool(discord, false, "Enable Discord rich presence", "General");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace app {
|
namespace app {
|
||||||
|
@ -85,7 +85,7 @@ bool EmulatorWindow::Initialize() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_discord) {
|
if (cvars::discord) {
|
||||||
discord::DiscordPresence::InitializeDiscord();
|
discord::DiscordPresence::InitializeDiscord();
|
||||||
discord::DiscordPresence::NotPlaying();
|
discord::DiscordPresence::NotPlaying();
|
||||||
}
|
}
|
||||||
|
@ -344,7 +344,7 @@ void EmulatorWindow::FileOpen() {
|
||||||
void EmulatorWindow::FileClose() {
|
void EmulatorWindow::FileClose() {
|
||||||
if (emulator_->is_title_open()) {
|
if (emulator_->is_title_open()) {
|
||||||
emulator_->TerminateTitle();
|
emulator_->TerminateTitle();
|
||||||
if (FLAGS_discord) {
|
if (cvars::discord) {
|
||||||
discord::DiscordPresence::NotPlaying();
|
discord::DiscordPresence::NotPlaying();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -398,7 +398,7 @@ void EmulatorWindow::CpuTimeScalarSetDouble() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatorWindow::CpuBreakIntoDebugger() {
|
void EmulatorWindow::CpuBreakIntoDebugger() {
|
||||||
if (!FLAGS_debug) {
|
if (!cvars::debug) {
|
||||||
xe::ui::ImGuiDialog::ShowMessageBox(window_.get(), "Xenia Debugger",
|
xe::ui::ImGuiDialog::ShowMessageBox(window_.get(), "Xenia Debugger",
|
||||||
"Xenia must be launched with the "
|
"Xenia must be launched with the "
|
||||||
"--debug flag in order to enable "
|
"--debug flag in order to enable "
|
||||||
|
@ -444,7 +444,7 @@ void EmulatorWindow::UpdateTitle() {
|
||||||
auto game_title = emulator()->game_title();
|
auto game_title = emulator()->game_title();
|
||||||
title += xe::format_string(L" | [%.8X] %s", emulator()->title_id(),
|
title += xe::format_string(L" | [%.8X] %s", emulator()->title_id(),
|
||||||
game_title.c_str());
|
game_title.c_str());
|
||||||
if (FLAGS_discord) {
|
if (cvars::discord) {
|
||||||
discord::DiscordPresence::PlayingTitle(game_title);
|
discord::DiscordPresence::PlayingTitle(game_title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ project("xenia-app")
|
||||||
"aes_128",
|
"aes_128",
|
||||||
"capstone",
|
"capstone",
|
||||||
"discord-rpc",
|
"discord-rpc",
|
||||||
"gflags",
|
|
||||||
"glew",
|
"glew",
|
||||||
"glslang-spirv",
|
"glslang-spirv",
|
||||||
"imgui",
|
"imgui",
|
||||||
|
@ -45,9 +44,6 @@ project("xenia-app")
|
||||||
"XBYAK_NO_OP_NAMES",
|
"XBYAK_NO_OP_NAMES",
|
||||||
"XBYAK_ENABLE_OMITTED_OPERAND",
|
"XBYAK_ENABLE_OMITTED_OPERAND",
|
||||||
})
|
})
|
||||||
includedirs({
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
|
||||||
local_platform_files()
|
local_platform_files()
|
||||||
files({
|
files({
|
||||||
"xenia_main.cc",
|
"xenia_main.cc",
|
||||||
|
@ -89,6 +85,5 @@ project("xenia-app")
|
||||||
if not os.isfile(user_file) then
|
if not os.isfile(user_file) then
|
||||||
debugdir(project_root)
|
debugdir(project_root)
|
||||||
debugargs({
|
debugargs({
|
||||||
"--flagfile=scratch/flags.txt",
|
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,14 +7,14 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include "xenia/app/emulator_window.h"
|
#include "xenia/app/emulator_window.h"
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
#include "xenia/base/debugging.h"
|
#include "xenia/base/debugging.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/main.h"
|
#include "xenia/base/main.h"
|
||||||
#include "xenia/base/profiling.h"
|
#include "xenia/base/profiling.h"
|
||||||
#include "xenia/base/threading.h"
|
#include "xenia/base/threading.h"
|
||||||
|
#include "xenia/config.h"
|
||||||
#include "xenia/debug/ui/debug_window.h"
|
#include "xenia/debug/ui/debug_window.h"
|
||||||
#include "xenia/emulator.h"
|
#include "xenia/emulator.h"
|
||||||
#include "xenia/ui/file_picker.h"
|
#include "xenia/ui/file_picker.h"
|
||||||
|
@ -37,26 +37,33 @@
|
||||||
#include "xenia/hid/xinput/xinput_hid.h"
|
#include "xenia/hid/xinput/xinput_hid.h"
|
||||||
#endif // XE_PLATFORM_WIN32
|
#endif // XE_PLATFORM_WIN32
|
||||||
|
|
||||||
DEFINE_string(apu, "any", "Audio system. Use: [any, nop, xaudio2]");
|
#include "third_party/xbyak/xbyak/xbyak_util.h"
|
||||||
DEFINE_string(gpu, "any", "Graphics system. Use: [any, vulkan, null]");
|
|
||||||
DEFINE_string(hid, "any", "Input system. Use: [any, nop, winkey, xinput]");
|
|
||||||
|
|
||||||
DEFINE_string(target, "", "Specifies the target .xex or .iso to execute.");
|
DEFINE_string(apu, "any", "Audio system. Use: [any, nop, xaudio2]", "General");
|
||||||
DEFINE_bool(fullscreen, false, "Toggles fullscreen");
|
DEFINE_string(gpu, "any", "Graphics system. Use: [any, vulkan, null]",
|
||||||
|
"General");
|
||||||
|
DEFINE_string(hid, "any", "Input system. Use: [any, nop, winkey, xinput]",
|
||||||
|
"General");
|
||||||
|
|
||||||
DEFINE_string(content_root, "", "Root path for content (save/etc) storage.");
|
DEFINE_bool(fullscreen, false, "Toggles fullscreen", "General");
|
||||||
|
|
||||||
DEFINE_bool(mount_scratch, false, "Enable scratch mount");
|
DEFINE_string(content_root, "", "Root path for content (save/etc) storage.",
|
||||||
DEFINE_bool(mount_cache, false, "Enable cache mount");
|
"General");
|
||||||
|
|
||||||
|
DEFINE_bool(mount_scratch, false, "Enable scratch mount", "General");
|
||||||
|
DEFINE_bool(mount_cache, false, "Enable cache mount", "General");
|
||||||
|
|
||||||
|
CmdVar(target, "", "Specifies the target .xex or .iso to execute.");
|
||||||
|
DECLARE_bool(debug);
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
std::unique_ptr<apu::AudioSystem> CreateAudioSystem(cpu::Processor* processor) {
|
std::unique_ptr<apu::AudioSystem> CreateAudioSystem(cpu::Processor* processor) {
|
||||||
if (FLAGS_apu.compare("nop") == 0) {
|
if (cvars::apu.compare("nop") == 0) {
|
||||||
return apu::nop::NopAudioSystem::Create(processor);
|
return apu::nop::NopAudioSystem::Create(processor);
|
||||||
#if XE_PLATFORM_WIN32
|
#if XE_PLATFORM_WIN32
|
||||||
} else if (FLAGS_apu.compare("xaudio2") == 0) {
|
} else if (cvars::apu.compare("xaudio2") == 0) {
|
||||||
return apu::xaudio2::XAudio2AudioSystem::Create(processor);
|
return apu::xaudio2::XAudio2AudioSystem::Create(processor);
|
||||||
#endif // XE_PLATFORM_WIN32
|
#endif // XE_PLATFORM_WIN32
|
||||||
} else {
|
} else {
|
||||||
|
@ -76,10 +83,10 @@ std::unique_ptr<apu::AudioSystem> CreateAudioSystem(cpu::Processor* processor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<gpu::GraphicsSystem> CreateGraphicsSystem() {
|
std::unique_ptr<gpu::GraphicsSystem> CreateGraphicsSystem() {
|
||||||
if (FLAGS_gpu.compare("vulkan") == 0) {
|
if (cvars::gpu.compare("vulkan") == 0) {
|
||||||
return std::unique_ptr<gpu::GraphicsSystem>(
|
return std::unique_ptr<gpu::GraphicsSystem>(
|
||||||
new xe::gpu::vulkan::VulkanGraphicsSystem());
|
new xe::gpu::vulkan::VulkanGraphicsSystem());
|
||||||
} else if (FLAGS_gpu.compare("null") == 0) {
|
} else if (cvars::gpu.compare("null") == 0) {
|
||||||
return std::unique_ptr<gpu::GraphicsSystem>(
|
return std::unique_ptr<gpu::GraphicsSystem>(
|
||||||
new xe::gpu::null::NullGraphicsSystem());
|
new xe::gpu::null::NullGraphicsSystem());
|
||||||
} else {
|
} else {
|
||||||
|
@ -100,12 +107,12 @@ std::unique_ptr<gpu::GraphicsSystem> CreateGraphicsSystem() {
|
||||||
std::vector<std::unique_ptr<hid::InputDriver>> CreateInputDrivers(
|
std::vector<std::unique_ptr<hid::InputDriver>> CreateInputDrivers(
|
||||||
ui::Window* window) {
|
ui::Window* window) {
|
||||||
std::vector<std::unique_ptr<hid::InputDriver>> drivers;
|
std::vector<std::unique_ptr<hid::InputDriver>> drivers;
|
||||||
if (FLAGS_hid.compare("nop") == 0) {
|
if (cvars::hid.compare("nop") == 0) {
|
||||||
drivers.emplace_back(xe::hid::nop::Create(window));
|
drivers.emplace_back(xe::hid::nop::Create(window));
|
||||||
#if XE_PLATFORM_WIN32
|
#if XE_PLATFORM_WIN32
|
||||||
} else if (FLAGS_hid.compare("winkey") == 0) {
|
} else if (cvars::hid.compare("winkey") == 0) {
|
||||||
drivers.emplace_back(xe::hid::winkey::Create(window));
|
drivers.emplace_back(xe::hid::winkey::Create(window));
|
||||||
} else if (FLAGS_hid.compare("xinput") == 0) {
|
} else if (cvars::hid.compare("xinput") == 0) {
|
||||||
drivers.emplace_back(xe::hid::xinput::Create(window));
|
drivers.emplace_back(xe::hid::xinput::Create(window));
|
||||||
#endif // XE_PLATFORM_WIN32
|
#endif // XE_PLATFORM_WIN32
|
||||||
} else {
|
} else {
|
||||||
|
@ -139,16 +146,17 @@ int xenia_main(const std::vector<std::wstring>& args) {
|
||||||
Profiler::ThreadEnter("main");
|
Profiler::ThreadEnter("main");
|
||||||
|
|
||||||
// Figure out where content should go.
|
// Figure out where content should go.
|
||||||
std::wstring content_root;
|
std::wstring content_root = xe::to_wstring(cvars::content_root);
|
||||||
if (!FLAGS_content_root.empty()) {
|
std::wstring config_folder;
|
||||||
content_root = xe::to_wstring(FLAGS_content_root);
|
|
||||||
} else {
|
if (content_root.empty()) {
|
||||||
auto base_path = xe::filesystem::GetExecutableFolder();
|
auto base_path = xe::filesystem::GetExecutableFolder();
|
||||||
base_path = xe::to_absolute_path(base_path);
|
base_path = xe::to_absolute_path(base_path);
|
||||||
|
|
||||||
auto portable_path = xe::join_paths(base_path, L"portable.txt");
|
auto portable_path = xe::join_paths(base_path, L"portable.txt");
|
||||||
if (xe::filesystem::PathExists(portable_path)) {
|
if (xe::filesystem::PathExists(portable_path)) {
|
||||||
content_root = xe::join_paths(base_path, L"content");
|
content_root = xe::join_paths(base_path, L"content");
|
||||||
|
config_folder = base_path;
|
||||||
} else {
|
} else {
|
||||||
content_root = xe::filesystem::GetUserFolder();
|
content_root = xe::filesystem::GetUserFolder();
|
||||||
#if defined(XE_PLATFORM_WIN32)
|
#if defined(XE_PLATFORM_WIN32)
|
||||||
|
@ -159,11 +167,14 @@ int xenia_main(const std::vector<std::wstring>& args) {
|
||||||
#warning Unhandled platform for content root.
|
#warning Unhandled platform for content root.
|
||||||
content_root = xe::join_paths(content_root, L"Xenia");
|
content_root = xe::join_paths(content_root, L"Xenia");
|
||||||
#endif
|
#endif
|
||||||
|
config_folder = content_root;
|
||||||
content_root = xe::join_paths(content_root, L"content");
|
content_root = xe::join_paths(content_root, L"content");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
content_root = xe::to_absolute_path(content_root);
|
content_root = xe::to_absolute_path(content_root);
|
||||||
|
|
||||||
XELOGI("Content root: %S", content_root.c_str());
|
XELOGI("Content root: %S", content_root.c_str());
|
||||||
|
config::SetupConfig(config_folder);
|
||||||
|
|
||||||
// Create the emulator but don't initialize so we can setup the window.
|
// Create the emulator but don't initialize so we can setup the window.
|
||||||
auto emulator = std::make_unique<Emulator>(L"", content_root);
|
auto emulator = std::make_unique<Emulator>(L"", content_root);
|
||||||
|
@ -181,7 +192,7 @@ int xenia_main(const std::vector<std::wstring>& args) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_mount_scratch) {
|
if (cvars::mount_scratch) {
|
||||||
auto scratch_device = std::make_unique<xe::vfs::HostPathDevice>(
|
auto scratch_device = std::make_unique<xe::vfs::HostPathDevice>(
|
||||||
"\\SCRATCH", L"scratch", false);
|
"\\SCRATCH", L"scratch", false);
|
||||||
if (!scratch_device->Initialize()) {
|
if (!scratch_device->Initialize()) {
|
||||||
|
@ -195,7 +206,7 @@ int xenia_main(const std::vector<std::wstring>& args) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_mount_cache) {
|
if (cvars::mount_cache) {
|
||||||
auto cache0_device =
|
auto cache0_device =
|
||||||
std::make_unique<xe::vfs::HostPathDevice>("\\CACHE0", L"cache0", false);
|
std::make_unique<xe::vfs::HostPathDevice>("\\CACHE0", L"cache0", false);
|
||||||
if (!cache0_device->Initialize()) {
|
if (!cache0_device->Initialize()) {
|
||||||
|
@ -224,7 +235,7 @@ int xenia_main(const std::vector<std::wstring>& args) {
|
||||||
// Set a debug handler.
|
// Set a debug handler.
|
||||||
// This will respond to debugging requests so we can open the debug UI.
|
// This will respond to debugging requests so we can open the debug UI.
|
||||||
std::unique_ptr<xe::debug::ui::DebugWindow> debug_window;
|
std::unique_ptr<xe::debug::ui::DebugWindow> debug_window;
|
||||||
if (FLAGS_debug) {
|
if (cvars::debug) {
|
||||||
emulator->processor()->set_debug_listener_request_handler(
|
emulator->processor()->set_debug_listener_request_handler(
|
||||||
[&](xe::cpu::Processor* processor) {
|
[&](xe::cpu::Processor* processor) {
|
||||||
if (debug_window) {
|
if (debug_window) {
|
||||||
|
@ -270,20 +281,12 @@ int xenia_main(const std::vector<std::wstring>& args) {
|
||||||
|
|
||||||
// Grab path from the flag or unnamed argument.
|
// Grab path from the flag or unnamed argument.
|
||||||
std::wstring path;
|
std::wstring path;
|
||||||
if (!FLAGS_target.empty() || args.size() >= 2) {
|
if (!cvars::target.empty()) {
|
||||||
if (!FLAGS_target.empty()) {
|
path = xe::to_wstring(cvars::target);
|
||||||
// Passed as a named argument.
|
|
||||||
// TODO(benvanik): find something better than gflags that supports
|
|
||||||
// unicode.
|
|
||||||
path = xe::to_wstring(FLAGS_target);
|
|
||||||
} else {
|
|
||||||
// Passed as an unnamed argument.
|
|
||||||
path = args[1];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggles fullscreen
|
// Toggles fullscreen
|
||||||
if (FLAGS_fullscreen) emulator_window->ToggleFullscreen();
|
if (cvars::fullscreen) emulator_window->ToggleFullscreen();
|
||||||
|
|
||||||
if (!path.empty()) {
|
if (!path.empty()) {
|
||||||
// Normalize the path and make absolute.
|
// Normalize the path and make absolute.
|
||||||
|
|
|
@ -9,4 +9,4 @@
|
||||||
|
|
||||||
#include "xenia/apu/apu_flags.h"
|
#include "xenia/apu/apu_flags.h"
|
||||||
|
|
||||||
DEFINE_bool(mute, false, "Mutes all audio output.");
|
DEFINE_bool(mute, false, "Mutes all audio output.", "Audio")
|
||||||
|
|
|
@ -10,8 +10,7 @@
|
||||||
#ifndef XENIA_APU_APU_FLAGS_H_
|
#ifndef XENIA_APU_APU_FLAGS_H_
|
||||||
#define XENIA_APU_APU_FLAGS_H_
|
#define XENIA_APU_APU_FLAGS_H_
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
#include "xenia/base/cvar.h"
|
||||||
|
DECLARE_bool(mute)
|
||||||
DECLARE_bool(mute);
|
|
||||||
|
|
||||||
#endif // XENIA_APU_APU_FLAGS_H_
|
#endif // XENIA_APU_APU_FLAGS_H_
|
||||||
|
|
|
@ -10,6 +10,4 @@
|
||||||
#ifndef XENIA_APU_NOP_NOP_APU_FLAGS_H_
|
#ifndef XENIA_APU_NOP_NOP_APU_FLAGS_H_
|
||||||
#define XENIA_APU_NOP_NOP_APU_FLAGS_H_
|
#define XENIA_APU_NOP_NOP_APU_FLAGS_H_
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#endif // XENIA_APU_NOP_NOP_APU_FLAGS_H_
|
#endif // XENIA_APU_NOP_NOP_APU_FLAGS_H_
|
||||||
|
|
|
@ -12,7 +12,4 @@ project("xenia-apu-nop")
|
||||||
})
|
})
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
|
||||||
local_platform_files()
|
local_platform_files()
|
||||||
|
|
|
@ -14,7 +14,6 @@ project("xenia-apu")
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
includedirs({
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
project_root.."/third_party/libav/",
|
project_root.."/third_party/libav/",
|
||||||
})
|
})
|
||||||
local_platform_files()
|
local_platform_files()
|
||||||
|
|
|
@ -12,7 +12,4 @@ project("xenia-apu-xaudio2")
|
||||||
})
|
})
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
|
||||||
local_platform_files()
|
local_platform_files()
|
||||||
|
|
|
@ -10,6 +10,4 @@
|
||||||
#ifndef XENIA_APU_XAUDIO2_XAUDIO2_APU_FLAGS_H_
|
#ifndef XENIA_APU_XAUDIO2_XAUDIO2_APU_FLAGS_H_
|
||||||
#define XENIA_APU_XAUDIO2_XAUDIO2_APU_FLAGS_H_
|
#define XENIA_APU_XAUDIO2_XAUDIO2_APU_FLAGS_H_
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#endif // XENIA_APU_XAUDIO2_XAUDIO2_APU_FLAGS_H_
|
#endif // XENIA_APU_XAUDIO2_XAUDIO2_APU_FLAGS_H_
|
||||||
|
|
|
@ -151,7 +151,7 @@ bool XAudio2AudioDriver::Initialize() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_mute) {
|
if (cvars::mute) {
|
||||||
pcm_voice_->SetVolume(0.0f);
|
pcm_voice_->SetVolume(0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,8 @@
|
||||||
|
|
||||||
#include "xenia/apu/xma_decoder.h"
|
#include "xenia/apu/xma_decoder.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include "xenia/apu/xma_context.h"
|
#include "xenia/apu/xma_context.h"
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/math.h"
|
#include "xenia/base/math.h"
|
||||||
#include "xenia/base/profiling.h"
|
#include "xenia/base/profiling.h"
|
||||||
|
@ -49,7 +48,8 @@ extern "C" {
|
||||||
// do this, it's likely they are either passing the context to XAudio or
|
// do this, it's likely they are either passing the context to XAudio or
|
||||||
// using the XMA* functions.
|
// using the XMA* functions.
|
||||||
|
|
||||||
DEFINE_bool(libav_verbose, false, "Verbose libav output (debug and above)");
|
DEFINE_bool(libav_verbose, false, "Verbose libav output (debug and above)",
|
||||||
|
"Audio");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace apu {
|
namespace apu {
|
||||||
|
@ -60,7 +60,7 @@ XmaDecoder::XmaDecoder(cpu::Processor* processor)
|
||||||
XmaDecoder::~XmaDecoder() = default;
|
XmaDecoder::~XmaDecoder() = default;
|
||||||
|
|
||||||
void av_log_callback(void* avcl, int level, const char* fmt, va_list va) {
|
void av_log_callback(void* avcl, int level, const char* fmt, va_list va) {
|
||||||
if (!FLAGS_libav_verbose && level > AV_LOG_WARNING) {
|
if (!cvars::libav_verbose && level > AV_LOG_WARNING) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
#include "cvar.h"
|
||||||
|
|
||||||
|
namespace cvar {
|
||||||
|
cxxopts::Options options("xenia", "Xbox 360 Emulator");
|
||||||
|
std::map<std::string, ICommandVar*>* CmdVars;
|
||||||
|
std::map<std::string, IConfigVar*>* ConfigVars;
|
||||||
|
|
||||||
|
void PrintHelpAndExit() {
|
||||||
|
std::cout << options.help({""}) << std::endl;
|
||||||
|
std::cout << "For the full list of command line arguments, see xenia.cfg."
|
||||||
|
<< std::endl;
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParseLaunchArguments(int argc, char** argv) {
|
||||||
|
options.add_options()("help", "Prints help and exit.");
|
||||||
|
if (!CmdVars) CmdVars = new std::map<std::string, ICommandVar*>();
|
||||||
|
if (!ConfigVars) ConfigVars = new std::map<std::string, IConfigVar*>();
|
||||||
|
for (auto& it : *CmdVars) {
|
||||||
|
auto cmdVar = it.second;
|
||||||
|
cmdVar->AddToLaunchOptions(&options);
|
||||||
|
}
|
||||||
|
std::vector<IConfigVar*> vars;
|
||||||
|
for (const auto& s : *ConfigVars) vars.push_back(s.second);
|
||||||
|
|
||||||
|
for (auto& it : *ConfigVars) {
|
||||||
|
auto configVar = it.second;
|
||||||
|
configVar->AddToLaunchOptions(&options);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
options.positional_help("[Path to .iso/.xex]");
|
||||||
|
options.parse_positional({"target"});
|
||||||
|
|
||||||
|
auto result = options.parse(argc, argv);
|
||||||
|
if (result.count("help")) {
|
||||||
|
PrintHelpAndExit();
|
||||||
|
}
|
||||||
|
for (auto& it : *CmdVars) {
|
||||||
|
auto cmdVar = static_cast<ICommandVar*>(it.second);
|
||||||
|
if (result.count(cmdVar->GetName())) {
|
||||||
|
cmdVar->LoadFromLaunchOptions(&result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto& it : *ConfigVars) {
|
||||||
|
auto configVar = static_cast<IConfigVar*>(it.second);
|
||||||
|
if (result.count(configVar->GetName())) {
|
||||||
|
configVar->LoadFromLaunchOptions(&result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (const cxxopts::OptionException& e) {
|
||||||
|
std::cout << e.what() << std::endl;
|
||||||
|
PrintHelpAndExit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cvar
|
|
@ -0,0 +1,258 @@
|
||||||
|
#ifndef XENIA_CVAR_H_
|
||||||
|
#define XENIA_CVAR_H_
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include "cpptoml/include/cpptoml.h"
|
||||||
|
#include "cxxopts/include/cxxopts.hpp"
|
||||||
|
#include "xenia/base/string_util.h"
|
||||||
|
namespace cvar {
|
||||||
|
|
||||||
|
class ICommandVar {
|
||||||
|
public:
|
||||||
|
virtual ~ICommandVar() = default;
|
||||||
|
virtual std::string GetName() = 0;
|
||||||
|
virtual std::string GetDescription() = 0;
|
||||||
|
virtual void UpdateValue() = 0;
|
||||||
|
virtual void AddToLaunchOptions(cxxopts::Options* options) = 0;
|
||||||
|
virtual void LoadFromLaunchOptions(cxxopts::ParseResult* result) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IConfigVar : virtual public ICommandVar {
|
||||||
|
public:
|
||||||
|
virtual std::string GetCategory() = 0;
|
||||||
|
virtual std::string GetConfigValue() = 0;
|
||||||
|
virtual void LoadConfigValue(std::shared_ptr<cpptoml::base> result) = 0;
|
||||||
|
virtual void LoadGameConfigValue(std::shared_ptr<cpptoml::base> result) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class CommandVar : virtual public ICommandVar {
|
||||||
|
public:
|
||||||
|
CommandVar<T>(const char* name, T* defaultValue, const char* description);
|
||||||
|
std::string GetName() override;
|
||||||
|
std::string GetDescription() override;
|
||||||
|
void AddToLaunchOptions(cxxopts::Options* options) override;
|
||||||
|
void LoadFromLaunchOptions(cxxopts::ParseResult* result) override;
|
||||||
|
T* GetCurrentValue() { return currentValue_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string name_;
|
||||||
|
T defaultValue_;
|
||||||
|
T* currentValue_;
|
||||||
|
std::unique_ptr<T> commandLineValue_;
|
||||||
|
std::string description_;
|
||||||
|
T Convert(std::string val);
|
||||||
|
static std::string ToString(T val);
|
||||||
|
void SetValue(T val);
|
||||||
|
void SetCommandLineValue(T val);
|
||||||
|
void UpdateValue() override;
|
||||||
|
};
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4250)
|
||||||
|
template <class T>
|
||||||
|
class ConfigVar : public CommandVar<T>, virtual public IConfigVar {
|
||||||
|
public:
|
||||||
|
ConfigVar<T>(const char* name, T* defaultValue, const char* description,
|
||||||
|
const char* category);
|
||||||
|
std::string GetConfigValue() override;
|
||||||
|
std::string GetCategory() override;
|
||||||
|
void AddToLaunchOptions(cxxopts::Options* options) override;
|
||||||
|
void LoadConfigValue(std::shared_ptr<cpptoml::base> result) override;
|
||||||
|
void LoadGameConfigValue(std::shared_ptr<cpptoml::base> result) override;
|
||||||
|
void SetConfigValue(T val);
|
||||||
|
void SetGameConfigValue(T val);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string category_;
|
||||||
|
std::unique_ptr<T> configValue_ = nullptr;
|
||||||
|
std::unique_ptr<T> gameConfigValue_ = nullptr;
|
||||||
|
void UpdateValue() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma warning(pop)
|
||||||
|
template <class T>
|
||||||
|
std::string CommandVar<T>::GetName() {
|
||||||
|
return name_;
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
std::string CommandVar<T>::GetDescription() {
|
||||||
|
return description_;
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
void CommandVar<T>::AddToLaunchOptions(cxxopts::Options* options) {
|
||||||
|
options->add_options()(this->name_, this->description_, cxxopts::value<T>());
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
void ConfigVar<T>::AddToLaunchOptions(cxxopts::Options* options) {
|
||||||
|
options->add_options(category_)(this->name_, this->description_,
|
||||||
|
cxxopts::value<T>());
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
void CommandVar<T>::LoadFromLaunchOptions(cxxopts::ParseResult* result) {
|
||||||
|
T value = (*result)[this->name_].template as<T>();
|
||||||
|
SetCommandLineValue(value);
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
void ConfigVar<T>::LoadConfigValue(std::shared_ptr<cpptoml::base> result) {
|
||||||
|
SetConfigValue(*cpptoml::get_impl<T>(result));
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
void ConfigVar<T>::LoadGameConfigValue(std::shared_ptr<cpptoml::base> result) {
|
||||||
|
SetGameConfigValue(*cpptoml::get_impl<T>(result));
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
CommandVar<T>::CommandVar(const char* name, T* defaultValue,
|
||||||
|
const char* description)
|
||||||
|
: name_(name),
|
||||||
|
defaultValue_(*defaultValue),
|
||||||
|
description_(description),
|
||||||
|
currentValue_(defaultValue) {}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
ConfigVar<T>::ConfigVar(const char* name, T* defaultValue,
|
||||||
|
const char* description, const char* category)
|
||||||
|
: CommandVar<T>(name, defaultValue, description), category_(category) {}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void CommandVar<T>::UpdateValue() {
|
||||||
|
if (this->commandLineValue_) return this->SetValue(*this->commandLineValue_);
|
||||||
|
return this->SetValue(defaultValue_);
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
void ConfigVar<T>::UpdateValue() {
|
||||||
|
if (this->commandLineValue_) return this->SetValue(*this->commandLineValue_);
|
||||||
|
if (this->gameConfigValue_) return this->SetValue(*this->gameConfigValue_);
|
||||||
|
if (this->configValue_) return this->SetValue(*this->configValue_);
|
||||||
|
return this->SetValue(this->defaultValue_);
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
T CommandVar<T>::Convert(std::string val) {
|
||||||
|
return xe::string_util::from_string<T>(val);
|
||||||
|
}
|
||||||
|
template <>
|
||||||
|
inline std::string CommandVar<std::string>::Convert(std::string val) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline std::string CommandVar<bool>::ToString(bool val) {
|
||||||
|
return val ? "true" : "false";
|
||||||
|
}
|
||||||
|
template <>
|
||||||
|
inline std::string CommandVar<std::string>::ToString(std::string val) {
|
||||||
|
return "\"" + val + "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::string CommandVar<T>::ToString(T val) {
|
||||||
|
return std::to_string(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void CommandVar<T>::SetValue(T val) {
|
||||||
|
*currentValue_ = val;
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
std::string ConfigVar<T>::GetCategory() {
|
||||||
|
return category_;
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
std::string ConfigVar<T>::GetConfigValue() {
|
||||||
|
if (this->configValue_) return this->ToString(*this->configValue_);
|
||||||
|
return this->ToString(this->defaultValue_);
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
void CommandVar<T>::SetCommandLineValue(const T val) {
|
||||||
|
this->commandLineValue_ = std::make_unique<T>(val);
|
||||||
|
this->UpdateValue();
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
void ConfigVar<T>::SetConfigValue(T val) {
|
||||||
|
this->configValue_ = std::make_unique<T>(val);
|
||||||
|
this->UpdateValue();
|
||||||
|
}
|
||||||
|
template <class T>
|
||||||
|
void ConfigVar<T>::SetGameConfigValue(T val) {
|
||||||
|
this->gameConfigValue_ = std::make_unique<T>(val);
|
||||||
|
this->UpdateValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern std::map<std::string, ICommandVar*>* CmdVars;
|
||||||
|
extern std::map<std::string, IConfigVar*>* ConfigVars;
|
||||||
|
|
||||||
|
inline void AddConfigVar(IConfigVar* cv) {
|
||||||
|
if (!ConfigVars) ConfigVars = new std::map<std::string, IConfigVar*>();
|
||||||
|
ConfigVars->insert(std::pair<std::string, IConfigVar*>(cv->GetName(), cv));
|
||||||
|
}
|
||||||
|
inline void AddCommandVar(ICommandVar* cv) {
|
||||||
|
if (!CmdVars) CmdVars = new std::map<std::string, ICommandVar*>();
|
||||||
|
CmdVars->insert(std::pair<std::string, ICommandVar*>(cv->GetName(), cv));
|
||||||
|
}
|
||||||
|
void ParseLaunchArguments(int argc, char** argv);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T* define_configvar(const char* name, T* defaultValue, const char* description,
|
||||||
|
const char* category) {
|
||||||
|
IConfigVar* cfgVar =
|
||||||
|
new ConfigVar<T>(name, defaultValue, description, category);
|
||||||
|
AddConfigVar(cfgVar);
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T* define_cmdvar(const char* name, T* defaultValue, const char* description) {
|
||||||
|
ICommandVar* cmdVar = new CommandVar<T>(name, defaultValue, description);
|
||||||
|
AddCommandVar(cmdVar);
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
#define DEFINE_double(name, defaultValue, description, category) \
|
||||||
|
DEFINE_CVar(name, defaultValue, description, category, double)
|
||||||
|
|
||||||
|
#define DEFINE_int32(name, defaultValue, description, category) \
|
||||||
|
DEFINE_CVar(name, defaultValue, description, category, int32_t)
|
||||||
|
|
||||||
|
#define DEFINE_uint64(name, defaultValue, description, category) \
|
||||||
|
DEFINE_CVar(name, defaultValue, description, category, uint64_t)
|
||||||
|
|
||||||
|
#define DEFINE_string(name, defaultValue, description, category) \
|
||||||
|
DEFINE_CVar(name, defaultValue, description, category, std::string)
|
||||||
|
|
||||||
|
#define DEFINE_bool(name, defaultValue, description, category) \
|
||||||
|
DEFINE_CVar(name, defaultValue, description, category, bool)
|
||||||
|
|
||||||
|
#define DEFINE_CVar(name, defaultValue, description, category, type) \
|
||||||
|
namespace cvars { \
|
||||||
|
type name = defaultValue; \
|
||||||
|
} \
|
||||||
|
namespace cv { \
|
||||||
|
static auto cv_##name = \
|
||||||
|
cvar::define_configvar(#name, &cvars::name, description, category); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// CmdVars can only be strings for now, we don't need any others
|
||||||
|
#define CmdVar(name, defaultValue, description) \
|
||||||
|
namespace cvars { \
|
||||||
|
std::string name = defaultValue; \
|
||||||
|
} \
|
||||||
|
namespace cv { \
|
||||||
|
static auto cv_##name = \
|
||||||
|
cvar::define_cmdvar(#name, &cvars::name, description); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DECLARE_double(name) DECLARE_CVar(name, double)
|
||||||
|
|
||||||
|
#define DECLARE_bool(name) DECLARE_CVar(name, bool)
|
||||||
|
|
||||||
|
#define DECLARE_string(name) DECLARE_CVar(name, std::string)
|
||||||
|
|
||||||
|
#define DECLARE_int32(name) DECLARE_CVar(name, int32_t)
|
||||||
|
|
||||||
|
#define DECLARE_uint64(name) DECLARE_CVar(name, uint64_t)
|
||||||
|
|
||||||
|
#define DECLARE_CVar(name, type) \
|
||||||
|
namespace cvars { \
|
||||||
|
extern type name; \
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cvar
|
||||||
|
#endif // XENIA_CVAR_H_
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
|
@ -19,6 +17,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "xenia/base/atomic.h"
|
#include "xenia/base/atomic.h"
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
#include "xenia/base/debugging.h"
|
#include "xenia/base/debugging.h"
|
||||||
#include "xenia/base/filesystem.h"
|
#include "xenia/base/filesystem.h"
|
||||||
#include "xenia/base/main.h"
|
#include "xenia/base/main.h"
|
||||||
|
@ -26,6 +25,7 @@
|
||||||
#include "xenia/base/memory.h"
|
#include "xenia/base/memory.h"
|
||||||
#include "xenia/base/ring_buffer.h"
|
#include "xenia/base/ring_buffer.h"
|
||||||
#include "xenia/base/threading.h"
|
#include "xenia/base/threading.h"
|
||||||
|
//#include "xenia/base/cvar.h"
|
||||||
|
|
||||||
// For MessageBox:
|
// For MessageBox:
|
||||||
// TODO(benvanik): generic API? logging_win.cc?
|
// TODO(benvanik): generic API? logging_win.cc?
|
||||||
|
@ -35,12 +35,15 @@
|
||||||
|
|
||||||
DEFINE_string(
|
DEFINE_string(
|
||||||
log_file, "",
|
log_file, "",
|
||||||
"Logs are written to the given file (specify stdout for command line)");
|
"Logs are written to the given file (specify stdout for command line)",
|
||||||
DEFINE_bool(log_debugprint, false, "Dump the log to DebugPrint.");
|
"Logging");
|
||||||
DEFINE_bool(flush_log, true, "Flush log file after each log line batch.");
|
DEFINE_bool(log_debugprint, false, "Dump the log to DebugPrint.", "Logging");
|
||||||
|
DEFINE_bool(flush_log, true, "Flush log file after each log line batch.",
|
||||||
|
"Logging");
|
||||||
DEFINE_int32(
|
DEFINE_int32(
|
||||||
log_level, 2,
|
log_level, 2,
|
||||||
"Maximum level to be logged. (0=error, 1=warning, 2=info, 3=debug)");
|
"Maximum level to be logged. (0=error, 1=warning, 2=info, 3=debug)",
|
||||||
|
"Logging");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
|
||||||
|
@ -52,16 +55,16 @@ thread_local std::vector<char> log_format_buffer_(64 * 1024);
|
||||||
class Logger {
|
class Logger {
|
||||||
public:
|
public:
|
||||||
explicit Logger(const std::wstring& app_name) : running_(true) {
|
explicit Logger(const std::wstring& app_name) : running_(true) {
|
||||||
if (FLAGS_log_file.empty()) {
|
if (cvars::log_file.empty()) {
|
||||||
// Default to app name.
|
// Default to app name.
|
||||||
auto file_path = app_name + L".log";
|
auto file_path = app_name + L".log";
|
||||||
xe::filesystem::CreateParentFolder(file_path);
|
xe::filesystem::CreateParentFolder(file_path);
|
||||||
file_ = xe::filesystem::OpenFile(file_path, "wt");
|
file_ = xe::filesystem::OpenFile(file_path, "wt");
|
||||||
} else {
|
} else {
|
||||||
if (FLAGS_log_file == "stdout") {
|
if (cvars::log_file == "stdout") {
|
||||||
file_ = stdout;
|
file_ = stdout;
|
||||||
} else {
|
} else {
|
||||||
auto file_path = xe::to_wstring(FLAGS_log_file.c_str());
|
auto file_path = xe::to_wstring(cvars::log_file);
|
||||||
xe::filesystem::CreateParentFolder(file_path);
|
xe::filesystem::CreateParentFolder(file_path);
|
||||||
file_ = xe::filesystem::OpenFile(file_path, "wt");
|
file_ = xe::filesystem::OpenFile(file_path, "wt");
|
||||||
}
|
}
|
||||||
|
@ -81,7 +84,7 @@ class Logger {
|
||||||
|
|
||||||
void AppendLine(uint32_t thread_id, LogLevel level, const char prefix_char,
|
void AppendLine(uint32_t thread_id, LogLevel level, const char prefix_char,
|
||||||
const char* buffer, size_t buffer_length) {
|
const char* buffer, size_t buffer_length) {
|
||||||
if (static_cast<int32_t>(level) > FLAGS_log_level) {
|
if (static_cast<int32_t>(level) > cvars::log_level) {
|
||||||
// Discard this line.
|
// Discard this line.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -148,7 +151,7 @@ class Logger {
|
||||||
fwrite(buf, 1, size, file_);
|
fwrite(buf, 1, size, file_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_log_debugprint) {
|
if (cvars::log_debugprint) {
|
||||||
debugging::DebugPrint("%.*s", size, buf);
|
debugging::DebugPrint("%.*s", size, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,7 +217,7 @@ class Logger {
|
||||||
read_head_ = rb.read_offset();
|
read_head_ = rb.read_offset();
|
||||||
}
|
}
|
||||||
if (did_write) {
|
if (did_write) {
|
||||||
if (FLAGS_flush_log) {
|
if (cvars::flush_log) {
|
||||||
fflush(file_);
|
fflush(file_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,9 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
#include "xenia/base/main.h"
|
#include "xenia/base/main.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/string.h"
|
#include "xenia/base/string.h"
|
||||||
|
|
||||||
|
@ -23,10 +22,7 @@ bool has_console_attached() { return true; }
|
||||||
extern "C" int main(int argc, char** argv) {
|
extern "C" int main(int argc, char** argv) {
|
||||||
auto entry_info = xe::GetEntryInfo();
|
auto entry_info = xe::GetEntryInfo();
|
||||||
|
|
||||||
google::SetUsageMessage(std::string("usage: ") +
|
cvar::ParseLaunchArguments(argc, argv);
|
||||||
xe::to_string(entry_info.usage));
|
|
||||||
google::SetVersionString("1.0");
|
|
||||||
google::ParseCommandLineFlags(&argc, &argv, true);
|
|
||||||
|
|
||||||
std::vector<std::wstring> args;
|
std::vector<std::wstring> args;
|
||||||
for (int n = 0; n < argc; n++) {
|
for (int n = 0; n < argc; n++) {
|
||||||
|
@ -39,6 +35,5 @@ extern "C" int main(int argc, char** argv) {
|
||||||
// Call app-provided entry point.
|
// Call app-provided entry point.
|
||||||
int result = entry_info.entry_point(args);
|
int result = entry_info.entry_point(args);
|
||||||
|
|
||||||
google::ShutDownCommandLineFlags();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "xenia/base/main.h"
|
#include "xenia/base/main.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <gflags/gflags.h>
|
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
@ -18,6 +17,7 @@
|
||||||
// Autogenerated by `xb premake`.
|
// Autogenerated by `xb premake`.
|
||||||
#include "build/version.h"
|
#include "build/version.h"
|
||||||
|
|
||||||
|
#include "xenia/base/filesystem.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/platform_win.h"
|
#include "xenia/base/platform_win.h"
|
||||||
#include "xenia/base/string.h"
|
#include "xenia/base/string.h"
|
||||||
|
@ -25,9 +25,10 @@
|
||||||
#include "third_party/xbyak/xbyak/xbyak_util.h"
|
#include "third_party/xbyak/xbyak/xbyak_util.h"
|
||||||
|
|
||||||
#include <bcrypt.h>
|
#include <bcrypt.h>
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
|
|
||||||
DEFINE_bool(win32_high_freq, true,
|
DEFINE_bool(win32_high_freq, true,
|
||||||
"Requests high performance from the NT kernel");
|
"Requests high performance from the NT kernel", "Kernel");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
|
||||||
|
@ -88,7 +89,6 @@ int Main() {
|
||||||
auto entry_info = xe::GetEntryInfo();
|
auto entry_info = xe::GetEntryInfo();
|
||||||
|
|
||||||
// Convert command line to an argv-like format so we can share code/use
|
// Convert command line to an argv-like format so we can share code/use
|
||||||
// gflags.
|
|
||||||
auto command_line = GetCommandLineW();
|
auto command_line = GetCommandLineW();
|
||||||
int argc;
|
int argc;
|
||||||
wchar_t** argv = CommandLineToArgvW(command_line, &argc);
|
wchar_t** argv = CommandLineToArgvW(command_line, &argc);
|
||||||
|
@ -96,11 +96,7 @@ int Main() {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
google::SetUsageMessage(std::string("usage: ") +
|
// Convert all args to narrow, as cxxopts doesn't support wchar.
|
||||||
xe::to_string(entry_info.usage));
|
|
||||||
google::SetVersionString("1.0");
|
|
||||||
|
|
||||||
// Convert all args to narrow, as gflags doesn't support wchar.
|
|
||||||
int argca = argc;
|
int argca = argc;
|
||||||
char** argva = reinterpret_cast<char**>(alloca(sizeof(char*) * argca));
|
char** argva = reinterpret_cast<char**>(alloca(sizeof(char*) * argca));
|
||||||
for (int n = 0; n < argca; n++) {
|
for (int n = 0; n < argca; n++) {
|
||||||
|
@ -109,8 +105,7 @@ int Main() {
|
||||||
std::wcstombs(argva[n], argv[n], len + 1);
|
std::wcstombs(argva[n], argv[n], len + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse flags; this may delete some of them.
|
cvar::ParseLaunchArguments(argca, argva);
|
||||||
google::ParseCommandLineFlags(&argc, &argva, true);
|
|
||||||
|
|
||||||
// Widen all remaining flags and convert to usable strings.
|
// Widen all remaining flags and convert to usable strings.
|
||||||
std::vector<std::wstring> args;
|
std::vector<std::wstring> args;
|
||||||
|
@ -143,7 +138,7 @@ int Main() {
|
||||||
XE_BUILD_DATE);
|
XE_BUILD_DATE);
|
||||||
|
|
||||||
// Request high performance timing.
|
// Request high performance timing.
|
||||||
if (FLAGS_win32_high_freq) {
|
if (cvars::win32_high_freq) {
|
||||||
RequestHighPerformance();
|
RequestHighPerformance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +146,6 @@ int Main() {
|
||||||
int result = entry_info.entry_point(args);
|
int result = entry_info.entry_point(args);
|
||||||
|
|
||||||
xe::ShutdownLogging();
|
xe::ShutdownLogging();
|
||||||
google::ShutDownCommandLineFlags();
|
|
||||||
LocalFree(argv);
|
LocalFree(argv);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,6 @@ project("xenia-base")
|
||||||
language("C++")
|
language("C++")
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
|
||||||
local_platform_files()
|
local_platform_files()
|
||||||
removefiles({"main_*.cc"})
|
removefiles({"main_*.cc"})
|
||||||
files({
|
files({
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
// NOTE: this must be included before microprofile as macro expansion needs
|
// NOTE: this must be included before microprofile as macro expansion needs
|
||||||
|
@ -30,6 +28,7 @@
|
||||||
#include "third_party/microprofile/microprofile.h"
|
#include "third_party/microprofile/microprofile.h"
|
||||||
|
|
||||||
#include "xenia/base/assert.h"
|
#include "xenia/base/assert.h"
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
#include "xenia/base/profiling.h"
|
#include "xenia/base/profiling.h"
|
||||||
#include "xenia/ui/window.h"
|
#include "xenia/ui/window.h"
|
||||||
|
|
||||||
|
@ -42,7 +41,7 @@
|
||||||
#include "xenia/ui/microprofile_drawer.h"
|
#include "xenia/ui/microprofile_drawer.h"
|
||||||
#endif // XE_OPTION_PROFILING_UI
|
#endif // XE_OPTION_PROFILING_UI
|
||||||
|
|
||||||
DEFINE_bool(show_profiler, false, "Show profiling UI by default.");
|
DEFINE_bool(show_profiler, false, "Show profiling UI by default.", "Other");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
|
||||||
|
@ -77,7 +76,7 @@ void Profiler::Initialize() {
|
||||||
g_MicroProfileUI.bShowSpikes = true;
|
g_MicroProfileUI.bShowSpikes = true;
|
||||||
g_MicroProfileUI.nOpacityBackground = 0x40u << 24;
|
g_MicroProfileUI.nOpacityBackground = 0x40u << 24;
|
||||||
g_MicroProfileUI.nOpacityForeground = 0xc0u << 24;
|
g_MicroProfileUI.nOpacityForeground = 0xc0u << 24;
|
||||||
if (FLAGS_show_profiler) {
|
if (cvars::show_profiler) {
|
||||||
MicroProfileSetDisplayMode(1);
|
MicroProfileSetDisplayMode(1);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -24,13 +24,13 @@ namespace string_util {
|
||||||
|
|
||||||
inline std::string to_hex_string(uint32_t value) {
|
inline std::string to_hex_string(uint32_t value) {
|
||||||
char buffer[21];
|
char buffer[21];
|
||||||
std::snprintf(buffer, sizeof(buffer), "%08" PRIX32, value);
|
snprintf(buffer, sizeof(buffer), "%08" PRIX32, value);
|
||||||
return std::string(buffer);
|
return std::string(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string to_hex_string(uint64_t value) {
|
inline std::string to_hex_string(uint64_t value) {
|
||||||
char buffer[21];
|
char buffer[21];
|
||||||
std::snprintf(buffer, sizeof(buffer), "%016" PRIX64, value);
|
snprintf(buffer, sizeof(buffer), "%016" PRIX64, value);
|
||||||
return std::string(buffer);
|
return std::string(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,8 +54,8 @@ inline std::string to_hex_string(double value) {
|
||||||
|
|
||||||
inline std::string to_hex_string(const vec128_t& value) {
|
inline std::string to_hex_string(const vec128_t& value) {
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
std::snprintf(buffer, sizeof(buffer), "[%.8X, %.8X, %.8X, %.8X]",
|
snprintf(buffer, sizeof(buffer), "[%.8X, %.8X, %.8X, %.8X]", value.u32[0],
|
||||||
value.u32[0], value.u32[1], value.u32[2], value.u32[3]);
|
value.u32[1], value.u32[2], value.u32[3]);
|
||||||
return std::string(buffer);
|
return std::string(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ inline std::string to_hex_string(const __m128& value) {
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
float f[4];
|
float f[4];
|
||||||
_mm_storeu_ps(f, value);
|
_mm_storeu_ps(f, value);
|
||||||
std::snprintf(
|
snprintf(
|
||||||
buffer, sizeof(buffer), "[%.8X, %.8X, %.8X, %.8X]",
|
buffer, sizeof(buffer), "[%.8X, %.8X, %.8X, %.8X]",
|
||||||
*reinterpret_cast<uint32_t*>(&f[0]), *reinterpret_cast<uint32_t*>(&f[1]),
|
*reinterpret_cast<uint32_t*>(&f[0]), *reinterpret_cast<uint32_t*>(&f[1]),
|
||||||
*reinterpret_cast<uint32_t*>(&f[2]), *reinterpret_cast<uint32_t*>(&f[3]));
|
*reinterpret_cast<uint32_t*>(&f[2]), *reinterpret_cast<uint32_t*>(&f[3]));
|
||||||
|
@ -77,15 +77,22 @@ inline std::string to_string(const __m128& value) {
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
float f[4];
|
float f[4];
|
||||||
_mm_storeu_ps(f, value);
|
_mm_storeu_ps(f, value);
|
||||||
std::snprintf(buffer, sizeof(buffer), "(%F, %F, %F, %F)", f[0], f[1], f[2],
|
snprintf(buffer, sizeof(buffer), "(%F, %F, %F, %F)", f[0], f[1], f[2], f[3]);
|
||||||
f[3]);
|
|
||||||
return std::string(buffer);
|
return std::string(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T from_string(const char* value, bool force_hex = false);
|
inline T from_string(const char* value, bool force_hex = false) {
|
||||||
|
// Missing implementation for converting type T to string
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline bool from_string<bool>(const char* value, bool force_hex) {
|
||||||
|
return std::strcmp(value, "true") == 0 || value[0] == '1';
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline int32_t from_string<int32_t>(const char* value, bool force_hex) {
|
inline int32_t from_string<int32_t>(const char* value, bool force_hex) {
|
||||||
|
|
|
@ -2,9 +2,6 @@ project_root = "../../../.."
|
||||||
include(project_root.."/tools/build")
|
include(project_root.."/tools/build")
|
||||||
|
|
||||||
test_suite("xenia-base-tests", project_root, ".", {
|
test_suite("xenia-base-tests", project_root, ".", {
|
||||||
includedirs = {
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
},
|
|
||||||
links = {
|
links = {
|
||||||
"xenia-base",
|
"xenia-base",
|
||||||
},
|
},
|
||||||
|
|
|
@ -266,8 +266,8 @@ static inline vec128_t vec128b(uint8_t x0, uint8_t x1, uint8_t x2, uint8_t x3,
|
||||||
|
|
||||||
inline std::string to_string(const vec128_t& value) {
|
inline std::string to_string(const vec128_t& value) {
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
std::snprintf(buffer, sizeof(buffer), "(%g, %g, %g, %g)", value.x, value.y,
|
snprintf(buffer, sizeof(buffer), "(%g, %g, %g, %g)", value.x, value.y,
|
||||||
value.z, value.w);
|
value.z, value.w);
|
||||||
return std::string(buffer);
|
return std::string(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
#include "config.h"
|
||||||
|
#include "cpptoml/include/cpptoml.h"
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
|
#include "xenia/base/filesystem.h"
|
||||||
|
#include "xenia/base/logging.h"
|
||||||
|
#include "xenia/base/string.h"
|
||||||
|
|
||||||
|
CmdVar(config, "", "Specifies the target config to load.");
|
||||||
|
namespace config {
|
||||||
|
std::wstring config_name = L"xenia.config.toml";
|
||||||
|
std::wstring config_folder;
|
||||||
|
std::wstring config_path;
|
||||||
|
|
||||||
|
bool sortCvar(cvar::IConfigVar* a, cvar::IConfigVar* b) {
|
||||||
|
if (a->GetCategory() < b->GetCategory()) return true;
|
||||||
|
if (a->GetCategory() > b->GetCategory()) return false;
|
||||||
|
if (a->GetName() < b->GetName()) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<cpptoml::table> ParseConfig(std::string config_path) {
|
||||||
|
try {
|
||||||
|
return cpptoml::parse_file(config_path);
|
||||||
|
} catch (cpptoml::parse_exception) {
|
||||||
|
xe::FatalError("Failed to parse config file: %s", config_path.c_str());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReadConfig(const std::wstring& file_path) {
|
||||||
|
const auto config = ParseConfig(xe::to_string(file_path));
|
||||||
|
for (auto& it : *cvar::ConfigVars) {
|
||||||
|
auto configVar = static_cast<cvar::IConfigVar*>(it.second);
|
||||||
|
auto configKey = configVar->GetCategory() + "." + configVar->GetName();
|
||||||
|
if (config->contains_qualified(configKey)) {
|
||||||
|
configVar->LoadConfigValue(config->get_qualified(configKey));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XELOGI("Loaded config: %S", file_path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReadGameConfig(std::wstring file_path) {
|
||||||
|
const auto config = ParseConfig(xe::to_string(file_path));
|
||||||
|
for (auto& it : *cvar::ConfigVars) {
|
||||||
|
auto configVar = static_cast<cvar::IConfigVar*>(it.second);
|
||||||
|
auto configKey = configVar->GetCategory() + "." + configVar->GetName();
|
||||||
|
if (config->contains_qualified(configKey)) {
|
||||||
|
configVar->LoadGameConfigValue(config->get_qualified(configKey));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XELOGI("Loaded game config: %S", file_path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveConfig() {
|
||||||
|
std::vector<cvar::IConfigVar*> vars;
|
||||||
|
for (const auto& s : *cvar::ConfigVars) vars.push_back(s.second);
|
||||||
|
std::sort(vars.begin(), vars.end(), sortCvar);
|
||||||
|
// we use our own write logic because cpptoml doesn't
|
||||||
|
// allow us to specify comments :(
|
||||||
|
std::ostringstream output;
|
||||||
|
std::string lastCategory;
|
||||||
|
for (auto configVar : vars) {
|
||||||
|
if (lastCategory != configVar->GetCategory()) {
|
||||||
|
if (!lastCategory.empty()) {
|
||||||
|
output << std::endl;
|
||||||
|
}
|
||||||
|
lastCategory = configVar->GetCategory();
|
||||||
|
output << xe::format_string("[%s]\n", lastCategory.c_str());
|
||||||
|
}
|
||||||
|
output << std::left << std::setw(40) << std::setfill(' ')
|
||||||
|
<< xe::format_string("%s = %s", configVar->GetName().c_str(),
|
||||||
|
configVar->GetConfigValue().c_str());
|
||||||
|
output << xe::format_string("\t# %s\n",
|
||||||
|
configVar->GetDescription().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xe::filesystem::PathExists(config_path)) {
|
||||||
|
std::ifstream existingConfigStream(xe::to_string(config_path).c_str());
|
||||||
|
const std::string existingConfig(
|
||||||
|
(std::istreambuf_iterator<char>(existingConfigStream)),
|
||||||
|
std::istreambuf_iterator<char>());
|
||||||
|
// if the config didn't change, no need to modify the file
|
||||||
|
if (existingConfig == output.str()) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// save the config file
|
||||||
|
xe::filesystem::CreateParentFolder(config_path);
|
||||||
|
std::ofstream file;
|
||||||
|
file.open(xe::to_string(config_path), std::ios::out | std::ios::trunc);
|
||||||
|
file << output.str();
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupConfig(const std::wstring& config_folder) {
|
||||||
|
config::config_folder = config_folder;
|
||||||
|
// check if the user specified a specific config to load
|
||||||
|
if (!cvars::config.empty()) {
|
||||||
|
config_path = xe::to_wstring(cvars::config);
|
||||||
|
if (xe::filesystem::PathExists(config_path)) {
|
||||||
|
ReadConfig(config_path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if the user specified a --config argument, but the file doesn't exist,
|
||||||
|
// let's also load the default config
|
||||||
|
if (!config_folder.empty()) {
|
||||||
|
config_path = xe::join_paths(config_folder, config_name);
|
||||||
|
if (xe::filesystem::PathExists(config_path)) {
|
||||||
|
ReadConfig(config_path);
|
||||||
|
}
|
||||||
|
// we only want to save the config if the user is using the default
|
||||||
|
// config, we don't want to override a user created specific config
|
||||||
|
SaveConfig();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadGameConfig(const std::wstring& title_id) {
|
||||||
|
const auto content_folder = xe::join_paths(config_folder, L"content");
|
||||||
|
const auto game_folder = xe::join_paths(content_folder, title_id);
|
||||||
|
const auto game_config_path = xe::join_paths(game_folder, config_name);
|
||||||
|
if (xe::filesystem::PathExists(game_config_path)) {
|
||||||
|
ReadGameConfig(game_config_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace config
|
|
@ -0,0 +1,10 @@
|
||||||
|
#ifndef XENIA_CONFIG_H_
|
||||||
|
#define XENIA_CONFIG_H_
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace config {
|
||||||
|
void SetupConfig(const std::wstring& config_folder);
|
||||||
|
void LoadGameConfig(const std::wstring& title_id);
|
||||||
|
} // namespace config
|
||||||
|
|
||||||
|
#endif // XENIA_CONFIG_H_
|
|
@ -27,6 +27,5 @@ project("xenia-cpu-backend-x64")
|
||||||
|
|
||||||
includedirs({
|
includedirs({
|
||||||
project_root.."/third_party/capstone/include",
|
project_root.."/third_party/capstone/include",
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
})
|
||||||
local_platform_files()
|
local_platform_files()
|
||||||
|
|
|
@ -28,7 +28,8 @@
|
||||||
|
|
||||||
DEFINE_bool(
|
DEFINE_bool(
|
||||||
enable_haswell_instructions, true,
|
enable_haswell_instructions, true,
|
||||||
"Uses the AVX2/FMA/etc instructions on Haswell processors, if available.");
|
"Uses the AVX2/FMA/etc instructions on Haswell processors, if available.",
|
||||||
|
"CPU");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
|
@ -83,7 +84,7 @@ bool X64Backend::Initialize(Processor* processor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Need movbe to do advanced LOAD/STORE tricks.
|
// Need movbe to do advanced LOAD/STORE tricks.
|
||||||
if (FLAGS_enable_haswell_instructions) {
|
if (cvars::enable_haswell_instructions) {
|
||||||
machine_info_.supports_extended_load_store =
|
machine_info_.supports_extended_load_store =
|
||||||
cpu.has(Xbyak::util::Cpu::tMOVBE);
|
cpu.has(Xbyak::util::Cpu::tMOVBE);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -10,10 +10,9 @@
|
||||||
#ifndef XENIA_CPU_BACKEND_X64_X64_BACKEND_H_
|
#ifndef XENIA_CPU_BACKEND_X64_X64_BACKEND_H_
|
||||||
#define XENIA_CPU_BACKEND_X64_X64_BACKEND_H_
|
#define XENIA_CPU_BACKEND_X64_X64_BACKEND_H_
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
#include "xenia/cpu/backend/backend.h"
|
#include "xenia/cpu/backend/backend.h"
|
||||||
|
|
||||||
DECLARE_bool(enable_haswell_instructions);
|
DECLARE_bool(enable_haswell_instructions);
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include "xenia/cpu/backend/x64/x64_emitter.h"
|
#include "xenia/cpu/backend/x64/x64_emitter.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -36,11 +34,12 @@
|
||||||
#include "xenia/cpu/thread_state.h"
|
#include "xenia/cpu/thread_state.h"
|
||||||
|
|
||||||
DEFINE_bool(enable_debugprint_log, false,
|
DEFINE_bool(enable_debugprint_log, false,
|
||||||
"Log debugprint traps to the active debugger");
|
"Log debugprint traps to the active debugger", "CPU");
|
||||||
DEFINE_bool(ignore_undefined_externs, true,
|
DEFINE_bool(ignore_undefined_externs, true,
|
||||||
"Don't exit when an undefined extern is called.");
|
"Don't exit when an undefined extern is called.", "CPU");
|
||||||
DEFINE_bool(emit_source_annotations, false,
|
DEFINE_bool(emit_source_annotations, false,
|
||||||
"Add extra movs and nops to make disassembly easier to read.");
|
"Add extra movs and nops to make disassembly easier to read.",
|
||||||
|
"CPU");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
|
@ -71,7 +70,7 @@ X64Emitter::X64Emitter(X64Backend* backend, XbyakAllocator* allocator)
|
||||||
backend_(backend),
|
backend_(backend),
|
||||||
code_cache_(backend->code_cache()),
|
code_cache_(backend->code_cache()),
|
||||||
allocator_(allocator) {
|
allocator_(allocator) {
|
||||||
if (FLAGS_enable_haswell_instructions) {
|
if (cvars::enable_haswell_instructions) {
|
||||||
feature_flags_ |= cpu_.has(Xbyak::util::Cpu::tAVX2) ? kX64EmitAVX2 : 0;
|
feature_flags_ |= cpu_.has(Xbyak::util::Cpu::tAVX2) ? kX64EmitAVX2 : 0;
|
||||||
feature_flags_ |= cpu_.has(Xbyak::util::Cpu::tFMA) ? kX64EmitFMA : 0;
|
feature_flags_ |= cpu_.has(Xbyak::util::Cpu::tFMA) ? kX64EmitFMA : 0;
|
||||||
feature_flags_ |= cpu_.has(Xbyak::util::Cpu::tLZCNT) ? kX64EmitLZCNT : 0;
|
feature_flags_ |= cpu_.has(Xbyak::util::Cpu::tLZCNT) ? kX64EmitLZCNT : 0;
|
||||||
|
@ -245,7 +244,7 @@ bool X64Emitter::Emit(HIRBuilder* builder, size_t* out_stack_size) {
|
||||||
add(rsp, (uint32_t)stack_size);
|
add(rsp, (uint32_t)stack_size);
|
||||||
ret();
|
ret();
|
||||||
|
|
||||||
if (FLAGS_emit_source_annotations) {
|
if (cvars::emit_source_annotations) {
|
||||||
nop();
|
nop();
|
||||||
nop();
|
nop();
|
||||||
nop();
|
nop();
|
||||||
|
@ -262,7 +261,7 @@ void X64Emitter::MarkSourceOffset(const Instr* i) {
|
||||||
entry->hir_offset = uint32_t(i->block->ordinal << 16) | i->ordinal;
|
entry->hir_offset = uint32_t(i->block->ordinal << 16) | i->ordinal;
|
||||||
entry->code_offset = static_cast<uint32_t>(getSize());
|
entry->code_offset = static_cast<uint32_t>(getSize());
|
||||||
|
|
||||||
if (FLAGS_emit_source_annotations) {
|
if (cvars::emit_source_annotations) {
|
||||||
nop();
|
nop();
|
||||||
nop();
|
nop();
|
||||||
mov(eax, entry->guest_address);
|
mov(eax, entry->guest_address);
|
||||||
|
@ -299,7 +298,7 @@ uint64_t TrapDebugPrint(void* raw_context, uint64_t address) {
|
||||||
// TODO(benvanik): truncate to length?
|
// TODO(benvanik): truncate to length?
|
||||||
XELOGD("(DebugPrint) %s", str);
|
XELOGD("(DebugPrint) %s", str);
|
||||||
|
|
||||||
if (FLAGS_enable_debugprint_log) {
|
if (cvars::enable_debugprint_log) {
|
||||||
debugging::DebugPrint("(DebugPrint) %s", str);
|
debugging::DebugPrint("(DebugPrint) %s", str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,7 +308,7 @@ uint64_t TrapDebugPrint(void* raw_context, uint64_t address) {
|
||||||
uint64_t TrapDebugBreak(void* raw_context, uint64_t address) {
|
uint64_t TrapDebugBreak(void* raw_context, uint64_t address) {
|
||||||
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
auto thread_state = *reinterpret_cast<ThreadState**>(raw_context);
|
||||||
XELOGE("tw/td forced trap hit! This should be a crash!");
|
XELOGE("tw/td forced trap hit! This should be a crash!");
|
||||||
if (FLAGS_break_on_debugbreak) {
|
if (cvars::break_on_debugbreak) {
|
||||||
xe::debugging::Break();
|
xe::debugging::Break();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -446,7 +445,7 @@ void X64Emitter::CallIndirect(const hir::Instr* instr,
|
||||||
|
|
||||||
uint64_t UndefinedCallExtern(void* raw_context, uint64_t function_ptr) {
|
uint64_t UndefinedCallExtern(void* raw_context, uint64_t function_ptr) {
|
||||||
auto function = reinterpret_cast<Function*>(function_ptr);
|
auto function = reinterpret_cast<Function*>(function_ptr);
|
||||||
if (!FLAGS_ignore_undefined_externs) {
|
if (!cvars::ignore_undefined_externs) {
|
||||||
xe::FatalError("undefined extern call to %.8X %s", function->address(),
|
xe::FatalError("undefined extern call to %.8X %s", function->address(),
|
||||||
function->name().c_str());
|
function->name().c_str());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include "xenia/cpu/compiler/passes/conditional_group_pass.h"
|
#include "xenia/cpu/compiler/passes/conditional_group_pass.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include "xenia/base/profiling.h"
|
#include "xenia/base/profiling.h"
|
||||||
#include "xenia/cpu/compiler/compiler.h"
|
#include "xenia/cpu/compiler/compiler.h"
|
||||||
#include "xenia/cpu/ppc/ppc_context.h"
|
#include "xenia/cpu/ppc/ppc_context.h"
|
||||||
|
|
|
@ -9,15 +9,16 @@
|
||||||
|
|
||||||
#include "xenia/cpu/compiler/passes/constant_propagation_pass.h"
|
#include "xenia/cpu/compiler/passes/constant_propagation_pass.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "xenia/base/assert.h"
|
#include "xenia/base/assert.h"
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
#include "xenia/base/profiling.h"
|
#include "xenia/base/profiling.h"
|
||||||
#include "xenia/cpu/function.h"
|
#include "xenia/cpu/function.h"
|
||||||
#include "xenia/cpu/processor.h"
|
#include "xenia/cpu/processor.h"
|
||||||
|
|
||||||
DEFINE_bool(inline_mmio_access, true, "Inline constant MMIO loads and stores.");
|
DEFINE_bool(inline_mmio_access, true, "Inline constant MMIO loads and stores.",
|
||||||
|
"CPU");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
|
@ -221,7 +222,7 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder, bool& result) {
|
||||||
|
|
||||||
auto mmio_range =
|
auto mmio_range =
|
||||||
processor_->memory()->LookupVirtualMappedRange(address);
|
processor_->memory()->LookupVirtualMappedRange(address);
|
||||||
if (FLAGS_inline_mmio_access && mmio_range) {
|
if (cvars::inline_mmio_access && mmio_range) {
|
||||||
i->Replace(&OPCODE_LOAD_MMIO_info, 0);
|
i->Replace(&OPCODE_LOAD_MMIO_info, 0);
|
||||||
i->src1.offset = reinterpret_cast<uint64_t>(mmio_range);
|
i->src1.offset = reinterpret_cast<uint64_t>(mmio_range);
|
||||||
i->src2.offset = address;
|
i->src2.offset = address;
|
||||||
|
@ -273,7 +274,7 @@ bool ConstantPropagationPass::Run(HIRBuilder* builder, bool& result) {
|
||||||
break;
|
break;
|
||||||
case OPCODE_STORE:
|
case OPCODE_STORE:
|
||||||
case OPCODE_STORE_OFFSET:
|
case OPCODE_STORE_OFFSET:
|
||||||
if (FLAGS_inline_mmio_access && i->src1.value->IsConstant()) {
|
if (cvars::inline_mmio_access && i->src1.value->IsConstant()) {
|
||||||
auto address = i->src1.value->constant.i32;
|
auto address = i->src1.value->constant.i32;
|
||||||
if (i->opcode->num == OPCODE_STORE_OFFSET) {
|
if (i->opcode->num == OPCODE_STORE_OFFSET) {
|
||||||
address += i->src2.value->constant.i32;
|
address += i->src2.value->constant.i32;
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
|
|
||||||
#include "xenia/cpu/compiler/passes/context_promotion_pass.h"
|
#include "xenia/cpu/compiler/passes/context_promotion_pass.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
#include "xenia/apu/apu_flags.h"
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
#include "xenia/base/profiling.h"
|
#include "xenia/base/profiling.h"
|
||||||
#include "xenia/cpu/compiler/compiler.h"
|
#include "xenia/cpu/compiler/compiler.h"
|
||||||
#include "xenia/cpu/ppc/ppc_context.h"
|
#include "xenia/cpu/ppc/ppc_context.h"
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
DECLARE_bool(debug);
|
DECLARE_bool(debug);
|
||||||
|
|
||||||
DEFINE_bool(store_all_context_values, false,
|
DEFINE_bool(store_all_context_values, false,
|
||||||
"Don't strip dead context stores to aid in debugging.");
|
"Don't strip dead context stores to aid in debugging.", "CPU");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
|
@ -77,7 +77,7 @@ bool ContextPromotionPass::Run(HIRBuilder* builder) {
|
||||||
// Remove all dead stores.
|
// Remove all dead stores.
|
||||||
// This will break debugging as we can't recover this information when
|
// This will break debugging as we can't recover this information when
|
||||||
// trying to extract stack traces/register values, so we don't do that.
|
// trying to extract stack traces/register values, so we don't do that.
|
||||||
if (!FLAGS_debug && !FLAGS_store_all_context_values) {
|
if (!cvars::debug && !cvars::store_all_context_values) {
|
||||||
block = builder->first_block();
|
block = builder->first_block();
|
||||||
while (block) {
|
while (block) {
|
||||||
RemoveDeadStoresBlock(block);
|
RemoveDeadStoresBlock(block);
|
||||||
|
|
|
@ -9,38 +9,42 @@
|
||||||
|
|
||||||
#include "xenia/cpu/cpu_flags.h"
|
#include "xenia/cpu/cpu_flags.h"
|
||||||
|
|
||||||
DEFINE_string(cpu, "any", "CPU backend [any, x64].");
|
DEFINE_string(cpu, "any", "CPU backend [any, x64].", "CPU");
|
||||||
|
|
||||||
DEFINE_string(
|
DEFINE_string(
|
||||||
load_module_map, "",
|
load_module_map, "",
|
||||||
"Loads a .map for symbol names and to diff with the generated symbol "
|
"Loads a .map for symbol names and to diff with the generated symbol "
|
||||||
"database.");
|
"database.",
|
||||||
|
"CPU");
|
||||||
|
|
||||||
DEFINE_bool(disassemble_functions, false,
|
DEFINE_bool(disassemble_functions, false,
|
||||||
"Disassemble functions during generation.");
|
"Disassemble functions during generation.", "CPU");
|
||||||
|
|
||||||
DEFINE_bool(trace_functions, false,
|
DEFINE_bool(trace_functions, false, "Generate tracing for function statistics.",
|
||||||
"Generate tracing for function statistics.");
|
"CPU");
|
||||||
DEFINE_bool(trace_function_coverage, false,
|
DEFINE_bool(trace_function_coverage, false,
|
||||||
"Generate tracing for function instruction coverage statistics.");
|
"Generate tracing for function instruction coverage statistics.",
|
||||||
|
"CPU");
|
||||||
DEFINE_bool(trace_function_references, false,
|
DEFINE_bool(trace_function_references, false,
|
||||||
"Generate tracing for function address references.");
|
"Generate tracing for function address references.", "CPU");
|
||||||
DEFINE_bool(trace_function_data, false,
|
DEFINE_bool(trace_function_data, false,
|
||||||
"Generate tracing for function result data.");
|
"Generate tracing for function result data.", "CPU");
|
||||||
|
|
||||||
DEFINE_bool(
|
DEFINE_bool(
|
||||||
disable_global_lock, false,
|
disable_global_lock, false,
|
||||||
"Disables global lock usage in guest code. Does not affect host code.");
|
"Disables global lock usage in guest code. Does not affect host code.",
|
||||||
|
"CPU");
|
||||||
|
|
||||||
DEFINE_bool(validate_hir, false,
|
DEFINE_bool(validate_hir, false,
|
||||||
"Perform validation checks on the HIR during compilation.");
|
"Perform validation checks on the HIR during compilation.", "CPU");
|
||||||
|
|
||||||
// Breakpoints:
|
// Breakpoints:
|
||||||
DEFINE_uint64(break_on_instruction, 0,
|
DEFINE_uint64(break_on_instruction, 0,
|
||||||
"int3 before the given guest address is executed.");
|
"int3 before the given guest address is executed.", "CPU");
|
||||||
DEFINE_int32(break_condition_gpr, -1, "GPR compared to");
|
DEFINE_int32(break_condition_gpr, -1, "GPR compared to", "CPU");
|
||||||
DEFINE_uint64(break_condition_value, 0, "value compared against");
|
DEFINE_uint64(break_condition_value, 0, "value compared against", "CPU");
|
||||||
DEFINE_string(break_condition_op, "eq", "comparison operator");
|
DEFINE_string(break_condition_op, "eq", "comparison operator", "CPU");
|
||||||
DEFINE_bool(break_condition_truncate, true, "truncate value to 32-bits");
|
DEFINE_bool(break_condition_truncate, true, "truncate value to 32-bits", "CPU");
|
||||||
|
|
||||||
DEFINE_bool(break_on_debugbreak, true, "int3 on JITed __debugbreak requests.");
|
DEFINE_bool(break_on_debugbreak, true, "int3 on JITed __debugbreak requests.",
|
||||||
|
"CPU");
|
||||||
|
|
|
@ -9,8 +9,7 @@
|
||||||
|
|
||||||
#ifndef XENIA_CPU_CPU_FLAGS_H_
|
#ifndef XENIA_CPU_CPU_FLAGS_H_
|
||||||
#define XENIA_CPU_CPU_FLAGS_H_
|
#define XENIA_CPU_CPU_FLAGS_H_
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
DECLARE_string(cpu);
|
DECLARE_string(cpu);
|
||||||
|
|
||||||
|
|
|
@ -728,12 +728,12 @@ int InstrEmit_mtmsr(PPCHIRBuilder& f, const InstrData& i) {
|
||||||
f.ZeroExtend(f.ZeroExtend(f.LoadGPR(i.X.RT), INT64_TYPE), INT64_TYPE));
|
f.ZeroExtend(f.ZeroExtend(f.LoadGPR(i.X.RT), INT64_TYPE), INT64_TYPE));
|
||||||
if (i.X.RT == 13) {
|
if (i.X.RT == 13) {
|
||||||
// iff storing from r13 we are taking a lock (disable interrupts).
|
// iff storing from r13 we are taking a lock (disable interrupts).
|
||||||
if (!FLAGS_disable_global_lock) {
|
if (!cvars::disable_global_lock) {
|
||||||
f.CallExtern(f.builtins()->enter_global_lock);
|
f.CallExtern(f.builtins()->enter_global_lock);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Otherwise we are restoring interrupts (probably).
|
// Otherwise we are restoring interrupts (probably).
|
||||||
if (!FLAGS_disable_global_lock) {
|
if (!cvars::disable_global_lock) {
|
||||||
f.CallExtern(f.builtins()->leave_global_lock);
|
f.CallExtern(f.builtins()->leave_global_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -753,12 +753,12 @@ int InstrEmit_mtmsrd(PPCHIRBuilder& f, const InstrData& i) {
|
||||||
f.ZeroExtend(f.LoadGPR(i.X.RT), INT64_TYPE));
|
f.ZeroExtend(f.LoadGPR(i.X.RT), INT64_TYPE));
|
||||||
if (i.X.RT == 13) {
|
if (i.X.RT == 13) {
|
||||||
// iff storing from r13 we are taking a lock (disable interrupts).
|
// iff storing from r13 we are taking a lock (disable interrupts).
|
||||||
if (!FLAGS_disable_global_lock) {
|
if (!cvars::disable_global_lock) {
|
||||||
f.CallExtern(f.builtins()->enter_global_lock);
|
f.CallExtern(f.builtins()->enter_global_lock);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Otherwise we are restoring interrupts (probably).
|
// Otherwise we are restoring interrupts (probably).
|
||||||
if (!FLAGS_disable_global_lock) {
|
if (!cvars::disable_global_lock) {
|
||||||
f.CallExtern(f.builtins()->leave_global_lock);
|
f.CallExtern(f.builtins()->leave_global_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,25 +182,25 @@ bool PPCHIRBuilder::Emit(GuestFunction* function, uint32_t flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCHIRBuilder::MaybeBreakOnInstruction(uint32_t address) {
|
void PPCHIRBuilder::MaybeBreakOnInstruction(uint32_t address) {
|
||||||
if (address != FLAGS_break_on_instruction) {
|
if (address != cvars::break_on_instruction) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Comment("--break-on-instruction target");
|
Comment("--break-on-instruction target");
|
||||||
|
|
||||||
if (FLAGS_break_condition_gpr < 0) {
|
if (cvars::break_condition_gpr < 0) {
|
||||||
DebugBreak();
|
DebugBreak();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto left = LoadGPR(FLAGS_break_condition_gpr);
|
auto left = LoadGPR(cvars::break_condition_gpr);
|
||||||
auto right = LoadConstantUint64(FLAGS_break_condition_value);
|
auto right = LoadConstantUint64(cvars::break_condition_value);
|
||||||
if (FLAGS_break_condition_truncate) {
|
if (cvars::break_condition_truncate) {
|
||||||
left = Truncate(left, INT32_TYPE);
|
left = Truncate(left, INT32_TYPE);
|
||||||
right = Truncate(right, INT32_TYPE);
|
right = Truncate(right, INT32_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto op = FLAGS_break_condition_op.c_str();
|
auto op = cvars::break_condition_op.c_str();
|
||||||
// TODO(rick): table?
|
// TODO(rick): table?
|
||||||
if (strcasecmp(op, "eq") == 0) {
|
if (strcasecmp(op, "eq") == 0) {
|
||||||
TrapTrue(CompareEQ(left, right));
|
TrapTrue(CompareEQ(left, right));
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include "xenia/cpu/ppc/ppc_translator.h"
|
#include "xenia/cpu/ppc/ppc_translator.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include "xenia/base/assert.h"
|
#include "xenia/base/assert.h"
|
||||||
#include "xenia/base/byte_order.h"
|
#include "xenia/base/byte_order.h"
|
||||||
#include "xenia/base/memory.h"
|
#include "xenia/base/memory.h"
|
||||||
|
@ -41,7 +39,7 @@ PPCTranslator::PPCTranslator(PPCFrontend* frontend) : frontend_(frontend) {
|
||||||
assembler_ = backend->CreateAssembler();
|
assembler_ = backend->CreateAssembler();
|
||||||
assembler_->Initialize();
|
assembler_->Initialize();
|
||||||
|
|
||||||
bool validate = FLAGS_validate_hir;
|
bool validate = cvars::validate_hir;
|
||||||
|
|
||||||
// Merge blocks early. This will let us use more context in other passes.
|
// Merge blocks early. This will let us use more context in other passes.
|
||||||
// The CFG is required for simplification and dirtied by it.
|
// The CFG is required for simplification and dirtied by it.
|
||||||
|
@ -108,19 +106,19 @@ bool PPCTranslator::Translate(GuestFunction* function,
|
||||||
xe::make_reset_scope(&string_buffer_);
|
xe::make_reset_scope(&string_buffer_);
|
||||||
|
|
||||||
// NOTE: we only want to do this when required, as it's expensive to build.
|
// NOTE: we only want to do this when required, as it's expensive to build.
|
||||||
if (FLAGS_disassemble_functions) {
|
if (cvars::disassemble_functions) {
|
||||||
debug_info_flags |= DebugInfoFlags::kDebugInfoAllDisasm;
|
debug_info_flags |= DebugInfoFlags::kDebugInfoAllDisasm;
|
||||||
}
|
}
|
||||||
if (FLAGS_trace_functions) {
|
if (cvars::trace_functions) {
|
||||||
debug_info_flags |= DebugInfoFlags::kDebugInfoTraceFunctions;
|
debug_info_flags |= DebugInfoFlags::kDebugInfoTraceFunctions;
|
||||||
}
|
}
|
||||||
if (FLAGS_trace_function_coverage) {
|
if (cvars::trace_function_coverage) {
|
||||||
debug_info_flags |= DebugInfoFlags::kDebugInfoTraceFunctionCoverage;
|
debug_info_flags |= DebugInfoFlags::kDebugInfoTraceFunctionCoverage;
|
||||||
}
|
}
|
||||||
if (FLAGS_trace_function_references) {
|
if (cvars::trace_function_references) {
|
||||||
debug_info_flags |= DebugInfoFlags::kDebugInfoTraceFunctionReferences;
|
debug_info_flags |= DebugInfoFlags::kDebugInfoTraceFunctionReferences;
|
||||||
}
|
}
|
||||||
if (FLAGS_trace_function_data) {
|
if (cvars::trace_function_data) {
|
||||||
debug_info_flags |= DebugInfoFlags::kDebugInfoTraceFunctionData;
|
debug_info_flags |= DebugInfoFlags::kDebugInfoTraceFunctionData;
|
||||||
}
|
}
|
||||||
std::unique_ptr<FunctionDebugInfo> debug_info;
|
std::unique_ptr<FunctionDebugInfo> debug_info;
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include "xenia/base/filesystem.h"
|
#include "xenia/base/filesystem.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/main.h"
|
#include "xenia/base/main.h"
|
||||||
|
@ -26,9 +24,9 @@
|
||||||
#endif // XE_COMPILER_MSVC
|
#endif // XE_COMPILER_MSVC
|
||||||
|
|
||||||
DEFINE_string(test_path, "src/xenia/cpu/ppc/testing/",
|
DEFINE_string(test_path, "src/xenia/cpu/ppc/testing/",
|
||||||
"Directory scanned for test files.");
|
"Directory scanned for test files.", "Other");
|
||||||
DEFINE_string(test_bin_path, "src/xenia/cpu/ppc/testing/bin/",
|
DEFINE_string(test_bin_path, "src/xenia/cpu/ppc/testing/bin/",
|
||||||
"Directory with binary outputs of the test files.");
|
"Directory with binary outputs of the test files.", "Other");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
|
@ -54,8 +52,8 @@ class TestSuite {
|
||||||
name = src_file_path.substr(src_file_path.find_last_of(xe::kPathSeparator) +
|
name = src_file_path.substr(src_file_path.find_last_of(xe::kPathSeparator) +
|
||||||
1);
|
1);
|
||||||
name = ReplaceExtension(name, L"");
|
name = ReplaceExtension(name, L"");
|
||||||
map_file_path = xe::to_wstring(FLAGS_test_bin_path) + name + L".map";
|
map_file_path = xe::to_wstring(cvars::test_bin_path) + name + L".map";
|
||||||
bin_file_path = xe::to_wstring(FLAGS_test_bin_path) + name + L".bin";
|
bin_file_path = xe::to_wstring(cvars::test_bin_path) + name + L".bin";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Load() {
|
bool Load() {
|
||||||
|
@ -192,11 +190,11 @@ class TestRunner {
|
||||||
std::unique_ptr<xe::cpu::backend::Backend> backend;
|
std::unique_ptr<xe::cpu::backend::Backend> backend;
|
||||||
if (!backend) {
|
if (!backend) {
|
||||||
#if defined(XENIA_HAS_X64_BACKEND) && XENIA_HAS_X64_BACKEND
|
#if defined(XENIA_HAS_X64_BACKEND) && XENIA_HAS_X64_BACKEND
|
||||||
if (FLAGS_cpu == "x64") {
|
if (cvars::cpu == "x64") {
|
||||||
backend.reset(new xe::cpu::backend::x64::X64Backend());
|
backend.reset(new xe::cpu::backend::x64::X64Backend());
|
||||||
}
|
}
|
||||||
#endif // XENIA_HAS_X64_BACKEND
|
#endif // XENIA_HAS_X64_BACKEND
|
||||||
if (FLAGS_cpu == "any") {
|
if (cvars::cpu == "any") {
|
||||||
#if defined(XENIA_HAS_X64_BACKEND) && XENIA_HAS_X64_BACKEND
|
#if defined(XENIA_HAS_X64_BACKEND) && XENIA_HAS_X64_BACKEND
|
||||||
if (!backend) {
|
if (!backend) {
|
||||||
backend.reset(new xe::cpu::backend::x64::X64Backend());
|
backend.reset(new xe::cpu::backend::x64::X64Backend());
|
||||||
|
@ -408,7 +406,7 @@ bool RunTests(const std::wstring& test_name) {
|
||||||
int passed_count = 0;
|
int passed_count = 0;
|
||||||
|
|
||||||
auto test_path_root =
|
auto test_path_root =
|
||||||
xe::fix_path_separators(xe::to_wstring(FLAGS_test_path));
|
xe::fix_path_separators(xe::to_wstring(cvars::test_path));
|
||||||
std::vector<std::wstring> test_files;
|
std::vector<std::wstring> test_files;
|
||||||
if (!DiscoverTests(test_path_root, test_files)) {
|
if (!DiscoverTests(test_path_root, test_files)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include "xenia/base/filesystem.h"
|
#include "xenia/base/filesystem.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/main.h"
|
#include "xenia/base/main.h"
|
||||||
|
@ -58,8 +56,8 @@ class TestSuite {
|
||||||
name = src_file_path.substr(src_file_path.find_last_of(xe::kPathSeparator) +
|
name = src_file_path.substr(src_file_path.find_last_of(xe::kPathSeparator) +
|
||||||
1);
|
1);
|
||||||
name = ReplaceExtension(name, L"");
|
name = ReplaceExtension(name, L"");
|
||||||
map_file_path = xe::to_wstring(FLAGS_test_bin_path) + name + L".map";
|
map_file_path = xe::to_wstring(cvars::test_bin_path) + name + L".map";
|
||||||
bin_file_path = xe::to_wstring(FLAGS_test_bin_path) + name + L".bin";
|
bin_file_path = xe::to_wstring(cvars::test_bin_path) + name + L".bin";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Load() {
|
bool Load() {
|
||||||
|
@ -454,7 +452,7 @@ bool RunTests(const std::wstring& test_name) {
|
||||||
int passed_count = 0;
|
int passed_count = 0;
|
||||||
|
|
||||||
auto test_path_root =
|
auto test_path_root =
|
||||||
xe::fix_path_separators(xe::to_wstring(FLAGS_test_path));
|
xe::fix_path_separators(xe::to_wstring(cvars::test_path));
|
||||||
std::vector<std::wstring> test_files;
|
std::vector<std::wstring> test_files;
|
||||||
if (!DiscoverTests(test_path_root, test_files)) {
|
if (!DiscoverTests(test_path_root, test_files)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -11,7 +11,6 @@ project("xenia-cpu-ppc-tests")
|
||||||
"xenia-cpu-backend-x64",
|
"xenia-cpu-backend-x64",
|
||||||
"xenia-cpu",
|
"xenia-cpu",
|
||||||
"xenia-base",
|
"xenia-base",
|
||||||
"gflags",
|
|
||||||
"capstone", -- cpu-backend-x64
|
"capstone", -- cpu-backend-x64
|
||||||
"mspack",
|
"mspack",
|
||||||
})
|
})
|
||||||
|
@ -22,15 +21,11 @@ project("xenia-cpu-ppc-tests")
|
||||||
files({
|
files({
|
||||||
"*.s",
|
"*.s",
|
||||||
})
|
})
|
||||||
includedirs({
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
|
||||||
filter("files:*.s")
|
filter("files:*.s")
|
||||||
flags({"ExcludeFromBuild"})
|
flags({"ExcludeFromBuild"})
|
||||||
filter("platforms:Windows")
|
filter("platforms:Windows")
|
||||||
debugdir(project_root)
|
debugdir(project_root)
|
||||||
debugargs({
|
debugargs({
|
||||||
"--flagfile=scratch/flags.txt",
|
|
||||||
"2>&1",
|
"2>&1",
|
||||||
"1>scratch/stdout-testing.txt",
|
"1>scratch/stdout-testing.txt",
|
||||||
})
|
})
|
||||||
|
@ -46,7 +41,6 @@ project("xenia-cpu-ppc-nativetests")
|
||||||
language("C++")
|
language("C++")
|
||||||
links({
|
links({
|
||||||
"xenia-base",
|
"xenia-base",
|
||||||
"gflags",
|
|
||||||
})
|
})
|
||||||
files({
|
files({
|
||||||
"ppc_testing_native_main.cc",
|
"ppc_testing_native_main.cc",
|
||||||
|
@ -59,9 +53,6 @@ project("xenia-cpu-ppc-nativetests")
|
||||||
filter("files:instr_*.s", "files:seq_*.s")
|
filter("files:instr_*.s", "files:seq_*.s")
|
||||||
flags({"ExcludeFromBuild"})
|
flags({"ExcludeFromBuild"})
|
||||||
filter({})
|
filter({})
|
||||||
includedirs({
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
|
||||||
buildoptions({
|
buildoptions({
|
||||||
"-Wa,-mregnames", -- Tell GAS to accept register names.
|
"-Wa,-mregnames", -- Tell GAS to accept register names.
|
||||||
})
|
})
|
||||||
|
|
|
@ -12,7 +12,6 @@ project("xenia-cpu")
|
||||||
})
|
})
|
||||||
includedirs({
|
includedirs({
|
||||||
project_root.."/third_party/llvm/include",
|
project_root.."/third_party/llvm/include",
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
})
|
||||||
local_platform_files()
|
local_platform_files()
|
||||||
local_platform_files("backend")
|
local_platform_files("backend")
|
||||||
|
|
|
@ -9,12 +9,11 @@
|
||||||
|
|
||||||
#include "xenia/cpu/processor.h"
|
#include "xenia/cpu/processor.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include "xenia/base/assert.h"
|
#include "xenia/base/assert.h"
|
||||||
#include "xenia/base/atomic.h"
|
#include "xenia/base/atomic.h"
|
||||||
#include "xenia/base/byte_order.h"
|
#include "xenia/base/byte_order.h"
|
||||||
#include "xenia/base/byte_stream.h"
|
#include "xenia/base/byte_stream.h"
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
#include "xenia/base/debugging.h"
|
#include "xenia/base/debugging.h"
|
||||||
#include "xenia/base/exception_handler.h"
|
#include "xenia/base/exception_handler.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
|
@ -42,9 +41,11 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DEFINE_bool(debug, DEFAULT_DEBUG_FLAG,
|
DEFINE_bool(debug, DEFAULT_DEBUG_FLAG,
|
||||||
"Allow debugging and retain debug information.");
|
"Allow debugging and retain debug information.", "General");
|
||||||
DEFINE_string(trace_function_data_path, "", "File to write trace data to.");
|
DEFINE_string(trace_function_data_path, "", "File to write trace data to.",
|
||||||
DEFINE_bool(break_on_start, false, "Break into the debugger on startup.");
|
"CPU");
|
||||||
|
DEFINE_bool(break_on_start, false, "Break into the debugger on startup.",
|
||||||
|
"CPU");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
@ -132,14 +133,14 @@ bool Processor::Setup(std::unique_ptr<backend::Backend> backend) {
|
||||||
stack_walker_ = StackWalker::Create(backend_->code_cache());
|
stack_walker_ = StackWalker::Create(backend_->code_cache());
|
||||||
if (!stack_walker_) {
|
if (!stack_walker_) {
|
||||||
// TODO(benvanik): disable features.
|
// TODO(benvanik): disable features.
|
||||||
if (FLAGS_debug) {
|
if (cvars::debug) {
|
||||||
XELOGW("Disabling --debug due to lack of stack walker");
|
XELOGW("Disabling --debug due to lack of stack walker");
|
||||||
FLAGS_debug = false;
|
cvars::debug = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open the trace data path, if requested.
|
// Open the trace data path, if requested.
|
||||||
functions_trace_path_ = xe::to_wstring(FLAGS_trace_function_data_path);
|
functions_trace_path_ = xe::to_wstring(cvars::trace_function_data_path);
|
||||||
if (!functions_trace_path_.empty()) {
|
if (!functions_trace_path_.empty()) {
|
||||||
functions_trace_file_ = ChunkedMappedMemoryWriter::Open(
|
functions_trace_file_ = ChunkedMappedMemoryWriter::Open(
|
||||||
functions_trace_path_, 32 * 1024 * 1024, true);
|
functions_trace_path_, 32 * 1024 * 1024, true);
|
||||||
|
@ -149,7 +150,7 @@ bool Processor::Setup(std::unique_ptr<backend::Backend> backend) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Processor::PreLaunch() {
|
void Processor::PreLaunch() {
|
||||||
if (FLAGS_break_on_start) {
|
if (cvars::break_on_start) {
|
||||||
// Start paused.
|
// Start paused.
|
||||||
XELOGI("Breaking into debugger because of --break_on_start...");
|
XELOGI("Breaking into debugger because of --break_on_start...");
|
||||||
execution_state_ = ExecutionState::kRunning;
|
execution_state_ = ExecutionState::kRunning;
|
||||||
|
@ -629,9 +630,9 @@ bool Processor::OnThreadBreakpointHit(Exception* ex) {
|
||||||
SuspendAllBreakpoints();
|
SuspendAllBreakpoints();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update all thread states with their latest values, using the context we got
|
// Update all thread states with their latest values, using the context we
|
||||||
// from the exception instead of a sampled value (as it would just show the
|
// got from the exception instead of a sampled value (as it would just show
|
||||||
// exception handler).
|
// the exception handler).
|
||||||
UpdateThreadExecutionStates(thread_info->thread_id, ex->thread_context());
|
UpdateThreadExecutionStates(thread_info->thread_id, ex->thread_context());
|
||||||
|
|
||||||
// Walk the captured thread stack and look for breakpoints at any address in
|
// Walk the captured thread stack and look for breakpoints at any address in
|
||||||
|
|
|
@ -10,13 +10,12 @@
|
||||||
#ifndef XENIA_CPU_PROCESSOR_H_
|
#ifndef XENIA_CPU_PROCESSOR_H_
|
||||||
#define XENIA_CPU_PROCESSOR_H_
|
#define XENIA_CPU_PROCESSOR_H_
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
#include "xenia/base/mapped_memory.h"
|
#include "xenia/base/mapped_memory.h"
|
||||||
#include "xenia/base/mutex.h"
|
#include "xenia/base/mutex.h"
|
||||||
#include "xenia/cpu/backend/backend.h"
|
#include "xenia/cpu/backend/backend.h"
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include "xenia/cpu/stack_walker.h"
|
#include "xenia/cpu/stack_walker.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
|
@ -20,7 +18,7 @@
|
||||||
#include "xenia/cpu/processor.h"
|
#include "xenia/cpu/processor.h"
|
||||||
|
|
||||||
DEFINE_bool(debug_symbol_loader, false,
|
DEFINE_bool(debug_symbol_loader, false,
|
||||||
"Enable dbghelp debug logging and validation.");
|
"Enable dbghelp debug logging and validation.", "CPU");
|
||||||
|
|
||||||
// Must be included after platform_win.h:
|
// Must be included after platform_win.h:
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
|
@ -98,7 +96,7 @@ bool InitializeStackWalker() {
|
||||||
|
|
||||||
// Initialize the symbol lookup services.
|
// Initialize the symbol lookup services.
|
||||||
DWORD options = sym_get_options_();
|
DWORD options = sym_get_options_();
|
||||||
if (FLAGS_debug_symbol_loader) {
|
if (cvars::debug_symbol_loader) {
|
||||||
options |= SYMOPT_DEBUG;
|
options |= SYMOPT_DEBUG;
|
||||||
}
|
}
|
||||||
options |= SYMOPT_DEFERRED_LOADS;
|
options |= SYMOPT_DEFERRED_LOADS;
|
||||||
|
|
|
@ -2,9 +2,6 @@ project_root = "../../../.."
|
||||||
include(project_root.."/tools/build")
|
include(project_root.."/tools/build")
|
||||||
|
|
||||||
test_suite("xenia-cpu-tests", project_root, ".", {
|
test_suite("xenia-cpu-tests", project_root, ".", {
|
||||||
includedirs = {
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
},
|
|
||||||
links = {
|
links = {
|
||||||
"capstone",
|
"capstone",
|
||||||
"xenia-base",
|
"xenia-base",
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
#include "xenia/cpu/ppc/ppc_frontend.h"
|
#include "xenia/cpu/ppc/ppc_frontend.h"
|
||||||
#include "xenia/cpu/raw_module.h"
|
#include "xenia/cpu/raw_module.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
namespace sandbox {
|
namespace sandbox {
|
||||||
|
|
|
@ -1008,8 +1008,8 @@ bool XexModule::LoadContinue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load a specified module map and diff.
|
// Load a specified module map and diff.
|
||||||
if (FLAGS_load_module_map.size()) {
|
if (cvars::load_module_map.size()) {
|
||||||
if (!ReadMap(FLAGS_load_module_map.c_str())) {
|
if (!ReadMap(cvars::load_module_map.c_str())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include "xenia/debug/ui/debug_window.h"
|
#include "xenia/debug/ui/debug_window.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
@ -35,7 +33,7 @@
|
||||||
#include "xenia/ui/graphics_provider.h"
|
#include "xenia/ui/graphics_provider.h"
|
||||||
#include "xenia/ui/imgui_drawer.h"
|
#include "xenia/ui/imgui_drawer.h"
|
||||||
|
|
||||||
DEFINE_bool(imgui_debug, false, "Show ImGui debugging tools.");
|
DEFINE_bool(imgui_debug, false, "Show ImGui debugging tools.", "Other");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace debug {
|
namespace debug {
|
||||||
|
@ -238,7 +236,7 @@ void DebugWindow::DrawFrame() {
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
|
|
||||||
if (FLAGS_imgui_debug) {
|
if (cvars::imgui_debug) {
|
||||||
ImGui::ShowTestWindow();
|
ImGui::ShowTestWindow();
|
||||||
ImGui::ShowMetricsWindow();
|
ImGui::ShowMetricsWindow();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ project("xenia-debug-ui")
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
includedirs({
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
project_root.."/third_party/yaml-cpp/include/",
|
project_root.."/third_party/yaml-cpp/include/",
|
||||||
})
|
})
|
||||||
local_platform_files()
|
local_platform_files()
|
||||||
|
|
|
@ -9,13 +9,14 @@
|
||||||
|
|
||||||
#include "xenia/emulator.h"
|
#include "xenia/emulator.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include "xenia/apu/audio_system.h"
|
#include "xenia/apu/audio_system.h"
|
||||||
#include "xenia/base/assert.h"
|
#include "xenia/base/assert.h"
|
||||||
#include "xenia/base/byte_stream.h"
|
#include "xenia/base/byte_stream.h"
|
||||||
#include "xenia/base/clock.h"
|
#include "xenia/base/clock.h"
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
#include "xenia/base/debugging.h"
|
#include "xenia/base/debugging.h"
|
||||||
#include "xenia/base/exception_handler.h"
|
#include "xenia/base/exception_handler.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
|
@ -44,7 +45,8 @@
|
||||||
#include "xenia/vfs/virtual_file_system.h"
|
#include "xenia/vfs/virtual_file_system.h"
|
||||||
|
|
||||||
DEFINE_double(time_scalar, 1.0,
|
DEFINE_double(time_scalar, 1.0,
|
||||||
"Scalar used to speed or slow time (1x, 2x, 1/2x, etc).");
|
"Scalar used to speed or slow time (1x, 2x, 1/2x, etc).",
|
||||||
|
"General");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
|
||||||
|
@ -112,7 +114,7 @@ X_STATUS Emulator::Setup(
|
||||||
// We could reset this with save state data/constant value to help replays.
|
// We could reset this with save state data/constant value to help replays.
|
||||||
Clock::set_guest_system_time_base(Clock::QueryHostSystemTime());
|
Clock::set_guest_system_time_base(Clock::QueryHostSystemTime());
|
||||||
// This can be adjusted dynamically, as well.
|
// This can be adjusted dynamically, as well.
|
||||||
Clock::set_guest_time_scalar(FLAGS_time_scalar);
|
Clock::set_guest_time_scalar(cvars::time_scalar);
|
||||||
|
|
||||||
// Before we can set thread affinity we must enable the process to use all
|
// Before we can set thread affinity we must enable the process to use all
|
||||||
// logical processors.
|
// logical processors.
|
||||||
|
@ -130,11 +132,11 @@ X_STATUS Emulator::Setup(
|
||||||
std::unique_ptr<xe::cpu::backend::Backend> backend;
|
std::unique_ptr<xe::cpu::backend::Backend> backend;
|
||||||
if (!backend) {
|
if (!backend) {
|
||||||
#if defined(XENIA_HAS_X64_BACKEND) && XENIA_HAS_X64_BACKEND
|
#if defined(XENIA_HAS_X64_BACKEND) && XENIA_HAS_X64_BACKEND
|
||||||
if (FLAGS_cpu == "x64") {
|
if (cvars::cpu == "x64") {
|
||||||
backend.reset(new xe::cpu::backend::x64::X64Backend());
|
backend.reset(new xe::cpu::backend::x64::X64Backend());
|
||||||
}
|
}
|
||||||
#endif // XENIA_HAS_X64_BACKEND
|
#endif // XENIA_HAS_X64_BACKEND
|
||||||
if (FLAGS_cpu == "any") {
|
if (cvars::cpu == "any") {
|
||||||
#if defined(XENIA_HAS_X64_BACKEND) && XENIA_HAS_X64_BACKEND
|
#if defined(XENIA_HAS_X64_BACKEND) && XENIA_HAS_X64_BACKEND
|
||||||
if (!backend) {
|
if (!backend) {
|
||||||
backend.reset(new xe::cpu::backend::x64::X64Backend());
|
backend.reset(new xe::cpu::backend::x64::X64Backend());
|
||||||
|
@ -646,6 +648,7 @@ X_STATUS Emulator::CompleteLaunch(const std::wstring& path,
|
||||||
if (module->title_id()) {
|
if (module->title_id()) {
|
||||||
char title_id[9] = {0};
|
char title_id[9] = {0};
|
||||||
std::snprintf(title_id, xe::countof(title_id), "%08X", module->title_id());
|
std::snprintf(title_id, xe::countof(title_id), "%08X", module->title_id());
|
||||||
|
config::LoadGameConfig(xe::to_wstring(title_id));
|
||||||
uint32_t resource_data = 0;
|
uint32_t resource_data = 0;
|
||||||
uint32_t resource_size = 0;
|
uint32_t resource_size = 0;
|
||||||
if (XSUCCEEDED(
|
if (XSUCCEEDED(
|
||||||
|
|
|
@ -393,7 +393,7 @@ void CommandProcessor::IssueSwap(uint32_t frontbuffer_ptr,
|
||||||
// This prevents the display from pulling the backbuffer out from under us.
|
// This prevents the display from pulling the backbuffer out from under us.
|
||||||
// If we skip a lot then we may need to buffer more, but as the display
|
// If we skip a lot then we may need to buffer more, but as the display
|
||||||
// thread should be fairly idle that shouldn't happen.
|
// thread should be fairly idle that shouldn't happen.
|
||||||
if (!FLAGS_vsync) {
|
if (!cvars::vsync) {
|
||||||
std::lock_guard<std::mutex> lock(swap_state_.mutex);
|
std::lock_guard<std::mutex> lock(swap_state_.mutex);
|
||||||
if (swap_state_.pending) {
|
if (swap_state_.pending) {
|
||||||
swap_state_.pending = false;
|
swap_state_.pending = false;
|
||||||
|
@ -895,7 +895,7 @@ bool CommandProcessor::ExecutePacketType3_WAIT_REG_MEM(RingBuffer* reader,
|
||||||
// Wait.
|
// Wait.
|
||||||
if (wait >= 0x100) {
|
if (wait >= 0x100) {
|
||||||
PrepareForWait();
|
PrepareForWait();
|
||||||
if (!FLAGS_vsync) {
|
if (!cvars::vsync) {
|
||||||
// User wants it fast and dangerous.
|
// User wants it fast and dangerous.
|
||||||
xe::threading::MaybeYield();
|
xe::threading::MaybeYield();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -10,10 +10,10 @@
|
||||||
#include "xenia/gpu/gpu_flags.h"
|
#include "xenia/gpu/gpu_flags.h"
|
||||||
|
|
||||||
DEFINE_string(trace_gpu_prefix, "scratch/gpu/",
|
DEFINE_string(trace_gpu_prefix, "scratch/gpu/",
|
||||||
"Prefix path for GPU trace files.");
|
"Prefix path for GPU trace files.", "GPU");
|
||||||
DEFINE_bool(trace_gpu_stream, false, "Trace all GPU packets.");
|
DEFINE_bool(trace_gpu_stream, false, "Trace all GPU packets.", "GPU");
|
||||||
|
|
||||||
DEFINE_string(dump_shaders, "",
|
DEFINE_string(dump_shaders, "",
|
||||||
"Path to write GPU shaders to as they are compiled.");
|
"Path to write GPU shaders to as they are compiled.", "GPU");
|
||||||
|
|
||||||
DEFINE_bool(vsync, true, "Enable VSYNC.");
|
DEFINE_bool(vsync, true, "Enable VSYNC.", "GPU");
|
||||||
|
|
|
@ -9,8 +9,7 @@
|
||||||
|
|
||||||
#ifndef XENIA_GPU_GPU_FLAGS_H_
|
#ifndef XENIA_GPU_GPU_FLAGS_H_
|
||||||
#define XENIA_GPU_GPU_FLAGS_H_
|
#define XENIA_GPU_GPU_FLAGS_H_
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
DECLARE_string(trace_gpu_prefix);
|
DECLARE_string(trace_gpu_prefix);
|
||||||
DECLARE_bool(trace_gpu_stream);
|
DECLARE_bool(trace_gpu_stream);
|
||||||
|
|
|
@ -113,7 +113,7 @@ X_STATUS GraphicsSystem::Setup(cpu::Processor* processor,
|
||||||
vsync_worker_running_ = true;
|
vsync_worker_running_ = true;
|
||||||
vsync_worker_thread_ = kernel::object_ref<kernel::XHostThread>(
|
vsync_worker_thread_ = kernel::object_ref<kernel::XHostThread>(
|
||||||
new kernel::XHostThread(kernel_state_, 128 * 1024, 0, [this]() {
|
new kernel::XHostThread(kernel_state_, 128 * 1024, 0, [this]() {
|
||||||
uint64_t vsync_duration = FLAGS_vsync ? 16 : 1;
|
uint64_t vsync_duration = cvars::vsync ? 16 : 1;
|
||||||
uint64_t last_frame_time = Clock::QueryGuestTickCount();
|
uint64_t last_frame_time = Clock::QueryGuestTickCount();
|
||||||
while (vsync_worker_running_) {
|
while (vsync_worker_running_) {
|
||||||
uint64_t current_time = Clock::QueryGuestTickCount();
|
uint64_t current_time = Clock::QueryGuestTickCount();
|
||||||
|
@ -132,7 +132,7 @@ X_STATUS GraphicsSystem::Setup(cpu::Processor* processor,
|
||||||
vsync_worker_thread_->set_name("GraphicsSystem Vsync");
|
vsync_worker_thread_->set_name("GraphicsSystem Vsync");
|
||||||
vsync_worker_thread_->Create();
|
vsync_worker_thread_->Create();
|
||||||
|
|
||||||
if (FLAGS_trace_gpu_stream) {
|
if (cvars::trace_gpu_stream) {
|
||||||
BeginTracing();
|
BeginTracing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,11 +270,12 @@ void GraphicsSystem::ClearCaches() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsSystem::RequestFrameTrace() {
|
void GraphicsSystem::RequestFrameTrace() {
|
||||||
command_processor_->RequestFrameTrace(xe::to_wstring(FLAGS_trace_gpu_prefix));
|
command_processor_->RequestFrameTrace(
|
||||||
|
xe::to_wstring(cvars::trace_gpu_prefix));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsSystem::BeginTracing() {
|
void GraphicsSystem::BeginTracing() {
|
||||||
command_processor_->BeginTracing(xe::to_wstring(FLAGS_trace_gpu_prefix));
|
command_processor_->BeginTracing(xe::to_wstring(cvars::trace_gpu_prefix));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsSystem::EndTracing() { command_processor_->EndTracing(); }
|
void GraphicsSystem::EndTracing() { command_processor_->EndTracing(); }
|
||||||
|
|
|
@ -15,7 +15,4 @@ project("xenia-gpu-null")
|
||||||
})
|
})
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
|
||||||
local_platform_files()
|
local_platform_files()
|
||||||
|
|
|
@ -19,7 +19,6 @@ project("xenia-gpu")
|
||||||
})
|
})
|
||||||
includedirs({
|
includedirs({
|
||||||
project_root.."/third_party/spirv-tools/external/include",
|
project_root.."/third_party/spirv-tools/external/include",
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
})
|
||||||
local_platform_files()
|
local_platform_files()
|
||||||
-- local_platform_files("spirv")
|
-- local_platform_files("spirv")
|
||||||
|
@ -31,7 +30,6 @@ project("xenia-gpu-shader-compiler")
|
||||||
kind("ConsoleApp")
|
kind("ConsoleApp")
|
||||||
language("C++")
|
language("C++")
|
||||||
links({
|
links({
|
||||||
"gflags",
|
|
||||||
"glslang-spirv",
|
"glslang-spirv",
|
||||||
"spirv-tools",
|
"spirv-tools",
|
||||||
"xenia-base",
|
"xenia-base",
|
||||||
|
@ -40,9 +38,6 @@ project("xenia-gpu-shader-compiler")
|
||||||
})
|
})
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
|
||||||
files({
|
files({
|
||||||
"shader_compiler_main.cc",
|
"shader_compiler_main.cc",
|
||||||
"../base/main_"..platform_suffix..".cc",
|
"../base/main_"..platform_suffix..".cc",
|
||||||
|
@ -54,7 +49,6 @@ project("xenia-gpu-shader-compiler")
|
||||||
if not os.isfile(user_file) then
|
if not os.isfile(user_file) then
|
||||||
debugdir(project_root)
|
debugdir(project_root)
|
||||||
debugargs({
|
debugargs({
|
||||||
"--flagfile=scratch/flags.txt",
|
|
||||||
"2>&1",
|
"2>&1",
|
||||||
"1>scratch/stdout-shader-compiler.txt",
|
"1>scratch/stdout-shader-compiler.txt",
|
||||||
})
|
})
|
||||||
|
|
|
@ -7,13 +7,12 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/main.h"
|
#include "xenia/base/main.h"
|
||||||
#include "xenia/base/string.h"
|
#include "xenia/base/string.h"
|
||||||
|
@ -22,35 +21,36 @@
|
||||||
#include "xenia/gpu/spirv_shader_translator.h"
|
#include "xenia/gpu/spirv_shader_translator.h"
|
||||||
#include "xenia/ui/spirv/spirv_disassembler.h"
|
#include "xenia/ui/spirv/spirv_disassembler.h"
|
||||||
|
|
||||||
DEFINE_string(shader_input, "", "Input shader binary file path.");
|
DEFINE_string(shader_input, "", "Input shader binary file path.", "GPU");
|
||||||
DEFINE_string(shader_input_type, "",
|
DEFINE_string(shader_input_type, "",
|
||||||
"'vs', 'ps', or unspecified to infer from the given filename.");
|
"'vs', 'ps', or unspecified to infer from the given filename.",
|
||||||
DEFINE_string(shader_output, "", "Output shader file path.");
|
"GPU");
|
||||||
|
DEFINE_string(shader_output, "", "Output shader file path.", "GPU");
|
||||||
DEFINE_string(shader_output_type, "ucode",
|
DEFINE_string(shader_output_type, "ucode",
|
||||||
"Translator to use: [ucode, glsl45, spirv, spirvtext].");
|
"Translator to use: [ucode, glsl45, spirv, spirvtext].", "GPU");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
|
||||||
int shader_compiler_main(const std::vector<std::wstring>& args) {
|
int shader_compiler_main(const std::vector<std::wstring>& args) {
|
||||||
ShaderType shader_type;
|
ShaderType shader_type;
|
||||||
if (!FLAGS_shader_input_type.empty()) {
|
if (!cvars::shader_input_type.empty()) {
|
||||||
if (FLAGS_shader_input_type == "vs") {
|
if (cvars::shader_input_type == "vs") {
|
||||||
shader_type = ShaderType::kVertex;
|
shader_type = ShaderType::kVertex;
|
||||||
} else if (FLAGS_shader_input_type == "ps") {
|
} else if (cvars::shader_input_type == "ps") {
|
||||||
shader_type = ShaderType::kPixel;
|
shader_type = ShaderType::kPixel;
|
||||||
} else {
|
} else {
|
||||||
XELOGE("Invalid --shader_input_type; must be 'vs' or 'ps'.");
|
XELOGE("Invalid --shader_input_type; must be 'vs' or 'ps'.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto last_dot = FLAGS_shader_input.find_last_of('.');
|
auto last_dot = cvars::shader_input.find_last_of('.');
|
||||||
bool valid_type = false;
|
bool valid_type = false;
|
||||||
if (last_dot != std::string::npos) {
|
if (last_dot != std::string::npos) {
|
||||||
if (FLAGS_shader_input.substr(last_dot) == ".vs") {
|
if (cvars::shader_input.substr(last_dot) == ".vs") {
|
||||||
shader_type = ShaderType::kVertex;
|
shader_type = ShaderType::kVertex;
|
||||||
valid_type = true;
|
valid_type = true;
|
||||||
} else if (FLAGS_shader_input.substr(last_dot) == ".ps") {
|
} else if (cvars::shader_input.substr(last_dot) == ".ps") {
|
||||||
shader_type = ShaderType::kPixel;
|
shader_type = ShaderType::kPixel;
|
||||||
valid_type = true;
|
valid_type = true;
|
||||||
}
|
}
|
||||||
|
@ -63,9 +63,9 @@ int shader_compiler_main(const std::vector<std::wstring>& args) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto input_file = fopen(FLAGS_shader_input.c_str(), "rb");
|
auto input_file = fopen(cvars::shader_input.c_str(), "rb");
|
||||||
if (!input_file) {
|
if (!input_file) {
|
||||||
XELOGE("Unable to open input file: %s", FLAGS_shader_input.c_str());
|
XELOGE("Unable to open input file: %s", cvars::shader_input.c_str());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
fseek(input_file, 0, SEEK_END);
|
fseek(input_file, 0, SEEK_END);
|
||||||
|
@ -76,7 +76,7 @@ int shader_compiler_main(const std::vector<std::wstring>& args) {
|
||||||
fclose(input_file);
|
fclose(input_file);
|
||||||
|
|
||||||
XELOGI("Opened %s as a %s shader, %" PRId64 " words (%" PRId64 " bytes).",
|
XELOGI("Opened %s as a %s shader, %" PRId64 " words (%" PRId64 " bytes).",
|
||||||
FLAGS_shader_input.c_str(),
|
cvars::shader_input.c_str(),
|
||||||
shader_type == ShaderType::kVertex ? "vertex" : "pixel",
|
shader_type == ShaderType::kVertex ? "vertex" : "pixel",
|
||||||
ucode_dwords.size(), ucode_dwords.size() * 4);
|
ucode_dwords.size(), ucode_dwords.size() * 4);
|
||||||
|
|
||||||
|
@ -86,10 +86,10 @@ int shader_compiler_main(const std::vector<std::wstring>& args) {
|
||||||
shader_type, ucode_data_hash, ucode_dwords.data(), ucode_dwords.size());
|
shader_type, ucode_data_hash, ucode_dwords.data(), ucode_dwords.size());
|
||||||
|
|
||||||
std::unique_ptr<ShaderTranslator> translator;
|
std::unique_ptr<ShaderTranslator> translator;
|
||||||
if (FLAGS_shader_output_type == "spirv" ||
|
if (cvars::shader_output_type == "spirv" ||
|
||||||
FLAGS_shader_output_type == "spirvtext") {
|
cvars::shader_output_type == "spirvtext") {
|
||||||
translator = std::make_unique<SpirvShaderTranslator>();
|
translator = std::make_unique<SpirvShaderTranslator>();
|
||||||
} else if (FLAGS_shader_output_type == "glsl45") {
|
} else if (cvars::shader_output_type == "glsl45") {
|
||||||
translator = std::make_unique<GlslShaderTranslator>(
|
translator = std::make_unique<GlslShaderTranslator>(
|
||||||
GlslShaderTranslator::Dialect::kGL45);
|
GlslShaderTranslator::Dialect::kGL45);
|
||||||
} else {
|
} else {
|
||||||
|
@ -102,7 +102,7 @@ int shader_compiler_main(const std::vector<std::wstring>& args) {
|
||||||
size_t source_data_size = shader->translated_binary().size();
|
size_t source_data_size = shader->translated_binary().size();
|
||||||
|
|
||||||
std::unique_ptr<xe::ui::spirv::SpirvDisassembler::Result> spirv_disasm_result;
|
std::unique_ptr<xe::ui::spirv::SpirvDisassembler::Result> spirv_disasm_result;
|
||||||
if (FLAGS_shader_output_type == "spirvtext") {
|
if (cvars::shader_output_type == "spirvtext") {
|
||||||
// Disassemble SPIRV.
|
// Disassemble SPIRV.
|
||||||
spirv_disasm_result = xe::ui::spirv::SpirvDisassembler().Disassemble(
|
spirv_disasm_result = xe::ui::spirv::SpirvDisassembler().Disassemble(
|
||||||
reinterpret_cast<const uint32_t*>(source_data), source_data_size / 4);
|
reinterpret_cast<const uint32_t*>(source_data), source_data_size / 4);
|
||||||
|
@ -110,8 +110,8 @@ int shader_compiler_main(const std::vector<std::wstring>& args) {
|
||||||
source_data_size = std::strlen(spirv_disasm_result->text()) + 1;
|
source_data_size = std::strlen(spirv_disasm_result->text()) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FLAGS_shader_output.empty()) {
|
if (!cvars::shader_output.empty()) {
|
||||||
auto output_file = fopen(FLAGS_shader_output.c_str(), "wb");
|
auto output_file = fopen(cvars::shader_output.c_str(), "wb");
|
||||||
fwrite(source_data, 1, source_data_size, output_file);
|
fwrite(source_data, 1, source_data_size, output_file);
|
||||||
fclose(output_file);
|
fclose(output_file);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,19 +9,20 @@
|
||||||
|
|
||||||
#include "xenia/gpu/spirv_shader_translator.h"
|
#include "xenia/gpu/spirv_shader_translator.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/math.h"
|
#include "xenia/base/math.h"
|
||||||
|
|
||||||
DEFINE_bool(spv_validate, false, "Validate SPIR-V shaders after generation");
|
DEFINE_bool(spv_validate, false, "Validate SPIR-V shaders after generation",
|
||||||
DEFINE_bool(spv_disasm, false, "Disassemble SPIR-V shaders after generation");
|
"GPU");
|
||||||
|
DEFINE_bool(spv_disasm, false, "Disassemble SPIR-V shaders after generation",
|
||||||
|
"GPU");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
@ -667,7 +668,7 @@ std::vector<uint8_t> SpirvShaderTranslator::CompleteTranslation() {
|
||||||
|
|
||||||
void SpirvShaderTranslator::PostTranslation(Shader* shader) {
|
void SpirvShaderTranslator::PostTranslation(Shader* shader) {
|
||||||
// Validation.
|
// Validation.
|
||||||
if (FLAGS_spv_validate) {
|
if (cvars::spv_validate) {
|
||||||
auto validation = validator_.Validate(
|
auto validation = validator_.Validate(
|
||||||
reinterpret_cast<const uint32_t*>(shader->translated_binary().data()),
|
reinterpret_cast<const uint32_t*>(shader->translated_binary().data()),
|
||||||
shader->translated_binary().size() / sizeof(uint32_t));
|
shader->translated_binary().size() / sizeof(uint32_t));
|
||||||
|
@ -677,7 +678,7 @@ void SpirvShaderTranslator::PostTranslation(Shader* shader) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_spv_disasm) {
|
if (cvars::spv_disasm) {
|
||||||
// TODO(benvanik): only if needed? could be slowish.
|
// TODO(benvanik): only if needed? could be slowish.
|
||||||
auto disasm = disassembler_.Disassemble(
|
auto disasm = disassembler_.Disassemble(
|
||||||
reinterpret_cast<const uint32_t*>(shader->translated_binary().data()),
|
reinterpret_cast<const uint32_t*>(shader->translated_binary().data()),
|
||||||
|
|
|
@ -7,13 +7,12 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
#include "xenia/base/cvar.h"
|
||||||
|
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/math.h"
|
#include "xenia/base/math.h"
|
||||||
#include "xenia/gpu/texture_info.h"
|
#include "xenia/gpu/texture_info.h"
|
||||||
|
|
||||||
DEFINE_bool(texture_dump, false, "Dump textures to DDS");
|
DEFINE_bool(texture_dump, false, "Dump textures to DDS", "GPU");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include "xenia/gpu/trace_dump.h"
|
#include "xenia/gpu/trace_dump.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include "third_party/stb/stb_image_write.h"
|
#include "third_party/stb/stb_image_write.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/profiling.h"
|
#include "xenia/base/profiling.h"
|
||||||
|
@ -28,8 +26,9 @@
|
||||||
#undef _CRT_NONSTDC_NO_DEPRECATE
|
#undef _CRT_NONSTDC_NO_DEPRECATE
|
||||||
#include "third_party/stb/stb_image_write.h"
|
#include "third_party/stb/stb_image_write.h"
|
||||||
|
|
||||||
DEFINE_string(target_trace_file, "", "Specifies the trace file to load.");
|
DEFINE_string(target_trace_file, "", "Specifies the trace file to load.",
|
||||||
DEFINE_string(trace_dump_path, "", "Output path for dumped files.");
|
"GPU");
|
||||||
|
DEFINE_string(trace_dump_path, "", "Output path for dumped files.", "GPU");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
@ -44,11 +43,11 @@ int TraceDump::Main(const std::vector<std::wstring>& args) {
|
||||||
// Grab path from the flag or unnamed argument.
|
// Grab path from the flag or unnamed argument.
|
||||||
std::wstring path;
|
std::wstring path;
|
||||||
std::wstring output_path;
|
std::wstring output_path;
|
||||||
if (!FLAGS_target_trace_file.empty()) {
|
if (!cvars::target_trace_file.empty()) {
|
||||||
// Passed as a named argument.
|
// Passed as a named argument.
|
||||||
// TODO(benvanik): find something better than gflags that supports
|
// TODO(benvanik): find something better than gflags that supports
|
||||||
// unicode.
|
// unicode.
|
||||||
path = xe::to_wstring(FLAGS_target_trace_file);
|
path = xe::to_wstring(cvars::target_trace_file);
|
||||||
} else if (args.size() >= 2) {
|
} else if (args.size() >= 2) {
|
||||||
// Passed as an unnamed argument.
|
// Passed as an unnamed argument.
|
||||||
path = args[1];
|
path = args[1];
|
||||||
|
@ -79,7 +78,7 @@ int TraceDump::Main(const std::vector<std::wstring>& args) {
|
||||||
// Root file name for outputs.
|
// Root file name for outputs.
|
||||||
if (output_path.empty()) {
|
if (output_path.empty()) {
|
||||||
base_output_path_ =
|
base_output_path_ =
|
||||||
xe::fix_path_separators(xe::to_wstring(FLAGS_trace_dump_path));
|
xe::fix_path_separators(xe::to_wstring(cvars::trace_dump_path));
|
||||||
|
|
||||||
std::wstring output_name =
|
std::wstring output_name =
|
||||||
xe::find_name_from_path(xe::fix_path_separators(path));
|
xe::find_name_from_path(xe::fix_path_separators(path));
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include "xenia/gpu/trace_viewer.h"
|
#include "xenia/gpu/trace_viewer.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
|
|
||||||
#include "third_party/half/include/half.hpp"
|
#include "third_party/half/include/half.hpp"
|
||||||
|
@ -32,7 +30,8 @@
|
||||||
#include "xenia/ui/window.h"
|
#include "xenia/ui/window.h"
|
||||||
#include "xenia/xbox.h"
|
#include "xenia/xbox.h"
|
||||||
|
|
||||||
DEFINE_string(target_trace_file, "", "Specifies the trace file to load.");
|
DEFINE_string(target_trace_file, "", "Specifies the trace file to load.",
|
||||||
|
"GPU");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
@ -53,11 +52,11 @@ TraceViewer::~TraceViewer() = default;
|
||||||
int TraceViewer::Main(const std::vector<std::wstring>& args) {
|
int TraceViewer::Main(const std::vector<std::wstring>& args) {
|
||||||
// Grab path from the flag or unnamed argument.
|
// Grab path from the flag or unnamed argument.
|
||||||
std::wstring path;
|
std::wstring path;
|
||||||
if (!FLAGS_target_trace_file.empty()) {
|
if (!cvars::target_trace_file.empty()) {
|
||||||
// Passed as a named argument.
|
// Passed as a named argument.
|
||||||
// TODO(benvanik): find something better than gflags that supports
|
// TODO(benvanik): find something better than gflags that supports
|
||||||
// unicode.
|
// unicode.
|
||||||
path = xe::to_wstring(FLAGS_target_trace_file);
|
path = xe::to_wstring(cvars::target_trace_file);
|
||||||
} else if (args.size() >= 2) {
|
} else if (args.size() >= 2) {
|
||||||
// Passed as an unnamed argument.
|
// Passed as an unnamed argument.
|
||||||
path = args[1];
|
path = args[1];
|
||||||
|
|
|
@ -347,7 +347,7 @@ VkPipeline PipelineCache::GetPipeline(const RenderState* render_state,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dump shader disassembly.
|
// Dump shader disassembly.
|
||||||
if (FLAGS_vulkan_dump_disasm) {
|
if (cvars::vulkan_dump_disasm) {
|
||||||
if (device_->HasEnabledExtension(VK_AMD_SHADER_INFO_EXTENSION_NAME)) {
|
if (device_->HasEnabledExtension(VK_AMD_SHADER_INFO_EXTENSION_NAME)) {
|
||||||
DumpShaderDisasmAMD(pipeline);
|
DumpShaderDisasmAMD(pipeline);
|
||||||
} else if (device_->device_info().properties.vendorID == 0x10DE) {
|
} else if (device_->device_info().properties.vendorID == 0x10DE) {
|
||||||
|
@ -387,8 +387,8 @@ bool PipelineCache::TranslateShader(VulkanShader* shader,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dump shader files if desired.
|
// Dump shader files if desired.
|
||||||
if (!FLAGS_dump_shaders.empty()) {
|
if (!cvars::dump_shaders.empty()) {
|
||||||
shader->Dump(FLAGS_dump_shaders, "vk");
|
shader->Dump(cvars::dump_shaders, "vk");
|
||||||
}
|
}
|
||||||
|
|
||||||
return shader->is_valid();
|
return shader->is_valid();
|
||||||
|
@ -1398,7 +1398,7 @@ PipelineCache::UpdateStatus PipelineCache::UpdateMultisampleState() {
|
||||||
// PA_SU_SC_MODE_CNTL MSAA_ENABLE (0x10000)
|
// PA_SU_SC_MODE_CNTL MSAA_ENABLE (0x10000)
|
||||||
// If set, all samples will be sampled at set locations. Otherwise, they're
|
// If set, all samples will be sampled at set locations. Otherwise, they're
|
||||||
// all sampled from the pixel center.
|
// all sampled from the pixel center.
|
||||||
if (FLAGS_vulkan_native_msaa) {
|
if (cvars::vulkan_native_msaa) {
|
||||||
auto msaa_num_samples =
|
auto msaa_num_samples =
|
||||||
static_cast<MsaaSamples>((regs.rb_surface_info >> 16) & 0x3);
|
static_cast<MsaaSamples>((regs.rb_surface_info >> 16) & 0x3);
|
||||||
switch (msaa_num_samples) {
|
switch (msaa_num_samples) {
|
||||||
|
|
|
@ -17,9 +17,6 @@ project("xenia-gpu-vulkan")
|
||||||
})
|
})
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
|
||||||
local_platform_files()
|
local_platform_files()
|
||||||
files({
|
files({
|
||||||
"shaders/bin/*.h",
|
"shaders/bin/*.h",
|
||||||
|
@ -34,7 +31,6 @@ project("xenia-gpu-vulkan-trace-viewer")
|
||||||
links({
|
links({
|
||||||
"aes_128",
|
"aes_128",
|
||||||
"capstone",
|
"capstone",
|
||||||
"gflags",
|
|
||||||
"glslang-spirv",
|
"glslang-spirv",
|
||||||
"imgui",
|
"imgui",
|
||||||
"libavcodec",
|
"libavcodec",
|
||||||
|
@ -62,9 +58,6 @@ project("xenia-gpu-vulkan-trace-viewer")
|
||||||
})
|
})
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
|
||||||
files({
|
files({
|
||||||
"vulkan_trace_viewer_main.cc",
|
"vulkan_trace_viewer_main.cc",
|
||||||
"../../base/main_"..platform_suffix..".cc",
|
"../../base/main_"..platform_suffix..".cc",
|
||||||
|
@ -91,7 +84,6 @@ project("xenia-gpu-vulkan-trace-viewer")
|
||||||
if not os.isfile(user_file) then
|
if not os.isfile(user_file) then
|
||||||
debugdir(project_root)
|
debugdir(project_root)
|
||||||
debugargs({
|
debugargs({
|
||||||
"--flagfile=scratch/flags.txt",
|
|
||||||
"2>&1",
|
"2>&1",
|
||||||
"1>scratch/stdout-trace-viewer.txt",
|
"1>scratch/stdout-trace-viewer.txt",
|
||||||
})
|
})
|
||||||
|
@ -105,7 +97,6 @@ project("xenia-gpu-vulkan-trace-dump")
|
||||||
links({
|
links({
|
||||||
"aes_128",
|
"aes_128",
|
||||||
"capstone",
|
"capstone",
|
||||||
"gflags",
|
|
||||||
"glslang-spirv",
|
"glslang-spirv",
|
||||||
"imgui",
|
"imgui",
|
||||||
"libavcodec",
|
"libavcodec",
|
||||||
|
@ -133,9 +124,6 @@ project("xenia-gpu-vulkan-trace-dump")
|
||||||
})
|
})
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
|
||||||
files({
|
files({
|
||||||
"vulkan_trace_dump_main.cc",
|
"vulkan_trace_dump_main.cc",
|
||||||
"../../base/main_"..platform_suffix..".cc",
|
"../../base/main_"..platform_suffix..".cc",
|
||||||
|
@ -156,7 +144,6 @@ project("xenia-gpu-vulkan-trace-dump")
|
||||||
if not os.isfile(user_file) then
|
if not os.isfile(user_file) then
|
||||||
debugdir(project_root)
|
debugdir(project_root)
|
||||||
debugargs({
|
debugargs({
|
||||||
"--flagfile=scratch/flags.txt",
|
|
||||||
"2>&1",
|
"2>&1",
|
||||||
"1>scratch/stdout-trace-dump.txt",
|
"1>scratch/stdout-trace-dump.txt",
|
||||||
})
|
})
|
||||||
|
|
|
@ -194,7 +194,7 @@ VkResult CachedTileView::Initialize(VkCommandBuffer command_buffer) {
|
||||||
image_info.extent.depth = 1;
|
image_info.extent.depth = 1;
|
||||||
image_info.mipLevels = 1;
|
image_info.mipLevels = 1;
|
||||||
image_info.arrayLayers = 1;
|
image_info.arrayLayers = 1;
|
||||||
if (FLAGS_vulkan_native_msaa) {
|
if (cvars::vulkan_native_msaa) {
|
||||||
auto msaa_samples = static_cast<MsaaSamples>(key.msaa_samples);
|
auto msaa_samples = static_cast<MsaaSamples>(key.msaa_samples);
|
||||||
switch (msaa_samples) {
|
switch (msaa_samples) {
|
||||||
case MsaaSamples::k1X:
|
case MsaaSamples::k1X:
|
||||||
|
@ -422,7 +422,7 @@ CachedRenderPass::~CachedRenderPass() {
|
||||||
|
|
||||||
VkResult CachedRenderPass::Initialize() {
|
VkResult CachedRenderPass::Initialize() {
|
||||||
VkSampleCountFlagBits sample_count;
|
VkSampleCountFlagBits sample_count;
|
||||||
if (FLAGS_vulkan_native_msaa) {
|
if (cvars::vulkan_native_msaa) {
|
||||||
switch (config.surface_msaa) {
|
switch (config.surface_msaa) {
|
||||||
case MsaaSamples::k1X:
|
case MsaaSamples::k1X:
|
||||||
sample_count = VK_SAMPLE_COUNT_1_BIT;
|
sample_count = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
@ -534,7 +534,7 @@ VkResult CachedRenderPass::Initialize() {
|
||||||
bool CachedRenderPass::IsCompatible(
|
bool CachedRenderPass::IsCompatible(
|
||||||
const RenderConfiguration& desired_config) const {
|
const RenderConfiguration& desired_config) const {
|
||||||
if (config.surface_msaa != desired_config.surface_msaa &&
|
if (config.surface_msaa != desired_config.surface_msaa &&
|
||||||
FLAGS_vulkan_native_msaa) {
|
cvars::vulkan_native_msaa) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1040,7 +1040,7 @@ bool TextureCache::UploadTexture(VkCommandBuffer command_buffer,
|
||||||
unpack_offset += ComputeMipStorage(src, mip);
|
unpack_offset += ComputeMipStorage(src, mip);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_texture_dump) {
|
if (cvars::texture_dump) {
|
||||||
TextureDump(src, unpack_buffer, unpack_length);
|
TextureDump(src, unpack_buffer, unpack_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -356,7 +356,7 @@ void VulkanCommandProcessor::BeginFrame() {
|
||||||
// The capture will end when these commands are submitted to the queue.
|
// The capture will end when these commands are submitted to the queue.
|
||||||
static uint32_t frame = 0;
|
static uint32_t frame = 0;
|
||||||
if (device_->is_renderdoc_attached() && !capturing_ &&
|
if (device_->is_renderdoc_attached() && !capturing_ &&
|
||||||
(FLAGS_vulkan_renderdoc_capture_all || trace_requested_)) {
|
(cvars::vulkan_renderdoc_capture_all || trace_requested_)) {
|
||||||
if (queue_mutex_) {
|
if (queue_mutex_) {
|
||||||
queue_mutex_->lock();
|
queue_mutex_->lock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "xenia/gpu/vulkan/vulkan_gpu_flags.h"
|
#include "xenia/gpu/vulkan/vulkan_gpu_flags.h"
|
||||||
|
|
||||||
DEFINE_bool(vulkan_renderdoc_capture_all, false,
|
DEFINE_bool(vulkan_renderdoc_capture_all, false,
|
||||||
"Capture everything with RenderDoc.");
|
"Capture everything with RenderDoc.", "Vulkan");
|
||||||
DEFINE_bool(vulkan_native_msaa, false, "Use native MSAA");
|
DEFINE_bool(vulkan_native_msaa, false, "Use native MSAA", "Vulkan");
|
||||||
DEFINE_bool(vulkan_dump_disasm, false,
|
DEFINE_bool(vulkan_dump_disasm, false,
|
||||||
"Dump shader disassembly. NVIDIA only supported.");
|
"Dump shader disassembly. NVIDIA only supported.", "Vulkan");
|
||||||
|
|
|
@ -10,9 +10,8 @@
|
||||||
#ifndef XENIA_GPU_VULKAN_VULKAN_GPU_FLAGS_H_
|
#ifndef XENIA_GPU_VULKAN_VULKAN_GPU_FLAGS_H_
|
||||||
#define XENIA_GPU_VULKAN_VULKAN_GPU_FLAGS_H_
|
#define XENIA_GPU_VULKAN_VULKAN_GPU_FLAGS_H_
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#define FINE_GRAINED_DRAW_SCOPES 1
|
#define FINE_GRAINED_DRAW_SCOPES 1
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
|
|
||||||
DECLARE_bool(vulkan_renderdoc_capture_all);
|
DECLARE_bool(vulkan_renderdoc_capture_all);
|
||||||
DECLARE_bool(vulkan_native_msaa);
|
DECLARE_bool(vulkan_native_msaa);
|
||||||
|
|
|
@ -7,12 +7,11 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "third_party/imgui/imgui.h"
|
#include "third_party/imgui/imgui.h"
|
||||||
#include "xenia/base/clock.h"
|
#include "xenia/base/clock.h"
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/main.h"
|
#include "xenia/base/main.h"
|
||||||
#include "xenia/base/threading.h"
|
#include "xenia/base/threading.h"
|
||||||
|
@ -28,7 +27,8 @@
|
||||||
#include "xenia/hid/xinput/xinput_hid.h"
|
#include "xenia/hid/xinput/xinput_hid.h"
|
||||||
#endif // XE_PLATFORM_WIN32
|
#endif // XE_PLATFORM_WIN32
|
||||||
|
|
||||||
DEFINE_string(hid, "any", "Input system. Use: [any, nop, winkey, xinput]");
|
DEFINE_string(hid, "any", "Input system. Use: [any, nop, winkey, xinput]",
|
||||||
|
"General");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace hid {
|
namespace hid {
|
||||||
|
@ -38,12 +38,12 @@ std::unique_ptr<xe::hid::InputSystem> input_system_;
|
||||||
std::vector<std::unique_ptr<hid::InputDriver>> CreateInputDrivers(
|
std::vector<std::unique_ptr<hid::InputDriver>> CreateInputDrivers(
|
||||||
ui::Window* window) {
|
ui::Window* window) {
|
||||||
std::vector<std::unique_ptr<hid::InputDriver>> drivers;
|
std::vector<std::unique_ptr<hid::InputDriver>> drivers;
|
||||||
if (FLAGS_hid.compare("nop") == 0) {
|
if (cvars::hid.compare("nop") == 0) {
|
||||||
drivers.emplace_back(xe::hid::nop::Create(window));
|
drivers.emplace_back(xe::hid::nop::Create(window));
|
||||||
#if XE_PLATFORM_WIN32
|
#if XE_PLATFORM_WIN32
|
||||||
} else if (FLAGS_hid.compare("winkey") == 0) {
|
} else if (cvars::hid.compare("winkey") == 0) {
|
||||||
drivers.emplace_back(xe::hid::winkey::Create(window));
|
drivers.emplace_back(xe::hid::winkey::Create(window));
|
||||||
} else if (FLAGS_hid.compare("xinput") == 0) {
|
} else if (cvars::hid.compare("xinput") == 0) {
|
||||||
drivers.emplace_back(xe::hid::xinput::Create(window));
|
drivers.emplace_back(xe::hid::xinput::Create(window));
|
||||||
#endif // XE_PLATFORM_WIN32
|
#endif // XE_PLATFORM_WIN32
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -10,6 +10,4 @@
|
||||||
#ifndef XENIA_HID_HID_FLAGS_H_
|
#ifndef XENIA_HID_HID_FLAGS_H_
|
||||||
#define XENIA_HID_HID_FLAGS_H_
|
#define XENIA_HID_HID_FLAGS_H_
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#endif // XENIA_HID_HID_FLAGS_H_
|
#endif // XENIA_HID_HID_FLAGS_H_
|
||||||
|
|
|
@ -12,7 +12,4 @@ project("xenia-hid-nop")
|
||||||
})
|
})
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
|
||||||
local_platform_files()
|
local_platform_files()
|
||||||
|
|
|
@ -11,9 +11,6 @@ project("xenia-hid")
|
||||||
})
|
})
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
|
||||||
local_platform_files()
|
local_platform_files()
|
||||||
removefiles({"*_demo.cc"})
|
removefiles({"*_demo.cc"})
|
||||||
|
|
||||||
|
@ -23,7 +20,6 @@ project("xenia-hid-demo")
|
||||||
kind("WindowedApp")
|
kind("WindowedApp")
|
||||||
language("C++")
|
language("C++")
|
||||||
links({
|
links({
|
||||||
"gflags",
|
|
||||||
"glew",
|
"glew",
|
||||||
"imgui",
|
"imgui",
|
||||||
"volk",
|
"volk",
|
||||||
|
@ -37,9 +33,6 @@ project("xenia-hid-demo")
|
||||||
"GLEW_STATIC=1",
|
"GLEW_STATIC=1",
|
||||||
"GLEW_MX=1",
|
"GLEW_MX=1",
|
||||||
})
|
})
|
||||||
includedirs({
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
|
||||||
files({
|
files({
|
||||||
"hid_demo.cc",
|
"hid_demo.cc",
|
||||||
"../base/main_"..platform_suffix..".cc",
|
"../base/main_"..platform_suffix..".cc",
|
||||||
|
|
|
@ -13,7 +13,4 @@ project("xenia-hid-winkey")
|
||||||
})
|
})
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
|
||||||
local_platform_files()
|
local_platform_files()
|
||||||
|
|
|
@ -12,7 +12,4 @@ project("xenia-hid-xinput")
|
||||||
})
|
})
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
|
||||||
local_platform_files()
|
local_platform_files()
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xenia/kernel/kernel_flags.h"
|
||||||
|
|
||||||
|
DEFINE_bool(headless, false,
|
||||||
|
"Don't display any UI, using defaults for prompts as needed.",
|
||||||
|
"Other");
|
||||||
|
DEFINE_bool(log_high_frequency_kernel_calls, false,
|
||||||
|
"Log kernel calls with the kHighFrequency tag.", "Kernel");
|
|
@ -0,0 +1,17 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_KERNEL_KERNEL_FLAGS_H_
|
||||||
|
#define XENIA_KERNEL_KERNEL_FLAGS_H_
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
|
|
||||||
|
DECLARE_bool(headless);
|
||||||
|
DECLARE_bool(log_high_frequency_kernel_calls);
|
||||||
|
|
||||||
|
#endif // XENIA_KERNEL_KERNEL_FLAGS_H_
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include "xenia/kernel/kernel_state.h"
|
#include "xenia/kernel/kernel_state.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "xenia/base/assert.h"
|
#include "xenia/base/assert.h"
|
||||||
|
@ -29,9 +27,6 @@
|
||||||
#include "xenia/kernel/xobject.h"
|
#include "xenia/kernel/xobject.h"
|
||||||
#include "xenia/kernel/xthread.h"
|
#include "xenia/kernel/xthread.h"
|
||||||
|
|
||||||
DEFINE_bool(headless, false,
|
|
||||||
"Don't display any UI, using defaults for prompts as needed.");
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
#ifndef XENIA_KERNEL_KERNEL_STATE_H_
|
#ifndef XENIA_KERNEL_KERNEL_STATE_H_
|
||||||
#define XENIA_KERNEL_KERNEL_STATE_H_
|
#define XENIA_KERNEL_KERNEL_STATE_H_
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
@ -20,6 +18,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "xenia/base/bit_map.h"
|
#include "xenia/base/bit_map.h"
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
#include "xenia/base/mutex.h"
|
#include "xenia/base/mutex.h"
|
||||||
#include "xenia/cpu/export_resolver.h"
|
#include "xenia/cpu/export_resolver.h"
|
||||||
#include "xenia/kernel/util/native_list.h"
|
#include "xenia/kernel/util/native_list.h"
|
||||||
|
@ -39,8 +38,6 @@ class Processor;
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
||||||
DECLARE_bool(headless);
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,6 @@ project("xenia-kernel")
|
||||||
})
|
})
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
|
||||||
recursive_platform_files()
|
recursive_platform_files()
|
||||||
files({
|
files({
|
||||||
"debug_visualizers.natvis",
|
"debug_visualizers.natvis",
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "xenia/kernel/xfile.h"
|
#include "xenia/kernel/xfile.h"
|
||||||
#include "xenia/kernel/xthread.h"
|
#include "xenia/kernel/xthread.h"
|
||||||
|
|
||||||
DEFINE_bool(xex_apply_patches, true, "Apply XEX patches.");
|
DEFINE_bool(xex_apply_patches, true, "Apply XEX patches.", "Kernel");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
@ -102,7 +102,7 @@ X_STATUS UserModule::LoadFromFile(std::string path) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_xex_apply_patches) {
|
if (cvars::xex_apply_patches) {
|
||||||
// Search for xexp patch file
|
// Search for xexp patch file
|
||||||
auto patch_entry = kernel_state()->file_system()->ResolvePath(path_ + "p");
|
auto patch_entry = kernel_state()->file_system()->ResolvePath(path_ + "p");
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,6 @@
|
||||||
|
|
||||||
#include "xenia/kernel/util/shim_utils.h"
|
#include "xenia/kernel/util/shim_utils.h"
|
||||||
|
|
||||||
DEFINE_bool(log_high_frequency_kernel_calls, false,
|
|
||||||
"Log kernel calls with the kHighFrequency tag.");
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
namespace shim {
|
namespace shim {
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
#ifndef XENIA_KERNEL_UTIL_SHIM_UTILS_H_
|
#ifndef XENIA_KERNEL_UTIL_SHIM_UTILS_H_
|
||||||
#define XENIA_KERNEL_UTIL_SHIM_UTILS_H_
|
#define XENIA_KERNEL_UTIL_SHIM_UTILS_H_
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -21,10 +19,9 @@
|
||||||
#include "xenia/base/string_buffer.h"
|
#include "xenia/base/string_buffer.h"
|
||||||
#include "xenia/cpu/export_resolver.h"
|
#include "xenia/cpu/export_resolver.h"
|
||||||
#include "xenia/cpu/ppc/ppc_context.h"
|
#include "xenia/cpu/ppc/ppc_context.h"
|
||||||
|
#include "xenia/kernel/kernel_flags.h"
|
||||||
#include "xenia/kernel/kernel_state.h"
|
#include "xenia/kernel/kernel_state.h"
|
||||||
|
|
||||||
DECLARE_bool(log_high_frequency_kernel_calls);
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
|
||||||
|
@ -482,7 +479,7 @@ xe::cpu::Export* RegisterExport(R (*fn)(Ps&...), const char* name,
|
||||||
auto params = std::make_tuple<Ps...>(Ps(init)...);
|
auto params = std::make_tuple<Ps...>(Ps(init)...);
|
||||||
if (export_entry->tags & xe::cpu::ExportTag::kLog &&
|
if (export_entry->tags & xe::cpu::ExportTag::kLog &&
|
||||||
(!(export_entry->tags & xe::cpu::ExportTag::kHighFrequency) ||
|
(!(export_entry->tags & xe::cpu::ExportTag::kHighFrequency) ||
|
||||||
FLAGS_log_high_frequency_kernel_calls)) {
|
cvars::log_high_frequency_kernel_calls)) {
|
||||||
PrintKernelCall(export_entry, params);
|
PrintKernelCall(export_entry, params);
|
||||||
}
|
}
|
||||||
auto result =
|
auto result =
|
||||||
|
@ -516,7 +513,7 @@ xe::cpu::Export* RegisterExport(void (*fn)(Ps&...), const char* name,
|
||||||
auto params = std::make_tuple<Ps...>(Ps(init)...);
|
auto params = std::make_tuple<Ps...>(Ps(init)...);
|
||||||
if (export_entry->tags & xe::cpu::ExportTag::kLog &&
|
if (export_entry->tags & xe::cpu::ExportTag::kLog &&
|
||||||
(!(export_entry->tags & xe::cpu::ExportTag::kHighFrequency) ||
|
(!(export_entry->tags & xe::cpu::ExportTag::kHighFrequency) ||
|
||||||
FLAGS_log_high_frequency_kernel_calls)) {
|
cvars::log_high_frequency_kernel_calls)) {
|
||||||
PrintKernelCall(export_entry, params);
|
PrintKernelCall(export_entry, params);
|
||||||
}
|
}
|
||||||
KernelTrampoline(FN, std::forward<std::tuple<Ps...>>(params),
|
KernelTrampoline(FN, std::forward<std::tuple<Ps...>>(params),
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/emulator.h"
|
#include "xenia/emulator.h"
|
||||||
|
#include "xenia/kernel/kernel_flags.h"
|
||||||
#include "xenia/kernel/kernel_state.h"
|
#include "xenia/kernel/kernel_state.h"
|
||||||
#include "xenia/kernel/util/shim_utils.h"
|
#include "xenia/kernel/util/shim_utils.h"
|
||||||
#include "xenia/kernel/xam/xam_private.h"
|
#include "xenia/kernel/xam/xam_private.h"
|
||||||
|
@ -43,7 +44,7 @@ dword_result_t XamShowNuiTroubleshooterUI(unknown_t unk1, unknown_t unk2,
|
||||||
// unk1 is 0xFF - possibly user index?
|
// unk1 is 0xFF - possibly user index?
|
||||||
// unk2, unk3 appear to always be zero.
|
// unk2, unk3 appear to always be zero.
|
||||||
|
|
||||||
if (FLAGS_headless) {
|
if (cvars::headless) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "third_party/imgui/imgui.h"
|
#include "third_party/imgui/imgui.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/emulator.h"
|
#include "xenia/emulator.h"
|
||||||
|
#include "xenia/kernel/kernel_flags.h"
|
||||||
#include "xenia/kernel/kernel_state.h"
|
#include "xenia/kernel/kernel_state.h"
|
||||||
#include "xenia/kernel/util/shim_utils.h"
|
#include "xenia/kernel/util/shim_utils.h"
|
||||||
#include "xenia/kernel/xam/xam_private.h"
|
#include "xenia/kernel/xam/xam_private.h"
|
||||||
|
@ -111,7 +112,7 @@ dword_result_t XamShowMessageBoxUI(dword_t user_index, lpwstring_t title_ptr,
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t chosen_button;
|
uint32_t chosen_button;
|
||||||
if (FLAGS_headless) {
|
if (cvars::headless) {
|
||||||
// Auto-pick the focused button.
|
// Auto-pick the focused button.
|
||||||
chosen_button = active_button;
|
chosen_button = active_button;
|
||||||
} else {
|
} else {
|
||||||
|
@ -231,7 +232,7 @@ dword_result_t XamShowKeyboardUI(dword_t user_index, dword_t flags,
|
||||||
return X_ERROR_INVALID_PARAMETER;
|
return X_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_headless) {
|
if (cvars::headless) {
|
||||||
// Redirect default_text back into the buffer.
|
// Redirect default_text back into the buffer.
|
||||||
std::memset(buffer, 0, buffer_length * 2);
|
std::memset(buffer, 0, buffer_length * 2);
|
||||||
if (default_text) {
|
if (default_text) {
|
||||||
|
@ -309,7 +310,7 @@ dword_result_t XamShowDeviceSelectorUI(dword_t user_index, dword_t content_type,
|
||||||
DECLARE_XAM_EXPORT1(XamShowDeviceSelectorUI, kUI, kImplemented);
|
DECLARE_XAM_EXPORT1(XamShowDeviceSelectorUI, kUI, kImplemented);
|
||||||
|
|
||||||
void XamShowDirtyDiscErrorUI(dword_t user_index) {
|
void XamShowDirtyDiscErrorUI(dword_t user_index) {
|
||||||
if (FLAGS_headless) {
|
if (cvars::headless) {
|
||||||
assert_always();
|
assert_always();
|
||||||
exit(1);
|
exit(1);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_module.h"
|
#include "xenia/kernel/xboxkrnl/xboxkrnl_module.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "xenia/base/clock.h"
|
#include "xenia/base/clock.h"
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_module.h"
|
#include "xenia/kernel/xboxkrnl/xboxkrnl_module.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "xenia/base/clock.h"
|
#include "xenia/base/clock.h"
|
||||||
|
@ -47,7 +45,7 @@ void KeDebugMonitorCallback(cpu::ppc::PPCContext* ppc_context,
|
||||||
|
|
||||||
XELOGI("KeDebugMonitorCallback(%u, %08x)", static_cast<uint32_t>(id), arg);
|
XELOGI("KeDebugMonitorCallback(%u, %08x)", static_cast<uint32_t>(id), arg);
|
||||||
|
|
||||||
if (!FLAGS_kernel_pix) {
|
if (!cvars::kernel_pix) {
|
||||||
SHIM_SET_RETURN_32(-1);
|
SHIM_SET_RETURN_32(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_module.h"
|
#include "xenia/kernel/xboxkrnl/xboxkrnl_module.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "xenia/base/clock.h"
|
#include "xenia/base/clock.h"
|
||||||
|
@ -27,18 +25,19 @@
|
||||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_private.h"
|
#include "xenia/kernel/xboxkrnl/xboxkrnl_private.h"
|
||||||
#include "xenia/kernel/xthread.h"
|
#include "xenia/kernel/xthread.h"
|
||||||
|
|
||||||
DEFINE_string(cl, "", "Specify additional command-line provided to guest.");
|
DEFINE_string(cl, "", "Specify additional command-line provided to guest.",
|
||||||
|
"Kernel");
|
||||||
|
|
||||||
DEFINE_bool(kernel_debug_monitor, false, "Enable debug monitor.");
|
DEFINE_bool(kernel_debug_monitor, false, "Enable debug monitor.", "Kernel");
|
||||||
DEFINE_bool(kernel_cert_monitor, false, "Enable cert monitor.");
|
DEFINE_bool(kernel_cert_monitor, false, "Enable cert monitor.", "Kernel");
|
||||||
DEFINE_bool(kernel_pix, false, "Enable PIX.");
|
DEFINE_bool(kernel_pix, false, "Enable PIX.", "Kernel");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
namespace xboxkrnl {
|
namespace xboxkrnl {
|
||||||
|
|
||||||
bool XboxkrnlModule::SendPIXCommand(const char* cmd) {
|
bool XboxkrnlModule::SendPIXCommand(const char* cmd) {
|
||||||
if (!FLAGS_kernel_pix) {
|
if (!cvars::kernel_pix) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +102,7 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
|
||||||
// Offset 0x18 is a 4b pointer to a handler function that seems to take two
|
// Offset 0x18 is a 4b pointer to a handler function that seems to take two
|
||||||
// arguments. If we wanted to see what would happen we could fake that.
|
// arguments. If we wanted to see what would happen we could fake that.
|
||||||
uint32_t pKeDebugMonitorData;
|
uint32_t pKeDebugMonitorData;
|
||||||
if (!FLAGS_kernel_debug_monitor) {
|
if (!cvars::kernel_debug_monitor) {
|
||||||
pKeDebugMonitorData = memory_->SystemHeapAlloc(4);
|
pKeDebugMonitorData = memory_->SystemHeapAlloc(4);
|
||||||
auto lpKeDebugMonitorData = memory_->TranslateVirtual(pKeDebugMonitorData);
|
auto lpKeDebugMonitorData = memory_->TranslateVirtual(pKeDebugMonitorData);
|
||||||
xe::store_and_swap<uint32_t>(lpKeDebugMonitorData, 0);
|
xe::store_and_swap<uint32_t>(lpKeDebugMonitorData, 0);
|
||||||
|
@ -125,7 +124,7 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
|
||||||
// KeCertMonitorData (?*)
|
// KeCertMonitorData (?*)
|
||||||
// Always set to zero, ignored.
|
// Always set to zero, ignored.
|
||||||
uint32_t pKeCertMonitorData;
|
uint32_t pKeCertMonitorData;
|
||||||
if (!FLAGS_kernel_cert_monitor) {
|
if (!cvars::kernel_cert_monitor) {
|
||||||
pKeCertMonitorData = memory_->SystemHeapAlloc(4);
|
pKeCertMonitorData = memory_->SystemHeapAlloc(4);
|
||||||
auto lpKeCertMonitorData = memory_->TranslateVirtual(pKeCertMonitorData);
|
auto lpKeCertMonitorData = memory_->TranslateVirtual(pKeCertMonitorData);
|
||||||
xe::store_and_swap<uint32_t>(lpKeCertMonitorData, 0);
|
xe::store_and_swap<uint32_t>(lpKeCertMonitorData, 0);
|
||||||
|
@ -187,8 +186,8 @@ XboxkrnlModule::XboxkrnlModule(Emulator* emulator, KernelState* kernel_state)
|
||||||
// Always set to "default.xex" (with quotes) for now.
|
// Always set to "default.xex" (with quotes) for now.
|
||||||
// TODO(gibbed): set this to the actual module name.
|
// TODO(gibbed): set this to the actual module name.
|
||||||
std::string command_line("\"default.xex\"");
|
std::string command_line("\"default.xex\"");
|
||||||
if (FLAGS_cl.length()) {
|
if (cvars::cl.length()) {
|
||||||
command_line += " " + FLAGS_cl;
|
command_line += " " + cvars::cl;
|
||||||
}
|
}
|
||||||
uint32_t command_line_length =
|
uint32_t command_line_length =
|
||||||
xe::align(static_cast<uint32_t>(command_line.length()) + 1, 1024u);
|
xe::align(static_cast<uint32_t>(command_line.length()) + 1, 1024u);
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_video.h"
|
#include "xenia/kernel/xboxkrnl/xboxkrnl_video.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/emulator.h"
|
#include "xenia/emulator.h"
|
||||||
#include "xenia/gpu/graphics_system.h"
|
#include "xenia/gpu/graphics_system.h"
|
||||||
|
@ -24,9 +22,11 @@
|
||||||
|
|
||||||
DEFINE_int32(kernel_display_gamma_type, 1,
|
DEFINE_int32(kernel_display_gamma_type, 1,
|
||||||
"Display gamma type: 0 - linear, 1 - sRGB, 2 - TV (BT.709), "
|
"Display gamma type: 0 - linear, 1 - sRGB, 2 - TV (BT.709), "
|
||||||
"3 - power specified via kernel_display_gamma_power.");
|
"3 - power specified via kernel_display_gamma_power.",
|
||||||
|
"Kernel");
|
||||||
DEFINE_double(kernel_display_gamma_power, 2.22222233,
|
DEFINE_double(kernel_display_gamma_power, 2.22222233,
|
||||||
"Display gamma to use with kernel_display_gamma_type 3.");
|
"Display gamma to use with kernel_display_gamma_type 3.",
|
||||||
|
"Kernel");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
@ -51,8 +51,8 @@ void VdGetCurrentDisplayGamma(lpdword_t type_ptr, lpfloat_t power_ptr) {
|
||||||
// 3 - use the power written to *power_ptr.
|
// 3 - use the power written to *power_ptr.
|
||||||
// Anything else - linear.
|
// Anything else - linear.
|
||||||
// Used in D3D SetGammaRamp/SetPWLGamma to adjust the ramp for the display.
|
// Used in D3D SetGammaRamp/SetPWLGamma to adjust the ramp for the display.
|
||||||
*type_ptr = uint32_t(FLAGS_kernel_display_gamma_type);
|
*type_ptr = uint32_t(cvars::kernel_display_gamma_type);
|
||||||
*power_ptr = float(FLAGS_kernel_display_gamma_power);
|
*power_ptr = float(cvars::kernel_display_gamma_power);
|
||||||
}
|
}
|
||||||
DECLARE_XBOXKRNL_EXPORT1(VdGetCurrentDisplayGamma, kVideo, kStub);
|
DECLARE_XBOXKRNL_EXPORT1(VdGetCurrentDisplayGamma, kVideo, kStub);
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include "xenia/kernel/xthread.h"
|
#include "xenia/kernel/xthread.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#ifdef XE_PLATFORM_WIN32
|
#ifdef XE_PLATFORM_WIN32
|
||||||
|
@ -33,9 +31,9 @@
|
||||||
#include "xenia/kernel/xmutant.h"
|
#include "xenia/kernel/xmutant.h"
|
||||||
|
|
||||||
DEFINE_bool(ignore_thread_priorities, true,
|
DEFINE_bool(ignore_thread_priorities, true,
|
||||||
"Ignores game-specified thread priorities.");
|
"Ignores game-specified thread priorities.", "Kernel");
|
||||||
DEFINE_bool(ignore_thread_affinities, true,
|
DEFINE_bool(ignore_thread_affinities, true,
|
||||||
"Ignores game-specified thread affinities.");
|
"Ignores game-specified thread affinities.", "Kernel");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
|
@ -416,7 +414,7 @@ X_STATUS XThread::Create() {
|
||||||
return X_STATUS_NO_MEMORY;
|
return X_STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FLAGS_ignore_thread_affinities) {
|
if (!cvars::ignore_thread_affinities) {
|
||||||
thread_->set_affinity_mask(proc_mask);
|
thread_->set_affinity_mask(proc_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,7 +696,7 @@ void XThread::SetPriority(int32_t increment) {
|
||||||
} else {
|
} else {
|
||||||
target_priority = xe::threading::ThreadPriority::kNormal;
|
target_priority = xe::threading::ThreadPriority::kNormal;
|
||||||
}
|
}
|
||||||
if (!FLAGS_ignore_thread_priorities) {
|
if (!cvars::ignore_thread_priorities) {
|
||||||
thread_->set_priority(target_priority);
|
thread_->set_priority(target_priority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -719,7 +717,7 @@ void XThread::SetAffinity(uint32_t affinity) {
|
||||||
}
|
}
|
||||||
SetActiveCpu(GetFakeCpuNumber(affinity));
|
SetActiveCpu(GetFakeCpuNumber(affinity));
|
||||||
affinity_ = affinity;
|
affinity_ = affinity;
|
||||||
if (!FLAGS_ignore_thread_affinities) {
|
if (!cvars::ignore_thread_affinities) {
|
||||||
thread_->set_affinity_mask(affinity);
|
thread_->set_affinity_mask(affinity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,13 +9,12 @@
|
||||||
|
|
||||||
#include "xenia/memory.h"
|
#include "xenia/memory.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "xenia/base/byte_stream.h"
|
#include "xenia/base/byte_stream.h"
|
||||||
#include "xenia/base/clock.h"
|
#include "xenia/base/clock.h"
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/math.h"
|
#include "xenia/base/math.h"
|
||||||
#include "xenia/base/threading.h"
|
#include "xenia/base/threading.h"
|
||||||
|
@ -24,15 +23,14 @@
|
||||||
// TODO(benvanik): move xbox.h out
|
// TODO(benvanik): move xbox.h out
|
||||||
#include "xenia/xbox.h"
|
#include "xenia/xbox.h"
|
||||||
|
|
||||||
DEFINE_bool(protect_zero, true, "Protect the zero page from reads and writes.");
|
DEFINE_bool(protect_zero, true, "Protect the zero page from reads and writes.",
|
||||||
|
"Memory");
|
||||||
DEFINE_bool(protect_on_release, false,
|
DEFINE_bool(protect_on_release, false,
|
||||||
"Protect released memory to prevent accesses.");
|
"Protect released memory to prevent accesses.", "Memory");
|
||||||
|
|
||||||
DEFINE_bool(scribble_heap, false,
|
DEFINE_bool(scribble_heap, false,
|
||||||
"Scribble 0xCD into all allocated heap memory.");
|
"Scribble 0xCD into all allocated heap memory.", "Memory");
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
|
||||||
uint32_t get_page_count(uint32_t value, uint32_t page_size) {
|
uint32_t get_page_count(uint32_t value, uint32_t page_size) {
|
||||||
return xe::round_up(value, page_size) / page_size;
|
return xe::round_up(value, page_size) / page_size;
|
||||||
}
|
}
|
||||||
|
@ -54,10 +52,10 @@ uint32_t get_page_count(uint32_t value, uint32_t page_size) {
|
||||||
*
|
*
|
||||||
* We create our own heap of committed memory that lives at
|
* We create our own heap of committed memory that lives at
|
||||||
* memory_HEAP_LOW to memory_HEAP_HIGH - all normal user allocations
|
* memory_HEAP_LOW to memory_HEAP_HIGH - all normal user allocations
|
||||||
* come from there. Since the Xbox has no paging, we know that the size of this
|
* come from there. Since the Xbox has no paging, we know that the size of
|
||||||
* heap will never need to be larger than ~512MB (realistically, smaller than
|
* this heap will never need to be larger than ~512MB (realistically, smaller
|
||||||
* that). We place it far away from the XEX data and keep the memory around it
|
* than that). We place it far away from the XEX data and keep the memory
|
||||||
* uncommitted so that we have some warning if things go astray.
|
* around it uncommitted so that we have some warning if things go astray.
|
||||||
*
|
*
|
||||||
* For XEX/GPU/etc data we allow placement allocations (base_address != 0) and
|
* For XEX/GPU/etc data we allow placement allocations (base_address != 0) and
|
||||||
* commit the requested memory as needed. This bypasses the standard heap, but
|
* commit the requested memory as needed. This bypasses the standard heap, but
|
||||||
|
@ -175,8 +173,8 @@ bool Memory::Initialize() {
|
||||||
heaps_.v00000000.AllocFixed(
|
heaps_.v00000000.AllocFixed(
|
||||||
0x00000000, 0x10000, 0x10000,
|
0x00000000, 0x10000, 0x10000,
|
||||||
kMemoryAllocationReserve | kMemoryAllocationCommit,
|
kMemoryAllocationReserve | kMemoryAllocationCommit,
|
||||||
!FLAGS_protect_zero ? kMemoryProtectRead | kMemoryProtectWrite
|
!cvars::protect_zero ? kMemoryProtectRead | kMemoryProtectWrite
|
||||||
: kMemoryProtectNoAccess);
|
: kMemoryProtectNoAccess);
|
||||||
heaps_.physical.AllocFixed(0x1FFF0000, 0x10000, 0x10000,
|
heaps_.physical.AllocFixed(0x1FFF0000, 0x10000, 0x10000,
|
||||||
kMemoryAllocationReserve, kMemoryProtectNoAccess);
|
kMemoryAllocationReserve, kMemoryProtectNoAccess);
|
||||||
|
|
||||||
|
@ -763,7 +761,7 @@ bool BaseHeap::AllocFixed(uint32_t base_address, uint32_t size,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_scribble_heap && protect & kMemoryProtectWrite) {
|
if (cvars::scribble_heap && protect & kMemoryProtectWrite) {
|
||||||
std::memset(result, 0xCD, page_count * page_size_);
|
std::memset(result, 0xCD, page_count * page_size_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -911,7 +909,7 @@ bool BaseHeap::AllocRange(uint32_t low_address, uint32_t high_address,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_scribble_heap && (protect & kMemoryProtectWrite)) {
|
if (cvars::scribble_heap && (protect & kMemoryProtectWrite)) {
|
||||||
std::memset(result, 0xCD, page_count * page_size_);
|
std::memset(result, 0xCD, page_count * page_size_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -996,10 +994,10 @@ bool BaseHeap::Release(uint32_t base_address, uint32_t* out_region_size) {
|
||||||
xe::memory::page_size() ==
|
xe::memory::page_size() ==
|
||||||
0 &&
|
0 &&
|
||||||
((base_page_number * page_size_) % xe::memory::page_size() == 0))) {
|
((base_page_number * page_size_) % xe::memory::page_size() == 0))) {
|
||||||
// TODO(benvanik): figure out why games are using memory after releasing it.
|
// TODO(benvanik): figure out why games are using memory after releasing
|
||||||
// It's possible this is some virtual/physical stuff where the GPU still can
|
// it. It's possible this is some virtual/physical stuff where the GPU
|
||||||
// access it.
|
// still can access it.
|
||||||
if (FLAGS_protect_on_release) {
|
if (cvars::protect_on_release) {
|
||||||
if (!xe::memory::Protect(
|
if (!xe::memory::Protect(
|
||||||
membase_ + heap_base_ + base_page_number * page_size_,
|
membase_ + heap_base_ + base_page_number * page_size_,
|
||||||
base_page_entry.region_page_count * page_size_,
|
base_page_entry.region_page_count * page_size_,
|
||||||
|
@ -1211,7 +1209,8 @@ bool PhysicalHeap::Alloc(uint32_t size, uint32_t alignment,
|
||||||
bool top_down, uint32_t* out_address) {
|
bool top_down, uint32_t* out_address) {
|
||||||
*out_address = 0;
|
*out_address = 0;
|
||||||
|
|
||||||
// Default top-down. Since parent heap is bottom-up this prevents collisions.
|
// Default top-down. Since parent heap is bottom-up this prevents
|
||||||
|
// collisions.
|
||||||
top_down = true;
|
top_down = true;
|
||||||
|
|
||||||
// Adjust alignment size our page size differs from the parent.
|
// Adjust alignment size our page size differs from the parent.
|
||||||
|
|
|
@ -11,7 +11,4 @@ project("xenia-core")
|
||||||
})
|
})
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
|
||||||
files({"*.h", "*.cc"})
|
files({"*.h", "*.cc"})
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
#include "api_scanner_loader.h"
|
#include "api_scanner_loader.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
@ -20,8 +19,8 @@ int api_scanner_main(std::vector<std::wstring>& args) {
|
||||||
|
|
||||||
if (args.size() == 2 || !FLAGS_target.empty()) {
|
if (args.size() == 2 || !FLAGS_target.empty()) {
|
||||||
apiscanner_loader loader_;
|
apiscanner_loader loader_;
|
||||||
std::wstring target(FLAGS_target.empty() ? args[1]
|
std::wstring target(cvars::target.empty() ? args[1]
|
||||||
: xe::to_wstring(FLAGS_target));
|
: xe::to_wstring(cvars::target));
|
||||||
|
|
||||||
std::wstring target_abs = xe::to_absolute_path(target);
|
std::wstring target_abs = xe::to_absolute_path(target);
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,5 @@ project("xenia-ui")
|
||||||
})
|
})
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
})
|
|
||||||
local_platform_files()
|
local_platform_files()
|
||||||
removefiles({"*_demo.cc"})
|
removefiles({"*_demo.cc"})
|
||||||
|
|
|
@ -14,7 +14,6 @@ project("xenia-ui-spirv")
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
includedirs({
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
project_root.."/third_party/spirv-tools/external/include",
|
project_root.."/third_party/spirv-tools/external/include",
|
||||||
})
|
})
|
||||||
local_platform_files()
|
local_platform_files()
|
||||||
|
|
|
@ -14,7 +14,6 @@ project("xenia-ui-vulkan")
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
includedirs({
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
project_root.."/third_party/vulkan/",
|
project_root.."/third_party/vulkan/",
|
||||||
})
|
})
|
||||||
local_platform_files()
|
local_platform_files()
|
||||||
|
@ -29,7 +28,6 @@ project("xenia-ui-window-vulkan-demo")
|
||||||
kind("WindowedApp")
|
kind("WindowedApp")
|
||||||
language("C++")
|
language("C++")
|
||||||
links({
|
links({
|
||||||
"gflags",
|
|
||||||
"imgui",
|
"imgui",
|
||||||
"volk",
|
"volk",
|
||||||
"xenia-base",
|
"xenia-base",
|
||||||
|
@ -40,7 +38,6 @@ project("xenia-ui-window-vulkan-demo")
|
||||||
defines({
|
defines({
|
||||||
})
|
})
|
||||||
includedirs({
|
includedirs({
|
||||||
project_root.."/third_party/gflags/src",
|
|
||||||
project_root.."/third_party/vulkan/",
|
project_root.."/third_party/vulkan/",
|
||||||
})
|
})
|
||||||
files({
|
files({
|
||||||
|
|
|
@ -9,8 +9,10 @@
|
||||||
|
|
||||||
#include "xenia/ui/vulkan/vulkan.h"
|
#include "xenia/ui/vulkan/vulkan.h"
|
||||||
|
|
||||||
DEFINE_bool(vulkan_validation, false, "Enable Vulkan validation layers.");
|
DEFINE_bool(vulkan_validation, false, "Enable Vulkan validation layers.",
|
||||||
|
"Vulkan");
|
||||||
|
|
||||||
DEFINE_bool(vulkan_primary_queue_only, false,
|
DEFINE_bool(vulkan_primary_queue_only, false,
|
||||||
"Force the use of the primary queue, ignoring any additional that "
|
"Force the use of the primary queue, ignoring any additional that "
|
||||||
"may be present.");
|
"may be present.",
|
||||||
|
"Vulkan");
|
||||||
|
|
|
@ -10,8 +10,6 @@
|
||||||
#ifndef XENIA_UI_VULKAN_VULKAN_H_
|
#ifndef XENIA_UI_VULKAN_VULKAN_H_
|
||||||
#define XENIA_UI_VULKAN_VULKAN_H_
|
#define XENIA_UI_VULKAN_VULKAN_H_
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include "xenia/base/platform.h"
|
#include "xenia/base/platform.h"
|
||||||
|
|
||||||
#if XE_PLATFORM_WIN32
|
#if XE_PLATFORM_WIN32
|
||||||
|
@ -25,6 +23,7 @@
|
||||||
// We use a loader with its own function prototypes.
|
// We use a loader with its own function prototypes.
|
||||||
#include "third_party/volk/volk.h"
|
#include "third_party/volk/volk.h"
|
||||||
#include "third_party/vulkan/vulkan.h"
|
#include "third_party/vulkan/vulkan.h"
|
||||||
|
#include "xenia/base/cvar.h"
|
||||||
|
|
||||||
#define XELOGVK XELOGI
|
#define XELOGVK XELOGI
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include "xenia/ui/vulkan/vulkan_device.h"
|
#include "xenia/ui/vulkan/vulkan_device.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -33,7 +31,7 @@ namespace ui {
|
||||||
namespace vulkan {
|
namespace vulkan {
|
||||||
|
|
||||||
VulkanDevice::VulkanDevice(VulkanInstance* instance) : instance_(instance) {
|
VulkanDevice::VulkanDevice(VulkanInstance* instance) : instance_(instance) {
|
||||||
if (FLAGS_vulkan_validation) {
|
if (cvars::vulkan_validation) {
|
||||||
DeclareRequiredLayer("VK_LAYER_LUNARG_standard_validation",
|
DeclareRequiredLayer("VK_LAYER_LUNARG_standard_validation",
|
||||||
Version::Make(0, 0, 0), true);
|
Version::Make(0, 0, 0), true);
|
||||||
// DeclareRequiredLayer("VK_LAYER_GOOGLE_unique_objects", Version::Make(0,
|
// DeclareRequiredLayer("VK_LAYER_GOOGLE_unique_objects", Version::Make(0,
|
||||||
|
@ -150,7 +148,7 @@ bool VulkanDevice::Initialize(DeviceInfo device_info) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some tools *cough* renderdoc *cough* can't handle multiple queues.
|
// Some tools *cough* renderdoc *cough* can't handle multiple queues.
|
||||||
if (FLAGS_vulkan_primary_queue_only) {
|
if (cvars::vulkan_primary_queue_only) {
|
||||||
queue_count = 1;
|
queue_count = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
#include "xenia/ui/vulkan/vulkan_instance.h"
|
#include "xenia/ui/vulkan/vulkan_instance.h"
|
||||||
|
|
||||||
#include <gflags/gflags.h>
|
|
||||||
|
|
||||||
#include <cinttypes>
|
#include <cinttypes>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -38,7 +36,7 @@ namespace ui {
|
||||||
namespace vulkan {
|
namespace vulkan {
|
||||||
|
|
||||||
VulkanInstance::VulkanInstance() {
|
VulkanInstance::VulkanInstance() {
|
||||||
if (FLAGS_vulkan_validation) {
|
if (cvars::vulkan_validation) {
|
||||||
DeclareRequiredLayer("VK_LAYER_LUNARG_standard_validation",
|
DeclareRequiredLayer("VK_LAYER_LUNARG_standard_validation",
|
||||||
Version::Make(0, 0, 0), true);
|
Version::Make(0, 0, 0), true);
|
||||||
// DeclareRequiredLayer("VK_LAYER_GOOGLE_unique_objects", Version::Make(0,
|
// DeclareRequiredLayer("VK_LAYER_GOOGLE_unique_objects", Version::Make(0,
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue