Compare commits

..

No commits in common. "canary_experimental" and "0dc0f18" have entirely different histories.

249 changed files with 3557 additions and 9446 deletions

View File

@ -1,59 +0,0 @@
name: Create release
on:
workflow_call:
inputs:
os:
required: true
type: string
secrets:
RELEASE_TOKEN:
required: true
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@main
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
GH_REPO: ${{ github.repository_owner }}/xenia-canary-releases
notes: ${{ github.event.head_commit.message }}
run: |
rm -rf **/*.pdb
case ${{ inputs.os }} in
windows)
asset=xenia_canary_windows.zip
7z a $asset './xenia_canary_windows/*'
;;
linux)
asset=xenia_canary_linux.tar.gz
cd xenia_canary_linux
chmod +x xenia_canary
tar -cvpf ../$asset *
cd -
;;
esac
if [ ! -f $asset ]; then
echo "::error::$asset doesn't exist!"
exit 1
fi
if [ $(stat -c%s $asset) -lt 100000 ]; then
echo "::error::$asset is too small!"
exit 1
fi
create_or_edit_release() {
local tag=$1
local title=$2
if gh release view $tag; then
gh release edit $tag -t $title -n "$notes"
gh release upload $tag $asset --clobber
else
gh release create $tag $asset --target 925ed98d5dce604b651027c36fb522dc1ff0fa55 -t $title -n "$notes"
fi
}
tag=${GITHUB_SHA::7}
create_or_edit_release $tag ${tag}_$GITHUB_REF_NAME
create_or_edit_release $GITHUB_REF_NAME $tag

View File

@ -7,14 +7,13 @@ on:
- '.drone.star'
- '.gitattributes'
- '.gitignore'
- '.gdbinit'
- '.github/*'
- '.github/workflows/Windows_build.yml'
- '.github/*_TEMPLATE/**'
- '*.bat'
- '*.md'
- '*.ps1'
- '*.txt'
- '*.yml'
- '*.txt'
- 'docs/**'
- 'src/**/*_windows.*'
- 'src/**/*_android.*'
@ -26,14 +25,13 @@ on:
- '.drone.star'
- '.gitattributes'
- '.gitignore'
- '.gdbinit'
- '.github/*'
- '.github/workflows/Windows_build.yml'
- '.github/*_TEMPLATE/**'
- '*.bat'
- '*.md'
- '*.ps1'
- '*.txt'
- '*.yml'
- '*.txt'
- 'docs/**'
- 'src/**/*_windows.*'
- 'src/**/*_android.*'
@ -44,68 +42,36 @@ on:
jobs:
lint:
name: Lint
runs-on: ubuntu-24.04
runs-on: windows-latest
steps:
- uses: actions/checkout@main
- name: Setup
run: |
LLVM_VERSION=18 # Same as Windows
UBUNTU_BASE=jammy
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
sudo apt-add-repository "deb http://apt.llvm.org/${UBUNTU_BASE}/ llvm-toolchain-${UBUNTU_BASE}-$LLVM_VERSION main"
sudo apt-get -y update
sudo apt-get -y install clang-format-$LLVM_VERSION
- name: Check Clang-Format Version
run: clang-format --version
- name: Lint
run: ./xb lint --all
build:
name: Build (LLVM ${{ matrix.LLVM_VERSION }})
build-linux:
name: Build (Linux) # runner.os can't be used here
needs: lint
runs-on: ubuntu-24.04
strategy:
fail-fast: false
matrix:
LLVM_VERSION: [19]
steps:
- uses: actions/checkout@main
with:
fetch-depth: 0
- name: Set environment variables
run: |
LLVM_VERSION=19
echo "LLVM_VERSION=$LLVM_VERSION" >> $GITHUB_ENV
echo "UBUNTU_BASE=jammy" >> $GITHUB_ENV
echo "CC=clang-${LLVM_VERSION}" >> $GITHUB_ENV
echo "CXX=clang++-${LLVM_VERSION}" >> $GITHUB_ENV
echo "AR=llvm-ar-${LLVM_VERSION}" >> $GITHUB_ENV
- name: Setup
run: |
UBUNTU_BASE=jammy
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
sudo apt-add-repository "deb http://apt.llvm.org/${UBUNTU_BASE}/ llvm-toolchain-${UBUNTU_BASE}-${{ matrix.LLVM_VERSION }} main"
sudo apt-add-repository "deb http://apt.llvm.org/${UBUNTU_BASE}/ llvm-toolchain-${UBUNTU_BASE}-$LLVM_VERSION main"
sudo apt-get -y update
sudo apt-get -y install mesa-vulkan-drivers valgrind libc++-dev libc++abi-dev libgtk-3-dev libsdl2-dev libvulkan-dev libx11-xcb-dev clang-${{ matrix.LLVM_VERSION }} llvm-${{ matrix.LLVM_VERSION }} ninja-build
sudo apt-get -y install mesa-vulkan-drivers valgrind libc++-dev libc++abi-dev libgtk-3-dev libsdl2-dev libvulkan-dev libx11-dev libx11-xcb-dev clang-$LLVM_VERSION clang-format-$LLVM_VERSION llvm-$LLVM_VERSION
./xb setup
- name: Build
env:
CC: clang-${{ matrix.LLVM_VERSION }}
CXX: clang++-${{ matrix.LLVM_VERSION }}
AR: llvm-ar-${{ matrix.LLVM_VERSION }}
run: ./xb build --config=Release
- name: Prepare artifacts
id: prepare_artifacts
run: |
mkdir -p artifacts
cp -r build/bin/Linux/Release/xenia_canary LICENSE artifacts
- name: Upload xenia canary artifacts
if: steps.prepare_artifacts.outcome == 'success'
uses: actions/upload-artifact@main
with:
name: xenia_canary_linux
path: artifacts
if-no-files-found: error
create-release:
name: Create release
needs: [lint, build]
if: |
github.repository == 'xenia-canary/xenia-canary' &&
github.event.action != 'pull_request' &&
github.ref == 'refs/heads/canary_experimental'
uses: ./.github/workflows/Create_release.yml
with:
os: linux
secrets:
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}

View File

@ -51,17 +51,21 @@ jobs:
lint:
name: Lint
runs-on: windows-latest
env:
POWERSHELL_TELEMETRY_OPTOUT: 1
steps:
- uses: actions/checkout@main
- name: Check Clang-Format Version
run: clang-format --version
- name: Lint
run: .\xb lint --all
build:
name: Build
build-windows:
name: Build (Windows, VS${{ matrix.vsver }}) # runner.os can't be used here
needs: lint
runs-on: windows-2025
strategy:
fail-fast: false
matrix:
vsver: [2022]
runs-on: windows-${{ matrix.vsver }}
env:
POWERSHELL_TELEMETRY_OPTOUT: 1
steps:
@ -80,21 +84,34 @@ jobs:
If ($LastExitCode -le 7) { echo "LastExitCode = $LastExitCode";$LastExitCode = 0 }
- name: Upload xenia canary artifacts
if: steps.prepare_artifacts.outcome == 'success'
id: upload_artifacts
uses: actions/upload-artifact@main
with:
name: xenia_canary_windows
name: xenia_canary_vs${{ matrix.vsver }}
path: artifacts\xenia_canary
if-no-files-found: error
create-release:
name: Create release
needs: [lint, build]
if: |
github.repository == 'xenia-canary/xenia-canary' &&
github.event.action != 'pull_request' &&
github.ref == 'refs/heads/canary_experimental'
uses: ./.github/workflows/Create_release.yml
with:
os: windows
secrets:
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
- name: Create release
if: |
github.repository == 'xenia-canary/xenia-canary' &&
github.event.action != 'pull_request' &&
github.ref == 'refs/heads/canary_experimental' &&
steps.upload_artifacts.outcome == 'success'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
$asset="xenia_canary.zip"
rm -recurse -force artifacts\xenia_canary\*.pdb # Ideally this would use xr, but I can't get it to work
7z a $asset .\artifacts\xenia_canary\*
If ($(Get-Item $asset).length -le 100000) {
Throw "Error: Archive $asset too small!"
}
$tag=$env:GITHUB_SHA.SubString(0,7)
$branch=$($env:GITHUB_REF -replace 'refs/heads/')
$title="${tag}_$branch"
gh release create $tag $asset --target $env:GITHUB_SHA -t $title
# Remove canary_ to prevent conflicts from tag
$tag=$($branch -replace 'canary_')
gh release delete $tag -y
git push --delete origin $tag
git tag -d $tag
gh release create $tag $asset --target $env:GITHUB_SHA -t $branch

5
.gitmodules vendored
View File

@ -42,7 +42,7 @@
url = https://github.com/libsdl-org/SDL.git
[submodule "third_party/utfcpp"]
path = third_party/utfcpp
url = https://github.com/nemtrif/utfcpp.git
url = https://github.com/xenia-project/utfcpp.git
[submodule "third_party/fmt"]
path = third_party/fmt
url = https://github.com/fmtlib/fmt.git
@ -103,6 +103,3 @@
[submodule "third_party/pugixml"]
path = third_party/pugixml
url = https://github.com/zeux/pugixml.git
[submodule "third_party/libusb"]
path = third_party/libusb
url = https://github.com/libusb/libusb.git

View File

@ -20,7 +20,7 @@ Discussing illegal activities will get you banned.
Buildbot | Status | Releases
-------- | ------ | --------
Windows | [![CI](https://github.com/xenia-canary/xenia-canary/actions/workflows/Windows_build.yml/badge.svg?branch=canary_experimental)](https://github.com/xenia-canary/xenia-canary/actions/workflows/Windows_build.yml) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/cd506034fd8148309a45034925648499)](https://app.codacy.com/gh/xenia-canary/xenia-canary/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) | [Latest](https://github.com/xenia-canary/xenia-canary-releases/releases/latest) ◦ [All](https://github.com/xenia-canary/xenia-canary-releases/releases) ◦ [Old](https://github.com/xenia-canary/xenia-canary/releases)
Windows | [![CI](https://github.com/xenia-canary/xenia-canary/actions/workflows/Windows_build.yml/badge.svg?branch=canary_experimental)](https://github.com/xenia-canary/xenia-canary/actions/workflows/Windows_build.yml) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/cd506034fd8148309a45034925648499)](https://app.codacy.com/gh/xenia-canary/xenia-canary/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) | [Latest](https://github.com/xenia-canary/xenia-canary/releases/latest) ◦ [All](https://github.com/xenia-canary/xenia-canary/releases)
Linux | [![CI](https://github.com/xenia-canary/xenia-canary/actions/workflows/Linux_build.yml/badge.svg?branch=canary_experimental)](https://github.com/xenia-canary/xenia-canary/actions/workflows/Linux_build.yml)
Netplay Build | | [Latest](https://github.com/AdrianCassar/xenia-canary/releases/latest)

View File

@ -7,11 +7,6 @@ location(build_root)
targetdir(build_bin)
objdir(build_obj)
-- Define variables for enabling specific submodules
-- Todo: Add changing from xb command
enableTests = false
enableMiscSubprojects = false
-- Define an ARCH variable
-- Only use this to enable architecture-specific functionality.
if os.istarget("linux") then
@ -35,8 +30,6 @@ cppdialect("C++20")
exceptionhandling("On")
rtti("On")
symbols("On")
characterset("Unicode")
fatalwarnings("All")
-- TODO(DrChat): Find a way to disable this on other architectures.
if ARCH ~= "ppc64" then
@ -45,6 +38,11 @@ if ARCH ~= "ppc64" then
filter({})
end
characterset("Unicode")
flags({
"FatalWarnings", -- Treat warnings as errors.
})
filter("kind:StaticLib")
defines({
"_LIB",
@ -52,24 +50,23 @@ filter("kind:StaticLib")
filter("configurations:Checked")
runtime("Debug")
sanitize("Address")
flags("NoIncrementalLink")
editandcontinue("Off")
staticruntime("Off")
optimize("Off")
defines({
"DEBUG",
})
filter({"configurations:Checked", "platforms:Windows"})
buildoptions({
"/RTCsu", -- Full Run-Time Checks.
})
filter({"configurations:Checked", "platforms:Linux"})
defines({
"_GLIBCXX_DEBUG", -- libstdc++ debug mode
})
filter({"configurations:Release", "platforms:Windows"})
buildoptions({
"/Gw",
"/Ob3",
})
filter("configurations:Debug")
runtime("Release")
@ -78,7 +75,6 @@ filter("configurations:Debug")
"DEBUG",
"_NO_DEBUG_HEAP=1",
})
filter({"configurations:Debug", "platforms:Linux"})
defines({
"_GLIBCXX_DEBUG", -- make dbg symbols work on some distros
@ -92,28 +88,19 @@ filter("configurations:Release")
})
optimize("Speed")
inlining("Auto")
editandcontinue("Off")
flags({
"LinkTimeOptimization",
"NoBufferSecurityCheck",
})
-- Not using floatingpoint("Fast") - NaN checks are used in some places
-- (though rarely), overall preferable to avoid any functional differences
-- between debug and release builds, and to have calculations involved in GPU
-- (especially anything that may affect vertex position invariance) and CPU
-- (such as constant propagation) emulation as predictable as possible,
-- including handling of specials since games make assumptions about them.
filter({"configurations:Release", "platforms:Windows"})
linktimeoptimization("On")
flags({
"NoBufferSecurityCheck"
})
buildoptions({
"/Gw",
"/Ob3",
})
filter("platforms:Linux")
system("linux")
toolset("clang")
vectorextensions("AVX2")
buildoptions({
-- "-mlzcnt", -- (don't) Assume lzcnt is supported.
})
@ -126,6 +113,9 @@ filter("platforms:Linux")
"rt",
})
filter({"platforms:Linux"})
vectorextensions("AVX2")
filter({"platforms:Linux", "kind:*App"})
linkgroups("On")
@ -155,7 +145,6 @@ filter({"platforms:Linux", "language:C++", "toolset:clang"})
"deprecated-volatile",
"switch",
"deprecated-enum-enum-conversion",
"attributes",
})
filter({"platforms:Linux", "language:C++", "toolset:clang", "files:*.cc or *.cpp"})
buildoptions({
@ -185,8 +174,16 @@ filter("platforms:Windows")
toolset("msc")
buildoptions({
"/utf-8", -- 'build correctly on systems with non-Latin codepages'.
-- Mark warnings as severe
"/w14839", -- non-standard use of class 'type' as an argument to a variadic function
"/w14840", -- non-portable use of class 'type' as an argument to a variadic function
-- Disable warnings
"/wd4100", -- Unreferenced parameters are ok.
"/wd4201", -- Nameless struct/unions are ok.
"/wd4512", -- 'assignment operator was implicitly defined as deleted'.
"/wd4127", -- 'conditional expression is constant'.
"/wd4324", -- 'structure was padded due to alignment specifier'.
"/wd4189", -- 'local variable is initialized but not referenced'.
})
flags({
"MultiProcessorCompile", -- Multiprocessor compilation.
@ -278,10 +275,6 @@ workspace("xenia")
include("third_party/zlib.lua")
include("third_party/pugixml.lua")
if os.istarget("windows") then
include("third_party/libusb.lua")
end
if not os.istarget("android") then
-- SDL2 requires sdl2-config, and as of November 2020 isn't high-quality on
-- Android yet, most importantly in game controllers - the keycode and axis
@ -299,7 +292,9 @@ workspace("xenia")
removefiles({
"src/xenia/base/app_win32.manifest"
})
removefatalwarnings("All")
removeflags({
"FatalWarnings",
})
end
include("src/xenia")
@ -316,7 +311,6 @@ workspace("xenia")
include("src/xenia/gpu/vulkan")
include("src/xenia/hid")
include("src/xenia/hid/nop")
include("src/xenia/hid/skylander")
include("src/xenia/kernel")
include("src/xenia/patcher")
include("src/xenia/ui")

View File

@ -167,8 +167,8 @@ using xe::ui::UIEvent;
using namespace xe::hid;
using namespace xe::gpu;
constexpr std::string_view kRecentlyPlayedTitlesFilename = "recent.toml";
constexpr std::string_view kBaseTitle = "Xenia-canary";
const std::string kRecentlyPlayedTitlesFilename = "recent.toml";
const std::string kBaseTitle = "Xenia-canary";
EmulatorWindow::EmulatorWindow(Emulator* emulator,
ui::WindowedAppContext& app_context,
@ -181,7 +181,7 @@ EmulatorWindow::EmulatorWindow(Emulator* emulator,
std::make_unique<ui::ImGuiDrawer>(window_.get(), kZOrderImGui)),
display_config_game_config_load_callback_(
new DisplayConfigGameConfigLoadCallback(*emulator, *this)) {
base_title_ = std::string(kBaseTitle) +
base_title_ = kBaseTitle +
#ifdef DEBUG
#if _NO_DEBUG_HEAP == 1
" DEBUG"
@ -569,96 +569,6 @@ void EmulatorWindow::DisplayConfigDialog::OnDraw(ImGuiIO& io) {
}
}
void EmulatorWindow::ContentInstallDialog::OnDraw(ImGuiIO& io) {
ImGui::SetNextWindowPos(ImVec2(20, 20), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(20, 20), ImGuiCond_FirstUseEver);
bool dialog_open = true;
if (!ImGui::Begin(
fmt::format("Installation Progress###{}", window_id_).c_str(),
&dialog_open,
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_AlwaysAutoResize |
ImGuiWindowFlags_HorizontalScrollbar)) {
Close();
ImGui::End();
return;
}
bool is_everything_installed = true;
for (const auto& entry : *installation_entries_) {
ImGui::BeginTable(fmt::format("table_{}", entry.name_).c_str(), 2);
ImGui::TableNextRow(0);
ImGui::TableSetColumnIndex(0);
if (entry.icon_) {
ImGui::Image(reinterpret_cast<ImTextureID>(entry.icon_.get()),
ui::default_image_icon_size);
} else {
ImGui::Dummy(ui::default_image_icon_size);
}
ImGui::TableNextColumn();
ImGui::Text("Name: %s", entry.name_.c_str());
ImGui::Text("Installation Path:");
ImGui::SameLine();
if (ImGui::TextLink(
xe::path_to_utf8(entry.data_installation_path_).c_str())) {
LaunchFileExplorer(emulator_window_.emulator_->content_root() /
entry.data_installation_path_);
}
if (entry.content_type_ != xe::XContentType::kInvalid) {
ImGui::Text("Content Type: %s",
XContentTypeMap.at(entry.content_type_).c_str());
}
std::string result = fmt::format(
"Status: {}", xe::Emulator::installStateStringName[static_cast<uint8_t>(
entry.installation_state_)]);
if (entry.installation_state_ == xe::Emulator::InstallState::failed) {
result += fmt::format(" - {} ({:08X})",
entry.installation_error_message_.c_str(),
entry.installation_result_);
}
ImGui::Text("%s", result.c_str());
ImGui::EndTable();
if (entry.content_size_ > 0) {
ImGui::ProgressBar(static_cast<float>(entry.currently_installed_size_) /
entry.content_size_);
if (entry.currently_installed_size_ != entry.content_size_ &&
entry.installation_result_ == X_ERROR_SUCCESS) {
is_everything_installed = false;
}
} else {
ImGui::ProgressBar(0.0f);
}
if (installation_entries_->size() > 1) {
ImGui::Separator();
}
}
ImGui::Spacing();
ImGui::BeginDisabled(!is_everything_installed);
if (ImGui::Button("Close")) {
ImGui::EndDisabled();
Close();
ImGui::End();
return;
}
ImGui::EndDisabled();
if (!dialog_open && is_everything_installed) {
Close();
ImGui::End();
return;
}
ImGui::End();
}
bool EmulatorWindow::Initialize() {
window_->AddListener(&window_listener_);
window_->AddInputListener(&window_listener_, kZOrderEmulatorWindowInput);
@ -1025,16 +935,11 @@ void EmulatorWindow::OnMouseUp(const ui::MouseEvent& e) {
void EmulatorWindow::TakeScreenshot() {
xe::ui::RawImage image;
imgui_drawer_->EnableNotifications(false);
if (!GetGraphicsSystemPresenter()->CaptureGuestOutput(image) ||
GetGraphicsSystemPresenter() == nullptr) {
XELOGE("Failed to capture guest output for screenshot");
return;
}
imgui_drawer_->EnableNotifications(true);
ExportScreenshot(image);
}
@ -1101,9 +1006,9 @@ void EmulatorWindow::ToggleFullscreenOnDoubleClick() {
// this function tests if user has double clicked.
// if double click was achieved the fullscreen gets toggled
const auto now = steady_clock::now(); // current mouse event time
constexpr int16_t mouse_down_max_threshold = 250;
constexpr int16_t mouse_up_max_threshold = 250;
constexpr int16_t mouse_up_down_max_delta = 100;
const int16_t mouse_down_max_threshold = 250;
const int16_t mouse_up_max_threshold = 250;
const int16_t mouse_up_down_max_delta = 100;
// max delta to prevent 'chaining' of double clicks with next mouse events
const auto last_mouse_down_delta = diff_in_ms(now, last_mouse_down);
@ -1178,27 +1083,62 @@ void EmulatorWindow::InstallContent() {
return;
}
std::shared_ptr<std::vector<Emulator::ContentInstallEntry>>
content_installation_status =
std::make_shared<std::vector<Emulator::ContentInstallEntry>>();
using content_installation_data =
std::tuple<X_STATUS, std::string, std::string>;
std::map<XContentType, std::vector<content_installation_data>>
content_installation_details;
for (const auto& path : paths) {
content_installation_status->push_back({path});
// Normalize the path and make absolute.
auto abs_path = std::filesystem::absolute(path);
Emulator::ContentInstallationInfo installation_info;
auto result = emulator_->InstallContentPackage(abs_path, installation_info);
auto entry =
content_installation_details.find(installation_info.content_type);
// There is no entry with that specific type of XContent, so we must add it.
if (entry == content_installation_details.end()) {
content_installation_details.insert({installation_info.content_type, {}});
entry = content_installation_details.find(installation_info.content_type);
};
entry->second.push_back({result, installation_info.content_name,
installation_info.installation_path});
}
for (auto& entry : *content_installation_status) {
emulator_->ProcessContentPackageHeader(entry.path_, entry);
}
// Prepare installation process summary message
std::string summary = "Installation result: \n";
auto installationThread = std::thread([this, content_installation_status] {
for (auto& entry : *content_installation_status) {
emulator_->InstallContentPackage(entry.path_, entry);
for (const auto& content_type : content_installation_details) {
if (XContentTypeMap.find(content_type.first) != XContentTypeMap.cend()) {
summary += XContentTypeMap.at(content_type.first) + ":\n";
} else {
summary += "Unknown:\n";
}
});
installationThread.detach();
new ContentInstallDialog(imgui_drawer_.get(), *this,
content_installation_status);
for (const auto& content_installation_entry : content_type.second) {
const std::string status =
std::get<0>(content_installation_entry) == X_STATUS_SUCCESS
? "Success"
: fmt::format("Failed (0x{:08X})",
std::get<0>(content_installation_entry));
summary += fmt::format("\t{} - {} => {}\n", status,
std::get<1>(content_installation_entry),
std::get<2>(content_installation_entry));
}
summary += "\n";
}
if (content_installation_details.count(XContentType::kProfile)) {
emulator_->kernel_state()->xam_state()->profile_manager()->ReloadProfiles();
}
xe::ui::ImGuiDialog::ShowMessageBox(imgui_drawer_.get(),
"Content Installation Summary", summary);
}
void EmulatorWindow::ExtractZarchive() {
@ -1484,12 +1424,6 @@ void EmulatorWindow::ToggleControllerVibration() {
auto input_lock = input_sys->lock();
input_sys->ToggleVibration();
if (emulator_->kernel_state()) {
emulator_->kernel_state()->BroadcastNotification(
kXNotificationSystemProfileSettingChanged,
static_cast<uint32_t>(input_sys->GetConnectedSlots().count()));
}
}
}
@ -1690,7 +1624,7 @@ EmulatorWindow::ControllerHotKey EmulatorWindow::ProcessControllerHotkey(
}
// Hotkey cool-down to prevent toggling too fast
constexpr std::chrono::milliseconds delay(75);
const std::chrono::milliseconds delay(75);
// If the Xbox Gamebar is enabled or the Guide button is disabled then
// replace the Guide button with the Back button without redeclaring the key
@ -1860,11 +1794,10 @@ EmulatorWindow::ControllerHotKey EmulatorWindow::ProcessControllerHotkey(
}
if (!notificationTitle.empty()) {
app_context_.CallInUIThread(
[imgui_drawer = imgui_drawer(), notificationTitle, notificationDesc]() {
new xe::ui::HostNotificationWindow(imgui_drawer, notificationTitle,
notificationDesc, 0);
});
app_context_.CallInUIThread([&]() {
new xe::ui::HostNotificationWindow(imgui_drawer(), notificationTitle,
notificationDesc, 0);
});
}
xe::threading::Sleep(delay);
@ -1875,7 +1808,7 @@ EmulatorWindow::ControllerHotKey EmulatorWindow::ProcessControllerHotkey(
void EmulatorWindow::VibrateController(xe::hid::InputSystem* input_sys,
uint32_t user_index,
bool toggle_rumble) {
constexpr std::chrono::milliseconds rumble_duration(100);
const std::chrono::milliseconds rumble_duration(100);
// Hold lock while sleeping this thread for the duration of the rumble,
// otherwise the rumble may fail.
@ -1897,7 +1830,7 @@ void EmulatorWindow::VibrateController(xe::hid::InputSystem* input_sys,
void EmulatorWindow::GamepadHotKeys() {
X_INPUT_STATE state;
constexpr std::chrono::milliseconds thread_delay(75);
const std::chrono::milliseconds thread_delay(75);
auto input_sys = emulator_->input_system();
@ -1956,7 +1889,8 @@ void EmulatorWindow::DisplayHotKeysConfig() {
if (!guide_enabled) {
pretty_text = std::regex_replace(
pretty_text, std::regex("Guide", std::regex_constants::icase),
pretty_text,
std::regex("Guide", std::regex_constants::syntax_option_type::icase),
"Back");
}

View File

@ -167,34 +167,6 @@ class EmulatorWindow {
EmulatorWindow& emulator_window_;
};
class ContentInstallDialog final : public ui::ImGuiDialog {
public:
ContentInstallDialog(
ui::ImGuiDrawer* imgui_drawer, EmulatorWindow& emulator_window,
std::shared_ptr<std::vector<Emulator::ContentInstallEntry>> entries)
: ui::ImGuiDialog(imgui_drawer),
emulator_window_(emulator_window),
installation_entries_(entries) {
window_id_ = GetWindowId();
}
~ContentInstallDialog() {
for (auto& entry : *installation_entries_) {
entry.icon_.release();
}
}
protected:
void OnDraw(ImGuiIO& io) override;
private:
uint64_t window_id_;
EmulatorWindow& emulator_window_;
std::shared_ptr<std::vector<Emulator::ContentInstallEntry>>
installation_entries_;
};
class DisplayConfigDialog final : public ui::ImGuiDialog {
public:
DisplayConfigDialog(ui::ImGuiDrawer* imgui_drawer,

View File

@ -54,13 +54,11 @@ project("xenia-app")
-- Unified library containing all apps as StaticLibs, not just the main
-- emulator windowed app.
kind("SharedLib")
if enableMiscSubprojects then
links({
"xenia-gpu-vulkan-trace-viewer",
"xenia-hid-demo",
"xenia-ui-window-vulkan-demo",
})
end
links({
"xenia-gpu-vulkan-trace-viewer",
"xenia-hid-demo",
"xenia-ui-window-vulkan-demo",
})
filter(NOT_SINGLE_LIBRARY_FILTER)
kind("WindowedApp")
@ -116,13 +114,15 @@ project("xenia-app")
"xenia-ui-d3d12",
})
if enableMiscSubprojects then
filter({"platforms:Windows", SINGLE_LIBRARY_FILTER})
links({
"xenia-gpu-d3d12-trace-viewer",
"xenia-ui-window-d3d12-demo",
})
end
filter({"platforms:Windows", SINGLE_LIBRARY_FILTER})
links({
"xenia-gpu-d3d12-trace-viewer",
"xenia-ui-window-d3d12-demo",
})
-- filter({"configurations:Release", "platforms:Windows"})
-- buildoptions({
-- "/O1",
-- })
filter("platforms:Windows")
-- Only create the .user file if it doesn't already exist.

View File

@ -95,15 +95,9 @@ UPDATE_from_bool(mount_cache, 2024, 8, 31, 20, false);
DEFINE_transient_path(target, "",
"Specifies the target .xex or .iso to execute.",
"General");
#ifndef XE_PLATFORM_WIN32
DEFINE_transient_bool(portable, false,
"Specifies if Xenia should run in portable mode.",
"General");
#else
DEFINE_transient_bool(portable, true,
"Specifies if Xenia should run in portable mode.",
"General");
#endif
DECLARE_bool(debug);
@ -427,7 +421,7 @@ bool EmulatorApp::OnInitialize() {
if (!cvars::portable &&
!std::filesystem::exists(storage_root / "portable.txt")) {
storage_root = xe::filesystem::GetUserFolder();
#if defined(XE_PLATFORM_WIN32) || defined(XE_PLATFORM_LINUX)
#if defined(XE_PLATFORM_WIN32) || defined(XE_PLATFORM_GNU_LINUX)
storage_root = storage_root / "Xenia";
#else
// TODO(Triang3l): Point to the app's external storage "files" directory

View File

@ -18,12 +18,12 @@ namespace apu {
class AudioDriver {
public:
static constexpr uint32_t kFrameFrequencyDefault = 48000;
static constexpr uint32_t kFrameChannelsDefault = 6;
static constexpr uint32_t kChannelSamplesDefault = 256;
static constexpr uint32_t kFrameSamplesMax =
static const uint32_t kFrameFrequencyDefault = 48000;
static const uint32_t kFrameChannelsDefault = 6;
static const uint32_t kChannelSamplesDefault = 256;
static const uint32_t kFrameSamplesMax =
kFrameChannelsDefault * kChannelSamplesDefault;
static constexpr uint32_t kFrameSizeMax = sizeof(float) * kFrameSamplesMax;
static const uint32_t kFrameSizeMax = sizeof(float) * kFrameSamplesMax;
virtual ~AudioDriver();

View File

@ -10,7 +10,6 @@
#ifndef XENIA_APU_AUDIO_MEDIA_PLAYER_H_
#define XENIA_APU_AUDIO_MEDIA_PLAYER_H_
#include "xenia/apu/audio_driver.h"
#include "xenia/apu/audio_system.h"
#include "xenia/kernel/xam/apps/xmp_app.h"

View File

@ -32,7 +32,7 @@ class AudioSystem {
public:
// TODO(gibbed): respect XAUDIO2_MAX_QUEUED_BUFFERS somehow (ie min(64,
// XAUDIO2_MAX_QUEUED_BUFFERS))
static constexpr size_t kMaximumQueuedFrames = 64;
static const size_t kMaximumQueuedFrames = 64;
virtual ~AudioSystem();
@ -81,7 +81,7 @@ class AudioSystem {
kernel::object_ref<kernel::XHostThread> worker_thread_;
xe::global_critical_region global_critical_region_;
static constexpr size_t kMaximumClientCount = 8;
static const size_t kMaximumClientCount = 8;
struct {
AudioDriver* driver;
uint32_t callback;

View File

@ -137,10 +137,10 @@ bool XAudio2AudioDriver::InitializeObjects(Objects& objects) {
api::XAUDIO2_DEBUG_CONFIGURATION config;
config.TraceMask = api::XE_XAUDIO2_LOG_ERRORS | api::XE_XAUDIO2_LOG_WARNINGS;
config.BreakMask = 0;
config.LogThreadID = false;
config.LogTiming = true;
config.LogFunctionName = true;
config.LogFileline = true;
config.LogThreadID = FALSE;
config.LogTiming = TRUE;
config.LogFunctionName = TRUE;
config.LogFileline = TRUE;
objects.audio->SetDebugConfiguration(&config);
hr = objects.audio->CreateMasteringVoice(&objects.mastering_voice);
@ -165,7 +165,7 @@ bool XAudio2AudioDriver::InitializeObjects(Objects& objects) {
waveformat.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
waveformat.Samples.wValidBitsPerSample = waveformat.Format.wBitsPerSample;
static constexpr DWORD kChannelMasks[] = {
static const DWORD kChannelMasks[] = {
0,
0,
SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT,

View File

@ -106,7 +106,7 @@ class XAudio2AudioDriver : public AudioDriver {
uint32_t frame_size_;
bool need_format_conversion_;
static constexpr uint32_t frame_count_ = api::XE_XAUDIO2_MAX_QUEUED_BUFFERS;
static const uint32_t frame_count_ = api::XE_XAUDIO2_MAX_QUEUED_BUFFERS;
float frames_[frame_count_][kFrameSamplesMax];
uint32_t current_frame_ = 0;

View File

@ -160,23 +160,23 @@ static_assert_size(Xma2ExtraData, 34);
class XmaContext {
public:
static constexpr uint32_t kBytesPerPacket = 2048;
static constexpr uint32_t kBitsPerPacket = kBytesPerPacket * 8;
static constexpr uint32_t kBitsPerHeader = 32;
static const uint32_t kBytesPerPacket = 2048;
static const uint32_t kBitsPerPacket = kBytesPerPacket * 8;
static const uint32_t kBitsPerHeader = 32;
static constexpr uint32_t kBytesPerSample = 2;
static constexpr uint32_t kSamplesPerFrame = 512;
static constexpr uint32_t kSamplesPerSubframe = 128;
static constexpr uint32_t kBytesPerFrameChannel =
static const uint32_t kBytesPerSample = 2;
static const uint32_t kSamplesPerFrame = 512;
static const uint32_t kSamplesPerSubframe = 128;
static const uint32_t kBytesPerFrameChannel =
kSamplesPerFrame * kBytesPerSample;
static constexpr uint32_t kBytesPerSubframeChannel =
static const uint32_t kBytesPerSubframeChannel =
kSamplesPerSubframe * kBytesPerSample;
// static const uint32_t kOutputBytesPerBlock = 256;
// static const uint32_t kOutputMaxSizeBytes = 31 * kOutputBytesPerBlock;
explicit XmaContext();
virtual ~XmaContext();
~XmaContext();
virtual int Setup(uint32_t id, Memory* memory, uint32_t guest_ptr) {
return 0;

View File

@ -45,28 +45,28 @@ static constexpr int kIdToSampleRate[4] = {24000, 32000, 44100, 48000};
class XmaContextNew : public XmaContext {
public:
static constexpr uint32_t kBytesPerPacket = 2048;
static constexpr uint32_t kBytesPerPacketHeader = 4;
static constexpr uint32_t kBytesPerPacketData =
static const uint32_t kBytesPerPacket = 2048;
static const uint32_t kBytesPerPacketHeader = 4;
static const uint32_t kBytesPerPacketData =
kBytesPerPacket - kBytesPerPacketHeader;
static constexpr uint32_t kBitsPerPacket = kBytesPerPacket * 8;
static constexpr uint32_t kBitsPerPacketHeader = 32;
static constexpr uint32_t kBitsPerFrameHeader = 15;
static const uint32_t kBitsPerPacket = kBytesPerPacket * 8;
static const uint32_t kBitsPerPacketHeader = 32;
static const uint32_t kBitsPerFrameHeader = 15;
static constexpr uint32_t kBytesPerSample = 2;
static constexpr uint32_t kSamplesPerFrame = 512;
static constexpr uint32_t kSamplesPerSubframe = 128;
static constexpr uint32_t kBytesPerFrameChannel =
static const uint32_t kBytesPerSample = 2;
static const uint32_t kSamplesPerFrame = 512;
static const uint32_t kSamplesPerSubframe = 128;
static const uint32_t kBytesPerFrameChannel =
kSamplesPerFrame * kBytesPerSample;
static constexpr uint32_t kBytesPerSubframeChannel =
static const uint32_t kBytesPerSubframeChannel =
kSamplesPerSubframe * kBytesPerSample;
static constexpr uint32_t kOutputBytesPerBlock = 256;
static constexpr uint32_t kOutputMaxSizeBytes = 31 * kOutputBytesPerBlock;
static const uint32_t kOutputBytesPerBlock = 256;
static const uint32_t kOutputMaxSizeBytes = 31 * kOutputBytesPerBlock;
static constexpr uint32_t kLastFrameMarker = 0x7FFF;
static constexpr uint32_t kMaxFrameSizeinBits = 0x4000 - kBitsPerPacketHeader;
static const uint32_t kLastFrameMarker = 0x7FFF;
static const uint32_t kMaxFrameSizeinBits = 0x4000 - kBitsPerPacketHeader;
explicit XmaContextNew();
~XmaContextNew();

View File

@ -18,7 +18,7 @@ namespace xe {
namespace apu {
namespace xma {
static constexpr uint32_t kMaxFrameLength = 0x7FFF;
static const uint32_t kMaxFrameLength = 0x7FFF;
// Get number of frames that /begin/ in this packet. This is valid only for XMA2
// packets

View File

@ -32,7 +32,7 @@ class XmaRegisterFile {
static const XmaRegisterInfo* GetRegisterInfo(uint32_t index);
static constexpr size_t kRegisterCount = (0xFFFF + 1) / 4;
static const size_t kRegisterCount = (0xFFFF + 1) / 4;
uint32_t values[kRegisterCount];
uint32_t operator[](uint32_t reg) const { return values[reg]; }

View File

@ -46,8 +46,8 @@ class BitMap {
std::vector<uint64_t>& data() { return data_; }
private:
constexpr static size_t kDataSize = 8;
constexpr static size_t kDataSizeBits = kDataSize * 8;
const static size_t kDataSize = 8;
const static size_t kDataSizeBits = kDataSize * 8;
std::vector<uint64_t> data_;
inline size_t TryAcquireAt(size_t i);
};

View File

@ -30,7 +30,7 @@ std::pair<size_t, size_t> NextUnsetRange(const Block* bits, size_t first,
return std::make_pair(size_t(first), size_t(0));
}
size_t last = first + length - 1;
constexpr size_t block_bits = sizeof(Block) * CHAR_BIT;
const size_t block_bits = sizeof(Block) * CHAR_BIT;
size_t block_first = first / block_bits;
size_t block_last = last / block_bits;
size_t range_start = SIZE_MAX;
@ -80,7 +80,7 @@ void SetRange(Block* bits, size_t first, size_t length) {
return;
}
size_t last = first + length - 1;
constexpr size_t block_bits = sizeof(Block) * CHAR_BIT;
const size_t block_bits = sizeof(Block) * CHAR_BIT;
size_t block_first = first / block_bits;
size_t block_last = last / block_bits;
Block set_first = ~((Block(1) << (first & (block_bits - 1))) - 1);

View File

@ -53,5 +53,4 @@ uint64_t Clock::QueryHostUptimeMillis() {
return host_tick_count_platform() * 1000 / host_tick_frequency_platform();
}
uint64_t Clock::QueryHostInterruptTime() { return host_tick_count_platform(); }
} // namespace xe

View File

@ -9,7 +9,7 @@
#include "xenia/base/cvar.h"
#include <iostream>
#define UTF_CPP_CPLUSPLUS 202002L
#define UTF_CPP_CPLUSPLUS 201703L
#include "third_party/utfcpp/source/utf8.h"
#include "xenia/base/console.h"
@ -125,9 +125,9 @@ std::string EscapeBasicString(const std::string_view view) {
result += "\\\\";
} else if (c < 0x20 || c == 0x7F) {
if (c <= 0xFFFF) {
result += fmt::format("\\u{:04X}", static_cast<uint32_t>(c));
result += fmt::format("\\u{:04X}", c);
} else {
result += fmt::format("\\u{:08X}", static_cast<uint32_t>(c));
result += fmt::format("\\u{:08X}", c);
}
} else {
utfcpp::append(static_cast<char32_t>(c), result);
@ -159,7 +159,7 @@ std::string EscapeMultilineBasicString(const std::string_view view) {
if (c == '\b') {
result += "\\b";
} else if (c == '\t' || c == '\n') {
result += static_cast<uint32_t>(c);
result += c;
} else if (c == '\f') {
result += "\\f";
} else if (c == '\r') {
@ -171,9 +171,9 @@ std::string EscapeMultilineBasicString(const std::string_view view) {
result += "\\\\";
} else if (c < 0x20 || c == 0x7F) {
if (c <= 0xFFFF) {
result += fmt::format("\\u{:04X}", static_cast<uint32_t>(c));
result += fmt::format("\\u{:04X}", c);
} else {
result += fmt::format("\\u{:08X}", static_cast<uint32_t>(c));
result += fmt::format("\\u{:08X}", c);
}
} else {
utfcpp::append(static_cast<char32_t>(c), result);
@ -189,8 +189,8 @@ std::string EscapeMultilineBasicString(const std::string_view view) {
}
std::string EscapeString(const std::string_view view) {
constexpr auto multiline_chars = std::string_view("\r\n");
constexpr auto escape_chars = std::string_view(
const auto multiline_chars = std::string_view("\r\n");
const auto escape_chars = std::string_view(
"\0\b\v\f"
"\x01\x02\x03\x04\x05\x06\x07\x0E\x0F"
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"

View File

@ -168,7 +168,7 @@ static void ExceptionHandlerCallback(int signal_number, siginfo_t* signal_info,
mcontext.gregs[REG_EFL] = greg_t(thread_context.eflags);
uint32_t modified_register_index;
// The order must match the order in X64Register.
static constexpr size_t kIntRegisterMap[] = {
static const size_t kIntRegisterMap[] = {
REG_RAX, REG_RCX, REG_RDX, REG_RBX, REG_RSP, REG_RBP,
REG_RSI, REG_RDI, REG_R8, REG_R9, REG_R10, REG_R11,
REG_R12, REG_R13, REG_R14, REG_R15,

View File

@ -24,42 +24,5 @@ bool CreateParentFolder(const std::filesystem::path& path) {
return true;
}
std::error_code CreateFolder(const std::filesystem::path& path) {
if (std::filesystem::exists(path)) {
return {};
}
std::error_code ec;
if (std::filesystem::create_directories(path, ec)) {
return {};
}
return ec;
}
std::vector<FileInfo> ListDirectories(const std::filesystem::path& path) {
std::vector<FileInfo> files = ListFiles(path);
std::vector<FileInfo> directories = {};
std::copy_if(files.cbegin(), files.cend(), std::back_inserter(directories),
[](const FileInfo& file) {
return file.type == FileInfo::Type::kDirectory;
});
return std::move(directories);
}
std::vector<FileInfo> FilterByName(const std::vector<FileInfo>& files,
const std::regex pattern) {
std::vector<FileInfo> filtered_entries = {};
std::copy_if(
files.cbegin(), files.cend(), std::back_inserter(filtered_entries),
[pattern](const FileInfo& file) {
return std::regex_match(file.name.filename().string(), pattern);
});
return std::move(filtered_entries);
}
} // namespace filesystem
} // namespace xe

View File

@ -45,10 +45,6 @@ std::filesystem::path GetUserFolder();
// attempting to create it.
bool CreateParentFolder(const std::filesystem::path& path);
// Creates folder on specified path.
// If folder already exists it returns success (no error).
std::error_code CreateFolder(const std::filesystem::path& path);
// Creates an empty file at the given path, overwriting if it exists.
bool CreateEmptyFile(const std::filesystem::path& path);
@ -69,14 +65,14 @@ bool TruncateStdioFile(FILE* file, uint64_t length);
struct FileAccess {
// Implies kFileReadData.
static constexpr uint32_t kGenericRead = 0x80000000;
static const uint32_t kGenericRead = 0x80000000;
// Implies kFileWriteData.
static constexpr uint32_t kGenericWrite = 0x40000000;
static constexpr uint32_t kGenericExecute = 0x20000000;
static constexpr uint32_t kGenericAll = 0x10000000;
static constexpr uint32_t kFileReadData = 0x00000001;
static constexpr uint32_t kFileWriteData = 0x00000002;
static constexpr uint32_t kFileAppendData = 0x00000004;
static const uint32_t kGenericWrite = 0x40000000;
static const uint32_t kGenericExecute = 0x20000000;
static const uint32_t kGenericAll = 0x10000000;
static const uint32_t kFileReadData = 0x00000001;
static const uint32_t kFileWriteData = 0x00000002;
static const uint32_t kFileAppendData = 0x00000004;
};
class FileHandle {

View File

@ -214,7 +214,7 @@ bool IsAndroidContentUri(const std::string_view source) {
// still including // in the comparison to distinguish from a file with a name
// starting from content: (as this is the main purpose of this code -
// separating URIs from file paths) more clearly.
static constexpr char kContentSchema[] = "content://";
static const char kContentSchema[] = "content://";
constexpr size_t kContentSchemaLength = xe::countof(kContentSchema) - 1;
return source.size() >= kContentSchemaLength &&
!xe_strncasecmp(source.data(), kContentSchema, kContentSchemaLength);

View File

@ -192,26 +192,20 @@ std::unique_ptr<FileHandle> FileHandle::OpenExisting(
return std::make_unique<PosixFileHandle>(path, handle);
}
std::optional<FileInfo> GetInfo(const std::filesystem::path& path) {
FileInfo info{};
bool GetInfo(const std::filesystem::path& path, FileInfo* out_info) {
struct stat st;
if (stat(path.c_str(), &st) == 0) {
if (S_ISDIR(st.st_mode)) {
info.type = FileInfo::Type::kDirectory;
// On Linux st.st_size can have non-zero size (generally 4096) so make 0
info.total_size = 0;
out_info->type = FileInfo::Type::kDirectory;
} else {
info.type = FileInfo::Type::kFile;
info.total_size = st.st_size;
out_info->type = FileInfo::Type::kFile;
}
info.path = path.parent_path();
info.name = path.filename();
info.create_timestamp = convertUnixtimeToWinFiletime(st.st_ctime);
info.access_timestamp = convertUnixtimeToWinFiletime(st.st_atime);
info.write_timestamp = convertUnixtimeToWinFiletime(st.st_mtime);
return std::move(info);
out_info->create_timestamp = convertUnixtimeToWinFiletime(st.st_ctime);
out_info->access_timestamp = convertUnixtimeToWinFiletime(st.st_atime);
out_info->write_timestamp = convertUnixtimeToWinFiletime(st.st_mtime);
return true;
}
return {};
return false;
}
std::vector<FileInfo> ListFiles(const std::filesystem::path& path) {
@ -246,7 +240,7 @@ std::vector<FileInfo> ListFiles(const std::filesystem::path& path) {
result.push_back(info);
}
closedir(dir);
return std::move(result);
return result;
}
bool SetAttributes(const std::filesystem::path& path, uint64_t attributes) {

View File

@ -263,6 +263,30 @@ std::vector<FileInfo> ListFiles(const std::filesystem::path& path) {
return result;
}
std::vector<FileInfo> ListDirectories(const std::filesystem::path& path) {
std::vector<FileInfo> files = ListFiles(path);
std::vector<FileInfo> directories = {};
std::copy_if(
files.cbegin(), files.cend(), std::back_inserter(directories),
[](FileInfo file) { return file.type == FileInfo::Type::kDirectory; });
return directories;
}
std::vector<FileInfo> FilterByName(const std::vector<FileInfo>& files,
const std::regex pattern) {
std::vector<FileInfo> filtered_entries = {};
std::copy_if(files.cbegin(), files.cend(),
std::back_inserter(filtered_entries), [pattern](FileInfo file) {
return std::regex_match(file.name.filename().string(),
pattern);
});
return filtered_entries;
}
bool SetAttributes(const std::filesystem::path& path, uint64_t attributes) {
return SetFileAttributes(path.c_str(), static_cast<DWORD>(attributes));
}

View File

@ -14,23 +14,23 @@
namespace xe::literals {
constexpr size_t operator""_KiB(const unsigned long long int x) {
constexpr size_t operator""_KiB(unsigned long long int x) {
return 1024ULL * x;
}
constexpr size_t operator""_MiB(const unsigned long long int x) {
constexpr size_t operator""_MiB(unsigned long long int x) {
return 1024_KiB * x;
}
constexpr size_t operator""_GiB(const unsigned long long int x) {
constexpr size_t operator""_GiB(unsigned long long int x) {
return 1024_MiB * x;
}
constexpr size_t operator""_TiB(const unsigned long long int x) {
constexpr size_t operator""_TiB(unsigned long long int x) {
return 1024_GiB * x;
}
constexpr size_t operator""_PiB(const unsigned long long int x) {
constexpr size_t operator""_PiB(unsigned long long int x) {
return 1024_TiB * x;
}

View File

@ -244,12 +244,12 @@ class Logger {
}
private:
static constexpr size_t kBufferSize = 8_MiB;
static const size_t kBufferSize = 8_MiB;
uint8_t buffer_[kBufferSize];
static constexpr size_t kBlockSize = 256;
static constexpr size_t kBlockCount = kBufferSize / kBlockSize;
static constexpr size_t kBlockIndexMask = kBlockCount - 1;
static const size_t kBlockSize = 256;
static const size_t kBlockCount = kBufferSize / kBlockSize;
static const size_t kBlockIndexMask = kBlockCount - 1;
static const size_t kClaimStrategyFootprint =
sizeof(std::atomic<dp::sequence_t>[kBlockCount]);
@ -353,14 +353,14 @@ class Logger {
? line_range.second[line_range.second_length - 1]
: line_range.first[line_range.first_length - 1];
if (last_char != '\n') {
constexpr char suffix[1] = {'\n'};
const char suffix[1] = {'\n'};
Write(suffix, 1);
}
rb.EndRead(std::move(line_range));
} else {
// Always ensure there is a newline.
constexpr char suffix[1] = {'\n'};
const char suffix[1] = {'\n'};
Write(suffix, 1);
}

View File

@ -1,46 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2023 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <xbyak/xbyak/xbyak_util.h>
#include "xenia/ui/window_gtk.h"
class StartupCpuFeatureCheck {
public:
StartupCpuFeatureCheck() {
Xbyak::util::Cpu cpu;
const char* error_message = nullptr;
if (!cpu.has(Xbyak::util::Cpu::tAVX)) {
error_message =
"Your CPU does not support AVX, which is required by Xenia. See "
"the "
"FAQ for system requirements at https://xenia.jp";
}
if (error_message == nullptr) {
return;
} else {
GtkDialogFlags flags = GTK_DIALOG_DESTROY_WITH_PARENT;
auto dialog =
gtk_message_dialog_new(nullptr, flags, GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE, "%s", error_message);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
exit(1);
}
}
};
// This is a hack to get an instance of StartupAvxCheck
// constructed before any initialization code,
// where the AVX check then happens in the constructor.
// Ref:
// https://reviews.llvm.org/D12689#243295
__attribute__((
init_priority(101))) static StartupCpuFeatureCheck gStartupAvxCheck;

View File

@ -60,7 +60,7 @@ static void RequestWin32HighResolutionTimer() {
ULONG minimum_resolution, maximum_resolution, current_resolution;
nt_query_timer_resolution(&minimum_resolution, &maximum_resolution,
&current_resolution);
nt_set_timer_resolution(maximum_resolution, true, &current_resolution);
nt_set_timer_resolution(maximum_resolution, TRUE, &current_resolution);
}
static void RequestWin32MMCSS() {
@ -74,7 +74,7 @@ static void RequestWin32MMCSS() {
dwm_enable_mmcss = reinterpret_cast<decltype(dwm_enable_mmcss)>(
GetProcAddress(dwmapi_module, "DwmEnableMMCSS"));
if (dwm_enable_mmcss) {
dwm_enable_mmcss(true);
dwm_enable_mmcss(TRUE);
}
FreeLibrary(dwmapi_module);
}

View File

@ -29,7 +29,7 @@ class Win32MappedMemory : public MappedMemory {
public:
// CreateFile returns INVALID_HANDLE_VALUE in case of failure.
// chrispy: made inline const to get around clang error
static inline constexpr HANDLE kFileHandleInvalid = INVALID_HANDLE_VALUE;
static inline const HANDLE kFileHandleInvalid = INVALID_HANDLE_VALUE;
// CreateFileMapping returns nullptr in case of failure.
static constexpr HANDLE kMappingHandleInvalid = nullptr;

View File

@ -473,7 +473,7 @@ void copy_and_swap_16_unaligned(void* dst_ptr, const void* src_ptr,
auto dst = reinterpret_cast<uint8_t*>(dst_ptr);
auto src = reinterpret_cast<const uint8_t*>(src_ptr);
constexpr uint8x16_t tbl_idx =
const uint8x16_t tbl_idx =
vcombine_u8(vcreate_u8(UINT64_C(0x0607040502030001)),
vcreate_u8(UINT64_C(0x0E0F0C0D0A0B0809)));
@ -507,7 +507,7 @@ void copy_and_swap_32_unaligned(void* dst_ptr, const void* src_ptr,
auto dst = reinterpret_cast<uint8_t*>(dst_ptr);
auto src = reinterpret_cast<const uint8_t*>(src_ptr);
constexpr uint8x16_t tbl_idx =
const uint8x16_t tbl_idx =
vcombine_u8(vcreate_u8(UINT64_C(0x405060700010203)),
vcreate_u8(UINT64_C(0x0C0D0E0F08090A0B)));
@ -539,7 +539,7 @@ void copy_and_swap_64_unaligned(void* dst_ptr, const void* src_ptr,
auto dst = reinterpret_cast<uint8_t*>(dst_ptr);
auto src = reinterpret_cast<const uint8_t*>(src_ptr);
constexpr uint8x16_t tbl_idx =
const uint8x16_t tbl_idx =
vcombine_u8(vcreate_u8(UINT64_C(0x0001020304050607)),
vcreate_u8(UINT64_C(0x08090A0B0C0D0E0F)));

View File

@ -813,12 +813,12 @@ template <unsigned Size>
static void smallset_const(void* destination, unsigned char fill_value) {
#if XE_ARCH_AMD64 == 1 && XE_COMPILER_MSVC == 1
if constexpr ((Size & 7) == 0) {
static unsigned long long fill =
unsigned long long fill =
static_cast<unsigned long long>(fill_value) * 0x0101010101010101ULL;
__stosq((unsigned long long*)destination, fill, Size / 8);
} else if constexpr ((Size & 3) == 0) {
static unsigned long fill =
static constexpr unsigned long fill =
static_cast<unsigned long>(fill_value) * 0x01010101U;
__stosd((unsigned long*)destination, fill, Size / 4);
// dont even bother with movsw, i think the operand size override prefix

View File

@ -13,9 +13,6 @@
#include <sys/mman.h>
#include <unistd.h>
#include <cstddef>
#include <fstream>
#include <mutex>
#include <sstream>
#include "xenia/base/math.h"
#include "xenia/base/platform.h"
@ -82,50 +79,19 @@ uint32_t ToPosixProtectFlags(PageAccess access) {
}
}
PageAccess ToXeniaProtectFlags(const char* protection) {
if (protection[0] == 'r' && protection[1] == 'w' && protection[2] == 'x') {
return PageAccess::kExecuteReadWrite;
}
if (protection[0] == 'r' && protection[1] == '-' && protection[2] == 'x') {
return PageAccess::kExecuteReadOnly;
}
if (protection[0] == 'r' && protection[1] == 'w' && protection[2] == '-') {
return PageAccess::kReadWrite;
}
if (protection[0] == 'r' && protection[1] == '-' && protection[2] == '-') {
return PageAccess::kReadOnly;
}
return PageAccess::kNoAccess;
}
bool IsWritableExecutableMemorySupported() { return true; }
struct MappedFileRange {
uintptr_t region_begin;
uintptr_t region_end;
};
std::vector<MappedFileRange> mapped_file_ranges;
std::mutex g_mapped_file_ranges_mutex;
void* AllocFixed(void* base_address, size_t length,
AllocationType allocation_type, PageAccess access) {
// mmap does not support reserve / commit, so ignore allocation_type.
uint32_t prot = ToPosixProtectFlags(access);
int flags = MAP_PRIVATE | MAP_ANONYMOUS;
int flags = 0;
if (base_address != nullptr) {
if (allocation_type == AllocationType::kCommit) {
if (Protect(base_address, length, access)) {
return base_address;
}
return nullptr;
}
flags |= MAP_FIXED_NOREPLACE;
flags = MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS;
} else {
flags = MAP_PRIVATE | MAP_ANONYMOUS;
}
void* result = mmap(base_address, length, prot, flags, -1, 0);
if (result != MAP_FAILED) {
return result;
}
@ -134,90 +100,19 @@ void* AllocFixed(void* base_address, size_t length,
bool DeallocFixed(void* base_address, size_t length,
DeallocationType deallocation_type) {
const auto region_begin = reinterpret_cast<uintptr_t>(base_address);
const uintptr_t region_end =
reinterpret_cast<uintptr_t>(base_address) + length;
std::lock_guard guard(g_mapped_file_ranges_mutex);
for (const auto& mapped_range : mapped_file_ranges) {
if (region_begin >= mapped_range.region_begin &&
region_end <= mapped_range.region_end) {
switch (deallocation_type) {
case DeallocationType::kDecommit:
return Protect(base_address, length, PageAccess::kNoAccess);
case DeallocationType::kRelease:
assert_always("Error: Tried to release mapped memory!");
default:
assert_unhandled_case(deallocation_type);
}
}
}
switch (deallocation_type) {
case DeallocationType::kDecommit:
return Protect(base_address, length, PageAccess::kNoAccess);
case DeallocationType::kRelease:
return munmap(base_address, length) == 0;
default:
assert_unhandled_case(deallocation_type);
}
return munmap(base_address, length) == 0;
}
bool Protect(void* base_address, size_t length, PageAccess access,
PageAccess* out_old_access) {
if (out_old_access) {
size_t length_copy = length;
QueryProtect(base_address, length_copy, *out_old_access);
}
// Linux does not have a syscall to query memory permissions.
assert_null(out_old_access);
uint32_t prot = ToPosixProtectFlags(access);
return mprotect(base_address, length, prot) == 0;
}
bool QueryProtect(void* base_address, size_t& length, PageAccess& access_out) {
// No generic POSIX solution exists. The Linux solution should work on all
// Linux kernel based OS, including Android.
std::ifstream memory_maps;
memory_maps.open("/proc/self/maps", std::ios_base::in);
std::string maps_entry_string;
while (std::getline(memory_maps, maps_entry_string)) {
std::stringstream entry_stream(maps_entry_string);
uintptr_t map_region_begin, map_region_end;
char separator, protection[4];
entry_stream >> std::hex >> map_region_begin >> separator >>
map_region_end >> protection;
if (map_region_begin <= reinterpret_cast<uintptr_t>(base_address) &&
map_region_end > reinterpret_cast<uintptr_t>(base_address)) {
length = map_region_end - reinterpret_cast<uintptr_t>(base_address);
access_out = ToXeniaProtectFlags(protection);
// Look at the next consecutive mappings
while (std::getline(memory_maps, maps_entry_string)) {
std::stringstream next_entry_stream(maps_entry_string);
uintptr_t next_map_region_begin, next_map_region_end;
char next_protection[4];
next_entry_stream >> std::hex >> next_map_region_begin >> separator >>
next_map_region_end >> next_protection;
if (map_region_end == next_map_region_begin &&
access_out == ToXeniaProtectFlags(next_protection)) {
length =
next_map_region_end - reinterpret_cast<uintptr_t>(base_address);
continue;
}
break;
}
memory_maps.close();
return true;
}
}
memory_maps.close();
return false;
}
@ -287,41 +182,12 @@ void CloseFileMappingHandle(FileMappingHandle handle,
void* MapFileView(FileMappingHandle handle, void* base_address, size_t length,
PageAccess access, size_t file_offset) {
uint32_t prot = ToPosixProtectFlags(access);
int flags = MAP_SHARED;
if (base_address != nullptr) {
flags |= MAP_FIXED_NOREPLACE;
}
void* result = mmap(base_address, length, prot, flags, handle, file_offset);
if (result != MAP_FAILED) {
std::lock_guard guard(g_mapped_file_ranges_mutex);
mapped_file_ranges.push_back(
{reinterpret_cast<uintptr_t>(result),
reinterpret_cast<uintptr_t>(result) + length});
return result;
}
return nullptr;
return mmap64(base_address, length, prot, MAP_PRIVATE | MAP_ANONYMOUS, handle,
file_offset);
}
bool UnmapFileView(FileMappingHandle handle, void* base_address,
size_t length) {
std::lock_guard guard(g_mapped_file_ranges_mutex);
for (auto mapped_range = mapped_file_ranges.begin();
mapped_range != mapped_file_ranges.end();) {
if (mapped_range->region_begin ==
reinterpret_cast<uintptr_t>(base_address) &&
mapped_range->region_end ==
reinterpret_cast<uintptr_t>(base_address) + length) {
mapped_file_ranges.erase(mapped_range);
return munmap(base_address, length) == 0;
}
++mapped_range;
}
// TODO: Implement partial file unmapping.
assert_always("Error: Partial unmapping of files not yet supported.");
return munmap(base_address, length) == 0;
}

View File

@ -181,12 +181,12 @@
namespace xe {
#if XE_PLATFORM_WIN32
constexpr char kPathSeparator = '\\';
const char kPathSeparator = '\\';
#else
constexpr char kPathSeparator = '/';
const char kPathSeparator = '/';
#endif // XE_PLATFORM_WIN32
constexpr char kGuestPathSeparator = '\\';
const char kGuestPathSeparator = '\\';
} // namespace xe
#if XE_ARCH_AMD64 == 1

View File

@ -17,6 +17,4 @@ project("xenia-base")
"debug_visualizers.natvis",
})
if enableTests then
include("testing")
end
include("testing")

View File

@ -96,7 +96,7 @@ class Win32Socket : public Socket {
// Keepalive for a looong time, as we may be paused by the debugger/etc.
struct tcp_keepalive alive;
alive.onoff = true;
alive.onoff = TRUE;
alive.keepalivetime = 7200000;
alive.keepaliveinterval = 6000;
DWORD bytes_returned;
@ -209,7 +209,7 @@ class Win32SocketServer : public SocketServer {
SOCKET socket = socket_;
socket_ = INVALID_SOCKET;
linger so_linger;
so_linger.l_onoff = true;
so_linger.l_onoff = TRUE;
so_linger.l_linger = 30;
setsockopt(socket, SOL_SOCKET, SO_LINGER,
reinterpret_cast<const char*>(&so_linger), sizeof(so_linger));
@ -231,7 +231,7 @@ class Win32SocketServer : public SocketServer {
return false;
}
struct tcp_keepalive alive;
alive.onoff = true;
alive.onoff = TRUE;
alive.keepalivetime = 7200000;
alive.keepaliveinterval = 6000;
DWORD bytes_returned;

View File

@ -22,7 +22,7 @@
#include <strings.h>
#endif // !XE_PLATFORM_WIN32
#define UTF_CPP_CPLUSPLUS 202002L
#define UTF_CPP_CPLUSPLUS 201703L
#include "third_party/utfcpp/source/utf8.h"
namespace utfcpp = utf8;

View File

@ -16,7 +16,6 @@
#include <cstring>
#include <regex>
#include <string>
#include <variant>
#include "third_party/fmt/include/fmt/format.h"
#include "xenia/base/assert.h"
@ -429,28 +428,6 @@ inline vec128_t from_string<vec128_t>(const std::string_view value,
return v;
}
inline std::u16string read_u16string_and_swap(const char16_t* string_ptr) {
std::u16string input_str = std::u16string(string_ptr);
std::u16string output_str = {};
output_str.resize(input_str.size() + 1);
copy_and_swap_truncating(output_str.data(), input_str, input_str.size() + 1);
return output_str;
}
inline size_t size_in_bytes(std::variant<std::string, std::u16string> string,
bool include_terminator = true) {
if (std::holds_alternative<std::string>(string)) {
return std::get<std::string>(string).size() + include_terminator;
} else if (std::holds_alternative<std::u16string>(string)) {
return (std::get<std::u16string>(string).size() + include_terminator) *
sizeof(char16_t);
} else {
assert_always();
}
return 0;
}
} // namespace string_util
} // namespace xe

View File

@ -65,8 +65,8 @@ bool SetProcessPriorityClass(const uint32_t priority_class) {
}
bool IsUseNexusForGameBarEnabled() {
constexpr LPCWSTR reg_path = L"SOFTWARE\\Microsoft\\GameBar";
constexpr LPCWSTR key = L"UseNexusForGameBarEnabled";
const LPCWSTR reg_path = L"SOFTWARE\\Microsoft\\GameBar";
const LPCWSTR key = L"UseNexusForGameBarEnabled";
DWORD value = 0;
DWORD dataSize = sizeof(value);

View File

@ -516,7 +516,7 @@ TEST_CASE("create_and_close_file_mapping", "Virtual Memory Mapping") {
TEST_CASE("map_view", "[virtual_memory_mapping]") {
auto path = fmt::format("xenia_test_{}", Clock::QueryHostTickCount());
constexpr size_t length = 0x100;
const size_t length = 0x100;
auto memory = xe::memory::CreateFileMappingHandle(
path, length, xe::memory::PageAccess::kReadWrite, true);
REQUIRE(memory != xe::memory::kFileMappingHandleInvalid);
@ -532,7 +532,7 @@ TEST_CASE("map_view", "[virtual_memory_mapping]") {
}
TEST_CASE("read_write_view", "[virtual_memory_mapping]") {
constexpr size_t length = 0x100;
const size_t length = 0x100;
auto path = fmt::format("xenia_test_{}", Clock::QueryHostTickCount());
auto memory = xe::memory::CreateFileMappingHandle(
path, length, xe::memory::PageAccess::kReadWrite, true);

View File

@ -404,19 +404,19 @@ class Timer : public WaitHandle {
#if XE_PLATFORM_WIN32
struct ThreadPriority {
static constexpr int32_t kLowest = -2;
static constexpr int32_t kBelowNormal = -1;
static constexpr int32_t kNormal = 0;
static constexpr int32_t kAboveNormal = 1;
static constexpr int32_t kHighest = 2;
static const int32_t kLowest = -2;
static const int32_t kBelowNormal = -1;
static const int32_t kNormal = 0;
static const int32_t kAboveNormal = 1;
static const int32_t kHighest = 2;
};
#else
struct ThreadPriority {
static constexpr int32_t kLowest = 1;
static constexpr int32_t kBelowNormal = 8;
static constexpr int32_t kNormal = 16;
static constexpr int32_t kAboveNormal = 24;
static constexpr int32_t kHighest = 32;
static const int32_t kLowest = 1;
static const int32_t kBelowNormal = 8;
static const int32_t kNormal = 16;
static const int32_t kAboveNormal = 24;
static const int32_t kHighest = 32;
};
#endif

View File

@ -82,7 +82,8 @@ void AndroidShutdown() {
#endif
template <typename _Rep, typename _Period>
timespec DurationToTimeSpec(std::chrono::duration<_Rep, _Period> duration) {
inline timespec DurationToTimeSpec(
std::chrono::duration<_Rep, _Period> duration) {
auto nanoseconds =
std::chrono::duration_cast<std::chrono::nanoseconds>(duration);
auto div = ldiv(nanoseconds.count(), 1000000000L);
@ -160,8 +161,6 @@ void Sleep(std::chrono::microseconds duration) {
} while (ret == -1 && errno == EINTR);
}
void NanoSleep(int64_t duration) { Sleep(std::chrono::nanoseconds(duration)); }
// TODO(bwrsandman) Implement by allowing alert interrupts from IO operations
thread_local bool alertable_state_ = false;
SleepResult AlertableSleep(std::chrono::microseconds duration) {
@ -179,25 +178,28 @@ TlsHandle AllocateTlsHandle() {
return static_cast<TlsHandle>(key);
}
bool FreeTlsHandle(TlsHandle handle) { return pthread_key_delete(handle) == 0; }
bool FreeTlsHandle(TlsHandle handle) {
return pthread_key_delete(static_cast<pthread_key_t>(handle)) == 0;
}
uintptr_t GetTlsValue(TlsHandle handle) {
return reinterpret_cast<uintptr_t>(pthread_getspecific(handle));
return reinterpret_cast<uintptr_t>(
pthread_getspecific(static_cast<pthread_key_t>(handle)));
}
bool SetTlsValue(TlsHandle handle, uintptr_t value) {
return pthread_setspecific(handle, reinterpret_cast<void*>(value)) == 0;
return pthread_setspecific(static_cast<pthread_key_t>(handle),
reinterpret_cast<void*>(value)) == 0;
}
class PosixConditionBase {
public:
virtual ~PosixConditionBase() = default;
virtual bool Signal() = 0;
WaitResult Wait(std::chrono::milliseconds timeout) {
bool executed;
auto predicate = [this] { return this->signaled(); };
auto lock = std::unique_lock(mutex_);
auto lock = std::unique_lock<std::mutex>(mutex_);
if (predicate()) {
executed = true;
} else {
@ -211,14 +213,15 @@ class PosixConditionBase {
if (executed) {
post_execution();
return WaitResult::kSuccess;
} else {
return WaitResult::kTimeout;
}
return WaitResult::kTimeout;
}
static std::pair<WaitResult, size_t> WaitMultiple(
std::vector<PosixConditionBase*>&& handles, bool wait_all,
std::chrono::milliseconds timeout) {
assert_true(!handles.empty());
assert_true(handles.size() > 0);
// Construct a condition for all or any depending on wait_all
std::function<bool()> predicate;
@ -236,16 +239,17 @@ class PosixConditionBase {
// TODO(bwrsandman, Triang3l) This is controversial, see issue #1677
// This will probably cause a deadlock on the next thread doing any waiting
// if the thread is suspended between locking and waiting
std::unique_lock lock(mutex_);
std::unique_lock<std::mutex> lock(PosixConditionBase::mutex_);
bool wait_success = true;
// If the timeout is infinite, wait without timeout.
// The predicate will be checked before beginning the wait
if (timeout == std::chrono::milliseconds::max()) {
cond_.wait(lock, predicate);
PosixConditionBase::cond_.wait(lock, predicate);
} else {
// Wait with timeout.
wait_success = cond_.wait_for(lock, timeout, predicate);
wait_success =
PosixConditionBase::cond_.wait_for(lock, timeout, predicate);
}
if (wait_success) {
auto first_signaled = std::numeric_limits<size_t>::max();
@ -260,16 +264,15 @@ class PosixConditionBase {
}
assert_true(std::numeric_limits<size_t>::max() != first_signaled);
return std::make_pair(WaitResult::kSuccess, first_signaled);
} else {
return std::make_pair<WaitResult, size_t>(WaitResult::kTimeout, 0);
}
return std::make_pair<WaitResult, size_t>(WaitResult::kTimeout, 0);
}
[[nodiscard]] virtual void* native_handle() const {
return cond_.native_handle();
}
virtual void* native_handle() const { return cond_.native_handle(); }
protected:
[[nodiscard]] inline virtual bool signaled() const = 0;
inline virtual bool signaled() const = 0;
inline virtual void post_execution() = 0;
static std::condition_variable cond_;
static std::mutex mutex_;
@ -290,23 +293,23 @@ class PosixCondition<Event> : public PosixConditionBase {
public:
PosixCondition(bool manual_reset, bool initial_state)
: signal_(initial_state), manual_reset_(manual_reset) {}
~PosixCondition() override = default;
virtual ~PosixCondition() = default;
bool Signal() override {
auto lock = std::unique_lock(mutex_);
auto lock = std::unique_lock<std::mutex>(mutex_);
signal_ = true;
cond_.notify_all();
return true;
}
void Reset() {
auto lock = std::unique_lock(mutex_);
auto lock = std::unique_lock<std::mutex>(mutex_);
signal_ = false;
}
private:
[[nodiscard]] bool signaled() const override { return signal_; }
void post_execution() override {
inline bool signaled() const override { return signal_; }
inline void post_execution() override {
if (!manual_reset_) {
signal_ = false;
}
@ -316,7 +319,7 @@ class PosixCondition<Event> : public PosixConditionBase {
};
template <>
class PosixCondition<Semaphore> final : public PosixConditionBase {
class PosixCondition<Semaphore> : public PosixConditionBase {
public:
PosixCondition(uint32_t initial_count, uint32_t maximum_count)
: count_(initial_count), maximum_count_(maximum_count) {}
@ -325,7 +328,7 @@ class PosixCondition<Semaphore> final : public PosixConditionBase {
bool Release(uint32_t release_count, int* out_previous_count) {
if (maximum_count_ - count_ >= release_count) {
auto lock = std::unique_lock(mutex_);
auto lock = std::unique_lock<std::mutex>(mutex_);
if (out_previous_count) *out_previous_count = count_;
count_ += release_count;
cond_.notify_all();
@ -335,8 +338,8 @@ class PosixCondition<Semaphore> final : public PosixConditionBase {
}
private:
[[nodiscard]] bool signaled() const override { return count_ > 0; }
void post_execution() override {
inline bool signaled() const override { return count_ > 0; }
inline void post_execution() override {
count_--;
cond_.notify_all();
}
@ -345,7 +348,7 @@ class PosixCondition<Semaphore> final : public PosixConditionBase {
};
template <>
class PosixCondition<Mutant> final : public PosixConditionBase {
class PosixCondition<Mutant> : public PosixConditionBase {
public:
explicit PosixCondition(bool initial_owner) : count_(0) {
if (initial_owner) {
@ -358,7 +361,7 @@ class PosixCondition<Mutant> final : public PosixConditionBase {
bool Release() {
if (owner_ == std::this_thread::get_id() && count_ > 0) {
auto lock = std::unique_lock(mutex_);
auto lock = std::unique_lock<std::mutex>(mutex_);
--count_;
// Free to be acquired by another thread
if (count_ == 0) {
@ -369,15 +372,13 @@ class PosixCondition<Mutant> final : public PosixConditionBase {
return false;
}
[[nodiscard]] void* native_handle() const override {
return mutex_.native_handle();
}
void* native_handle() const override { return mutex_.native_handle(); }
private:
[[nodiscard]] bool signaled() const override {
inline bool signaled() const override {
return count_ == 0 || owner_ == std::this_thread::get_id();
}
void post_execution() override {
inline void post_execution() override {
count_++;
owner_ = std::this_thread::get_id();
}
@ -386,15 +387,15 @@ class PosixCondition<Mutant> final : public PosixConditionBase {
};
template <>
class PosixCondition<Timer> final : public PosixConditionBase {
class PosixCondition<Timer> : public PosixConditionBase {
public:
explicit PosixCondition(bool manual_reset)
: callback_(nullptr), signal_(false), manual_reset_(manual_reset) {}
~PosixCondition() override { Cancel(); }
virtual ~PosixCondition() { Cancel(); }
bool Signal() override {
std::lock_guard lock(mutex_);
std::lock_guard<std::mutex> lock(mutex_);
signal_ = true;
cond_.notify_all();
return true;
@ -404,7 +405,7 @@ class PosixCondition<Timer> final : public PosixConditionBase {
std::function<void()> opt_callback) {
Cancel();
std::lock_guard lock(mutex_);
std::lock_guard<std::mutex> lock(mutex_);
callback_ = std::move(opt_callback);
signal_ = false;
@ -416,7 +417,7 @@ class PosixCondition<Timer> final : public PosixConditionBase {
std::function<void()> opt_callback) {
Cancel();
std::lock_guard lock(mutex_);
std::lock_guard<std::mutex> lock(mutex_);
callback_ = std::move(opt_callback);
signal_ = false;
@ -424,13 +425,13 @@ class PosixCondition<Timer> final : public PosixConditionBase {
QueueTimerRecurring(&CompletionRoutine, this, due_time, period);
}
void Cancel() const {
void Cancel() {
if (auto wait_item = wait_item_.lock()) {
wait_item->Disarm();
}
}
[[nodiscard]] void* native_handle() const override {
void* native_handle() const override {
assert_always();
return nullptr;
}
@ -438,12 +439,12 @@ class PosixCondition<Timer> final : public PosixConditionBase {
private:
static void CompletionRoutine(void* userdata) {
assert_not_null(userdata);
auto timer = static_cast<PosixCondition*>(userdata);
auto timer = reinterpret_cast<PosixCondition<Timer>*>(userdata);
timer->Signal();
// As the callback may reset the timer, store local.
std::function<void()> callback;
{
std::lock_guard lock(timer->mutex_);
std::lock_guard<std::mutex> lock(timer->mutex_);
callback = timer->callback_;
}
if (callback) {
@ -451,8 +452,9 @@ class PosixCondition<Timer> final : public PosixConditionBase {
}
}
[[nodiscard]] bool signaled() const override { return signal_; }
void post_execution() override {
private:
inline bool signaled() const override { return signal_; }
inline void post_execution() override {
if (!manual_reset_) {
signal_ = false;
}
@ -470,7 +472,7 @@ struct ThreadStartData {
};
template <>
class PosixCondition<Thread> final : public PosixConditionBase {
class PosixCondition<Thread> : public PosixConditionBase {
enum class State {
kUninitialized,
kRunning,
@ -524,18 +526,13 @@ class PosixCondition<Thread> final : public PosixConditionBase {
: thread_(thread),
signaled_(false),
exit_code_(0),
state_(State::kRunning),
suspend_count_(0) {
state_(State::kRunning) {
#if XE_PLATFORM_ANDROID
android_pre_api_26_name_[0] = '\0';
#endif
}
~PosixCondition() override {
// FIXME(RodoMa92): This causes random crashes.
// The proper way to handle them according to the webs is properly shutdown
// instead on relying on killing them using pthread_cancel.
/*
virtual ~PosixCondition() {
if (thread_ && !signaled_) {
#if XE_PLATFORM_ANDROID
if (pthread_kill(thread_,
@ -551,7 +548,6 @@ class PosixCondition<Thread> final : public PosixConditionBase {
assert_always();
}
}
*/
}
bool Signal() override { return true; }
@ -559,7 +555,7 @@ class PosixCondition<Thread> final : public PosixConditionBase {
std::string name() const {
WaitStarted();
auto result = std::array<char, 17>{'\0'};
std::unique_lock lock(state_mutex_);
std::unique_lock<std::mutex> lock(state_mutex_);
if (state_ != State::kUninitialized && state_ != State::kFinished) {
#if XE_PLATFORM_ANDROID
// pthread_getname_np was added in API 26 - below that, store the name in
@ -583,7 +579,7 @@ class PosixCondition<Thread> final : public PosixConditionBase {
return std::string(result.data());
}
void set_name(const std::string& name) const {
void set_name(const std::string& name) {
WaitStarted();
std::unique_lock<std::mutex> lock(state_mutex_);
if (state_ != State::kUninitialized && state_ != State::kFinished) {
@ -607,7 +603,7 @@ class PosixCondition<Thread> final : public PosixConditionBase {
uint32_t system_id() const { return static_cast<uint32_t>(thread_); }
uint64_t affinity_mask() const {
uint64_t affinity_mask() {
WaitStarted();
cpu_set_t cpu_set;
#if XE_PLATFORM_ANDROID
@ -629,7 +625,7 @@ class PosixCondition<Thread> final : public PosixConditionBase {
return result;
}
void set_affinity_mask(uint64_t mask) const {
void set_affinity_mask(uint64_t mask) {
WaitStarted();
cpu_set_t cpu_set;
CPU_ZERO(&cpu_set);
@ -650,7 +646,7 @@ class PosixCondition<Thread> final : public PosixConditionBase {
#endif
}
int priority() const {
int priority() {
WaitStarted();
int policy;
sched_param param{};
@ -662,7 +658,7 @@ class PosixCondition<Thread> final : public PosixConditionBase {
return param.sched_priority;
}
void set_priority(int new_priority) const {
void set_priority(int new_priority) {
WaitStarted();
sched_param param{};
param.sched_priority = new_priority;
@ -682,7 +678,7 @@ class PosixCondition<Thread> final : public PosixConditionBase {
void QueueUserCallback(std::function<void()> callback) {
WaitStarted();
std::unique_lock lock(callback_mutex_);
std::unique_lock<std::mutex> lock(callback_mutex_);
user_callback_ = std::move(callback);
sigval value{};
value.sival_ptr = this;
@ -695,8 +691,8 @@ class PosixCondition<Thread> final : public PosixConditionBase {
#endif
}
void CallUserCallback() const {
std::unique_lock lock(callback_mutex_);
void CallUserCallback() {
std::unique_lock<std::mutex> lock(callback_mutex_);
user_callback_();
}
@ -705,7 +701,7 @@ class PosixCondition<Thread> final : public PosixConditionBase {
*out_previous_suspend_count = 0;
}
WaitStarted();
std::unique_lock lock(state_mutex_);
std::unique_lock<std::mutex> lock(state_mutex_);
if (state_ != State::kSuspended) return false;
if (out_previous_suspend_count) {
*out_previous_suspend_count = suspend_count_;
@ -735,7 +731,7 @@ class PosixCondition<Thread> final : public PosixConditionBase {
void Terminate(int exit_code) {
bool is_current_thread = pthread_self() == thread_;
{
std::unique_lock lock(state_mutex_);
std::unique_lock<std::mutex> lock(state_mutex_);
if (state_ == State::kFinished) {
if (is_current_thread) {
// This is really bad. Some thread must have called Terminate() on us
@ -751,7 +747,7 @@ class PosixCondition<Thread> final : public PosixConditionBase {
}
{
std::lock_guard lock(mutex_);
std::lock_guard<std::mutex> lock(mutex_);
exit_code_ = exit_code;
signaled_ = true;
@ -759,28 +755,29 @@ class PosixCondition<Thread> final : public PosixConditionBase {
}
if (is_current_thread) {
pthread_exit(reinterpret_cast<void*>(exit_code));
}
} else {
#ifdef XE_PLATFORM_ANDROID
if (pthread_kill(thread_, GetSystemSignal(SignalType::kThreadTerminate)) !=
0) {
assert_always();
}
if (pthread_kill(thread_,
GetSystemSignal(SignalType::kThreadTerminate)) != 0) {
assert_always();
}
#else
if (pthread_cancel(thread_) != 0) {
assert_always();
}
if (pthread_cancel(thread_) != 0) {
assert_always();
}
#endif
}
}
void WaitStarted() const {
std::unique_lock lock(state_mutex_);
std::unique_lock<std::mutex> lock(state_mutex_);
state_signal_.wait(lock,
[this] { return state_ != State::kUninitialized; });
}
/// Set state to suspended and wait until it reset by another thread
void WaitSuspended() {
std::unique_lock lock(state_mutex_);
std::unique_lock<std::mutex> lock(state_mutex_);
state_signal_.wait(lock, [this] { return suspend_count_ == 0; });
state_ = State::kRunning;
}
@ -791,8 +788,8 @@ class PosixCondition<Thread> final : public PosixConditionBase {
private:
static void* ThreadStartRoutine(void* parameter);
bool signaled() const override { return signaled_; }
void post_execution() override {
inline bool signaled() const override { return signaled_; }
inline void post_execution() override {
if (thread_) {
pthread_join(thread_, nullptr);
}
@ -816,7 +813,6 @@ class PosixCondition<Thread> final : public PosixConditionBase {
class PosixWaitHandle {
public:
virtual ~PosixWaitHandle() = default;
virtual PosixConditionBase& condition() = 0;
};
@ -833,9 +829,7 @@ class PosixConditionHandle : public T, public PosixWaitHandle {
~PosixConditionHandle() override = default;
PosixCondition<T>& condition() override { return handle_; }
[[nodiscard]] void* native_handle() const override {
return handle_.native_handle();
}
void* native_handle() const override { return handle_.native_handle(); }
protected:
PosixCondition<T> handle_;
@ -916,7 +910,7 @@ std::pair<WaitResult, size_t> WaitMultiple(WaitHandle* wait_handles[],
return result;
}
class PosixEvent final : public PosixConditionHandle<Event> {
class PosixEvent : public PosixConditionHandle<Event> {
public:
PosixEvent(bool manual_reset, bool initial_state)
: PosixConditionHandle(manual_reset, initial_state) {}
@ -945,7 +939,7 @@ std::unique_ptr<Event> Event::CreateAutoResetEvent(bool initial_state) {
return std::make_unique<PosixEvent>(false, initial_state);
}
class PosixSemaphore final : public PosixConditionHandle<Semaphore> {
class PosixSemaphore : public PosixConditionHandle<Semaphore> {
public:
PosixSemaphore(int initial_count, int maximum_count)
: PosixConditionHandle(static_cast<uint32_t>(initial_count),
@ -969,7 +963,7 @@ std::unique_ptr<Semaphore> Semaphore::Create(int initial_count,
return std::make_unique<PosixSemaphore>(initial_count, maximum_count);
}
class PosixMutant final : public PosixConditionHandle<Mutant> {
class PosixMutant : public PosixConditionHandle<Mutant> {
public:
explicit PosixMutant(bool initial_owner)
: PosixConditionHandle(initial_owner) {}
@ -981,9 +975,9 @@ std::unique_ptr<Mutant> Mutant::Create(bool initial_owner) {
return std::make_unique<PosixMutant>(initial_owner);
}
class PosixTimer final : public PosixConditionHandle<Timer> {
using WClock_ = WClock_;
using GClock_ = GClock_;
class PosixTimer : public PosixConditionHandle<Timer> {
using WClock_ = Timer::WClock_;
using GClock_ = Timer::GClock_;
public:
explicit PosixTimer(bool manual_reset) : PosixConditionHandle(manual_reset) {}
@ -1036,7 +1030,7 @@ std::unique_ptr<Timer> Timer::CreateSynchronizationTimer() {
return std::make_unique<PosixTimer>(false);
}
class PosixThread final : public PosixConditionHandle<Thread> {
class PosixThread : public PosixConditionHandle<Thread> {
public:
PosixThread() = default;
explicit PosixThread(pthread_t thread) : PosixConditionHandle(thread) {}
@ -1108,14 +1102,14 @@ void* PosixCondition<Thread>::ThreadStartRoutine(void* parameter) {
current_thread_ = thread;
{
std::unique_lock lock(thread->handle_.state_mutex_);
std::unique_lock<std::mutex> lock(thread->handle_.state_mutex_);
thread->handle_.state_ =
create_suspended ? State::kSuspended : State::kRunning;
thread->handle_.state_signal_.notify_all();
}
if (create_suspended) {
std::unique_lock lock(thread->handle_.state_mutex_);
std::unique_lock<std::mutex> lock(thread->handle_.state_mutex_);
thread->handle_.suspend_count_ = 1;
thread->handle_.state_signal_.wait(
lock, [thread] { return thread->handle_.suspend_count_ == 0; });
@ -1124,11 +1118,11 @@ void* PosixCondition<Thread>::ThreadStartRoutine(void* parameter) {
start_routine();
{
std::unique_lock lock(thread->handle_.state_mutex_);
std::unique_lock<std::mutex> lock(thread->handle_.state_mutex_);
thread->handle_.state_ = State::kFinished;
}
std::unique_lock lock(mutex_);
std::unique_lock<std::mutex> lock(mutex_);
thread->handle_.exit_code_ = 0;
thread->handle_.signaled_ = true;
cond_.notify_all();

View File

@ -170,7 +170,7 @@ void Sleep(std::chrono::microseconds duration) {
}
SleepResult AlertableSleep(std::chrono::microseconds duration) {
if (SleepEx(static_cast<DWORD>(duration.count() / 1000), true) ==
if (SleepEx(static_cast<DWORD>(duration.count() / 1000), TRUE) ==
WAIT_IO_COMPLETION) {
return SleepResult::kAlerted;
}
@ -211,7 +211,7 @@ WaitResult Wait(WaitHandle* wait_handle, bool is_alertable,
HANDLE handle = wait_handle->native_handle();
DWORD result;
DWORD timeout_dw = DWORD(timeout.count());
BOOL bAlertable = is_alertable ? true : false;
BOOL bAlertable = is_alertable ? TRUE : FALSE;
// todo: we might actually be able to use NtWaitForSingleObject even if its
// alertable, just need to study whether
// RtlDeactivateActivationContextUnsafeFast/RtlActivateActivationContext are
@ -251,7 +251,7 @@ WaitResult SignalAndWait(WaitHandle* wait_handle_to_signal,
HANDLE handle_to_wait_on = wait_handle_to_wait_on->native_handle();
DWORD result =
SignalObjectAndWait(handle_to_signal, handle_to_wait_on,
DWORD(timeout.count()), is_alertable ? true : false);
DWORD(timeout.count()), is_alertable ? TRUE : FALSE);
switch (result) {
case WAIT_OBJECT_0:
return WaitResult::kSuccess;
@ -278,8 +278,8 @@ std::pair<WaitResult, size_t> WaitMultiple(WaitHandle* wait_handles[],
handles[i] = wait_handles[i]->native_handle();
}
DWORD result = WaitForMultipleObjectsEx(
static_cast<DWORD>(wait_handle_count), handles, wait_all ? true : false,
DWORD(timeout.count()), is_alertable ? true : false);
static_cast<DWORD>(wait_handle_count), handles, wait_all ? TRUE : FALSE,
DWORD(timeout.count()), is_alertable ? TRUE : FALSE);
if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + wait_handle_count) {
return std::pair<WaitResult, size_t>(WaitResult::kSuccess,
result - WAIT_OBJECT_0);
@ -339,7 +339,7 @@ class Win32Event : public Win32Handle<Event> {
std::unique_ptr<Event> Event::CreateManualResetEvent(bool initial_state) {
HANDLE handle =
CreateEvent(nullptr, true, initial_state ? true : false, nullptr);
CreateEvent(nullptr, TRUE, initial_state ? TRUE : FALSE, nullptr);
if (handle) {
return std::make_unique<Win32Event>(handle);
} else {
@ -351,7 +351,7 @@ std::unique_ptr<Event> Event::CreateManualResetEvent(bool initial_state) {
std::unique_ptr<Event> Event::CreateAutoResetEvent(bool initial_state) {
HANDLE handle =
CreateEvent(nullptr, false, initial_state ? true : false, nullptr);
CreateEvent(nullptr, FALSE, initial_state ? TRUE : FALSE, nullptr);
if (handle) {
return std::make_unique<Win32Event>(handle);
} else {
@ -397,7 +397,7 @@ class Win32Mutant : public Win32Handle<Mutant> {
};
std::unique_ptr<Mutant> Mutant::Create(bool initial_owner) {
HANDLE handle = CreateMutex(nullptr, initial_owner ? true : false, nullptr);
HANDLE handle = CreateMutex(nullptr, initial_owner ? TRUE : FALSE, nullptr);
if (handle) {
return std::make_unique<Win32Mutant>(handle);
} else {
@ -433,7 +433,7 @@ class Win32Timer : public Win32Handle<Timer> {
callback_ ? reinterpret_cast<PTIMERAPCROUTINE>(CompletionRoutine)
: NULL;
return SetWaitableTimer(handle_, &due_time_li, 0, completion_routine, this,
false)
FALSE)
? true
: false;
}
@ -461,7 +461,7 @@ class Win32Timer : public Win32Handle<Timer> {
callback_ ? reinterpret_cast<PTIMERAPCROUTINE>(CompletionRoutine)
: NULL;
return SetWaitableTimer(handle_, &due_time_li, int32_t(period.count()),
completion_routine, this, false)
completion_routine, this, FALSE)
? true
: false;
}
@ -490,7 +490,7 @@ class Win32Timer : public Win32Handle<Timer> {
};
std::unique_ptr<Timer> Timer::CreateManualResetTimer() {
HANDLE handle = CreateWaitableTimer(NULL, true, NULL);
HANDLE handle = CreateWaitableTimer(NULL, TRUE, NULL);
if (handle) {
return std::make_unique<Win32Timer>(handle);
} else {
@ -500,7 +500,7 @@ std::unique_ptr<Timer> Timer::CreateManualResetTimer() {
}
std::unique_ptr<Timer> Timer::CreateSynchronizationTimer() {
HANDLE handle = CreateWaitableTimer(NULL, false, NULL);
HANDLE handle = CreateWaitableTimer(NULL, FALSE, NULL);
if (handle) {
return std::make_unique<Win32Timer>(handle);
} else {

View File

@ -15,7 +15,7 @@
#include <numeric>
#include <tuple>
#define UTF_CPP_CPLUSPLUS 202002L
#define UTF_CPP_CPLUSPLUS 201703L
#include "third_party/utfcpp/source/utf8.h"
namespace utfcpp = utf8;
@ -82,10 +82,10 @@ std::string upper_ascii(const std::string_view view) {
template <bool LOWER>
inline size_t hash_fnv1a(const std::string_view view) {
constexpr size_t offset_basis = 0xCBF29CE484222325ull;
const size_t offset_basis = 0xCBF29CE484222325ull;
// chrispy: constant capture errors on clang
auto work = [](size_t hash, uint8_t byte_of_data) {
constexpr size_t prime = 0x00000100000001B3ull;
const size_t prime = 0x00000100000001B3ull;
hash ^= byte_of_data;
hash *= prime;
return hash;

View File

@ -206,7 +206,7 @@ void SaveConfig() {
line_count = xe::utf8::count(*last);
}
constexpr size_t value_alignment = 50;
const size_t value_alignment = 50;
const auto& description = config_var->description();
if (!description.empty()) {
if (line_count < value_alignment) {

View File

@ -636,7 +636,7 @@ HostToGuestThunk X64HelperEmitter::EmitHostToGuestThunk() {
_code_offsets code_offsets = {};
constexpr size_t stack_size = StackLayout::THUNK_STACK_SIZE;
const size_t stack_size = StackLayout::THUNK_STACK_SIZE;
code_offsets.prolog = getSize();
@ -681,10 +681,13 @@ HostToGuestThunk X64HelperEmitter::EmitHostToGuestThunk() {
size_t tail;
} code_offsets = {};
constexpr size_t stack_size = StackLayout::THUNK_STACK_SIZE;
const size_t stack_size = StackLayout::THUNK_STACK_SIZE;
code_offsets.prolog = getSize();
// rsp + 0 = return address
mov(qword[rsp + 8 * 3], rdx);
mov(qword[rsp + 8 * 2], rsi);
mov(qword[rsp + 8 * 1], rdi);
sub(rsp, stack_size);
code_offsets.prolog_stack_alloc = getSize();
@ -704,6 +707,9 @@ HostToGuestThunk X64HelperEmitter::EmitHostToGuestThunk() {
code_offsets.epilog = getSize();
add(rsp, stack_size);
mov(rdi, qword[rsp + 8 * 1]);
mov(rsi, qword[rsp + 8 * 2]);
mov(rdx, qword[rsp + 8 * 3]);
ret();
#else
assert_always("Unknown platform ABI in host to guest thunk!");
@ -735,7 +741,7 @@ GuestToHostThunk X64HelperEmitter::EmitGuestToHostThunk() {
_code_offsets code_offsets = {};
constexpr size_t stack_size = StackLayout::THUNK_STACK_SIZE;
const size_t stack_size = StackLayout::THUNK_STACK_SIZE;
code_offsets.prolog = getSize();
@ -781,7 +787,7 @@ GuestToHostThunk X64HelperEmitter::EmitGuestToHostThunk() {
size_t tail;
} code_offsets = {};
constexpr size_t stack_size = StackLayout::THUNK_STACK_SIZE;
const size_t stack_size = StackLayout::THUNK_STACK_SIZE;
code_offsets.prolog = getSize();
@ -838,7 +844,7 @@ ResolveFunctionThunk X64HelperEmitter::EmitResolveFunctionThunk() {
_code_offsets code_offsets = {};
constexpr size_t stack_size = StackLayout::THUNK_STACK_SIZE;
const size_t stack_size = StackLayout::THUNK_STACK_SIZE;
code_offsets.prolog = getSize();
@ -878,7 +884,7 @@ ResolveFunctionThunk X64HelperEmitter::EmitResolveFunctionThunk() {
size_t epilog;
size_t tail;
} code_offsets = {};
constexpr size_t stack_size = StackLayout::THUNK_STACK_SIZE;
const size_t stack_size = StackLayout::THUNK_STACK_SIZE;
code_offsets.prolog = getSize();
@ -1737,7 +1743,7 @@ void X64Backend::PrepareForReentry(void* ctx) {
bctx->current_stackpoint_depth = 0;
}
constexpr uint32_t mxcsr_table[8] = {
const uint32_t mxcsr_table[8] = {
0x1F80, 0x7F80, 0x5F80, 0x3F80, 0x9F80, 0xFF80, 0xDF80, 0xBF80,
};

View File

@ -120,7 +120,7 @@ constexpr unsigned int DEFAULT_FPU_MXCSR = 0x1F80;
extern const uint32_t mxcsr_table[8];
class X64Backend : public Backend {
public:
static constexpr uint32_t kForceReturnAddress = 0x9FFF0000u;
static const uint32_t kForceReturnAddress = 0x9FFF0000u;
explicit X64Backend();
~X64Backend() override;

View File

@ -79,13 +79,13 @@ class X64CodeCache : public CodeCache {
protected:
// All executable code falls within 0x80000000 to 0x9FFFFFFF, so we can
// only map enough for lookups within that range.
static constexpr size_t kIndirectionTableSize = 0x1FFFFFFF;
static constexpr uintptr_t kIndirectionTableBase = 0x80000000;
static const size_t kIndirectionTableSize = 0x1FFFFFFF;
static const uintptr_t kIndirectionTableBase = 0x80000000;
// The code range is 512MB, but we know the total code games will have is
// pretty small (dozens of mb at most) and our expansion is reasonablish
// so 256MB should be more than enough.
static constexpr size_t kGeneratedCodeSize = 0x0FFFFFFF;
static constexpr uintptr_t kGeneratedCodeExecuteBase = 0xA0000000;
static const size_t kGeneratedCodeSize = 0x0FFFFFFF;
static const uintptr_t kGeneratedCodeExecuteBase = 0xA0000000;
// Used for writing when PageAccess::kExecuteReadWrite is not supported.
static const uintptr_t kGeneratedCodeWriteBase =
kGeneratedCodeExecuteBase + kGeneratedCodeSize + 1;
@ -95,7 +95,7 @@ class X64CodeCache : public CodeCache {
// in analysis triggering.
// chrispy: raised this, some games that were compiled with low optimization
// levels can exceed this
static constexpr size_t kMaximumFunctionCount = 1000000;
static const size_t kMaximumFunctionCount = 1000000;
struct UnwindReservation {
size_t data_size = 0;

View File

@ -92,7 +92,7 @@ typedef struct _UNWIND_INFO {
// Size of unwind info per function.
// TODO(benvanik): move this to emitter.
static constexpr uint32_t kUnwindInfoSize =
static const uint32_t kUnwindInfoSize =
sizeof(UNWIND_INFO) + (sizeof(UNWIND_CODE) * (6 - 1));
class Win32X64CodeCache : public X64CodeCache {

View File

@ -72,17 +72,17 @@ using xe::cpu::hir::HIRBuilder;
using xe::cpu::hir::Instr;
using namespace xe::literals;
static constexpr size_t kMaxCodeSize = 1_MiB;
static const size_t kMaxCodeSize = 1_MiB;
// static const size_t kStashOffsetHigh = 32 + 32;
constexpr uint32_t X64Emitter::gpr_reg_map_[X64Emitter::GPR_COUNT] = {
const uint32_t X64Emitter::gpr_reg_map_[X64Emitter::GPR_COUNT] = {
Xbyak::Operand::RBX, Xbyak::Operand::R10, Xbyak::Operand::R11,
Xbyak::Operand::R12, Xbyak::Operand::R13, Xbyak::Operand::R14,
Xbyak::Operand::R15,
};
constexpr uint32_t X64Emitter::xmm_reg_map_[X64Emitter::XMM_COUNT] = {
const uint32_t X64Emitter::xmm_reg_map_[X64Emitter::XMM_COUNT] = {
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
};
@ -1242,11 +1242,11 @@ void* X64Emitter::FindQwordConstantOffset(uint64_t qwordvalue) {
return nullptr;
}
// First location to try and place constants.
static constexpr uintptr_t kConstDataLocation = 0x20000000;
static constexpr uintptr_t kConstDataSize = sizeof(xmm_consts);
static const uintptr_t kConstDataLocation = 0x20000000;
static const uintptr_t kConstDataSize = sizeof(xmm_consts);
// Increment the location by this amount for every allocation failure.
static constexpr uintptr_t kConstDataIncrement = 0x00001000;
static const uintptr_t kConstDataIncrement = 0x00001000;
// This function places constant data that is used by the emitter later on.
// Only called once and used by multiple instances of the emitter.

View File

@ -227,8 +227,8 @@ class X64Emitter : public Xbyak::CodeGenerator {
// xmm0-2
// Available: rbx, r10-r15
// xmm4-xmm15 (save to get xmm3)
static constexpr int GPR_COUNT = 7;
static constexpr int XMM_COUNT = 12;
static const int GPR_COUNT = 7;
static const int XMM_COUNT = 12;
static constexpr size_t kStashOffset = 32;
static void SetupReg(const hir::Value* v, Xbyak::Reg8& r) {
auto idx = gpr_reg_map_[v->reg.index];

View File

@ -123,7 +123,7 @@ struct OpBase {};
template <typename T, KeyType KEY_TYPE>
struct Op : OpBase {
static constexpr KeyType key_type = KEY_TYPE;
static const KeyType key_type = KEY_TYPE;
};
struct VoidOp : Op<VoidOp, KEY_TYPE_X> {
@ -298,7 +298,7 @@ struct I;
template <hir::Opcode OPCODE, typename DEST>
struct I<OPCODE, DEST> : DestField<DEST> {
typedef DestField<DEST> BASE;
static constexpr hir::Opcode opcode = OPCODE;
static const hir::Opcode opcode = OPCODE;
static const uint32_t key =
InstrKey::Construct<OPCODE, DEST::key_type>::value;
static const KeyType dest_type = DEST::key_type;
@ -318,7 +318,7 @@ struct I<OPCODE, DEST> : DestField<DEST> {
template <hir::Opcode OPCODE, typename DEST, typename SRC1>
struct I<OPCODE, DEST, SRC1> : DestField<DEST> {
typedef DestField<DEST> BASE;
static constexpr hir::Opcode opcode = OPCODE;
static const hir::Opcode opcode = OPCODE;
static const uint32_t key =
InstrKey::Construct<OPCODE, DEST::key_type, SRC1::key_type>::value;
static const KeyType dest_type = DEST::key_type;
@ -341,7 +341,7 @@ struct I<OPCODE, DEST, SRC1> : DestField<DEST> {
template <hir::Opcode OPCODE, typename DEST, typename SRC1, typename SRC2>
struct I<OPCODE, DEST, SRC1, SRC2> : DestField<DEST> {
typedef DestField<DEST> BASE;
static constexpr hir::Opcode opcode = OPCODE;
static const hir::Opcode opcode = OPCODE;
static const uint32_t key =
InstrKey::Construct<OPCODE, DEST::key_type, SRC1::key_type,
SRC2::key_type>::value;
@ -369,7 +369,7 @@ template <hir::Opcode OPCODE, typename DEST, typename SRC1, typename SRC2,
typename SRC3>
struct I<OPCODE, DEST, SRC1, SRC2, SRC3> : DestField<DEST> {
typedef DestField<DEST> BASE;
static constexpr hir::Opcode opcode = OPCODE;
static const hir::Opcode opcode = OPCODE;
static const uint32_t key =
InstrKey::Construct<OPCODE, DEST::key_type, SRC1::key_type,
SRC2::key_type, SRC3::key_type>::value;

View File

@ -95,7 +95,7 @@ class StackLayout {
});
static_assert(sizeof(Thunk) % 16 == 0,
"sizeof(Thunk) must be a multiple of 16!");
static constexpr size_t THUNK_STACK_SIZE = sizeof(Thunk) + 8;
static const size_t THUNK_STACK_SIZE = sizeof(Thunk) + 8;
/**
*
@ -121,16 +121,16 @@ class StackLayout {
* +------------------+
*
*/
static constexpr size_t GUEST_STACK_SIZE = 104;
static const size_t GUEST_STACK_SIZE = 104;
// was GUEST_CTX_HOME, can't remove because that'd throw stack alignment off.
// instead, can be used as a temporary in sequences
static constexpr size_t GUEST_SCRATCH = 0;
static const size_t GUEST_SCRATCH = 0;
// when profiling is on, this stores the nanosecond time at the start of the
// function
static constexpr size_t GUEST_PROFILER_START = 80;
static constexpr size_t GUEST_RET_ADDR = 88;
static constexpr size_t GUEST_CALL_RET_ADDR = 96;
static const size_t GUEST_PROFILER_START = 80;
static const size_t GUEST_RET_ADDR = 88;
static const size_t GUEST_CALL_RET_ADDR = 96;
};
} // namespace x64

View File

@ -48,7 +48,7 @@ bool ControlFlowSimplificationPass::Run(HIRBuilder* builder) {
block = builder->last_block();
while (block) {
auto prev_block = block->prev;
constexpr uint32_t expected = Edge::DOMINATES | Edge::UNCONDITIONAL;
const uint32_t expected = Edge::DOMINATES | Edge::UNCONDITIONAL;
if (block->incoming_edge_head &&
(block->incoming_edge_head->flags & expected) == expected) {
// Dominated by the incoming block.

View File

@ -33,15 +33,8 @@ DEFINE_bool(trace_function_data, false,
DEFINE_bool(validate_hir, false,
"Perform validation checks on the HIR during compilation.", "CPU");
// https://github.com/bitsh1ft3r/Xenon/blob/091e8cd4dc4a7c697b4979eb200be7c9dee3590b/Xenon/Core/XCPU/PPU/PowerPC.h#L370
DEFINE_uint64(
pvr, 0x710700,
"Known PVR's.\n"
" 0x710200 = Used by Zephyr \n"
" 0x710300 = Used by Zephyr\n"
" 0x710500 = Used by Jasper\n"
" 0x710700 = Default\n"
" 0x710800 = Used by Corona V1 & V2\n"
"Processor version and revision number.\nBits 0 to 15 are the version "
"number.\nBits 16 to 31 are the revision number.\nNote: Some XEXs (such as "
"mfgbootlauncher.xex) may check for a value that's less than 0x710700.",

View File

@ -2100,7 +2100,7 @@ Value* HIRBuilder::CountLeadingZeros(Value* value) {
ASSERT_INTEGER_TYPE(value);
if (value->IsConstantZero()) {
static constexpr uint8_t zeros[] = {
static const uint8_t zeros[] = {
8,
16,
32,

View File

@ -14,7 +14,7 @@ namespace cpu {
namespace hir {
#define DEFINE_OPCODE(num, name, sig, flags) \
constexpr OpcodeInfo num##_info = { \
const OpcodeInfo num##_info = { \
num, \
flags, \
sig, \

View File

@ -20,8 +20,8 @@ namespace cpu {
namespace ppc {
constexpr size_t kNamePad = 11;
constexpr uint8_t kSpaces[kNamePad] = {0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20};
const uint8_t kSpaces[kNamePad] = {0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20};
void PadStringBuffer(StringBuffer* str, size_t base, size_t pad);
void PrintDisasm_bcx(const PPCDecodeData& d, StringBuffer* str);

View File

@ -44,7 +44,7 @@ using namespace xe::literals;
typedef std::vector<std::pair<std::string, std::string>> AnnotationList;
constexpr uint32_t START_ADDRESS = 0x80000000;
const uint32_t START_ADDRESS = 0x80000000;
struct TestCase {
TestCase(uint32_t address, std::string& name)

View File

@ -43,7 +43,7 @@ struct Context {
typedef std::vector<std::pair<std::string, std::string>> AnnotationList;
constexpr uint32_t START_ADDRESS = 0x00000000;
const uint32_t START_ADDRESS = 0x00000000;
struct TestCase {
TestCase(uint32_t address, std::string& name)

View File

@ -17,7 +17,6 @@ project("xenia-cpu-ppc-tests")
"xenia-base",
"xenia-kernel",
"xenia-patcher",
"xenia-hid-skylander",
})
files({
"ppc_testing_main.cc",

View File

@ -21,7 +21,9 @@ project("xenia-cpu")
local_platform_files("hir")
local_platform_files("ppc")
if enableTests then
include("testing")
include("ppc/testing")
end
include("testing")
include("ppc/testing")
-- filter({"configurations:Release", "platforms:Windows"})
-- buildoptions({
-- "/O1",
-- })

View File

@ -104,7 +104,7 @@ bool InitializeStackWalker() {
options |= SYMOPT_LOAD_LINES;
options |= SYMOPT_FAIL_CRITICAL_ERRORS;
sym_set_options_(options);
if (!sym_initialize_(GetCurrentProcess(), nullptr, true)) {
if (!sym_initialize_(GetCurrentProcess(), nullptr, TRUE)) {
XELOGE("Unable to initialize symbol services - already in use?");
return false;
}
@ -192,7 +192,7 @@ class Win32StackWalker : public StackWalker {
}
// Setup the frame for walking.
STACKFRAME64 stack_frame = {};
STACKFRAME64 stack_frame = {0};
stack_frame.AddrPC.Mode = AddrModeFlat;
stack_frame.AddrPC.Offset = thread_context.Rip;
stack_frame.AddrFrame.Mode = AddrModeFlat;

View File

@ -10,7 +10,6 @@ test_suite("xenia-cpu-tests", project_root, ".", {
"xenia-core",
"xenia-cpu",
"xenia-gpu",
"xenia-hid-skylander",
-- TODO(benvanik): cut these dependencies?
"xenia-kernel",

View File

@ -50,10 +50,10 @@ DEFINE_bool(
DECLARE_bool(allow_plugins);
static constexpr uint8_t xe_xex2_retail_key[16] = {
static const uint8_t xe_xex2_retail_key[16] = {
0x20, 0xB1, 0x85, 0xA5, 0x9D, 0x28, 0xFD, 0xC3,
0x40, 0x58, 0x3F, 0xBB, 0x08, 0x96, 0xBF, 0x91};
static constexpr uint8_t xe_xex2_devkit_key[16] = {
static const uint8_t xe_xex2_devkit_key[16] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@ -1505,13 +1505,13 @@ std::vector<uint32_t> XexModule::PreanalyzeCode() {
uint32_t* range_end = (uint32_t*)memory()->TranslateVirtual(
high_8_aligned); // align down to multiple of 8
constexpr uint8_t mfspr_r12_lr[4] = {0x7D, 0x88, 0x02, 0xA6};
const uint8_t mfspr_r12_lr[4] = {0x7D, 0x88, 0x02, 0xA6};
// a blr instruction, with 4 zero bytes afterwards to pad the next address
// to 8 byte alignment
// if we see this prior to our address, we can assume we are a function
// start
constexpr uint8_t blr[4] = {0x4E, 0x80, 0x0, 0x20};
const uint8_t blr[4] = {0x4E, 0x80, 0x0, 0x20};
uint32_t blr32 = *reinterpret_cast<const uint32_t*>(&blr[0]);
@ -1631,7 +1631,7 @@ bool XexModule::FindSaveRest() {
// special codegen.
// __savegprlr_14 to __savegprlr_31
// __restgprlr_14 to __restgprlr_31
static constexpr uint32_t gprlr_code_values[] = {
static const uint32_t gprlr_code_values[] = {
0x68FFC1F9, // __savegprlr_14
0x70FFE1F9, // __savegprlr_15
0x78FF01FA, // __savegprlr_16
@ -1673,7 +1673,7 @@ bool XexModule::FindSaveRest() {
};
// __savefpr_14 to __savefpr_31
// __restfpr_14 to __restfpr_31
static constexpr uint32_t fpr_code_values[] = {
static const uint32_t fpr_code_values[] = {
0x70FFCCD9, // __savefpr_14
0x78FFECD9, // __savefpr_15
0x80FF0CDA, // __savefpr_16
@ -1717,7 +1717,7 @@ bool XexModule::FindSaveRest() {
// __savevmx_64 to __savevmx_127
// __restvmx_14 to __restvmx_31
// __restvmx_64 to __restvmx_127
static constexpr uint32_t vmx_code_values[] = {
static const uint32_t vmx_code_values[] = {
0xE0FE6039, // __savevmx_14
0xCE61CB7D, 0xF0FE6039, 0xCE61EB7D, 0x00FF6039, 0xCE610B7E, 0x10FF6039,
0xCE612B7E, 0x20FF6039, 0xCE614B7E, 0x30FF6039, 0xCE616B7E, 0x40FF6039,

View File

@ -55,7 +55,7 @@ void DebugWindow::DebugDialog::OnDraw(ImGuiIO& io) {
debug_window_.DrawFrame(io);
}
static constexpr std::string_view kBaseTitle = "Xenia Debugger";
static const std::string kBaseTitle = "Xenia Debugger";
DebugWindow::DebugWindow(Emulator* emulator,
xe::ui::WindowedAppContext& app_context)
@ -1460,7 +1460,7 @@ void DebugWindow::UpdateCache() {
auto object_table = kernel_state->object_table();
app_context_.CallInUIThread([this]() {
std::string title = std::string(kBaseTitle);
std::string title = kBaseTitle;
switch (processor_->execution_state()) {
case cpu::ExecutionState::kEnded:
title += " (ended)";

View File

@ -137,8 +137,8 @@ class DebugWindow : public cpu::DebugListener {
// The current state of the UI. Use this to synchronize multiple parts of the
// UI.
struct ImState {
static constexpr int kRightPaneThreads = 0;
static constexpr int kRightPaneMemory = 1;
static const int kRightPaneThreads = 0;
static const int kRightPaneMemory = 1;
int right_pane_tab = kRightPaneThreads;
cpu::ThreadDebugInfo* thread_info = nullptr;

View File

@ -41,9 +41,9 @@
#include "xenia/hid/input_system.h"
#include "xenia/kernel/kernel_state.h"
#include "xenia/kernel/user_module.h"
#include "xenia/kernel/util/xdbf_utils.h"
#include "xenia/kernel/xam/achievement_manager.h"
#include "xenia/kernel/xam/xam_module.h"
#include "xenia/kernel/xam/xdbf/spa_info.h"
#include "xenia/kernel/xbdm/xbdm_module.h"
#include "xenia/kernel/xboxkrnl/xboxkrnl_module.h"
#include "xenia/memory.h"
@ -215,15 +215,12 @@ X_STATUS Emulator::Setup(
// logical processors.
xe::threading::EnableAffinityConfiguration();
XELOGI("{}: Initializing Memory...", __func__);
// Create memory system first, as it is required for other systems.
memory_ = std::make_unique<Memory>();
if (!memory_->Initialize()) {
XELOGE("{}: Cannot initalize memory!", __func__);
return result;
return false;
}
XELOGI("{}: Initializing Exports...", __func__);
// Shared export resolver used to attach and query for HLE exports.
export_resolver_ = std::make_unique<xe::cpu::ExportResolver>();
@ -244,38 +241,30 @@ X_STATUS Emulator::Setup(
backend.reset(new xe::cpu::backend::NullBackend());
}
XELOGI("{}: Initializing Processor...", __func__);
// Initialize the CPU.
processor_ = std::make_unique<xe::cpu::Processor>(memory_.get(),
export_resolver_.get());
if (!processor_->Setup(std::move(backend))) {
XELOGE("{}: Cannot initalize processor!", __func__);
return X_STATUS_UNSUCCESSFUL;
}
XELOGI("{}: Initializing Audio...", __func__);
// Initialize the APU.
if (audio_system_factory) {
audio_system_ = audio_system_factory(processor_.get());
if (!audio_system_) {
XELOGE("{}: Cannot initalize audio_system!", __func__);
return X_STATUS_NOT_IMPLEMENTED;
}
}
XELOGI("{}: Initializing Graphics...", __func__);
// Initialize the GPU.
graphics_system_ = graphics_system_factory();
if (!graphics_system_) {
XELOGE("{}: Cannot initalize graphics_system!", __func__);
return X_STATUS_NOT_IMPLEMENTED;
}
XELOGI("{}: Initializing HID...", __func__);
// Initialize the HID.
input_system_ = std::make_unique<xe::hid::InputSystem>(display_window_);
if (!input_system_) {
XELOGE("{}: Cannot initalize input_system!", __func__);
return X_STATUS_NOT_IMPLEMENTED;
}
if (input_driver_factory) {
@ -293,13 +282,11 @@ X_STATUS Emulator::Setup(
return result;
}
XELOGI("{}: Initializing VFS...", __func__);
// Bring up the virtual filesystem used by the kernel.
file_system_ = std::make_unique<xe::vfs::VirtualFileSystem>();
patcher_ = std::make_unique<xe::patcher::Patcher>(storage_root_);
XELOGI("{}: Initializing Kernel...", __func__);
// Shared kernel state.
kernel_state_ = std::make_unique<xe::kernel::KernelState>(this);
#define LOAD_KERNEL_MODULE(t) \
@ -312,22 +299,18 @@ X_STATUS Emulator::Setup(
plugin_loader_ = std::make_unique<xe::patcher::PluginLoader>(
kernel_state_.get(), storage_root() / "plugins");
XELOGI("{}: Starting graphics_system...", __func__);
// Setup the core components.
result = graphics_system_->Setup(
processor_.get(), kernel_state_.get(),
display_window_ ? &display_window_->app_context() : nullptr,
display_window_ != nullptr);
if (result) {
XELOGE("{}: Failed to setup graphics_system!", __func__);
return result;
}
if (audio_system_) {
XELOGI("{}: Starting audio_system...", __func__);
result = audio_system_->Setup(kernel_state_.get());
if (result) {
XELOGE("{}: Failed to setup audio_system!", __func__);
return result;
}
audio_media_player_ = std::make_unique<apu::AudioMediaPlayer>(
@ -461,7 +444,7 @@ Emulator::FileSignatureType Emulator::GetFileSignature(
}
const uint64_t file_size = std::filesystem::file_size(path);
constexpr int64_t header_size = 4;
const int64_t header_size = 4;
if (file_size < header_size) {
return FileSignatureType::Unknown;
@ -785,93 +768,53 @@ X_STATUS Emulator::DataMigration(const uint64_t xuid) {
return X_STATUS_SUCCESS;
}
X_STATUS Emulator::ProcessContentPackageHeader(
const std::filesystem::path& path, ContentInstallEntry& installation_info) {
installation_info.name_ = "Invalid Content Package!";
installation_info.content_type_ = XContentType::kInvalid;
installation_info.data_installation_path_ = xe::path_to_utf8(path.filename());
const auto header = vfs::XContentContainerDevice::ReadContainerHeader(path);
if (!header || !header->content_header.is_magic_valid()) {
installation_info.installation_state_ = InstallState::failed;
installation_info.installation_result_ = X_STATUS_INVALID_PARAMETER;
installation_info.installation_error_message_ = "Invalid Package Type!";
XELOGE("Failed to initialize device");
return X_STATUS_INVALID_PARAMETER;
}
// Always install savefiles to user signed to slot 0.
const auto profile =
kernel_state_->xam_state()->profile_manager()->GetProfile(
static_cast<uint8_t>(0));
uint64_t xuid = header->content_metadata.profile_id;
if (header->content_metadata.content_type == XContentType::kSavedGame &&
profile) {
xuid = profile->xuid();
}
installation_info.data_installation_path_ = fmt::format(
"{:016X}/{:08X}/{:08X}/{}", xuid,
header->content_metadata.execution_info.title_id.get(),
static_cast<uint32_t>(header->content_metadata.content_type.get()),
path.filename());
installation_info.header_installation_path_ = fmt::format(
"{:016X}/{:08X}/Headers/{:08X}/{}", xuid,
header->content_metadata.execution_info.title_id.get(),
static_cast<uint32_t>(header->content_metadata.content_type.get()),
path.filename());
installation_info.name_ =
xe::to_utf8(header->content_metadata.display_name(XLanguage::kEnglish));
installation_info.content_type_ =
static_cast<XContentType>(header->content_metadata.content_type);
installation_info.content_size_ = header->content_metadata.content_size;
installation_info.installation_state_ = InstallState::pending;
installation_info.icon_ = imgui_drawer_->LoadImGuiIcon(
std::span<const uint8_t>(header->content_metadata.title_thumbnail,
header->content_metadata.title_thumbnail_size));
return X_STATUS_SUCCESS;
}
X_STATUS Emulator::InstallContentPackage(
const std::filesystem::path& path, ContentInstallEntry& installation_info) {
installation_info.installation_state_ = InstallState::preparing;
std::unique_ptr<vfs::XContentContainerDevice> device =
const std::filesystem::path& path,
ContentInstallationInfo& installation_info) {
std::unique_ptr<vfs::Device> device =
vfs::XContentContainerDevice::CreateContentDevice("", path);
installation_info.content_name = "Invalid Content Package!";
installation_info.content_type = static_cast<XContentType>(0);
installation_info.installation_path = xe::path_to_utf8(path.filename());
if (!device || !device->Initialize()) {
XELOGE("Failed to initialize device");
return X_STATUS_INVALID_PARAMETER;
}
const std::filesystem::path installation_path =
content_root() / installation_info.data_installation_path_;
const vfs::XContentContainerDevice* dev =
(vfs::XContentContainerDevice*)device.get();
const std::filesystem::path header_path =
content_root() / installation_info.header_installation_path_;
// Always install savefiles to user signed to slot 0.
const auto profile =
kernel_state_->xam_state()->profile_manager()->GetProfile(
static_cast<uint8_t>(0));
if (!std::filesystem::exists(content_root())) {
const std::error_code ec = xe::filesystem::CreateFolder(content_root());
if (ec) {
installation_info.installation_state_ = InstallState::failed;
installation_info.installation_error_message_ = ec.message();
installation_info.installation_result_ = X_STATUS_ACCESS_DENIED;
return X_STATUS_ACCESS_DENIED;
}
uint64_t xuid = dev->xuid();
if (dev->content_type() == static_cast<uint32_t>(XContentType::kSavedGame) &&
profile) {
xuid = profile->xuid();
}
const auto disk_space = std::filesystem::space(content_root());
if (disk_space.available < installation_info.content_size_ * 1.1f) {
installation_info.installation_state_ = InstallState::failed;
installation_info.installation_error_message_ = "Insufficient disk space!";
installation_info.installation_result_ = X_STATUS_DISK_FULL;
return X_STATUS_DISK_FULL;
}
std::filesystem::path installation_path =
content_root() / fmt::format("{:016X}", xuid) /
fmt::format("{:08X}", dev->title_id()) /
fmt::format("{:08X}", dev->content_type()) / path.filename();
std::filesystem::path header_path =
content_root() / fmt::format("{:016X}", xuid) /
fmt::format("{:08X}", dev->title_id()) / "Headers" /
fmt::format("{:08X}", dev->content_type()) / path.filename();
installation_info.installation_path =
fmt::format("{:016X}/{:08X}/{:08X}/{}", xuid, dev->title_id(),
dev->content_type(), path.filename());
installation_info.content_name =
xe::to_utf8(dev->content_header().display_name());
installation_info.content_type =
static_cast<XContentType>(dev->content_type());
if (std::filesystem::exists(installation_path)) {
// TODO(Gliniak): Popup
@ -880,35 +823,21 @@ X_STATUS Emulator::InstallContentPackage(
std::error_code error_code;
std::filesystem::create_directories(installation_path, error_code);
if (error_code) {
installation_info.installation_state_ = InstallState::failed;
installation_info.installation_error_message_ =
"Cannot Create Content Directory!";
installation_info.installation_result_ = error_code.value();
installation_info.content_name = "Cannot Create Content Directory!";
return error_code.value();
}
}
installation_info.content_size_ = device->data_size();
installation_info.installation_state_ = InstallState::installing;
vfs::VirtualFileSystem::ExtractContentHeader(device.get(), header_path);
X_STATUS error_code = vfs::VirtualFileSystem::ExtractContentFiles(
device.get(), installation_path,
installation_info.currently_installed_size_);
device.get(), installation_path);
if (error_code != X_ERROR_SUCCESS) {
installation_info.installation_state_ = InstallState::failed;
return error_code;
}
installation_info.installation_state_ = InstallState::installed;
installation_info.currently_installed_size_ = installation_info.content_size_;
kernel_state()->BroadcastNotification(kXNotificationLiveContentInstalled, 0);
if (installation_info.content_type_ == XContentType::kProfile) {
kernel_state_->xam_state()->profile_manager()->ReloadProfiles();
}
return error_code;
}
@ -933,9 +862,7 @@ X_STATUS Emulator::ExtractZarchivePackage(
}
}
uint64_t progress = 0;
return vfs::VirtualFileSystem::ExtractContentFiles(device.get(), extract_dir,
progress);
return vfs::VirtualFileSystem::ExtractContentFiles(device.get(), extract_dir);
}
X_STATUS Emulator::CreateZarchivePackage(
@ -1389,9 +1316,19 @@ std::string Emulator::FindLaunchModule() {
}
static std::string format_version(xex2_version version) {
// fmt::format doesn't like bit fields we use + to bypass it
return fmt::format("{}.{}.{}.{}", +version.major, +version.minor,
+version.build, +version.qfe);
// fmt::format doesn't like bit fields
uint32_t major, minor, build, qfe;
major = version.major;
minor = version.minor;
build = version.build;
qfe = version.qfe;
if (qfe) {
return fmt::format("{}.{}.{}.{}", major, minor, build, qfe);
}
if (build) {
return fmt::format("{}.{}.{}", major, minor, build);
}
return fmt::format("{}.{}", major, minor);
}
X_STATUS Emulator::CompleteLaunch(const std::filesystem::path& path,
@ -1490,13 +1427,9 @@ X_STATUS Emulator::CompleteLaunch(const std::filesystem::path& path,
}
game_config_load_callback_loop_next_index_ = SIZE_MAX;
const auto db = kernel_state_->module_xdbf(module);
const kernel::util::XdbfGameData db = kernel_state_->module_xdbf(module);
game_info_database_ =
std::make_unique<kernel::util::GameInfoDatabase>(db.get());
kernel_state_->xam_state()->LoadSpaInfo(db.get());
kernel_state_->xam_state()->user_tracker()->AddTitleToPlayedList();
game_info_database_ = std::make_unique<kernel::util::GameInfoDatabase>(&db);
if (game_info_database_->IsValid()) {
title_name_ = game_info_database_->GetTitleName(
@ -1557,6 +1490,17 @@ X_STATUS Emulator::CompleteLaunch(const std::filesystem::path& path,
if (!icon_block.empty()) {
display_window_->SetIcon(icon_block.data(), icon_block.size());
}
for (uint8_t slot = 0; slot < XUserMaxUserCount; slot++) {
auto user =
kernel_state_->xam_state()->profile_manager()->GetProfile(slot);
if (user) {
kernel_state_->xam_state()
->achievement_manager()
->LoadTitleAchievements(user->xuid(), db);
}
}
}
}
@ -1582,8 +1526,7 @@ X_STATUS Emulator::CompleteLaunch(const std::filesystem::path& path,
if (cvars::allow_plugins) {
if (plugin_loader_->IsAnyPluginForTitleAvailable(title_id_.value(),
module->hash().value())) {
plugin_loader_->LoadTitlePlugins(title_id_.value(),
module->hash().value());
plugin_loader_->LoadTitlePlugins(title_id_.value());
}
}

View File

@ -26,7 +26,6 @@
#include "xenia/memory.h"
#include "xenia/patcher/patcher.h"
#include "xenia/patcher/plugin_loader.h"
#include "xenia/ui/immediate_drawer.h"
#include "xenia/vfs/device.h"
#include "xenia/vfs/virtual_file_system.h"
#include "xenia/xbox.h"
@ -56,8 +55,8 @@ class Window;
namespace xe {
constexpr fourcc_t kEmulatorSaveSignature = make_fourcc("XSAV");
static constexpr std::string_view kDefaultGameSymbolicLink = "GAME:";
static constexpr std::string_view kDefaultPartitionSymbolicLink = "D:";
static const std::string kDefaultGameSymbolicLink = "GAME:";
static const std::string kDefaultPartitionSymbolicLink = "D:";
// The main type that runs the whole emulator.
// This is responsible for initializing and managing all the various subsystems.
@ -172,9 +171,6 @@ class Emulator {
patcher::PluginLoader* plugin_loader() const { return plugin_loader_.get(); }
kernel::util::GameInfoDatabase* game_info_database() const {
return game_info_database_.get();
}
// Initializes the emulator and configures all components.
// The given window is used for display and the provided functions are used
// to create subsystems as required.
@ -235,45 +231,18 @@ class Emulator {
X_STATUS LaunchDefaultModule(const std::filesystem::path& path);
enum class InstallState : uint8_t {
preparing,
pending,
installing,
installed,
failed
};
constexpr static std::string_view installStateStringName[5] = {
"Preparing", "Pending", "Installing", "Success", "Failed"};
struct ContentInstallEntry {
ContentInstallEntry(std::filesystem::path path) : path_(path) {};
std::string name_{};
std::filesystem::path path_;
std::filesystem::path data_installation_path_;
std::filesystem::path header_installation_path_;
uint64_t content_size_ = 0;
uint64_t currently_installed_size_ = 0;
XContentType content_type_{};
InstallState installation_state_{};
X_STATUS installation_result_{};
std::string installation_error_message_{};
std::unique_ptr<ui::ImmediateTexture> icon_;
struct ContentInstallationInfo {
XContentType content_type;
std::string installation_path;
std::string content_name;
};
// Migrates data from content to content/xuid with respect to common data.
X_STATUS DataMigration(const uint64_t xuid);
X_STATUS ProcessContentPackageHeader(const std::filesystem::path& path,
ContentInstallEntry& installation_info);
// Extract content of package to content specific directory.
X_STATUS InstallContentPackage(const std::filesystem::path& path,
ContentInstallEntry& installation_info);
ContentInstallationInfo& installation_info);
// Extract content of zar package to desired directory.
X_STATUS ExtractZarchivePackage(const std::filesystem::path& path,

View File

@ -285,7 +285,7 @@ void CommandProcessor::WorkerThreadMain() {
do {
// If we spin around too much, revert to a "low-power" state.
if (loop_count > 500) {
constexpr int wait_time_ms = 2;
const int wait_time_ms = 2;
xe::threading::Wait(write_ptr_index_event_.get(), true,
std::chrono::milliseconds(wait_time_ms));
} else {

View File

@ -810,7 +810,7 @@ bool D3D12CommandProcessor::SetupContext() {
ID3D12Device* device = provider.GetDevice();
ID3D12CommandQueue* direct_queue = provider.GetDirectQueue();
fence_completion_event_ = CreateEvent(nullptr, false, false, nullptr);
fence_completion_event_ = CreateEvent(nullptr, FALSE, FALSE, nullptr);
if (fence_completion_event_ == nullptr) {
XELOGE("Failed to create the fence completion event");
return false;
@ -1199,7 +1199,7 @@ bool D3D12CommandProcessor::SetupContext() {
ui::d3d12::util::FillBufferResourceDesc(
gamma_ramp_buffer_desc, (256 + 128 * 3) * 4, D3D12_RESOURCE_FLAG_NONE);
// The first action will be uploading.
gamma_ramp_buffer_state_ = D3D12_RESOURCE_STATE_COMMON;
gamma_ramp_buffer_state_ = D3D12_RESOURCE_STATE_COPY_DEST;
if (FAILED(device->CreateCommittedResource(
&ui::d3d12::util::kHeapPropertiesDefault, heap_flag_create_not_zeroed,
&gamma_ramp_buffer_desc, gamma_ramp_buffer_state_, nullptr,

View File

@ -100,7 +100,7 @@ bool D3D12PrimitiveProcessor::InitializeBuiltinIndexBuffer(
if (FAILED(device->CreateCommittedResource(
&ui::d3d12::util::kHeapPropertiesDefault,
provider.GetHeapFlagCreateNotZeroed(), &resource_desc,
D3D12_RESOURCE_STATE_COMMON, nullptr,
D3D12_RESOURCE_STATE_COPY_DEST, nullptr,
IID_PPV_ARGS(&draw_resource)))) {
XELOGE(
"D3D12 primitive processor: Failed to create the built-in index "

View File

@ -109,7 +109,7 @@ namespace shaders {
#include "xenia/gpu/shaders/bytecode/d3d12_5_1/resolve_full_8bpp_scaled_cs.h"
} // namespace shaders
constexpr D3D12RenderTargetCache::ResolveCopyShaderCode
const D3D12RenderTargetCache::ResolveCopyShaderCode
D3D12RenderTargetCache::kResolveCopyShaders[size_t(
draw_util::ResolveCopyShaderIndex::kCount)] = {
{shaders::resolve_fast_32bpp_1x2xmsaa_cs,
@ -146,7 +146,7 @@ constexpr D3D12RenderTargetCache::ResolveCopyShaderCode
sizeof(shaders::resolve_full_128bpp_scaled_cs)},
};
constexpr uint32_t D3D12RenderTargetCache::kTransferUsedRootParameters[size_t(
const uint32_t D3D12RenderTargetCache::kTransferUsedRootParameters[size_t(
TransferRootSignatureIndex::kCount)] = {
// kColor
kTransferUsedRootParameterColorSRVBit |
@ -184,7 +184,7 @@ constexpr uint32_t D3D12RenderTargetCache::kTransferUsedRootParameters[size_t(
kTransferUsedRootParameterHostDepthAddressConstantBit,
};
constexpr D3D12RenderTargetCache::TransferModeInfo
const D3D12RenderTargetCache::TransferModeInfo
D3D12RenderTargetCache::kTransferModes[size_t(TransferMode::kCount)] = {
// kColorToDepth
{TransferOutput::kDepth, TransferRootSignatureIndex::kColor,
@ -263,7 +263,7 @@ bool D3D12RenderTargetCache::Initialize() {
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
// The first operation will likely be depth self-comparison with host render
// targets or drawing with ROV.
edram_buffer_state_ = D3D12_RESOURCE_STATE_COMMON;
edram_buffer_state_ = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
// Creating zeroed for stable initial value with ROV (though on a real
// console it has to be cleared anyway probably) and not to leak irrelevant
// data to trace dumps when not covered by host render targets entirely.
@ -467,7 +467,7 @@ bool D3D12RenderTargetCache::Initialize() {
// instead.
if (cvars::native_2x_msaa) {
msaa_2x_supported_ = true;
static constexpr DXGI_FORMAT kRenderTargetDXGIFormats[] = {
static const DXGI_FORMAT kRenderTargetDXGIFormats[] = {
DXGI_FORMAT_R16G16B16A16_FLOAT,
DXGI_FORMAT_R16G16B16A16_SNORM,
DXGI_FORMAT_R32G32_FLOAT,
@ -969,7 +969,7 @@ bool D3D12RenderTargetCache::Initialize() {
D3D12_FILL_MODE_SOLID;
uint32_rtv_clear_pipeline_desc.RasterizerState.CullMode =
D3D12_CULL_MODE_NONE;
uint32_rtv_clear_pipeline_desc.RasterizerState.DepthClipEnable = true;
uint32_rtv_clear_pipeline_desc.RasterizerState.DepthClipEnable = TRUE;
uint32_rtv_clear_pipeline_desc.PrimitiveTopologyType =
D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
uint32_rtv_clear_pipeline_desc.NumRenderTargets = 1;
@ -4327,12 +4327,12 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
}
pipeline_desc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
pipeline_desc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE;
pipeline_desc.RasterizerState.DepthClipEnable = true;
pipeline_desc.RasterizerState.DepthClipEnable = TRUE;
pipeline_desc.InputLayout.pInputElementDescs = &pipeline_input_element_desc;
pipeline_desc.InputLayout.NumElements = 1;
pipeline_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
if (dest_is_stencil_bit) {
pipeline_desc.DepthStencilState.StencilEnable = true;
pipeline_desc.DepthStencilState.StencilEnable = TRUE;
pipeline_desc.DepthStencilState.FrontFace.StencilFailOp =
D3D12_STENCIL_OP_KEEP;
pipeline_desc.DepthStencilState.FrontFace.StencilDepthFailOp =
@ -4375,14 +4375,14 @@ D3D12RenderTargetCache::GetOrCreateTransferPipelines(TransferShaderKey key) {
pipeline_desc.RTVFormats[0] =
GetColorOwnershipTransferDXGIFormat(dest_color_format);
} else {
pipeline_desc.DepthStencilState.DepthEnable = true;
pipeline_desc.DepthStencilState.DepthEnable = TRUE;
pipeline_desc.DepthStencilState.DepthWriteMask =
D3D12_DEPTH_WRITE_MASK_ALL;
pipeline_desc.DepthStencilState.DepthFunc =
cvars::depth_transfer_not_equal_test ? D3D12_COMPARISON_FUNC_NOT_EQUAL
: D3D12_COMPARISON_FUNC_ALWAYS;
if (use_stencil_reference_output_) {
pipeline_desc.DepthStencilState.StencilEnable = true;
pipeline_desc.DepthStencilState.StencilEnable = TRUE;
pipeline_desc.DepthStencilState.StencilWriteMask = UINT8_MAX;
pipeline_desc.DepthStencilState.FrontFace.StencilFailOp =
D3D12_STENCIL_OP_KEEP;
@ -4804,7 +4804,7 @@ void D3D12RenderTargetCache::PerformTransfersAndResolveClears(
are_current_command_list_render_targets_valid_ = false;
if (dest_rt_key.is_depth) {
auto handle = dest_d3d12_rt.descriptor_draw().GetHandle();
command_list.D3DOMSetRenderTargets(0, nullptr, false, &handle);
command_list.D3DOMSetRenderTargets(0, nullptr, FALSE, &handle);
if (!use_stencil_reference_output_) {
command_processor_.SetStencilReference(UINT8_MAX);
}
@ -4812,7 +4812,7 @@ void D3D12RenderTargetCache::PerformTransfersAndResolveClears(
auto handle = dest_d3d12_rt.descriptor_load_separate().IsValid()
? dest_d3d12_rt.descriptor_load_separate().GetHandle()
: dest_d3d12_rt.descriptor_draw().GetHandle();
command_list.D3DOMSetRenderTargets(1, &handle, false, nullptr);
command_list.D3DOMSetRenderTargets(1, &handle, FALSE, nullptr);
}
uint32_t dest_pitch_tiles = dest_rt_key.GetPitchTiles();
@ -5432,7 +5432,7 @@ void D3D12RenderTargetCache::PerformTransfersAndResolveClears(
? dest_d3d12_rt.descriptor_load_separate().GetHandle()
: dest_d3d12_rt.descriptor_draw().GetHandle());
command_list.D3DOMSetRenderTargets(1, &handle, false, nullptr);
command_list.D3DOMSetRenderTargets(1, &handle, FALSE, nullptr);
are_current_command_list_render_targets_valid_ = true;
D3D12_VIEWPORT clear_viewport;
clear_viewport.TopLeftX = float(clear_rect.left);
@ -5553,7 +5553,7 @@ void D3D12RenderTargetCache::SetCommandListRenderTargets(
: d3d12_rt.descriptor_draw().GetHandle();
}
command_processor_.GetDeferredCommandList().D3DOMSetRenderTargets(
rtv_count, rtv_handles, false,
rtv_count, rtv_handles, FALSE,
depth_and_color_render_targets[0] ? &dsv_handle : nullptr);
are_current_command_list_render_targets_valid_ = true;
}

View File

@ -394,7 +394,7 @@ bool D3D12SharedMemory::AllocateSparseHostGpuMemoryRange(
region_start_coordinates.Subresource = 0;
D3D12_TILE_REGION_SIZE region_size;
region_size.NumTiles = length_bytes / D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES;
region_size.UseBox = false;
region_size.UseBox = FALSE;
D3D12_TILE_RANGE_FLAGS range_flags = D3D12_TILE_RANGE_FLAG_NONE;
UINT heap_range_start_offset = 0;
direct_queue->UpdateTileMappings(

View File

@ -758,7 +758,7 @@ void D3D12TextureCache::WriteSampler(SamplerParameters parameters,
D3D12_FILTER_REDUCTION_TYPE_STANDARD);
desc.MaxAnisotropy = 1;
}
static constexpr D3D12_TEXTURE_ADDRESS_MODE kAddressModeMap[] = {
static const D3D12_TEXTURE_ADDRESS_MODE kAddressModeMap[] = {
/* kRepeat */ D3D12_TEXTURE_ADDRESS_MODE_WRAP,
/* kMirroredRepeat */ D3D12_TEXTURE_ADDRESS_MODE_MIRROR,
/* kClampToEdge */ D3D12_TEXTURE_ADDRESS_MODE_CLAMP,
@ -968,7 +968,7 @@ bool D3D12TextureCache::EnsureScaledResolveMemoryCommitted(
D3D12_TILE_REGION_SIZE region_size;
region_size.NumTiles =
kScaledResolveHeapSize / D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES;
region_size.UseBox = false;
region_size.UseBox = FALSE;
D3D12_TILE_RANGE_FLAGS range_flags = D3D12_TILE_RANGE_FLAG_NONE;
UINT heap_range_start_offset = 0;
UINT range_tile_count =
@ -1490,7 +1490,8 @@ bool D3D12TextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture,
level_host_slice_size;
copy_buffer_size += level_host_slice_size * array_size;
}
D3D12_RESOURCE_STATES copy_buffer_state = D3D12_RESOURCE_STATE_COMMON;
D3D12_RESOURCE_STATES copy_buffer_state =
D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
ID3D12Resource* copy_buffer = command_processor_.RequestScratchGPUBuffer(
uint32_t(copy_buffer_size), copy_buffer_state);
if (copy_buffer == nullptr) {
@ -1686,7 +1687,7 @@ bool D3D12TextureCache::LoadTextureDataFromResidentMemoryImpl(Texture& texture,
}
std::memcpy(cbuffer_mapping, &load_constants, sizeof(load_constants));
command_list.D3DSetComputeRootConstantBufferView(0, cbuffer_gpu_address);
assert_true(copy_buffer_state == D3D12_RESOURCE_STATE_COMMON);
assert_true(copy_buffer_state == D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
command_processor_.SubmitBarriers();
command_list.D3DDispatch(group_count_x, group_count_y,
load_constants.size_blocks[2]);

View File

@ -144,7 +144,7 @@ void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list,
*reinterpret_cast<const D3DOMSetRenderTargetsArguments*>(stream);
command_list->OMSetRenderTargets(
args.num_render_target_descriptors, args.render_target_descriptors,
args.rts_single_handle_to_descriptor_range ? true : false,
args.rts_single_handle_to_descriptor_range ? TRUE : FALSE,
args.depth_stencil ? &args.depth_stencil_descriptor : nullptr);
} break;
case Command::kD3DOMSetStencilRef: {

View File

@ -269,7 +269,7 @@ class DeferredCommandList {
return;
}
static_assert(alignof(D3D12_RESOURCE_BARRIER) <= alignof(uintmax_t));
constexpr size_t header_size =
const size_t header_size =
xe::align(sizeof(UINT), alignof(D3D12_RESOURCE_BARRIER));
uint8_t* args = reinterpret_cast<uint8_t*>(WriteCommand(
Command::kD3DResourceBarrier,

View File

@ -272,7 +272,7 @@ void PipelineCache::InitializeShaderStorage(
}
pipeline_storage_file_flush_needed_ = false;
// 'XEPS'.
constexpr uint32_t pipeline_storage_magic = 0x53504558;
const uint32_t pipeline_storage_magic = 0x53504558;
// 'DXRO' or 'DXRT'.
const uint32_t pipeline_storage_magic_api =
edram_rov_used ? 0x4F525844 : 0x54525844;
@ -367,7 +367,7 @@ void PipelineCache::InitializeShaderStorage(
uint32_t version_swapped;
} shader_storage_file_header;
// 'XESH'.
constexpr uint32_t shader_storage_magic = 0x48534558;
const uint32_t shader_storage_magic = 0x48534558;
if (fread(&shader_storage_file_header, sizeof(shader_storage_file_header), 1,
shader_storage_file_) &&
shader_storage_file_header.magic == shader_storage_magic &&
@ -1577,7 +1577,7 @@ bool PipelineCache::GetCurrentStateDescription(
// Render targets and blending state. 32 because of 0x1F mask, for safety
// (all unknown to zero).
static constexpr PipelineBlendFactor kBlendFactorMap[32] = {
static const PipelineBlendFactor kBlendFactorMap[32] = {
/* 0 */ PipelineBlendFactor::kZero,
/* 1 */ PipelineBlendFactor::kOne,
/* 2 */ PipelineBlendFactor::kZero, // ?
@ -1603,7 +1603,7 @@ bool PipelineCache::GetCurrentStateDescription(
// Like kBlendFactorMap, but with color modes changed to alpha. Some
// pipelines aren't created in 545407E0 because a color mode is used for
// alpha.
static constexpr PipelineBlendFactor kBlendFactorAlphaMap[32] = {
static const PipelineBlendFactor kBlendFactorAlphaMap[32] = {
/* 0 */ PipelineBlendFactor::kZero,
/* 1 */ PipelineBlendFactor::kOne,
/* 2 */ PipelineBlendFactor::kZero, // ?
@ -3029,7 +3029,7 @@ ID3D12PipelineState* PipelineCache::CreateD3D12Pipeline(
break;
}
state_desc.RasterizerState.FrontCounterClockwise =
description.front_counter_clockwise ? true : false;
description.front_counter_clockwise ? TRUE : FALSE;
state_desc.RasterizerState.DepthBias = description.depth_bias;
state_desc.RasterizerState.DepthBiasClamp = 0.0f;
// With non-square resolution scaling, make sure the worst-case impact is
@ -3041,7 +3041,7 @@ ID3D12PipelineState* PipelineCache::CreateD3D12Pipeline(
float(std::max(render_target_cache_.draw_resolution_scale_x(),
render_target_cache_.draw_resolution_scale_y()));
state_desc.RasterizerState.DepthClipEnable =
description.depth_clip ? true : false;
description.depth_clip ? TRUE : FALSE;
uint32_t msaa_sample_count = uint32_t(1)
<< uint32_t(description.host_msaa_samples);
if (edram_rov_used) {
@ -3082,7 +3082,7 @@ ID3D12PipelineState* PipelineCache::CreateD3D12Pipeline(
// Depth/stencil.
if (description.depth_func != xenos::CompareFunction::kAlways ||
description.depth_write) {
state_desc.DepthStencilState.DepthEnable = true;
state_desc.DepthStencilState.DepthEnable = TRUE;
state_desc.DepthStencilState.DepthWriteMask =
description.depth_write ? D3D12_DEPTH_WRITE_MASK_ALL
: D3D12_DEPTH_WRITE_MASK_ZERO;
@ -3093,7 +3093,7 @@ ID3D12PipelineState* PipelineCache::CreateD3D12Pipeline(
uint32_t(description.depth_func));
}
if (description.stencil_enable) {
state_desc.DepthStencilState.StencilEnable = true;
state_desc.DepthStencilState.StencilEnable = TRUE;
state_desc.DepthStencilState.StencilReadMask =
description.stencil_read_mask;
state_desc.DepthStencilState.StencilWriteMask =
@ -3131,8 +3131,8 @@ ID3D12PipelineState* PipelineCache::CreateD3D12Pipeline(
}
// Render targets and blending.
state_desc.BlendState.IndependentBlendEnable = true;
static constexpr D3D12_BLEND kBlendFactorMap[] = {
state_desc.BlendState.IndependentBlendEnable = TRUE;
static const D3D12_BLEND kBlendFactorMap[] = {
D3D12_BLEND_ZERO, D3D12_BLEND_ONE,
D3D12_BLEND_SRC_COLOR, D3D12_BLEND_INV_SRC_COLOR,
D3D12_BLEND_SRC_ALPHA, D3D12_BLEND_INV_SRC_ALPHA,
@ -3142,7 +3142,7 @@ ID3D12PipelineState* PipelineCache::CreateD3D12Pipeline(
D3D12_BLEND_SRC_ALPHA_SAT,
};
// 8 entries for safety since 3 bits from the guest are passed directly.
static constexpr D3D12_BLEND_OP kBlendOpMap[] = {
static const D3D12_BLEND_OP kBlendOpMap[] = {
D3D12_BLEND_OP_ADD, D3D12_BLEND_OP_SUBTRACT, D3D12_BLEND_OP_MIN,
D3D12_BLEND_OP_MAX, D3D12_BLEND_OP_REV_SUBTRACT, D3D12_BLEND_OP_ADD,
D3D12_BLEND_OP_ADD, D3D12_BLEND_OP_ADD};
@ -3169,7 +3169,7 @@ ID3D12PipelineState* PipelineCache::CreateD3D12Pipeline(
rt.src_blend_alpha != PipelineBlendFactor::kOne ||
rt.dest_blend_alpha != PipelineBlendFactor::kZero ||
rt.blend_op_alpha != xenos::BlendOp::kAdd) {
blend_desc.BlendEnable = true;
blend_desc.BlendEnable = TRUE;
blend_desc.SrcBlend = kBlendFactorMap[uint32_t(rt.src_blend)];
blend_desc.DestBlend = kBlendFactorMap[uint32_t(rt.dest_blend)];
blend_desc.BlendOp = kBlendOpMap[uint32_t(rt.blend_op)];
@ -3196,8 +3196,8 @@ ID3D12PipelineState* PipelineCache::CreateD3D12Pipeline(
if (description.cull_mode == PipelineCullMode::kDisableRasterization) {
state_desc.PS.pShaderBytecode = nullptr;
state_desc.PS.BytecodeLength = 0;
state_desc.DepthStencilState.DepthEnable = false;
state_desc.DepthStencilState.StencilEnable = false;
state_desc.DepthStencilState.DepthEnable = FALSE;
state_desc.DepthStencilState.StencilEnable = FALSE;
}
// Create the D3D12 pipeline state object.

View File

@ -19,110 +19,106 @@ project("xenia-gpu-d3d12")
"../shaders/bytecode/d3d12_5_1/*.h",
})
if enableMiscSubprojects then
group("src")
project("xenia-gpu-d3d12-trace-viewer")
uuid("7b5b9fcb-7bf1-43ff-a774-d4c41c8706be")
single_library_windowed_app_kind()
language("C++")
links({
"xenia-apu",
"xenia-apu-nop",
"xenia-base",
"xenia-core",
"xenia-cpu",
"xenia-gpu",
"xenia-gpu-d3d12",
"xenia-hid",
"xenia-hid-nop",
"xenia-hid-skylander",
"xenia-kernel",
"xenia-patcher",
"xenia-ui",
"xenia-ui-d3d12",
"xenia-vfs",
group("src")
project("xenia-gpu-d3d12-trace-viewer")
uuid("7b5b9fcb-7bf1-43ff-a774-d4c41c8706be")
single_library_windowed_app_kind()
language("C++")
links({
"xenia-apu",
"xenia-apu-nop",
"xenia-base",
"xenia-core",
"xenia-cpu",
"xenia-gpu",
"xenia-gpu-d3d12",
"xenia-hid",
"xenia-hid-nop",
"xenia-kernel",
"xenia-patcher",
"xenia-ui",
"xenia-ui-d3d12",
"xenia-vfs",
})
links({
"aes_128",
"capstone",
"dxbc",
"fmt",
"imgui",
"libavcodec",
"libavutil",
"mspack",
"snappy",
"xxhash",
})
files({
"d3d12_trace_viewer_main.cc",
"../../ui/windowed_app_main_"..platform_suffix..".cc",
})
-- Only create the .user file if it doesn't already exist.
local user_file = project_root.."/build/xenia-gpu-d3d12-trace-viewer.vcxproj.user"
if not os.isfile(user_file) then
debugdir(project_root)
debugargs({
"2>&1",
"1>scratch/stdout-trace-viewer.txt",
})
links({
"aes_128",
"capstone",
"dxbc",
"fmt",
"imgui",
"libavcodec",
"libavutil",
"mspack",
"snappy",
"xxhash",
})
files({
"d3d12_trace_viewer_main.cc",
"../../ui/windowed_app_main_"..platform_suffix..".cc",
})
-- Only create the .user file if it doesn't already exist.
local user_file = project_root.."/build/xenia-gpu-d3d12-trace-viewer.vcxproj.user"
if not os.isfile(user_file) then
debugdir(project_root)
debugargs({
"2>&1",
"1>scratch/stdout-trace-viewer.txt",
})
end
end
filter("architecture:x86_64")
links({
"xenia-cpu-backend-x64",
})
group("src")
project("xenia-gpu-d3d12-trace-dump")
uuid("686b859c-0046-44c4-a02c-41fc3fb75698")
kind("ConsoleApp")
language("C++")
filter("architecture:x86_64")
links({
"xenia-apu",
"xenia-apu-nop",
"xenia-base",
"xenia-core",
"xenia-cpu",
"xenia-gpu",
"xenia-gpu-d3d12",
"xenia-hid",
"xenia-hid-nop",
"xenia-hid-skylander",
"xenia-kernel",
"xenia-ui",
"xenia-ui-d3d12",
"xenia-vfs",
"xenia-patcher",
"xenia-cpu-backend-x64",
})
links({
"aes_128",
"capstone",
"dxbc",
"fmt",
"imgui",
"libavcodec",
"libavutil",
"mspack",
"snappy",
"xxhash",
})
files({
"d3d12_trace_dump_main.cc",
"../../base/console_app_main_"..platform_suffix..".cc",
})
-- Only create the .user file if it doesn't already exist.
local user_file = project_root.."/build/xenia-gpu-d3d12-trace-dump.vcxproj.user"
if not os.isfile(user_file) then
debugdir(project_root)
debugargs({
"2>&1",
"1>scratch/stdout-trace-dump.txt",
})
end
filter("architecture:x86_64")
links({
"xenia-cpu-backend-x64",
})
end
group("src")
project("xenia-gpu-d3d12-trace-dump")
uuid("686b859c-0046-44c4-a02c-41fc3fb75698")
kind("ConsoleApp")
language("C++")
links({
"xenia-apu",
"xenia-apu-nop",
"xenia-base",
"xenia-core",
"xenia-cpu",
"xenia-gpu",
"xenia-gpu-d3d12",
"xenia-hid",
"xenia-hid-nop",
"xenia-kernel",
"xenia-ui",
"xenia-ui-d3d12",
"xenia-vfs",
"xenia-patcher",
})
links({
"aes_128",
"capstone",
"dxbc",
"fmt",
"imgui",
"libavcodec",
"libavutil",
"mspack",
"snappy",
"xxhash",
})
files({
"d3d12_trace_dump_main.cc",
"../../base/console_app_main_"..platform_suffix..".cc",
})
-- Only create the .user file if it doesn't already exist.
local user_file = project_root.."/build/xenia-gpu-d3d12-trace-dump.vcxproj.user"
if not os.isfile(user_file) then
debugdir(project_root)
debugargs({
"2>&1",
"1>scratch/stdout-trace-dump.txt",
})
end
filter("architecture:x86_64")
links({
"xenia-cpu-backend-x64",
})

View File

@ -77,8 +77,8 @@ reg::RB_DEPTHCONTROL GetNormalizedDepthControl(const RegisterFile& regs) {
}
// https://docs.microsoft.com/en-us/windows/win32/api/d3d11/ne-d3d11-d3d11_standard_multisample_quality_levels
constexpr int8_t kD3D10StandardSamplePositions2x[2][2] = {{4, 4}, {-4, -4}};
constexpr int8_t kD3D10StandardSamplePositions4x[4][2] = {
const int8_t kD3D10StandardSamplePositions2x[2][2] = {{4, 4}, {-4, -4}};
const int8_t kD3D10StandardSamplePositions4x[4][2] = {
{-2, -6}, {6, -2}, {-6, 2}, {2, 6}};
void GetPreferredFacePolygonOffset(const RegisterFile& regs,
@ -907,7 +907,7 @@ void GetResolveEdramTileSpan(ResolveEdramInfo edram_info,
rows_out = y1 - y0;
}
constexpr ResolveCopyShaderInfo
const ResolveCopyShaderInfo
resolve_copy_shader_info[size_t(ResolveCopyShaderIndex::kCount)] = {
{"Resolve Copy Fast 32bpp 1x/2xMSAA", false, 4, 4, 6, 3},
{"Resolve Copy Fast 32bpp 4xMSAA", false, 4, 4, 6, 3},

View File

@ -2051,7 +2051,7 @@ void DxbcShaderTranslator::ProcessAllocInstruction(
}
}
constexpr DxbcShaderTranslator::ShaderRdefType
const DxbcShaderTranslator::ShaderRdefType
DxbcShaderTranslator::rdef_types_[size_t(
DxbcShaderTranslator::ShaderRdefTypeIndex::kCount)] = {
// kFloat
@ -2104,7 +2104,7 @@ constexpr DxbcShaderTranslator::ShaderRdefType
dxbc::RdefVariableType::kUInt, 1, 4, 0, ShaderRdefTypeIndex::kUint4},
};
constexpr DxbcShaderTranslator::SystemConstantRdef
const DxbcShaderTranslator::SystemConstantRdef
DxbcShaderTranslator::system_constant_rdef_[size_t(
DxbcShaderTranslator::SystemConstants::Index::kCount)] = {
{"xe_flags", ShaderRdefTypeIndex::kUint, sizeof(uint32_t)},

View File

@ -585,7 +585,7 @@ uint32_t DxbcShaderTranslator::FindOrAddSamplerBinding(
name << "xe_sampler" << fetch_constant;
if (aniso_filter == xenos::AnisoFilter::kDisabled ||
aniso_filter == xenos::AnisoFilter::kUseFetchConst) {
static constexpr char kFilterSuffixes[] = {'p', 'l', 'b', 'f'};
static const char kFilterSuffixes[] = {'p', 'l', 'b', 'f'};
name << '_' << kFilterSuffixes[uint32_t(mag_filter)]
<< kFilterSuffixes[uint32_t(min_filter)]
<< kFilterSuffixes[uint32_t(mip_filter)];
@ -762,7 +762,7 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
// sampling apparently round differently, so `mul` gives a value that would
// be floored as expected, but the left/upper pixel is still sampled
// instead.
constexpr float rounding_offset = 1.5f / 1024.0f;
const float rounding_offset = 1.5f / 1024.0f;
switch (instr.dimension) {
case xenos::FetchOpDimension::k1D:
offsets[0] = instr.attributes.offset_x + rounding_offset;

View File

@ -173,7 +173,7 @@ X_STATUS GraphicsSystem::Setup(cpu::Processor* processor,
: 1.0;
uint64_t last_frame_time = Clock::QueryGuestTickCount();
// Sleep for 90% of the vblank duration, spin for 10%
constexpr double duration_scalar = 0.90;
const double duration_scalar = 0.90;
while (frame_limiter_worker_running_) {
register_file()->values[XE_GPU_REG_D1MODE_V_COUNTER] +=

View File

@ -47,8 +47,8 @@ PacketCategory PacketDisassembler::GetPacketCategory(const uint8_t* base_ptr) {
bool PacketDisassembler::DisasmPacketType0(const uint8_t* base_ptr,
uint32_t packet,
PacketInfo* out_info) {
static constexpr PacketTypeInfo type_0_info = {PacketCategory::kGeneric,
"PM4_TYPE0"};
static const PacketTypeInfo type_0_info = {PacketCategory::kGeneric,
"PM4_TYPE0"};
out_info->type_info = &type_0_info;
uint32_t count = ((packet >> 16) & 0x3FFF) + 1;
@ -72,8 +72,8 @@ bool PacketDisassembler::DisasmPacketType0(const uint8_t* base_ptr,
bool PacketDisassembler::DisasmPacketType1(const uint8_t* base_ptr,
uint32_t packet,
PacketInfo* out_info) {
static constexpr PacketTypeInfo type_1_info = {PacketCategory::kGeneric,
"PM4_TYPE1"};
static const PacketTypeInfo type_1_info = {PacketCategory::kGeneric,
"PM4_TYPE1"};
out_info->type_info = &type_1_info;
out_info->count = 1 + 2;
@ -94,8 +94,8 @@ bool PacketDisassembler::DisasmPacketType1(const uint8_t* base_ptr,
bool PacketDisassembler::DisasmPacketType2(const uint8_t* base_ptr,
uint32_t packet,
PacketInfo* out_info) {
static constexpr PacketTypeInfo type_2_info = {PacketCategory::kGeneric,
"PM4_TYPE2"};
static const PacketTypeInfo type_2_info = {PacketCategory::kGeneric,
"PM4_TYPE2"};
out_info->type_info = &type_2_info;
out_info->count = 1;
@ -106,8 +106,8 @@ bool PacketDisassembler::DisasmPacketType2(const uint8_t* base_ptr,
bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
uint32_t packet,
PacketInfo* out_info) {
static constexpr PacketTypeInfo type_3_unknown_info = {
PacketCategory::kGeneric, "PM4_TYPE3_UNKNOWN"};
static const PacketTypeInfo type_3_unknown_info = {PacketCategory::kGeneric,
"PM4_TYPE3_UNKNOWN"};
out_info->type_info = &type_3_unknown_info;
uint32_t opcode = (packet >> 8) & 0x7F;
@ -127,8 +127,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
switch (opcode) {
case PM4_ME_INIT: {
// initialize CP's micro-engine
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_ME_INIT"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_ME_INIT"};
out_actions.emplace_back(PacketAction::MeInit((uint32_t*)ptr, count));
@ -138,15 +138,15 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
case PM4_NOP: {
// skip N 32-bit words to get to the next packet
// No-op, ignore some data.
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_NOP"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_NOP"};
out_info->type_info = &op_info;
break;
}
case PM4_INTERRUPT: {
// generate interrupt from the command stream
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_INTERRUPT"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_INTERRUPT"};
out_info->type_info = &op_info;
PacketAction intaction;
@ -160,8 +160,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
// VdSwap will post this to tell us we need to swap the screen/fire an
// interrupt.
// 63 words here, but only the first has any data.
static constexpr PacketTypeInfo op_info = {PacketCategory::kSwap,
"PM4_XE_SWAP"};
static const PacketTypeInfo op_info = {PacketCategory::kSwap,
"PM4_XE_SWAP"};
out_info->type_info = &op_info;
PacketAction xsa;
@ -175,8 +175,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
case PM4_INDIRECT_BUFFER:
case PM4_INDIRECT_BUFFER_PFD: {
// indirect buffer dispatch
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_INDIRECT_BUFFER"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_INDIRECT_BUFFER"};
out_info->type_info = &op_info;
PacketAction iba;
@ -189,8 +189,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
}
case PM4_WAIT_REG_MEM: {
// wait until a register or memory location is a specific value
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_WAIT_REG_MEM"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_WAIT_REG_MEM"};
out_info->type_info = &op_info;
PacketAction wait_action;
@ -209,8 +209,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
case PM4_REG_RMW: {
// register read/modify/write
// ? (used during shader upload and edram setup)
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_REG_RMW"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_REG_RMW"};
out_info->type_info = &op_info;
PacketAction rmw_action;
rmw_action.type = PacketAction::Type::kRegRmw;
@ -227,8 +227,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
}
case PM4_COND_WRITE: {
// conditional write to memory or register
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_COND_WRITE"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_COND_WRITE"};
out_info->type_info = &op_info;
PacketAction cwr_action;
cwr_action.type = PacketAction::Type::kCondWrite;
@ -247,8 +247,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
}
case PM4_EVENT_WRITE: {
// generate an event that creates a write to memory when completed
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_EVENT_WRITE"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_EVENT_WRITE"};
out_info->type_info = &op_info;
PacketAction evw_action;
evw_action.type = Type::kEventWrite;
@ -260,8 +260,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
}
case PM4_EVENT_WRITE_SHD: {
// generate a VS|PS_done event
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_EVENT_WRITE_SHD"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_EVENT_WRITE_SHD"};
out_info->type_info = &op_info;
PacketAction evws_action;
evws_action.type = Type::kEventWriteSHD;
@ -276,8 +276,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
}
case PM4_EVENT_WRITE_EXT: {
// generate a screen extent event
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_EVENT_WRITE_EXT"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_EVENT_WRITE_EXT"};
out_info->type_info = &op_info;
PacketAction eve_action;
@ -295,8 +295,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
case PM4_DRAW_INDX: {
// initiate fetch of index buffer and draw
// dword0 = viz query info
static constexpr PacketTypeInfo op_info = {PacketCategory::kDraw,
"PM4_DRAW_INDX"};
static const PacketTypeInfo op_info = {PacketCategory::kDraw,
"PM4_DRAW_INDX"};
out_info->type_info = &op_info;
uint32_t dword0 = xe::load_and_swap<uint32_t>(ptr + 0);
uint32_t dword1 = xe::load_and_swap<uint32_t>(ptr + 4);
@ -337,8 +337,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
}
case PM4_DRAW_INDX_2: {
// draw using supplied indices in packet
static constexpr PacketTypeInfo op_info = {PacketCategory::kDraw,
"PM4_DRAW_INDX_2"};
static const PacketTypeInfo op_info = {PacketCategory::kDraw,
"PM4_DRAW_INDX_2"};
out_info->type_info = &op_info;
uint32_t dword0 = xe::load_and_swap<uint32_t>(ptr + 0);
uint32_t index_count = dword0 >> 16;
@ -372,8 +372,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
// load constant into chip and to memory
// PM4_REG(reg) ((0x4 << 16) | (GSL_HAL_SUBBLOCK_OFFSET(reg)))
// reg - 0x2000
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_SET_CONSTANT"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_SET_CONSTANT"};
out_info->type_info = &op_info;
uint32_t offset_type = xe::load_and_swap<uint32_t>(ptr + 0);
uint32_t index = offset_type & 0x7FF;
@ -407,8 +407,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
break;
}
case PM4_SET_CONSTANT2: {
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_SET_CONSTANT2"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_SET_CONSTANT2"};
out_info->type_info = &op_info;
uint32_t offset_type = xe::load_and_swap<uint32_t>(ptr + 0);
uint32_t index = offset_type & 0xFFFF;
@ -424,8 +424,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
}
case PM4_LOAD_ALU_CONSTANT: {
// load constants from memory
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_LOAD_ALU_CONSTANT"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_LOAD_ALU_CONSTANT"};
out_info->type_info = &op_info;
uint32_t address = xe::load_and_swap<uint32_t>(ptr + 0);
address &= 0x3FFFFFFF;
@ -465,8 +465,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
break;
}
case PM4_SET_SHADER_CONSTANTS: {
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_SET_SHADER_CONSTANTS"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_SET_SHADER_CONSTANTS"};
out_info->type_info = &op_info;
uint32_t offset_type = xe::load_and_swap<uint32_t>(ptr + 0);
uint32_t index = offset_type & 0xFFFF;
@ -481,8 +481,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
}
case PM4_IM_LOAD: {
// load sequencer instruction memory (pointer-based)
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_IM_LOAD"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_IM_LOAD"};
out_info->type_info = &op_info;
uint32_t addr_type = xe::load_and_swap<uint32_t>(ptr + 0);
auto shader_type = static_cast<xenos::ShaderType>(addr_type & 0x3);
@ -506,8 +506,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
}
case PM4_IM_LOAD_IMMEDIATE: {
// load sequencer instruction memory (code embedded in packet)
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_IM_LOAD_IMMEDIATE"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_IM_LOAD_IMMEDIATE"};
out_info->type_info = &op_info;
uint32_t dword0 = xe::load_and_swap<uint32_t>(ptr + 0);
uint32_t dword1 = xe::load_and_swap<uint32_t>(ptr + 4);
@ -534,8 +534,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
}
case PM4_INVALIDATE_STATE: {
// selective invalidation of state pointers
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_INVALIDATE_STATE"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_INVALIDATE_STATE"};
out_info->type_info = &op_info;
uint32_t mask = xe::load_and_swap<uint32_t>(ptr + 0);
@ -547,8 +547,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
break;
}
case PM4_SET_BIN_MASK_LO: {
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_SET_BIN_MASK_LO"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_SET_BIN_MASK_LO"};
out_info->type_info = &op_info;
uint32_t value = xe::load_and_swap<uint32_t>(ptr);
// bin_mask_ = (bin_mask_ & 0xFFFFFFFF00000000ull) | value;
@ -561,8 +561,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
break;
}
case PM4_SET_BIN_MASK_HI: {
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_SET_BIN_MASK_HI"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_SET_BIN_MASK_HI"};
out_info->type_info = &op_info;
uint32_t value = xe::load_and_swap<uint32_t>(ptr);
@ -573,8 +573,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
break;
}
case PM4_SET_BIN_SELECT_LO: {
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_SET_BIN_SELECT_LO"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_SET_BIN_SELECT_LO"};
out_info->type_info = &op_info;
uint32_t value = xe::load_and_swap<uint32_t>(ptr);
PacketAction action;
@ -585,8 +585,8 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
break;
}
case PM4_SET_BIN_SELECT_HI: {
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_SET_BIN_SELECT_HI"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_SET_BIN_SELECT_HI"};
out_info->type_info = &op_info;
uint32_t value = xe::load_and_swap<uint32_t>(ptr);
@ -670,14 +670,14 @@ bool PacketDisassembler::DisasmPacketType3(const uint8_t* base_ptr,
// Ignored packets - useful if breaking on the default handler below.
case 0x50: { // 0xC0015000 usually 2 words, 0xFFFFFFFF / 0x00000000
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_TYPE3_0x50"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_TYPE3_0x50"};
out_info->type_info = &op_info;
break;
}
case 0x51: { // 0xC0015100 usually 2 words, 0xFFFFFFFF / 0xFFFFFFFF
static constexpr PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_TYPE3_0x51"};
static const PacketTypeInfo op_info = {PacketCategory::kGeneric,
"PM4_TYPE3_0x51"};
out_info->type_info = &op_info;
break;
}

View File

@ -902,8 +902,7 @@ bool COMMAND_PROCESSOR::ExecutePacketType3_EVENT_WRITE_SHD(
data_value = GpuSwap(data_value, endianness);
uint8_t* write_destination = memory_->TranslatePhysical(address);
if (address > 0x1FFFFFFF) {
uint32_t writeback_base =
register_file_->values[XE_GPU_REG_WRITEBACK_START];
uint32_t writeback_base = register_file_->values[XE_GPU_REG_WRITEBACK_BASE];
uint32_t writeback_size = register_file_->values[XE_GPU_REG_WRITEBACK_SIZE];
uint32_t writeback_offset = address - writeback_base;
// check whether the guest has written writeback base. if they haven't, skip

File diff suppressed because it is too large Load Diff

View File

@ -13,14 +13,14 @@ namespace xe {
namespace gpu {
namespace reg {
constexpr Register RB_COLOR_INFO::rt_register_indices[4] = {
const Register RB_COLOR_INFO::rt_register_indices[4] = {
XE_GPU_REG_RB_COLOR_INFO,
XE_GPU_REG_RB_COLOR1_INFO,
XE_GPU_REG_RB_COLOR2_INFO,
XE_GPU_REG_RB_COLOR3_INFO,
};
constexpr Register RB_BLENDCONTROL::rt_register_indices[4] = {
const Register RB_BLENDCONTROL::rt_register_indices[4] = {
XE_GPU_REG_RB_BLENDCONTROL0,
XE_GPU_REG_RB_BLENDCONTROL1,
XE_GPU_REG_RB_BLENDCONTROL2,

View File

@ -121,11 +121,11 @@ constexpr SwizzleSource GetSwizzledAluSourceComponent(
component_index));
}
inline char GetCharForComponentIndex(uint32_t i) {
constexpr static char kChars[] = {'x', 'y', 'z', 'w'};
const static char kChars[] = {'x', 'y', 'z', 'w'};
return kChars[i];
}
inline char GetCharForSwizzle(SwizzleSource swizzle_source) {
constexpr static char kChars[] = {'x', 'y', 'z', 'w', '0', '1'};
const static char kChars[] = {'x', 'y', 'z', 'w', '0', '1'};
return kChars[static_cast<uint32_t>(swizzle_source)];
}

View File

@ -144,7 +144,7 @@ spv::Id SpirvShaderTranslator::ProcessVectorAluOperation(
EnsureBuildPointAvailable();
// Lookup table for variants of instructions with similar structure.
static constexpr unsigned int kOps[] = {
static const unsigned int kOps[] = {
static_cast<unsigned int>(spv::OpNop), // kAdd
static_cast<unsigned int>(spv::OpNop), // kMul
static_cast<unsigned int>(spv::OpFOrdGreaterThanEqual), // kMax
@ -883,7 +883,7 @@ spv::Id SpirvShaderTranslator::ProcessScalarAluOperation(
EnsureBuildPointAvailable();
// Lookup table for variants of instructions with similar structure.
static constexpr unsigned int kOps[] = {
static const unsigned int kOps[] = {
static_cast<unsigned int>(spv::OpFAdd), // kAdds
static_cast<unsigned int>(spv::OpFAdd), // kAddsPrev
static_cast<unsigned int>(spv::OpNop), // kMuls

View File

@ -763,7 +763,7 @@ void SpirvShaderTranslator::ProcessTextureFetchInstruction(
// multiplication in texture sampling apparently round differently, so
// `mul` gives a value that would be floored as expected, but the
// left/upper pixel is still sampled instead.
constexpr float kRoundingOffset = 1.5f / 1024.0f;
const float kRoundingOffset = 1.5f / 1024.0f;
switch (instr.dimension) {
case xenos::FetchOpDimension::k1D:
offset_values[0] = instr.attributes.offset_x + kRoundingOffset;
@ -2333,7 +2333,7 @@ size_t SpirvShaderTranslator::FindOrAddSamplerBinding(
new_sampler_binding.mip_filter = mip_filter;
new_sampler_binding.aniso_filter = aniso_filter;
std::ostringstream name;
static constexpr char kFilterSuffixes[] = {'p', 'l', 'b', 'f'};
static const char kFilterSuffixes[] = {'p', 'l', 'b', 'f'};
name << "xe_sampler" << fetch_constant << '_'
<< kFilterSuffixes[uint32_t(mag_filter)]
<< kFilterSuffixes[uint32_t(min_filter)]

View File

@ -566,7 +566,7 @@ void SpirvShaderTranslator::CompleteFragmentShaderInMain() {
spv::Id alpha_test_result_non_not_equal;
{
// Function other than "not equal".
static constexpr spv::Op kAlphaTestOps[] = {
static const spv::Op kAlphaTestOps[] = {
spv::OpFOrdLessThan, spv::OpFOrdEqual, spv::OpFOrdGreaterThan};
for (uint32_t i = 0; i < 3; ++i) {
spv::Id alpha_test_comparison_result = builder_->createBinOp(

View File

@ -60,7 +60,7 @@ void ConvertTexelCTX1ToR8G8(xenos::Endian endian, void* output,
} block;
static_assert(sizeof(block) == 8, "CTX1 block mismatch");
constexpr uint32_t bytes_per_block = 8;
const uint32_t bytes_per_block = 8;
CopySwapBlock(endian, block.data, input, bytes_per_block);
uint8_t cr[4] = {
@ -84,7 +84,7 @@ void ConvertTexelCTX1ToR8G8(xenos::Endian endian, void* output,
void ConvertTexelDXT3AToDXT3(xenos::Endian endian, void* output,
const void* input, size_t length) {
constexpr uint32_t bytes_per_block = 16;
const uint32_t bytes_per_block = 16;
auto output_bytes = static_cast<uint8_t*>(output);
CopySwapBlock(endian, &output_bytes[0], input, 8);
std::memset(&output_bytes[8], 0, 8);

View File

@ -100,7 +100,7 @@ void TextureDump(const TextureInfo& src, void* buffer, size_t length) {
FILE* handle = filesystem::OpenFile(path, "wb");
if (handle) {
constexpr char signature[4] = {'D', 'D', 'S', ' '};
const char signature[4] = {'D', 'D', 'S', ' '};
fwrite(&signature, sizeof(signature), 1, handle);
fwrite(&dds_header, sizeof(dds_header), 1, handle);
fwrite(buffer, 1, length, handle);

View File

@ -19,7 +19,7 @@ using namespace xe::gpu::xenos;
#define FORMAT_INFO(texture_format, format, block_width, block_height, bits_per_pixel) \
{xenos::TextureFormat::texture_format, FormatType::format, block_width, block_height, bits_per_pixel}
const FormatInfo* FormatInfo::Get(uint32_t gpu_format) {
static constexpr FormatInfo format_infos[64] = {
static const FormatInfo format_infos[64] = {
#include "texture_info_formats.inl"
};
return &format_infos[gpu_format];

View File

@ -16,7 +16,7 @@ namespace xe {
namespace gpu {
// Trace file extension.
static constexpr char kTraceExtension[] = "xtr";
static const char kTraceExtension[] = "xtr";
// Any byte changes to the files should bump this version.
// Only builds with matching versions will work.

View File

@ -47,11 +47,11 @@ namespace gpu {
using namespace xe::gpu::xenos;
static constexpr ImVec4 kColorError =
static const ImVec4 kColorError =
ImVec4(255 / 255.0f, 0 / 255.0f, 0 / 255.0f, 255 / 255.0f);
static constexpr ImVec4 kColorComment =
static const ImVec4 kColorComment =
ImVec4(42 / 255.0f, 179 / 255.0f, 0 / 255.0f, 255 / 255.0f);
static constexpr ImVec4 kColorIgnored =
static const ImVec4 kColorIgnored =
ImVec4(100 / 255.0f, 100 / 255.0f, 100 / 255.0f, 255 / 255.0f);
TraceViewer::TraceViewer(xe::ui::WindowedAppContext& app_context,
@ -815,11 +815,10 @@ void TraceViewer::DrawVertexFetcher(Shader* shader,
}
ImGui::BeginChild("#indices", ImVec2(0, 300));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10, 0));
int display_start = 0;
int display_end = 0;
// ImGui::CalcListClipping(vertex_count, ImGui::GetTextLineHeight(),
// &display_start, &display_end);
// ImGui::Dummy(ImVec2(0, (display_start)*ImGui::GetTextLineHeight()));
int display_start, display_end;
ImGui::CalcListClipping(vertex_count, ImGui::GetTextLineHeight(),
&display_start, &display_end);
ImGui::Dummy(ImVec2(0, (display_start)*ImGui::GetTextLineHeight()));
ImGui::Columns(column_count);
if (display_start <= 1) {
for (size_t el_index = 0; el_index < vertex_binding.attributes.size();
@ -1642,12 +1641,11 @@ void TraceViewer::DrawStateUI() {
ImGui::BeginChild("#vsvertices", ImVec2(0, 300));
int display_start = 0;
int display_end = 0;
// ImGui::CalcListClipping(int(vertices.size() / 4),
// ImGui::GetTextLineHeight(), &display_start,
// &display_end);
// ImGui::Dummy(ImVec2(0, (display_start)*ImGui::GetTextLineHeight()));
int display_start, display_end;
ImGui::CalcListClipping(int(vertices.size() / 4),
ImGui::GetTextLineHeight(), &display_start,
&display_end);
ImGui::Dummy(ImVec2(0, (display_start)*ImGui::GetTextLineHeight()));
ImGui::Columns(int(el_size), "#vsvertices", true);
for (size_t i = display_start; i < display_end; i++) {
@ -1708,12 +1706,11 @@ void TraceViewer::DrawStateUI() {
}
ImGui::BeginChild("#indices", ImVec2(0, 300));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
int display_start = 0;
int display_end = 0;
// ImGui::CalcListClipping(1 + draw_info.index_count,
// ImGui::GetTextLineHeight(), &display_start,
// &display_end);
// ImGui::Dummy(ImVec2(0, (display_start)*ImGui::GetTextLineHeight()));
int display_start, display_end;
ImGui::CalcListClipping(1 + draw_info.index_count,
ImGui::GetTextLineHeight(), &display_start,
&display_end);
ImGui::Dummy(ImVec2(0, (display_start)*ImGui::GetTextLineHeight()));
ImGui::Columns(2, "#indices", true);
ImGui::SetColumnOffset(1, 60);
if (display_start <= 1) {

Some files were not shown because too many files have changed in this diff Show More