From 02c95bee06c3de7496368ad7c5296e390ed3602d Mon Sep 17 00:00:00 2001 From: Adrian <78108584+AdrianCassar@users.noreply.github.com> Date: Wed, 1 Jan 2025 23:48:08 +0000 Subject: [PATCH 1/9] [XAM] Implemented XamShowCreateProfileUI --- src/xenia/kernel/xam/xam_ui.cc | 95 ++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/src/xenia/kernel/xam/xam_ui.cc b/src/xenia/kernel/xam/xam_ui.cc index 85561146b..1f81de2a6 100644 --- a/src/xenia/kernel/xam/xam_ui.cc +++ b/src/xenia/kernel/xam/xam_ui.cc @@ -1935,6 +1935,75 @@ class SigninDialog : public XamDialog { char gamertag_[16] = ""; }; +class CreateProfileDialog final : public XamDialog { + public: + CreateProfileDialog(ui::ImGuiDrawer* imgui_drawer, Emulator* emulator) + : XamDialog(imgui_drawer), emulator_(emulator) { + memset(gamertag_, 0, sizeof(gamertag_)); + } + + protected: + void OnDraw(ImGuiIO& io) override; + + bool has_opened_ = false; + char gamertag_[16] = ""; + Emulator* emulator_; +}; + +void CreateProfileDialog::OnDraw(ImGuiIO& io) { + if (!has_opened_) { + ImGui::OpenPopup("Create Profile"); + has_opened_ = true; + } + + auto profile_manager = + emulator_->kernel_state()->xam_state()->profile_manager(); + + bool dialog_open = true; + if (!ImGui::BeginPopupModal("Create Profile", &dialog_open, + ImGuiWindowFlags_NoCollapse | + ImGuiWindowFlags_AlwaysAutoResize | + ImGuiWindowFlags_HorizontalScrollbar)) { + Close(); + return; + } + + if (ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) && + !ImGui::IsAnyItemActive() && !ImGui::IsMouseClicked(0)) { + ImGui::SetKeyboardFocusHere(0); + } + + ImGui::TextUnformatted("Gamertag:"); + ImGui::InputText("##Gamertag", gamertag_, sizeof(gamertag_)); + + const std::string gamertag_string = std::string(gamertag_); + bool valid = profile_manager->IsGamertagValid(gamertag_string); + + ImGui::BeginDisabled(!valid); + if (ImGui::Button("Create")) { + if (!profile_manager->CreateProfile(gamertag_string, false)) { + XELOGE("Failed to create profile: {}", gamertag_string); + } + std::fill(std::begin(gamertag_), std::end(gamertag_), '\0'); + dialog_open = false; + } + ImGui::EndDisabled(); + ImGui::SameLine(); + + if (ImGui::Button("Cancel")) { + std::fill(std::begin(gamertag_), std::end(gamertag_), '\0'); + dialog_open = false; + } + + if (!dialog_open) { + ImGui::CloseCurrentPopup(); + Close(); + ImGui::EndPopup(); + return; + } + ImGui::EndPopup(); +} + X_RESULT xeXamShowSigninUI(uint32_t user_index, uint32_t users_needed, uint32_t flags) { // Mask values vary. Probably matching user types? Local/remote? @@ -1967,6 +2036,21 @@ X_RESULT xeXamShowSigninUI(uint32_t user_index, uint32_t users_needed, new SigninDialog(imgui_drawer, users_needed), close); } +X_RESULT xeXamShowCreateProfileUIEx(uint32_t user_index, dword_t unkn, + char* unkn2_ptr) { + Emulator* emulator = kernel_state()->emulator(); + ui::ImGuiDrawer* imgui_drawer = emulator->imgui_drawer(); + + if (cvars::headless) { + return X_ERROR_SUCCESS; + } + + auto close = [](CreateProfileDialog* dialog) -> void {}; + + return xeXamDispatchDialogAsync( + new CreateProfileDialog(imgui_drawer, emulator), close); +} + dword_result_t XamShowSigninUI_entry(dword_t users_needed, dword_t flags) { return xeXamShowSigninUI(XUserIndexAny, users_needed, flags); } @@ -1978,6 +2062,17 @@ dword_result_t XamShowSigninUIp_entry(dword_t user_index, dword_t users_needed, } DECLARE_XAM_EXPORT1(XamShowSigninUIp, kUserProfiles, kImplemented); +dword_result_t XamShowCreateProfileUIEx_entry(dword_t user_index, dword_t unkn, + lpstring_t unkn2_ptr) { + return xeXamShowCreateProfileUIEx(user_index, unkn, unkn2_ptr); +} +DECLARE_XAM_EXPORT1(XamShowCreateProfileUIEx, kUserProfiles, kImplemented); + +dword_result_t XamShowCreateProfileUI_entry(dword_t user_index, dword_t unkn) { + return xeXamShowCreateProfileUIEx(user_index, unkn, 0); +} +DECLARE_XAM_EXPORT1(XamShowCreateProfileUI, kUserProfiles, kImplemented); + dword_result_t XamShowAchievementsUI_entry(dword_t user_index, dword_t unk_mask) { auto user = kernel_state()->xam_state()->GetUserProfile(user_index); From d2b265e251c2d159a101c89ceedab2ff3c205b87 Mon Sep 17 00:00:00 2001 From: The-Little-Wolf <116989599+The-Little-Wolf@users.noreply.github.com> Date: Fri, 28 Feb 2025 15:13:27 -0800 Subject: [PATCH 2/9] [XAM/NUI] - Implement More Functions - Implement XamNuiIsDeviceReady, XamNuiIdentityGetSessionId, XamNuiHudGetInitializeFlags, XamIsNuiUIActive, XamUserNuiGetUserIndexForSignin and XamNuiHudGetVersions - Stub XamIsNuiAutomationEnabled/XamIsNatalPlaybackEnabled, XamUserNuiGetUserIndex, XamUserNuiEnableBiometric, XamNuiGetDepthCalibration, XamNuiSkeletonGetBestSkeletonIndex, XamNuiIsChatMicEnabled, XamNuiPlayerEngagementUpdate, XamNuiCameraTiltGetStatus, XamNuiCameraElevationGetAngle, XamNuiCameraGetTiltControllerType, XamNuiCameraSetFlags, XamShowNuiGuideUI, XamNuiHudIsEnabled, XamNuiIdentityEnrollForSignIn , XamNuiIdentityAbort and XamNuiHudSetEngagedTrackingID - According to Xam XamIsNuiAutomationEnabled, and XamIsNatalPlaybackEnabled are the same function. - Left Notes for future reference --- src/xenia/kernel/xam/apps/xam_app.cc | 12 +- src/xenia/kernel/xam/xam_module.cc | 2 + src/xenia/kernel/xam/xam_module.h | 1 + src/xenia/kernel/xam/xam_nui.cc | 397 ++++++++++++++++++++++++++- src/xenia/kernel/xam/xam_private.h | 1 + src/xenia/xbox.h | 22 +- 6 files changed, 419 insertions(+), 16 deletions(-) diff --git a/src/xenia/kernel/xam/apps/xam_app.cc b/src/xenia/kernel/xam/apps/xam_app.cc index 650360a47..79582f0fc 100644 --- a/src/xenia/kernel/xam/apps/xam_app.cc +++ b/src/xenia/kernel/xam/apps/xam_app.cc @@ -15,10 +15,14 @@ #include "xenia/kernel/xam/xam_content_device.h" #include "xenia/kernel/xenumerator.h" -// Notes: -// - Messages ids that start with 0x00021xxx are UI calls -// - Messages ids that start with 0x00023xxx are used for the user profile -// - Messages ids that start with 0x0002Bxxx are used for the Kinect +/* Notes: + - Messages ids that start with 0x00021xxx are UI calls + - Messages ids that start with 0x00023xxx are used for the user profile + - Messages ids that start with 0x0002Bxxx are used by the Kinect device + usually for camera related functions + - Messages ids that start with 0x0002Cxxx are used by the XamNuiIdentity + functions +*/ namespace xe { namespace kernel { diff --git a/src/xenia/kernel/xam/xam_module.cc b/src/xenia/kernel/xam/xam_module.cc index f02f5ee64..3487a9c27 100644 --- a/src/xenia/kernel/xam/xam_module.cc +++ b/src/xenia/kernel/xam/xam_module.cc @@ -20,6 +20,7 @@ namespace kernel { namespace xam { std::atomic xam_dialogs_shown_ = {0}; +std::atomic xam_nui_dialogs_shown_ = {0}; // FixMe(RodoMa92): Same hack as main_init_posix.cc:40 // Force initialization before constructor calling, mimicking @@ -33,6 +34,7 @@ static std::vector xam_exports(4096); bool xeXamIsUIActive() { return xam_dialogs_shown_ > 0; } +bool xeXamIsNuiUIActive() { return xam_nui_dialogs_shown_ > 0; } XamModule::XamModule(Emulator* emulator, KernelState* kernel_state) : KernelModule(kernel_state, "xe:\\xam.xex"), loader_data_() { diff --git a/src/xenia/kernel/xam/xam_module.h b/src/xenia/kernel/xam/xam_module.h index b331d8163..cfb3b764c 100644 --- a/src/xenia/kernel/xam/xam_module.h +++ b/src/xenia/kernel/xam/xam_module.h @@ -22,6 +22,7 @@ namespace kernel { namespace xam { bool xeXamIsUIActive(); +bool xeXamIsNuiUIActive(); static constexpr std::string_view kXamModuleLoaderDataFileName = "launch_data.bin"; diff --git a/src/xenia/kernel/xam/xam_nui.cc b/src/xenia/kernel/xam/xam_nui.cc index 512eb043b..8d3b79563 100644 --- a/src/xenia/kernel/xam/xam_nui.cc +++ b/src/xenia/kernel/xam/xam_nui.cc @@ -2,7 +2,7 @@ ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** - * Copyright 2022 Ben Vanik. All rights reserved. * + * Copyright 2025 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ @@ -19,13 +19,35 @@ #include "xenia/ui/windowed_app_context.h" #include "xenia/xbox.h" +DEFINE_bool(Allow_nui_initialization, false, + "Enable NUI initialization\n" + " Only set true when testing kinect games. Certain games may\n" + " require avatar implementation.", + "Kernel"); + namespace xe { namespace kernel { namespace xam { extern std::atomic xam_dialogs_shown_; +extern std::atomic xam_nui_dialogs_shown_; + +// https://web.cs.ucdavis.edu/~okreylos/ResDev/Kinect/MainPage.html struct X_NUI_DEVICE_STATUS { + /* Notes: + - for one side func of XamNuiGetDeviceStatus + - if some data addressis less than zero then unk1 = it + - else another func is called and its return can set unk1 = c0051200 or + some value involving DetroitDeviceRequest + - next PsCamDeviceRequest is called and if its return is less than zero + then X_NUI_DEVICE_STATUS = return of PsCamDeviceRequest + - else it equals an unknown local_1c + - finally McaDeviceRequest is called and if its return is less than zero + then unk2 = return of McaDeviceRequest + - else it equals an unknown local_14 + - status can be set to X_NUI_DEVICE_STATUS[3] | 0x44 or | 0x40 + */ xe::be unk0; xe::be unk1; xe::be unk2; @@ -35,23 +57,300 @@ struct X_NUI_DEVICE_STATUS { }; static_assert(sizeof(X_NUI_DEVICE_STATUS) == 24, "Size matters"); -void XamNuiGetDeviceStatus_entry(pointer_t status_ptr) { +// Get +dword_result_t XamNuiGetDeviceStatus_entry( + pointer_t status_ptr) { + /* Notes: + - it does return a value that is not always used + - returns values are X_ERROR_SUCCESS, 0xC0050006, and others + - 1) On func start *status_ptr = 0, status_ptr->unk1 = 0, status_ptr->unk2 + = 0, and status_ptr->status = 0 + - 2) calls XamXStudioRequest(6,&var <- = 0); + - if return is greater than -1 && var & 0x80000000 != 0 then set + status_ptr->unk1 = 0xC000009D, status_ptr->unk2 = 0xC000009D, and + status_ptr->status = status_ptr[3] = 0x20 + - lots of branching functions after + */ + status_ptr.Zero(); - status_ptr->status = 0; // Not connected. + status_ptr->status = cvars::Allow_nui_initialization; + return cvars::Allow_nui_initialization ? X_ERROR_SUCCESS : 0xC0050006; } DECLARE_XAM_EXPORT1(XamNuiGetDeviceStatus, kNone, kStub); +dword_result_t XamUserNuiGetUserIndex_entry(unknown_t unk, lpdword_t index) { + return X_E_NO_SUCH_USER; +} +DECLARE_XAM_EXPORT1(XamUserNuiGetUserIndex, kNone, kStub); + +dword_result_t XamUserNuiGetUserIndexForSignin_entry(lpdword_t index) { + for (uint32_t i = 0; i < XUserMaxUserCount; i++) { + auto profile = kernel_state()->xam_state()->GetUserProfile(i); + if (profile) { + *index = i; + return X_E_SUCCESS; + } + } + + return X_E_ACCESS_DENIED; +} +DECLARE_XAM_EXPORT1(XamUserNuiGetUserIndexForSignin, kNone, kImplemented); + +dword_result_t XamUserNuiGetUserIndexForBind_entry(lpdword_t index) { + return X_E_FAIL; +} +DECLARE_XAM_EXPORT1(XamUserNuiGetUserIndexForBind, kNone, kStub); + +dword_result_t XamNuiGetDepthCalibration_entry(lpdword_t unk1) { + /* Notes: + - Possible returns X_STATUS_NO_SUCH_FILE, and 0x10000000 + */ + return X_STATUS_NO_SUCH_FILE; +} +DECLARE_XAM_EXPORT1(XamNuiGetDepthCalibration, kNone, kStub); + +// Skeleton +qword_result_t XamNuiSkeletonGetBestSkeletonIndex_entry(int_t unk) { + return 0xffffffffffffffff; +} +DECLARE_XAM_EXPORT1(XamNuiSkeletonGetBestSkeletonIndex, kNone, kStub); + +/* XamNuiCamera Notes + - most require message calls to xam in 0x0002Bxxx area +*/ + +dword_result_t XamNuiCameraTiltGetStatus_entry(lpvoid_t unk) { + /* Notes: + - Used by XamNuiCameraElevationGetAngle, and XamNuiCameraSetFlags + - if it returns anything greater than -1 then both above functions continue + - Both funcs send in a param of *unk = 0x50 bytes to copy + - unk2 + - Ghidra decompile fails + */ + return X_E_FAIL; +} +DECLARE_XAM_EXPORT1(XamNuiCameraTiltGetStatus, kNone, kStub); + +dword_result_t XamNuiCameraElevationGetAngle_entry(lpqword_t unk1, + lpdword_t unk2) { + /* Notes: + - Xam 12611 does not show what unk1 is used for (Ghidra) + */ + uint32_t tilt_status[] = {0x58745373, 0x50}; // (XtSs)? & bytes to copy + X_STATUS result = XamNuiCameraTiltGetStatus_entry(tilt_status); + if (XSUCCEEDED(result)) { + // operation here + // *unk1 = output1 + // *unk2 = output2 + } + return result; +} +DECLARE_XAM_EXPORT1(XamNuiCameraElevationGetAngle, kNone, kStub); + +dword_result_t XamNuiCameraGetTiltControllerType_entry() { + /* Notes: + - undefined unk[8] + - undefined8 local_28; + - undefined8 local_20; + - undefined8 local_18; + - undefined4 local_10; + - local_20 = 0; + - local_18 = 0; + - local_10 = 0; + - local_28 = 0xf030000000000; + - calls DetroitDeviceRequest(unk) -> result + - returns (ulonglong)(LZCOUNT(result) << 0x20) >> 0x25 + */ + return X_E_FAIL; +} +DECLARE_XAM_EXPORT1(XamNuiCameraGetTiltControllerType, kNone, kStub); + +dword_result_t XamNuiCameraSetFlags_entry(qword_t unk1, dword_t unk2) { + /* Notes: + - if XamNuiCameraGetTiltControllerType returns 1 then operation is done + - else 0xffffffff8007048f + */ + X_STATUS result = X_E_DEVICE_NOT_CONNECTED; + int Controller_Type = XamNuiCameraGetTiltControllerType_entry(); + + if (Controller_Type == 1) { + uint32_t tilt_status[] = {0x58745373, 0x50}; // (XtSs)? & bytes to copy + result = XamNuiCameraTiltGetStatus_entry(tilt_status); + if (XSUCCEEDED(result)) { + // op here + // result = + } + } + return result; +} +DECLARE_XAM_EXPORT1(XamNuiCameraSetFlags, kNone, kStub); + +dword_result_t XamIsNuiUIActive_entry() { return xeXamIsNuiUIActive(); } +DECLARE_XAM_EXPORT1(XamIsNuiUIActive, kNone, kImplemented); + +dword_result_t XamNuiIsDeviceReady_entry() { + /* device_state Notes: + - used with XNotifyBroadcast(kXNotificationSystemNUIHardwareStatusChanged, + device_state) + - known values: + - 0x0001 + - 0x0004 + - 0x0040 + */ + uint16_t device_state = cvars::Allow_nui_initialization ? 1 : 0; + return device_state >> 1 & 1; +} +DECLARE_XAM_EXPORT1(XamNuiIsDeviceReady, kNone, kImplemented); + +dword_result_t XamIsNuiAutomationEnabled_entry(unknown_t unk1, unknown_t unk2) { + /* Notes: + - XamIsNuiAutomationEnabled = XamIsNatalPlaybackEnabled + - Always returns X_E_SUCCESS? Maybe check later versions + - Recieves param but never interacts with them + - No Operations + */ + return X_ERROR_SUCCESS; +} +DECLARE_XAM_EXPORT2(XamIsNuiAutomationEnabled, kNone, kStub, kHighFrequency); + +dword_result_t XamIsNatalPlaybackEnabled_entry(unknown_t unk1, unknown_t unk2) { + /* Notes: + - XamIsNuiAutomationEnabled = XamIsNatalPlaybackEnabled + - Always returns X_E_SUCCESS? Maybe check later versions + - Recieves param but never interacts with them + - No Operations + */ + return X_ERROR_SUCCESS; +} +DECLARE_XAM_EXPORT2(XamIsNatalPlaybackEnabled, kNone, kStub, kHighFrequency); + +dword_result_t XamNuiIsChatMicEnabled_entry() { + /* Notes: + - calls a second function with a param of uint local_20 [4]; + - Second function calls ExGetXConfigSetting(7,9,local_30,0x1c,local_40); + - Result is sent to *local_20[0] = ^ + - Once sent back to XamNuiIsChatMicEnabled it looks for byte that + correlates to NUI mic setting + - return uVar2 = (~(ulonglong)local_20[0] << 0x20) >> 0x23 & 1; + - unless the second function returns something -1 or less then + XamNuiIsChatMicEnabled 1 + */ + return false; +} +DECLARE_XAM_EXPORT1(XamNuiIsChatMicEnabled, kNone, kImplemented); + +/* HUD Notes: + - XamNuiHudGetEngagedTrackingID, XamNuiHudIsEnabled, + XamNuiHudSetEngagedTrackingID, XamNuiHudInterpretFrame, and + XamNuiHudGetEngagedEnrollmentIndex all utilize the same data address + - engaged_tracking_id set second param of XamShowNuiTroubleshooterUI +*/ +uint32_t nui_unknown_1 = 0; +uint32_t engaged_tracking_id = 0; +char nui_unknown_2 = '\0'; + +dword_result_t XamNuiHudSetEngagedTrackingID_entry(dword_t id) { + if (!id) { + return X_STATUS_SUCCESS; + } + + if (nui_unknown_1 != 0) { + engaged_tracking_id = id; + return X_STATUS_SUCCESS; + } + + return X_E_FAIL; +} +DECLARE_XAM_EXPORT1(XamNuiHudSetEngagedTrackingID, kNone, kImplemented); + +qword_result_t XamNuiHudGetEngagedTrackingID_entry() { + if (nui_unknown_1 != 0) { + return engaged_tracking_id; + } + + return X_STATUS_SUCCESS; +} +DECLARE_XAM_EXPORT1(XamNuiHudGetEngagedTrackingID, kNone, kImplemented); + +dword_result_t XamNuiHudIsEnabled_entry() { + /* Notes: + - checks if XamNuiIsDeviceReady false, if nui_unknown_1 exists, and + nui_unknown_2 is equal to null terminated string + - only returns true if one check fails and allows for other NUI functions + to progress + */ + bool result = XamNuiIsDeviceReady_entry(); + if (nui_unknown_1 != 0 && nui_unknown_2 != '\0' && result) { + return true; + } + return false; +} +DECLARE_XAM_EXPORT1(XamNuiHudIsEnabled, kNone, kImplemented); + +uint32_t XeXamNuiHudCheck(dword_t unk1) { + uint32_t check = XamNuiHudIsEnabled_entry(); + if (check == 0) { + return X_ERROR_ACCESS_DENIED; + } + + check = XamNuiHudSetEngagedTrackingID_entry(unk1); + if (check != 0) { + return X_ERROR_FUNCTION_FAILED; + } + return X_STATUS_SUCCESS; +} + +dword_result_t XamNuiHudGetInitializeFlags_entry() { + /* HUD_Flags Notes: + - set by 0x2B003 + - set to 0 by unnamed func alongside version_id + - known values: + - 0x40000000 + - 0x200 + */ + return 0; +} +DECLARE_XAM_EXPORT1(XamNuiHudGetInitializeFlags, kNone, kImplemented); + +void XamNuiHudGetVersions_entry(lpqword_t unk1, lpqword_t unk2) { + /* version_id Notes: + - set by 0x2B003 + - set to 0 by unnamed func alongside HUD_Flags + */ + if (unk1) { + *unk1 = 0; + } + if (unk2) { + *unk2 = 0; + } +} +DECLARE_XAM_EXPORT1(XamNuiHudGetVersions, kNone, kImplemented); + // UI dword_result_t XamShowNuiTroubleshooterUI_entry(unknown_t unk1, unknown_t unk2, dword_t flag) { /* Notes: - unk1 is 0xFF - possibly user index? - unk2 appear to always be zero. - - First calls XamPackageManagerGetExperienceMode and checks if the return - is less than zero - - If less than zero then returns error message below - - else it checks if flag = 0x800000 if it does then call - XamNuiGetDeviceStatus. if not return error + - calls XamPackageManagerGetExperienceMode(&var) with var = 1 + - If returns less than zero or (var & 1) == 0 then get error message: + - if XamPackageManagerGetExperienceMode = 0 then call XamShowMessageBoxUI + - if XamShowMessageBoxUI returns 0x3e5 then XamShowNuiTroubleshooterUI + returns 0 + - else XamShowNuiTroubleshooterUI returns 0x65b and call another func + - else: + - call XamNuiHudSetEngagedTrackingID(unk2) and doesn't care aboot return + and set var2 = 2 + - checks if (flag & 0x800000) == 0 + - if true call XamNuiGetDeviceStatus. + - if XamNuiGetDeviceStatus != 0 set var2 = 3 + - else var2 = 4 + - XamAppRequestLoadEx(var2); + - if return = 0 then XamShowNuiTroubleshooterUI returns 5 + - else set buffer[8] and call + XMsgSystemProcessCall(0xfe,0x21028,buffer,0xc); + - XamNuiNatalCameraUpdateComplete calls + XamShowNuiTroubleshooterUI(0xff,0,0) if param = -0x7ff8fffe */ if (cvars::headless) { @@ -75,7 +374,7 @@ dword_result_t XamShowNuiTroubleshooterUI_entry(unknown_t unk1, unknown_t unk2, } } - return 0; + return X_ERROR_SUCCESS; } DECLARE_XAM_EXPORT1(XamShowNuiTroubleshooterUI, kNone, kStub); @@ -88,6 +387,86 @@ dword_result_t XamShowNuiHardwareRequiredUI_entry(unknown_t unk1) { } DECLARE_XAM_EXPORT1(XamShowNuiHardwareRequiredUI, kNone, kImplemented); +dword_result_t XamShowNuiGuideUI_entry(unknown_t unk1, unknown_t unk2) { + /* Notes: + - calls an unnamed function that checks XamNuiHudIsEnabled and + XamNuiHudSetEngagedTrackingID + - if XamNuiHudIsEnabled returns false then fuctions fails return + X_ERROR_ACCESS_DENIED + - else calls XamNuiHudSetEngagedTrackingID and if returns less than 0 then + returns X_ERROR_FUNCTION_FAILED + - else return X_ERROR_SUCCESS + - if return offunc is X_ERROR_SUCCESS then call up ui screen + - else return value of func + */ + + // decompiler error stops me from knowing which param gets used here + uint32_t result = XeXamNuiHudCheck(0); + if (!result) { + // operations here + // XMsgSystemProcessCall(0xfe,0x21030, undefined local_30[8] ,0xc); + } + return result; +} +DECLARE_XAM_EXPORT1(XamShowNuiGuideUI, kNone, kStub); + +/* XamNuiIdentity Notes: + - most require message calls to xam in 0x0002Cxxx area +*/ +uint64_t NUI_Session_Id = 0; + +qword_result_t XamNuiIdentityGetSessionId_entry() { + if (NUI_Session_Id == 0) { + // xboxkrnl::XeCryptRandom_entry(NUI_Session_Id, 8); + NUI_Session_Id = 0xDEADF00DDEADF00D; + } + return NUI_Session_Id; +} +DECLARE_XAM_EXPORT1(XamNuiIdentityGetSessionId, kNone, kImplemented); + +dword_result_t XamNuiIdentityEnrollForSignIn_entry(dword_t unk1, qword_t unk2, + qword_t unk3, dword_t unk4) { + /* Notes: + - Decompiler issues so double check + */ + if (XamNuiHudIsEnabled_entry() == false) { + return X_E_FAIL; + } + // buffer [2] + // buffer[0] = unk + // var = unk4 + // return func(0xfe,0x2c010,buffer,0xc,unk3); + return X_E_FAIL; +} +DECLARE_XAM_EXPORT1(XamNuiIdentityEnrollForSignIn, kNone, kStub); + +dword_result_t XamNuiIdentityAbort_entry(dword_t unk) { + if (XamNuiHudIsEnabled_entry() == false) { + return X_E_FAIL; + } + // buffer [4] + // buffer[0] = unk + // return func(0xfe,0x2c00e,buffer,4,0) + return X_E_FAIL; +} +DECLARE_XAM_EXPORT1(XamNuiIdentityAbort, kNone, kStub); + +// Other +dword_result_t XamUserNuiEnableBiometric_entry(dword_t user_index, + int_t enable) { + return X_E_INVALIDARG; +} +DECLARE_XAM_EXPORT1(XamUserNuiEnableBiometric, kNone, kStub); + +void XamNuiPlayerEngagementUpdate_entry(qword_t unk1, unknown_t unk2, + lpunknown_t unk3) { + /* Notes: + - Only calls a second function with the params unk3, 0, and 0x1c in that + order + */ +} +DECLARE_XAM_EXPORT1(XamNuiPlayerEngagementUpdate, kNone, kStub); + } // namespace xam } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/xam/xam_private.h b/src/xenia/kernel/xam/xam_private.h index 9122bc21c..2f477b288 100644 --- a/src/xenia/kernel/xam/xam_private.h +++ b/src/xenia/kernel/xam/xam_private.h @@ -19,6 +19,7 @@ namespace kernel { namespace xam { bool xeXamIsUIActive(); +bool xeXamIsNuiUIActive(); xe::cpu::Export* RegisterExport_xam(xe::cpu::Export* export_entry); diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index c73017283..7a206d56d 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -108,6 +108,7 @@ typedef uint32_t X_RESULT; #define X_ERROR_DEVICE_NOT_CONNECTED X_RESULT_FROM_WIN32(0x0000048FL) #define X_ERROR_NOT_FOUND X_RESULT_FROM_WIN32(0x00000490L) #define X_ERROR_CANCELLED X_RESULT_FROM_WIN32(0x000004C7L) +#define X_ERROR_ABORTED X_RESULT_FROM_WIN32(0x000004D3L) #define X_ERROR_NOT_LOGGED_ON X_RESULT_FROM_WIN32(0x000004DDL) #define X_ERROR_NO_SUCH_USER X_RESULT_FROM_WIN32(0x00000525L) #define X_ERROR_FUNCTION_FAILED X_RESULT_FROM_WIN32(0x0000065BL) @@ -273,7 +274,7 @@ constexpr uint8_t XUserIndexAny = 0xFF; // https://github.com/ThirteenAG/Ultimate-ASI-Loader/blob/master/source/xlive/xliveless.h typedef uint32_t XNotificationID; enum : XNotificationID { - /* Notes: + /* XNotification Notes: - Notification Ids are split into three Sections: Area, Version, and Message Id. - Each Area has the potential to hold 65535 unique notifications as it @@ -292,6 +293,12 @@ enum : XNotificationID { kXNotifyAll = 0x000000EF, // XNotification System + /* System Notes: + - for some functions if XamIsNuiUIActive returns false then + XNotifyBroadcast(kXNotificationSystemNUIPause, unk data) is called + - XNotifyBroadcast(kXNotificationSystemNUIHardwareStatusChanged, + device_state) + */ kXNotificationSystemUI = 0x00000009, kXNotificationSystemSignInChanged = 0x0000000A, kXNotificationSystemStorageDevicesChanged = 0x0000000B, @@ -310,7 +317,7 @@ enum : XNotificationID { kXNotificationSystemNUIBindingChanged = 0x0006001D, kXNotificationSystemAudioLatencyChanged = 0x0008001E, kXNotificationSystemNUIChatBindingChanged = 0x0008001F, - kXNotificationSystemInputActivityChanged = 0x00009020, + kXNotificationSystemInputActivityChanged = 0x00090020, // XNotification Live kXNotificationLiveConnectionChanged = 0x02000001, @@ -331,9 +338,18 @@ enum : XNotificationID { kXNotificationCustomGamercard = 0x06010004, // XNotification Dvd ? - kXNotificationDvdDriveUnknown = 0x80000003, + /* Dvd Drive? Notes: + - after XamLoaderGetMediaInfoEx(media_type?, title_id?, unk) is used for + some funcs the first param is used with + XNotifyBroadcast(kXNotificationDvdDriveTrayStateChanged, media_type?) + - after XamLoaderGetMediaInfoEx(media_type?, title_id?, unk) is used for + some funcs the third param is used with + XNotifyBroadcast(kXNotificationDvdDriveUnknown2, unk) + */ + kXNotificationDvdDriveUnknown1 = 0x80000003, kXNotificationDvdDriveUnknownDashContext = 0x8000000C, kXNotificationDvdDriveTrayStateChanged = 0x8000000D, + kXNotificationDvdDriveUnknown2 = 0x80010014, // XNotification XMP kXNotificationXmpStateChanged = 0x0A000001, From 76679585567a4a2c51ff5b7bb3915dae31e5ef0b Mon Sep 17 00:00:00 2001 From: Gliniak Date: Sat, 5 Apr 2025 18:23:25 +0200 Subject: [PATCH 3/9] [3PP] Added Libusb --- .gitmodules | 3 +++ premake5.lua | 1 + third_party/libusb | 1 + third_party/libusb.lua | 46 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+) create mode 160000 third_party/libusb create mode 100644 third_party/libusb.lua diff --git a/.gitmodules b/.gitmodules index 7bb327b53..6c40a386d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -103,3 +103,6 @@ [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 diff --git a/premake5.lua b/premake5.lua index 323ca622e..17b14de89 100644 --- a/premake5.lua +++ b/premake5.lua @@ -265,6 +265,7 @@ workspace("xenia") include("third_party/fmt.lua") include("third_party/glslang-spirv.lua") include("third_party/imgui.lua") + include("third_party/libusb.lua") include("third_party/mspack.lua") include("third_party/snappy.lua") include("third_party/xxhash.lua") diff --git a/third_party/libusb b/third_party/libusb new file mode 160000 index 000000000..a61afe5f7 --- /dev/null +++ b/third_party/libusb @@ -0,0 +1 @@ +Subproject commit a61afe5f75d969c4561a1d0ad753aa23cee6329a diff --git a/third_party/libusb.lua b/third_party/libusb.lua new file mode 100644 index 000000000..c38165723 --- /dev/null +++ b/third_party/libusb.lua @@ -0,0 +1,46 @@ +group("third_party") +project("libusb") + uuid("5f8b5485-fde5-4a42-8a13-8545fcf6d25b") + kind("StaticLib") + language("C") + defines({ + "_LIB", + }) + includedirs({"libusb/libusb/"}) + + files({ + "libusb/libusb/core.c", + "libusb/libusb/descriptor.c", + "libusb/libusb/hotplug.c", + "libusb/libusb/io.c", + "libusb/libusb/strerror.c", + "libusb/libusb/sync.c", + }) + + filter({"platforms:Windows"}) + includedirs({"libusb/msvc/"}) + files({ + "libusb/libusb/os/events_windows.c", + "libusb/libusb/os/events_windows.h", + "libusb/libusb/os/threads_windows.c", + "libusb/libusb/os/threads_windows.h", + "libusb/libusb/os/windows_common.c", + "libusb/libusb/os/windows_common.h", + "libusb/libusb/os/windows_usbdk.c", + "libusb/libusb/os/windows_usbdk.h", + "libusb/libusb/os/windows_winusb.c", + "libusb/libusb/os/windows_winusb.h" + }) + + filter({"platforms:Linux"}) + files({ + "libusb/libusb/config.h", + "libusb/libusb/os/events_posix.c", + "libusb/libusb/os/events_posix.h", + "libusb/libusb/os/threads_posix.c", + "libusb/libusb/os/threads_posix.h", + "libusb/libusb/os/linux_netlink.c", + "libusb/libusb/os/linux_udev.c", + "libusb/libusb/os/linux_usbfs.c", + "libusb/libusb/os/linux_usbfs.h" + }) From 7298536d46e350e52fbbaf6239aac33b514da355 Mon Sep 17 00:00:00 2001 From: Gliniak Date: Mon, 7 Apr 2025 22:14:31 +0200 Subject: [PATCH 4/9] [HID] Added support for Xbox 360 Skylanders Portal - This requires Zadig for installation of WinUSB driver for portal --- premake5.lua | 6 +- src/xenia/cpu/ppc/testing/premake5.lua | 1 + src/xenia/cpu/testing/premake5.lua | 1 + src/xenia/gpu/d3d12/premake5.lua | 2 + src/xenia/gpu/vulkan/premake5.lua | 2 + src/xenia/hid/input_system.cc | 13 +- src/xenia/hid/input_system.h | 5 + src/xenia/hid/premake5.lua | 1 + src/xenia/hid/skylander/premake5.lua | 23 ++++ src/xenia/hid/skylander/skylander_emulated.cc | 32 +++++ src/xenia/hid/skylander/skylander_emulated.h | 34 +++++ src/xenia/hid/skylander/skylander_hardware.cc | 121 ++++++++++++++++++ src/xenia/hid/skylander/skylander_hardware.h | 47 +++++++ src/xenia/hid/skylander/skylander_portal.cc | 19 +++ src/xenia/hid/skylander/skylander_portal.h | 40 ++++++ src/xenia/kernel/xam/xam_input.cc | 38 ++++++ 16 files changed, 383 insertions(+), 2 deletions(-) create mode 100644 src/xenia/hid/skylander/premake5.lua create mode 100644 src/xenia/hid/skylander/skylander_emulated.cc create mode 100644 src/xenia/hid/skylander/skylander_emulated.h create mode 100644 src/xenia/hid/skylander/skylander_hardware.cc create mode 100644 src/xenia/hid/skylander/skylander_hardware.h create mode 100644 src/xenia/hid/skylander/skylander_portal.cc create mode 100644 src/xenia/hid/skylander/skylander_portal.h diff --git a/premake5.lua b/premake5.lua index 17b14de89..d9b02cb36 100644 --- a/premake5.lua +++ b/premake5.lua @@ -265,7 +265,6 @@ workspace("xenia") include("third_party/fmt.lua") include("third_party/glslang-spirv.lua") include("third_party/imgui.lua") - include("third_party/libusb.lua") include("third_party/mspack.lua") include("third_party/snappy.lua") include("third_party/xxhash.lua") @@ -274,6 +273,10 @@ 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 @@ -308,6 +311,7 @@ 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") diff --git a/src/xenia/cpu/ppc/testing/premake5.lua b/src/xenia/cpu/ppc/testing/premake5.lua index 1a7823138..736d02184 100644 --- a/src/xenia/cpu/ppc/testing/premake5.lua +++ b/src/xenia/cpu/ppc/testing/premake5.lua @@ -17,6 +17,7 @@ project("xenia-cpu-ppc-tests") "xenia-base", "xenia-kernel", "xenia-patcher", + "xenia-hid-skylander", }) files({ "ppc_testing_main.cc", diff --git a/src/xenia/cpu/testing/premake5.lua b/src/xenia/cpu/testing/premake5.lua index a02cd7f7d..23c0c6fb9 100644 --- a/src/xenia/cpu/testing/premake5.lua +++ b/src/xenia/cpu/testing/premake5.lua @@ -10,6 +10,7 @@ test_suite("xenia-cpu-tests", project_root, ".", { "xenia-core", "xenia-cpu", "xenia-gpu", + "xenia-hid-skylander", -- TODO(benvanik): cut these dependencies? "xenia-kernel", diff --git a/src/xenia/gpu/d3d12/premake5.lua b/src/xenia/gpu/d3d12/premake5.lua index 3bdee3233..34ca32947 100644 --- a/src/xenia/gpu/d3d12/premake5.lua +++ b/src/xenia/gpu/d3d12/premake5.lua @@ -34,6 +34,7 @@ project("xenia-gpu-d3d12-trace-viewer") "xenia-gpu-d3d12", "xenia-hid", "xenia-hid-nop", + "xenia-hid-skylander", "xenia-kernel", "xenia-patcher", "xenia-ui", @@ -86,6 +87,7 @@ project("xenia-gpu-d3d12-trace-dump") "xenia-gpu-d3d12", "xenia-hid", "xenia-hid-nop", + "xenia-hid-skylander", "xenia-kernel", "xenia-ui", "xenia-ui-d3d12", diff --git a/src/xenia/gpu/vulkan/premake5.lua b/src/xenia/gpu/vulkan/premake5.lua index a79749e65..b27610286 100644 --- a/src/xenia/gpu/vulkan/premake5.lua +++ b/src/xenia/gpu/vulkan/premake5.lua @@ -38,6 +38,7 @@ project("xenia-gpu-vulkan-trace-viewer") "xenia-gpu-vulkan", "xenia-hid", "xenia-hid-nop", + "xenia-hid-skylander", "xenia-kernel", "xenia-patcher", "xenia-ui", @@ -102,6 +103,7 @@ project("xenia-gpu-vulkan-trace-dump") "xenia-gpu-vulkan", "xenia-hid", "xenia-hid-nop", + "xenia-hid-skylander", "xenia-kernel", "xenia-ui", "xenia-ui-vulkan", diff --git a/src/xenia/hid/input_system.cc b/src/xenia/hid/input_system.cc index 10c27bfcd..f10d8696d 100644 --- a/src/xenia/hid/input_system.cc +++ b/src/xenia/hid/input_system.cc @@ -16,6 +16,11 @@ #include "xenia/hid/input_driver.h" #include "xenia/kernel/util/shim_utils.h" +#include "xenia/hid/skylander/skylander_emulated.h" +#ifdef XE_PLATFORM_WIN32 +#include "xenia/hid/skylander/skylander_hardware.h" +#endif // XE_PLATFORM_WIN32 + namespace xe { namespace hid { @@ -28,7 +33,13 @@ DEFINE_double( right_stick_deadzone_percentage, 0.0, "Defines deadzone level for right stick. Allowed range [0.0-1.0].", "HID"); -InputSystem::InputSystem(xe::ui::Window* window) : window_(window) {} +InputSystem::InputSystem(xe::ui::Window* window) : window_(window) { + skylander_portal_ = std::make_unique(); + +#ifdef XE_PLATFORM_WIN32 + skylander_portal_ = std::make_unique(); +#endif // XE_PLATFORM_WIN32 +} InputSystem::~InputSystem() = default; diff --git a/src/xenia/hid/input_system.h b/src/xenia/hid/input_system.h index 69b8710b9..774471684 100644 --- a/src/xenia/hid/input_system.h +++ b/src/xenia/hid/input_system.h @@ -16,6 +16,7 @@ #include "xenia/base/mutex.h" #include "xenia/hid/input.h" #include "xenia/hid/input_driver.h" +#include "xenia/hid/skylander/skylander_portal.h" #include "xenia/xbox.h" namespace xe { @@ -55,6 +56,8 @@ class InputSystem { uint32_t GetLastUsedSlot() const { return last_used_slot; } + SkylanderPortal* GetSkylanderPortal() { return skylander_portal_.get(); } + std::unique_lock lock(); private: @@ -74,6 +77,8 @@ class InputSystem { std::vector> drivers_; + std::unique_ptr skylander_portal_; + std::bitset connected_slots = {}; std::array, XUserMaxUserCount> controllers_max_joystick_value = {}; diff --git a/src/xenia/hid/premake5.lua b/src/xenia/hid/premake5.lua index d422980cc..f1b897702 100644 --- a/src/xenia/hid/premake5.lua +++ b/src/xenia/hid/premake5.lua @@ -8,6 +8,7 @@ project("xenia-hid") language("C++") links({ "xenia-base", + "xenia-hid-skylander", }) defines({ }) diff --git a/src/xenia/hid/skylander/premake5.lua b/src/xenia/hid/skylander/premake5.lua new file mode 100644 index 000000000..a55c4c7c3 --- /dev/null +++ b/src/xenia/hid/skylander/premake5.lua @@ -0,0 +1,23 @@ +project_root = "../../../.." +include(project_root.."/tools/build") + +group("src") +project("xenia-hid-skylander") + uuid("ddc114da-a279-4868-8b20-53108599bd78") + kind("StaticLib") + language("C++") + files({ + "skylander_portal.h", + "skylander_portal.cc", + "skylander_emulated.h", + "skylander_emulated.cc" + }) + + filter({"platforms:Windows"}) + links({ + "libusb", + }) + files({ + "skylander_hardware.h", + "skylander_hardware.cc" + }) diff --git a/src/xenia/hid/skylander/skylander_emulated.cc b/src/xenia/hid/skylander/skylander_emulated.cc new file mode 100644 index 000000000..d21e1b5dd --- /dev/null +++ b/src/xenia/hid/skylander/skylander_emulated.cc @@ -0,0 +1,32 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Xenia Canary. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include "xenia/hid/skylander/skylander_emulated.h" + +namespace xe { +namespace hid { + +SkylanderPortalEmulated::SkylanderPortalEmulated() : SkylanderPortal() {} + +SkylanderPortalEmulated::~SkylanderPortalEmulated() {} + +bool SkylanderPortalEmulated::init_device() { return false; } + +void SkylanderPortalEmulated::destroy_device() {} + +X_STATUS SkylanderPortalEmulated::read(std::vector& data) { + return X_ERROR_DEVICE_NOT_CONNECTED; +} + +X_STATUS SkylanderPortalEmulated::write(std::vector& data) { + return X_ERROR_DEVICE_NOT_CONNECTED; +}; + +} // namespace hid +} // namespace xe \ No newline at end of file diff --git a/src/xenia/hid/skylander/skylander_emulated.h b/src/xenia/hid/skylander/skylander_emulated.h new file mode 100644 index 000000000..9008418c4 --- /dev/null +++ b/src/xenia/hid/skylander/skylander_emulated.h @@ -0,0 +1,34 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Xenia Canary. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_HID_SKYLANDER_SKYLANDER_PORTAL_EMULATED_H_ +#define XENIA_HID_SKYLANDER_SKYLANDER_PORTAL_EMULATED_H_ + +#include "xenia/hid/skylander/skylander_portal.h" + +namespace xe { +namespace hid { + +class SkylanderPortalEmulated final : public SkylanderPortal { + public: + SkylanderPortalEmulated(); + ~SkylanderPortalEmulated() override; + + X_STATUS read(std::vector& data) override; + X_STATUS write(std::vector& data) override; + + private: + bool init_device() override; + void destroy_device() override; +}; + +} // namespace hid +} // namespace xe + +#endif \ No newline at end of file diff --git a/src/xenia/hid/skylander/skylander_hardware.cc b/src/xenia/hid/skylander/skylander_hardware.cc new file mode 100644 index 000000000..e27844768 --- /dev/null +++ b/src/xenia/hid/skylander/skylander_hardware.cc @@ -0,0 +1,121 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Xenia Canary. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include "xenia/hid/skylander/skylander_hardware.h" + +namespace xe { +namespace hid { + +SkylanderPortalLibusb::SkylanderPortalLibusb() : SkylanderPortal() { + libusb_init(&context_); +} + +SkylanderPortalLibusb::~SkylanderPortalLibusb() { + if (handle_) { + destroy_device(); + } + + libusb_exit(context_); +} + +bool SkylanderPortalLibusb::init_device() { + if (!context_) { + return false; + } + + libusb_device** devs; + ssize_t cnt = libusb_get_device_list(context_, &devs); + if (cnt < 0) { + // No device available... It might appear later. + return false; + } + + bool device_found = false; + for (ssize_t i = 0; i < cnt; ++i) { + libusb_device* dev = devs[i]; + + struct libusb_device_descriptor desc; + if (libusb_get_device_descriptor(dev, &desc) == 0) { + // Check if this device matches the target Vendor ID and Product ID + if (desc.idVendor == portal_vendor_product_id.first && + desc.idProduct == portal_vendor_product_id.second) { + libusb_device_handle* handle; + if (libusb_open(dev, &handle) == 0) { + libusb_claim_interface(handle, 0); + handle_ = reinterpret_cast(handle); + device_found = true; + } + } + } + } + libusb_free_device_list(devs, 0); + + return device_found; +} + +void SkylanderPortalLibusb::destroy_device() { + libusb_release_interface(reinterpret_cast(handle_), 0); + libusb_close(reinterpret_cast(handle_)); + handle_ = nullptr; +} + +X_STATUS SkylanderPortalLibusb::read(std::vector& data) { + if (!is_initialized()) { + if (!init_device()) { + return X_ERROR_DEVICE_NOT_CONNECTED; + } + } + + if (data.size() > skylander_buffer_size) { + return X_ERROR_INVALID_PARAMETER; + } + + const int result = libusb_interrupt_transfer( + reinterpret_cast(handle_), read_endpoint, + data.data(), static_cast(data.size()), nullptr, timeout); + + if (result == LIBUSB_ERROR_NO_DEVICE) { + return X_ERROR_DEVICE_NOT_CONNECTED; + } + + if (result < 0) { + destroy_device(); + } + + return X_ERROR_SUCCESS; +} + +X_STATUS SkylanderPortalLibusb::write(std::vector& data) { + if (!is_initialized()) { + if (!init_device()) { + return X_ERROR_DEVICE_NOT_CONNECTED; + } + } + + if (data.size() > skylander_buffer_size) { + return X_ERROR_INVALID_PARAMETER; + } + + const int result = libusb_interrupt_transfer( + reinterpret_cast(handle_), write_endpoint, + data.data(), static_cast(data.size()), nullptr, timeout); + + if (result == LIBUSB_ERROR_NO_DEVICE) { + return X_ERROR_DEVICE_NOT_CONNECTED; + } + + if (result < 0) { + destroy_device(); + } + + return X_ERROR_SUCCESS; +}; + +} // namespace hid +} // namespace xe \ No newline at end of file diff --git a/src/xenia/hid/skylander/skylander_hardware.h b/src/xenia/hid/skylander/skylander_hardware.h new file mode 100644 index 000000000..d8b5b84bc --- /dev/null +++ b/src/xenia/hid/skylander/skylander_hardware.h @@ -0,0 +1,47 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Xenia Canary. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_HID_SKYLANDER_SKYLANDER_PORTAL_LIBUSB_H_ +#define XENIA_HID_SKYLANDER_SKYLANDER_PORTAL_LIBUSB_H_ + +// Include order is important here. Including skylander_portal.h after libusb +// will cause conflicts. +#include "xenia/hid/skylander/skylander_portal.h" + +#include "third_party/libusb/libusb/libusb.h" + +namespace xe { +namespace hid { + +class SkylanderPortalLibusb final : public SkylanderPortal { + public: + SkylanderPortalLibusb(); + ~SkylanderPortalLibusb() override; + + X_STATUS read(std::vector& data) override; + X_STATUS write(std::vector& data) override; + + private: + bool init_device() override; + void destroy_device() override; + + bool is_initialized() const { return handle_ != nullptr; } + + const uint8_t read_endpoint = 0x81; + const uint8_t write_endpoint = 0x02; + const uint16_t timeout = 300; + + libusb_context* context_ = nullptr; + uintptr_t* handle_ = nullptr; +}; + +} // namespace hid +} // namespace xe + +#endif \ No newline at end of file diff --git a/src/xenia/hid/skylander/skylander_portal.cc b/src/xenia/hid/skylander/skylander_portal.cc new file mode 100644 index 000000000..fe46d4983 --- /dev/null +++ b/src/xenia/hid/skylander/skylander_portal.cc @@ -0,0 +1,19 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Xenia Canary. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#include "xenia/hid/skylander/skylander_portal.h" + +namespace xe { +namespace hid { + +SkylanderPortal::SkylanderPortal() {} +SkylanderPortal::~SkylanderPortal() {} + +} // namespace hid +} // namespace xe \ No newline at end of file diff --git a/src/xenia/hid/skylander/skylander_portal.h b/src/xenia/hid/skylander/skylander_portal.h new file mode 100644 index 000000000..7962184a2 --- /dev/null +++ b/src/xenia/hid/skylander/skylander_portal.h @@ -0,0 +1,40 @@ +/** + ****************************************************************************** + * Xenia : Xbox 360 Emulator Research Project * + ****************************************************************************** + * Copyright 2025 Xenia Canary. All rights reserved. * + * Released under the BSD license - see LICENSE in the root for more details. * + ****************************************************************************** + */ + +#ifndef XENIA_HID_SKYLANDER_SKYLANDER_PORTAL_H_ +#define XENIA_HID_SKYLANDER_SKYLANDER_PORTAL_H_ + +#include + +#include "xenia/xbox.h" + +namespace xe { +namespace hid { + +constexpr std::pair portal_vendor_product_id = {0x1430, + 0x1F17}; +constexpr uint8_t skylander_buffer_size = 0x20; + +class SkylanderPortal { + public: + SkylanderPortal(); + virtual ~SkylanderPortal(); + + virtual X_STATUS read(std::vector& data) = 0; + virtual X_STATUS write(std::vector& data) = 0; + + private: + virtual bool init_device() = 0; + virtual void destroy_device() = 0; +}; + +} // namespace hid +} // namespace xe + +#endif \ No newline at end of file diff --git a/src/xenia/kernel/xam/xam_input.cc b/src/xenia/kernel/xam/xam_input.cc index c60afed3f..3f49f852f 100644 --- a/src/xenia/kernel/xam/xam_input.cc +++ b/src/xenia/kernel/xam/xam_input.cc @@ -227,6 +227,44 @@ X_HRESULT_result_t XamUserGetDeviceContext_entry( } DECLARE_XAM_EXPORT1(XamUserGetDeviceContext, kInput, kStub); +X_HRESULT_result_t XamInputNonControllerGetRaw_entry( + lpdword_t state_ptr, lpdword_t buffer_length_ptr, lpdword_t buffer_ptr) { + if (!state_ptr || !buffer_length_ptr || !buffer_ptr) { + return X_ERROR_INVALID_PARAMETER; + } + + const uint32_t data_size = *buffer_length_ptr; + + if (data_size == 0 || data_size > 0x20) { + return X_ERROR_INVALID_PARAMETER; + } + + auto input_system = kernel_state()->emulator()->input_system(); + + std::vector data(data_size, 0); + const auto result = input_system->GetSkylanderPortal()->read(data); + *state_ptr = 1; + memcpy(buffer_ptr, data.data(), data.size()); + + return result; +} +DECLARE_XAM_EXPORT1(XamInputNonControllerGetRaw, kInput, kStub); + +X_HRESULT_result_t XamInputNonControllerSetRaw_entry(dword_t buffer_length, + lpdword_t buffer_ptr) { + if (!buffer_ptr || !buffer_length || buffer_length > 0x20) { + return X_ERROR_INVALID_PARAMETER; + } + + auto input_system = kernel_state()->emulator()->input_system(); + + std::vector data(buffer_length, 0); + memcpy(data.data(), buffer_ptr, buffer_length); + + return input_system->GetSkylanderPortal()->write(data); +} +DECLARE_XAM_EXPORT1(XamInputNonControllerSetRaw, kInput, kStub); + } // namespace xam } // namespace kernel } // namespace xe From 31d715d100ffaa72df4c9293ca8b000784441c11 Mon Sep 17 00:00:00 2001 From: Gliniak Date: Mon, 14 Apr 2025 22:17:00 +0200 Subject: [PATCH 5/9] [Premake] Removed unused/unnecessary subprojects. - Testing currently doesn't work - VFS Dump is unused. You can use internal function for it - Demos are only for fun - Trace Dump & Trace Viewer (unsure, but ok) You can re-enable them by changing values: enableTests and enableMiscSubprojects in main premake file. In the future there should be xb command support to overwrite them --- premake5.lua | 5 + src/xenia/app/premake5.lua | 28 ++-- src/xenia/base/premake5.lua | 4 +- src/xenia/cpu/premake5.lua | 10 +- src/xenia/gpu/d3d12/premake5.lua | 204 ++++++++++++------------ src/xenia/gpu/vulkan/premake5.lua | 248 +++++++++++++++--------------- src/xenia/ui/d3d12/premake5.lua | 47 +++--- src/xenia/ui/premake5.lua | 4 - src/xenia/ui/vulkan/premake5.lua | 63 ++++---- src/xenia/vfs/premake5.lua | 50 +++--- 10 files changed, 332 insertions(+), 331 deletions(-) diff --git a/premake5.lua b/premake5.lua index d9b02cb36..662547539 100644 --- a/premake5.lua +++ b/premake5.lua @@ -7,6 +7,11 @@ 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 diff --git a/src/xenia/app/premake5.lua b/src/xenia/app/premake5.lua index 11a7a0100..5a1dbf59d 100644 --- a/src/xenia/app/premake5.lua +++ b/src/xenia/app/premake5.lua @@ -54,11 +54,13 @@ project("xenia-app") -- Unified library containing all apps as StaticLibs, not just the main -- emulator windowed app. kind("SharedLib") - links({ - "xenia-gpu-vulkan-trace-viewer", - "xenia-hid-demo", - "xenia-ui-window-vulkan-demo", - }) + if enableMiscSubprojects then + links({ + "xenia-gpu-vulkan-trace-viewer", + "xenia-hid-demo", + "xenia-ui-window-vulkan-demo", + }) + end filter(NOT_SINGLE_LIBRARY_FILTER) kind("WindowedApp") @@ -114,15 +116,13 @@ project("xenia-app") "xenia-ui-d3d12", }) - filter({"platforms:Windows", SINGLE_LIBRARY_FILTER}) - links({ - "xenia-gpu-d3d12-trace-viewer", - "xenia-ui-window-d3d12-demo", - }) --- filter({"configurations:Release", "platforms:Windows"}) --- buildoptions({ --- "/O1", --- }) + if enableMiscSubprojects then + filter({"platforms:Windows", SINGLE_LIBRARY_FILTER}) + links({ + "xenia-gpu-d3d12-trace-viewer", + "xenia-ui-window-d3d12-demo", + }) + end filter("platforms:Windows") -- Only create the .user file if it doesn't already exist. diff --git a/src/xenia/base/premake5.lua b/src/xenia/base/premake5.lua index d53c34351..7edd282a8 100644 --- a/src/xenia/base/premake5.lua +++ b/src/xenia/base/premake5.lua @@ -17,4 +17,6 @@ project("xenia-base") "debug_visualizers.natvis", }) -include("testing") +if enableTests then + include("testing") +end \ No newline at end of file diff --git a/src/xenia/cpu/premake5.lua b/src/xenia/cpu/premake5.lua index 14a423126..6c0240c9d 100644 --- a/src/xenia/cpu/premake5.lua +++ b/src/xenia/cpu/premake5.lua @@ -21,9 +21,7 @@ project("xenia-cpu") local_platform_files("hir") local_platform_files("ppc") -include("testing") -include("ppc/testing") --- filter({"configurations:Release", "platforms:Windows"}) --- buildoptions({ --- "/O1", --- }) +if enableTests then + include("testing") + include("ppc/testing") +end diff --git a/src/xenia/gpu/d3d12/premake5.lua b/src/xenia/gpu/d3d12/premake5.lua index 34ca32947..c79ceec02 100644 --- a/src/xenia/gpu/d3d12/premake5.lua +++ b/src/xenia/gpu/d3d12/premake5.lua @@ -19,108 +19,110 @@ project("xenia-gpu-d3d12") "../shaders/bytecode/d3d12_5_1/*.h", }) -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", - }) - 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 - - filter("architecture:x86_64") +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-cpu-backend-x64", + "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-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-hid-skylander", - "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", + "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 + + 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++") + 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", + }) + 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 \ No newline at end of file diff --git a/src/xenia/gpu/vulkan/premake5.lua b/src/xenia/gpu/vulkan/premake5.lua index b27610286..bb37a61f1 100644 --- a/src/xenia/gpu/vulkan/premake5.lua +++ b/src/xenia/gpu/vulkan/premake5.lua @@ -23,132 +23,134 @@ project("xenia-gpu-vulkan") "../shaders/bytecode/vulkan_spirv/*.h", }) -group("src") -project("xenia-gpu-vulkan-trace-viewer") - uuid("86a1dddc-a26a-4885-8c55-cf745225d93e") - single_library_windowed_app_kind() - language("C++") - links({ - "xenia-apu", - "xenia-apu-nop", - "xenia-base", - "xenia-core", - "xenia-cpu", - "xenia-gpu", - "xenia-gpu-vulkan", - "xenia-hid", - "xenia-hid-nop", - "xenia-hid-skylander", - "xenia-kernel", - "xenia-patcher", - "xenia-ui", - "xenia-ui-vulkan", - "xenia-vfs", - }) - links({ - "aes_128", - "capstone", - "fmt", - "glslang-spirv", - "imgui", - "libavcodec", - "libavutil", - "mspack", - "snappy", - "xxhash", - }) - includedirs({ - project_root.."/third_party/Vulkan-Headers/include", - }) - files({ - "vulkan_trace_viewer_main.cc", - "../../ui/windowed_app_main_"..platform_suffix..".cc", - }) - - filter("architecture:x86_64") +if enableMiscSubprojects then + group("src") + project("xenia-gpu-vulkan-trace-viewer") + uuid("86a1dddc-a26a-4885-8c55-cf745225d93e") + single_library_windowed_app_kind() + language("C++") links({ - "xenia-cpu-backend-x64", + "xenia-apu", + "xenia-apu-nop", + "xenia-base", + "xenia-core", + "xenia-cpu", + "xenia-gpu", + "xenia-gpu-vulkan", + "xenia-hid", + "xenia-hid-nop", + "xenia-hid-skylander", + "xenia-kernel", + "xenia-patcher", + "xenia-ui", + "xenia-ui-vulkan", + "xenia-vfs", + }) + links({ + "aes_128", + "capstone", + "fmt", + "glslang-spirv", + "imgui", + "libavcodec", + "libavutil", + "mspack", + "snappy", + "xxhash", + }) + includedirs({ + project_root.."/third_party/Vulkan-Headers/include", + }) + files({ + "vulkan_trace_viewer_main.cc", + "../../ui/windowed_app_main_"..platform_suffix..".cc", }) - filter("platforms:Linux") - links({ - "X11", - "xcb", - "X11-xcb", - }) - - filter("platforms:Windows") - -- Only create the .user file if it doesn't already exist. - local user_file = project_root.."/build/xenia-gpu-vulkan-trace-viewer.vcxproj.user" - if not os.isfile(user_file) then - debugdir(project_root) - debugargs({ - "2>&1", - "1>scratch/stdout-trace-viewer.txt", + filter("architecture:x86_64") + links({ + "xenia-cpu-backend-x64", }) - end -group("src") -project("xenia-gpu-vulkan-trace-dump") - uuid("0dd0dd1c-b321-494d-ab9a-6c062f0c65cc") - kind("ConsoleApp") - language("C++") - links({ - "xenia-apu", - "xenia-apu-nop", - "xenia-base", - "xenia-core", - "xenia-cpu", - "xenia-gpu", - "xenia-gpu-vulkan", - "xenia-hid", - "xenia-hid-nop", - "xenia-hid-skylander", - "xenia-kernel", - "xenia-ui", - "xenia-ui-vulkan", - "xenia-vfs", - "xenia-patcher", - }) - links({ - "aes_128", - "capstone", - "fmt", - "glslang-spirv", - "imgui", - "libavcodec", - "libavutil", - "mspack", - "snappy", - "xxhash", - }) - includedirs({ - project_root.."/third_party/Vulkan-Headers/include", - }) - files({ - "vulkan_trace_dump_main.cc", - "../../base/console_app_main_"..platform_suffix..".cc", - }) - - filter("architecture:x86_64") - links({ - "xenia-cpu-backend-x64", - }) - - filter("platforms:Linux") - links({ - "X11", - "xcb", - "X11-xcb", - }) - - filter("platforms:Windows") - -- Only create the .user file if it doesn't already exist. - local user_file = project_root.."/build/xenia-gpu-vulkan-trace-dump.vcxproj.user" - if not os.isfile(user_file) then - debugdir(project_root) - debugargs({ - "2>&1", - "1>scratch/stdout-trace-dump.txt", + filter("platforms:Linux") + links({ + "X11", + "xcb", + "X11-xcb", }) - end + + filter("platforms:Windows") + -- Only create the .user file if it doesn't already exist. + local user_file = project_root.."/build/xenia-gpu-vulkan-trace-viewer.vcxproj.user" + if not os.isfile(user_file) then + debugdir(project_root) + debugargs({ + "2>&1", + "1>scratch/stdout-trace-viewer.txt", + }) + end + + group("src") + project("xenia-gpu-vulkan-trace-dump") + uuid("0dd0dd1c-b321-494d-ab9a-6c062f0c65cc") + kind("ConsoleApp") + language("C++") + links({ + "xenia-apu", + "xenia-apu-nop", + "xenia-base", + "xenia-core", + "xenia-cpu", + "xenia-gpu", + "xenia-gpu-vulkan", + "xenia-hid", + "xenia-hid-nop", + "xenia-hid-skylander", + "xenia-kernel", + "xenia-ui", + "xenia-ui-vulkan", + "xenia-vfs", + "xenia-patcher", + }) + links({ + "aes_128", + "capstone", + "fmt", + "glslang-spirv", + "imgui", + "libavcodec", + "libavutil", + "mspack", + "snappy", + "xxhash", + }) + includedirs({ + project_root.."/third_party/Vulkan-Headers/include", + }) + files({ + "vulkan_trace_dump_main.cc", + "../../base/console_app_main_"..platform_suffix..".cc", + }) + + filter("architecture:x86_64") + links({ + "xenia-cpu-backend-x64", + }) + + filter("platforms:Linux") + links({ + "X11", + "xcb", + "X11-xcb", + }) + + filter("platforms:Windows") + -- Only create the .user file if it doesn't already exist. + local user_file = project_root.."/build/xenia-gpu-vulkan-trace-dump.vcxproj.user" + if not os.isfile(user_file) then + debugdir(project_root) + debugargs({ + "2>&1", + "1>scratch/stdout-trace-dump.txt", + }) + end +end \ No newline at end of file diff --git a/src/xenia/ui/d3d12/premake5.lua b/src/xenia/ui/d3d12/premake5.lua index 9e667bbe9..fdbdf73bf 100644 --- a/src/xenia/ui/d3d12/premake5.lua +++ b/src/xenia/ui/d3d12/premake5.lua @@ -10,33 +10,30 @@ project("xenia-ui-d3d12") "xenia-base", "xenia-ui", }) --- filter({"configurations:Release", "platforms:Windows"}) --- buildoptions({ --- "/O1", --- }) --- filter {} local_platform_files() files({ "../shaders/bytecode/d3d12_5_1/*.h", }) -group("demos") -project("xenia-ui-window-d3d12-demo") - uuid("3b9686a7-0f04-4e17-8b00-aeb78ae1107c") - single_library_windowed_app_kind() - language("C++") - links({ - "fmt", - "imgui", - "xenia-base", - "xenia-ui", - "xenia-ui-d3d12", - }) - files({ - "../window_demo.cc", - "d3d12_window_demo.cc", - project_root.."/src/xenia/ui/windowed_app_main_"..platform_suffix..".cc", - }) - resincludedirs({ - project_root, - }) +if enableMiscSubprojects then + group("demos") + project("xenia-ui-window-d3d12-demo") + uuid("3b9686a7-0f04-4e17-8b00-aeb78ae1107c") + single_library_windowed_app_kind() + language("C++") + links({ + "fmt", + "imgui", + "xenia-base", + "xenia-ui", + "xenia-ui-d3d12", + }) + files({ + "../window_demo.cc", + "d3d12_window_demo.cc", + project_root.."/src/xenia/ui/windowed_app_main_"..platform_suffix..".cc", + }) + resincludedirs({ + project_root, + }) +end \ No newline at end of file diff --git a/src/xenia/ui/premake5.lua b/src/xenia/ui/premake5.lua index fde2ba8e2..5c55c8c88 100644 --- a/src/xenia/ui/premake5.lua +++ b/src/xenia/ui/premake5.lua @@ -14,10 +14,6 @@ project("xenia-ui") local_platform_files() removefiles({"*_demo.cc"}) removefiles({"windowed_app_main_*.cc"}) --- filter({"configurations:Release", "platforms:Windows"}) --- buildoptions({ --- "/O1", --- }) filter("platforms:Android-*") -- Exports JNI functions. wholelib("On") diff --git a/src/xenia/ui/vulkan/premake5.lua b/src/xenia/ui/vulkan/premake5.lua index 3c1bfb2a3..e272e1adb 100644 --- a/src/xenia/ui/vulkan/premake5.lua +++ b/src/xenia/ui/vulkan/premake5.lua @@ -10,11 +10,6 @@ project("xenia-ui-vulkan") "xenia-base", "xenia-ui", }) --- filter({"configurations:Release", "platforms:Windows"}) --- buildoptions({ --- "/O1", --- }) --- filter {} includedirs({ project_root.."/third_party/Vulkan-Headers/include", }) @@ -24,33 +19,35 @@ project("xenia-ui-vulkan") "../shaders/bytecode/vulkan_spirv/*.h", }) -group("demos") -project("xenia-ui-window-vulkan-demo") - uuid("97598f13-3177-454c-8e58-c59e2b6ede27") - single_library_windowed_app_kind() - language("C++") - links({ - "fmt", - "imgui", - "xenia-base", - "xenia-ui", - "xenia-ui-vulkan", - }) - includedirs({ - project_root.."/third_party/Vulkan-Headers/include", - }) - files({ - "../window_demo.cc", - "vulkan_window_demo.cc", - project_root.."/src/xenia/ui/windowed_app_main_"..platform_suffix..".cc", - }) - resincludedirs({ - project_root, - }) - - filter("platforms:Linux") +if enableMiscSubprojects then + group("demos") + project("xenia-ui-window-vulkan-demo") + uuid("97598f13-3177-454c-8e58-c59e2b6ede27") + single_library_windowed_app_kind() + language("C++") links({ - "X11", - "xcb", - "X11-xcb", + "fmt", + "imgui", + "xenia-base", + "xenia-ui", + "xenia-ui-vulkan", }) + includedirs({ + project_root.."/third_party/Vulkan-Headers/include", + }) + files({ + "../window_demo.cc", + "vulkan_window_demo.cc", + project_root.."/src/xenia/ui/windowed_app_main_"..platform_suffix..".cc", + }) + resincludedirs({ + project_root, + }) + + filter("platforms:Linux") + links({ + "X11", + "xcb", + "X11-xcb", + }) +end \ No newline at end of file diff --git a/src/xenia/vfs/premake5.lua b/src/xenia/vfs/premake5.lua index 214f18864..ee6709c65 100644 --- a/src/xenia/vfs/premake5.lua +++ b/src/xenia/vfs/premake5.lua @@ -7,35 +7,37 @@ project("xenia-vfs") kind("StaticLib") language("C++") links({ - "xenia-base", "zstd", "zarchive" + "xenia-base", + "zstd", + "zarchive" }) defines({ }) --- filter({"configurations:Release", "platforms:Windows"}) --- buildoptions({ --- "/O1", --- }) --- filter {} recursive_platform_files() removefiles({"vfs_dump.cc"}) -project("xenia-vfs-dump") - uuid("2EF270C7-41A8-4D0E-ACC5-59693A9CCE32") - kind("ConsoleApp") - language("C++") - links({ - "fmt", - "xenia-base", - "xenia-vfs", - }) - defines({}) +if enableMiscSubprojects then + project("xenia-vfs-dump") + uuid("2EF270C7-41A8-4D0E-ACC5-59693A9CCE32") + kind("ConsoleApp") + language("C++") + links({ + "fmt", + "xenia-base", + "xenia-vfs", + }) + defines({}) - files({ - "vfs_dump.cc", - project_root.."/src/xenia/base/console_app_main_"..platform_suffix..".cc", - }) - resincludedirs({ - project_root, - }) -include("testing") + files({ + "vfs_dump.cc", + project_root.."/src/xenia/base/console_app_main_"..platform_suffix..".cc", + }) + resincludedirs({ + project_root, + }) +end + +if enableTests then + include("testing") +end From bde7d5579acfc5abc93fbdf2c8f47ac196491ade Mon Sep 17 00:00:00 2001 From: Adrian <78108584+AdrianCassar@users.noreply.github.com> Date: Tue, 15 Apr 2025 12:15:46 +0100 Subject: [PATCH 6/9] [Kernel] Fixed xex2_version --- src/xenia/emulator.cc | 16 +++------------- src/xenia/kernel/util/xex2_info.h | 6 +++--- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index 055cc59cd..82ca8f1e9 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -1333,19 +1333,9 @@ std::string Emulator::FindLaunchModule() { } static std::string format_version(xex2_version version) { - // 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); + // fmt::format doesn't like bit fields we use + to bypass it + return fmt::format("{}.{}.{}.{}", +version.major, +version.minor, + +version.build, +version.qfe); } X_STATUS Emulator::CompleteLaunch(const std::filesystem::path& path, diff --git a/src/xenia/kernel/util/xex2_info.h b/src/xenia/kernel/util/xex2_info.h index d9e939478..52df96ad4 100644 --- a/src/xenia/kernel/util/xex2_info.h +++ b/src/xenia/kernel/util/xex2_info.h @@ -375,10 +375,10 @@ struct xex2_opt_file_format_info { union xex2_version { uint32_t value; struct { - uint32_t major : 4; - uint32_t minor : 4; - uint32_t build : 16; uint32_t qfe : 8; + uint32_t build : 16; + uint32_t minor : 4; + uint32_t major : 4; }; }; From 066391fb5995376449bf35029650e5543010c983 Mon Sep 17 00:00:00 2001 From: Marco Rodolfi Date: Sun, 9 Feb 2025 14:07:34 +0100 Subject: [PATCH 7/9] [main ui] Properly handle XDG format specifications for Linux systems. The issue was stemming from the fact that by default Xenia is running in portable mode, as in use the same root directory as the executable for its datafiles. This default is an issue when using this software from a POSIX platform, since a lot of the times the location where the binary resides is not writable by default. Therefore, force portable mode to be disabled on non Windows platforms. --- src/xenia/app/xenia_main.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/xenia/app/xenia_main.cc b/src/xenia/app/xenia_main.cc index d90246936..25fba3735 100644 --- a/src/xenia/app/xenia_main.cc +++ b/src/xenia/app/xenia_main.cc @@ -95,9 +95,15 @@ 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); @@ -421,7 +427,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_GNU_LINUX) +#if defined(XE_PLATFORM_WIN32) || defined(XE_PLATFORM_LINUX) storage_root = storage_root / "Xenia"; #else // TODO(Triang3l): Point to the app's external storage "files" directory From 5d5eb03127028cbbee70a87f0463c4a4bd84cdef Mon Sep 17 00:00:00 2001 From: Xphalnos <164882787+Xphalnos@users.noreply.github.com> Date: Wed, 2 Apr 2025 13:20:00 +0200 Subject: [PATCH 8/9] [GPU] Adding Registers from Xenon --- .../gpu/pm4_command_processor_implement.h | 3 +- src/xenia/gpu/register_table.inc | 872 ++++++++++++++++-- 2 files changed, 805 insertions(+), 70 deletions(-) diff --git a/src/xenia/gpu/pm4_command_processor_implement.h b/src/xenia/gpu/pm4_command_processor_implement.h index 3cb6fbb91..5b04df510 100644 --- a/src/xenia/gpu/pm4_command_processor_implement.h +++ b/src/xenia/gpu/pm4_command_processor_implement.h @@ -902,7 +902,8 @@ 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_BASE]; + uint32_t writeback_base = + register_file_->values[XE_GPU_REG_WRITEBACK_START]; 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 diff --git a/src/xenia/gpu/register_table.inc b/src/xenia/gpu/register_table.inc index 125c635fb..328247872 100644 --- a/src/xenia/gpu/register_table.inc +++ b/src/xenia/gpu/register_table.inc @@ -2,7 +2,7 @@ ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** - * Copyright 2013 Ben Vanik. All rights reserved. * + * Copyright 2025 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ @@ -11,24 +11,152 @@ // constructing various tables. // Almost all of these values are taken directly from: -// https://github.com/freedreno/amd-gpu/blob/master/include/reg/yamato/22/yamato_offset.h +// https://github.com/xenon-emu/xenon/blob/main/Xenon/Core/XGPU/XenosRegisters.h // #define XE_GPU_REGISTER(index, type, name) +XE_GPU_REGISTER(0x0000, kDword, RBBM_RTL_RELEASE) +XE_GPU_REGISTER(0x0001, kDword, RBBM_PATCH_RELEASE) +XE_GPU_REGISTER(0x0002, kDword, RBBM_AUXILIARY_CONFIG) +XE_GPU_REGISTER(0x0004, kDword, BIOS_0_SCRATCH) +XE_GPU_REGISTER(0x0005, kDword, BIOS_1_SCRATCH) +XE_GPU_REGISTER(0x0006, kDword, BIOS_2_SCRATCH) +XE_GPU_REGISTER(0x0007, kDword, BIOS_3_SCRATCH) +XE_GPU_REGISTER(0x0008, kDword, BIOS_4_SCRATCH) +XE_GPU_REGISTER(0x0009, kDword, BIOS_5_SCRATCH) +XE_GPU_REGISTER(0x000A, kDword, BIOS_6_SCRATCH) +XE_GPU_REGISTER(0x000B, kDword, BIOS_7_SCRATCH) +XE_GPU_REGISTER(0x0038, kDword, CONFIG_CNTL) +XE_GPU_REGISTER(0x0039, kDword, CONFIG_XSTRAP) +XE_GPU_REGISTER(0x003A, kDword, CONFIG_XSTRAP2) +XE_GPU_REGISTER(0x003B, kDword, RBBM_CNTL) +XE_GPU_REGISTER(0x003C, kDword, RBBM_SOFT_RESET) +XE_GPU_REGISTER(0x003D, kDword, RBBM_SKEW_CNTL) +XE_GPU_REGISTER(0x0040, kDword, MH_MMU_CONFIG) +XE_GPU_REGISTER(0x0041, kDword, MH_MMU_VA_RANGE) +XE_GPU_REGISTER(0x0042, kDword, MH_MMU_PT_BASE) +XE_GPU_REGISTER(0x0043, kDword, MH_MMU_PAGE_FAULT) +XE_GPU_REGISTER(0x0044, kDword, MH_MMU_TRAN_ERROR) +XE_GPU_REGISTER(0x0045, kDword, MH_MMU_INVALIDATE) +XE_GPU_REGISTER(0x0046, kDword, MH_MMU_MPU_BASE) +XE_GPU_REGISTER(0x0047, kDword, MH_MMU_MPU_END) XE_GPU_REGISTER(0x0048, kDword, BIF_PERFCOUNTER0_SELECT) XE_GPU_REGISTER(0x0049, kDword, BIF_PERFCOUNTER0_HI) XE_GPU_REGISTER(0x004A, kDword, BIF_PERFCOUNTER0_LOW) -XE_GPU_REGISTER(0x1C5, kDword, CP_RB_WPTR) - -XE_GPU_REGISTER(0x01DD, kDword, SCRATCH_ADDR) +XE_GPU_REGISTER(0x0064, kDword, ROM_PAR_DATA_REG) +XE_GPU_REGISTER(0x0065, kDword, ROM_BAD_PIPE_DISABLE_REGISTER) +XE_GPU_REGISTER(0x0066, kDword, ROM_PAR_ADDR_REG) +XE_GPU_REGISTER(0x0067, kDword, ROM_CLK_REG) +XE_GPU_REGISTER(0x0068, kDword, ROM_BAD_PIPE_FUSE_REG) +XE_GPU_REGISTER(0x0069, kDword, DBG_CNTL1_REG) +XE_GPU_REGISTER(0x006A, kDword, ROM_SIMD_PIPE_DISABLE_REGISTER) +XE_GPU_REGISTER(0x006B, kDword, DBG_READ_REG) +XE_GPU_REGISTER(0x006C, kDword, ROM_PADS_REG) +XE_GPU_REGISTER(0x006D, kDword, SOFT_STRAP_CNTL) +XE_GPU_REGISTER(0x006E, kDword, CONFIG_XSTRAP3) +XE_GPU_REGISTER(0x006F, kDword, EXTERN_TRIG_CNTL) +XE_GPU_REGISTER(0x0070, kDword, ROM_STATUS_REG) +XE_GPU_REGISTER(0x0071, kDword, ROM_PORT_REG) +XE_GPU_REGISTER(0x0080, kDword, SCLK_PWRMGT_CNTL1_REG) +XE_GPU_REGISTER(0x0081, kDword, SCLK_PWRMGT_CNTL2_REG) +XE_GPU_REGISTER(0x0082, kDword, SCLK_PWRMGT_CNTL3_REG) +XE_GPU_REGISTER(0x0083, kDword, FSB_STOP_CLK_REG) +XE_GPU_REGISTER(0x0084, kDword, SPLL_CNTL_REG) +XE_GPU_REGISTER(0x0085, kDword, CG_SCRATCH1) +XE_GPU_REGISTER(0x0086, kDword, RCLK_PWRMGT_CNTL_REG) +XE_GPU_REGISTER(0x0087, kDword, PSRO_REG) +XE_GPU_REGISTER(0x0091, kDword, RPLL_CNTL_REG) +XE_GPU_REGISTER(0x0092, kDword, FPLL_CNTL_REG) +XE_GPU_REGISTER(0x0093, kDword, CG_INT_MASK_REG) +XE_GPU_REGISTER(0x0094, kDword, CG_INT_STAT_REG) +XE_GPU_REGISTER(0x0095, kDword, CG_INT_ACK_REG) +XE_GPU_REGISTER(0x00A0, kDword, MCLK_CNTL1_REG) +XE_GPU_REGISTER(0x00A1, kDword, MPLL_CNTL_REG) +XE_GPU_REGISTER(0x00A2, kDword, YCLK_CNTL1_REG) +XE_GPU_REGISTER(0x00A3, kDword, MDLL_CNTL1_REG) +XE_GPU_REGISTER(0x00A6, kDword, MCLK_PWRMGT_CNTL_REG) +XE_GPU_REGISTER(0x00A7, kDword, MCLK_TEST_CNTL1_REG) +XE_GPU_REGISTER(0x00A8, kDword, CGM_MC0_IO_CNTL) +XE_GPU_REGISTER(0x00A9, kDword, CGM_DRAM_CNTL_REG) +XE_GPU_REGISTER(0x00AA, kDword, CGM_MC1_IO_CNTL) +XE_GPU_REGISTER(0x0128, kDword, PCLK_SOFT_RESET) +XE_GPU_REGISTER(0x0129, kDword, DCCG_SCLK_R_DISP_CNTL) +XE_GPU_REGISTER(0x012F, kDword, SCLK_G_SCL1_CNTL) +XE_GPU_REGISTER(0x0132, kDword, SCLK_SOFT_RESET) +XE_GPU_REGISTER(0x0133, kDword, DCCG_CLK_CNTL) +XE_GPU_REGISTER(0x0135, kDword, TEST_COUNT_CNTL) +XE_GPU_REGISTER(0x0136, kDword, DCCG_TEST_CLK_SEL) +XE_GPU_REGISTER(0x013C, kDword, DVOACLK_CNTL) +XE_GPU_REGISTER(0x0140, kDword, DCCG_ONE_SHOT_CLOCKING_CNTL) +XE_GPU_REGISTER(0x0141, kDword, DCCG_ONE_SHOT_STOP_CLOCKS_CNTL) +XE_GPU_REGISTER(0x0142, kDword, DCCG_ONE_SHOT_RUN_CLOCKS_CNTL) +XE_GPU_REGISTER(0x0143, kDword, DCCG_ONE_SHOT_RUN_CLOCKS_COUNT) +XE_GPU_REGISTER(0x0144, kDword, DCCG_DEBUG) +XE_GPU_REGISTER(0x015C, kDword, SCLK_G_DCP_CNTL) +XE_GPU_REGISTER(0x01C0, kDword, CP_RB_BASE) +XE_GPU_REGISTER(0x01C1, kDword, CP_RB_CNTL) +XE_GPU_REGISTER(0x01C3, kDword, CP_RB_RPTR_ADDR) +XE_GPU_REGISTER(0x01C4, kDword, CP_RB_RPTR) +XE_GPU_REGISTER(0x01C5, kDword, CP_RB_WPTR) +XE_GPU_REGISTER(0x01C6, kDword, CP_RB_WPTR_DELAY) +XE_GPU_REGISTER(0x01C7, kDword, CP_RB_RPTR_WR) +XE_GPU_REGISTER(0x01C8, kDword, CP_DMA_SRC_ADDR) +XE_GPU_REGISTER(0x01C9, kDword, CP_DMA_DST_ADDR) +XE_GPU_REGISTER(0x01CA, kDword, CP_DMA_COMMAND) +XE_GPU_REGISTER(0x01CC, kDword, CP_IB1_BASE) +XE_GPU_REGISTER(0x01CD, kDword, CP_IB1_BUFSZ) +XE_GPU_REGISTER(0x01CE, kDword, CP_IB2_BASE) +XE_GPU_REGISTER(0x01CF, kDword, CP_IB2_BUFSZ) +XE_GPU_REGISTER(0x01D0, kDword, CP_RT_BASE) +XE_GPU_REGISTER(0x01D1, kDword, CP_RT_BUFSZ) +XE_GPU_REGISTER(0x01D2, kDword, CP_RT_ST_BASE) +XE_GPU_REGISTER(0x01D3, kDword, CP_RT_ST_BUFSZ) +XE_GPU_REGISTER(0x01D5, kDword, CP_QUEUE_THRESHOLDS) +XE_GPU_REGISTER(0x01D6, kDword, CP_MEQ_THRESHOLDS) +XE_GPU_REGISTER(0x01D7, kDword, CP_CSQ_AVAIL) +XE_GPU_REGISTER(0x01D8, kDword, CP_STQ_AVAIL) +XE_GPU_REGISTER(0x01D9, kDword, CP_MEQ_AVAIL) +XE_GPU_REGISTER(0x01DA, kDword, CP_CMD_INDEX) +XE_GPU_REGISTER(0x01DB, kDword, CP_CMD_DATA) XE_GPU_REGISTER(0x01DC, kDword, SCRATCH_UMSK) -XE_GPU_REGISTER(0x01E6, kDword, CP_PERFCOUNTER0_SELECT) -XE_GPU_REGISTER(0x01E7, kDword, CP_PERFCOUNTER0_LOW) -XE_GPU_REGISTER(0x01E8, kDword, CP_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x01DD, kDword, SCRATCH_ADDR) +XE_GPU_REGISTER(0x01DE, kDword, SCRATCH_CMP_HI) +XE_GPU_REGISTER(0x01DF, kDword, SCRATCH_CMP_LO) +XE_GPU_REGISTER(0x01E0, kDword, CP_DMA_TABLE_ADDR) +XE_GPU_REGISTER(0x01E1, kDword, CP_DMA_SRC_ADDR_STAT) +XE_GPU_REGISTER(0x01E2, kDword, CP_DMA_DST_ADDR_STAT) +XE_GPU_REGISTER(0x01E3, kDword, CP_DMA_COMMAND_STAT) +XE_GPU_REGISTER(0x01E4, kDword, CP_DMA_STAT) +XE_GPU_REGISTER(0x01E5, kDword, CP_DMA_ACT_DSCR_STAT) +XE_GPU_REGISTER(0x01E6, kDword, CP_PERFCOUNTER_SELECT) +XE_GPU_REGISTER(0x01E7, kDword, CP_PERFCOUNTER_LO) +XE_GPU_REGISTER(0x01E8, kDword, CP_PERFCOUNTER_HI) +XE_GPU_REGISTER(0x01E9, kDword, SCRATCH_CMP_CNTL) +XE_GPU_REGISTER(0x01EA, kDword, CP_ME_RDADDR) +XE_GPU_REGISTER(0x01EC, kDword, CP_STATE_DEBUG_INDEX) +XE_GPU_REGISTER(0x01ED, kDword, CP_STATE_DEBUG_DATA) +XE_GPU_REGISTER(0x01EE, kDword, CP_NV_FLAGS_0) +XE_GPU_REGISTER(0x01EF, kDword, CP_NV_FLAGS_1) +XE_GPU_REGISTER(0x01F0, kDword, CP_NV_FLAGS_2) +XE_GPU_REGISTER(0x01F1, kDword, CP_NV_FLAGS_3) +XE_GPU_REGISTER(0x01F2, kDword, CP_INT_CNTL) +XE_GPU_REGISTER(0x01F3, kDword, CP_INT_STATUS) +XE_GPU_REGISTER(0x01F4, kDword, CP_INT_ACK) XE_GPU_REGISTER(0x01F5, kDword, CP_PERFMON_CNTL) +XE_GPU_REGISTER(0x01F6, kDword, CP_ME_CNTL) +XE_GPU_REGISTER(0x01F7, kDword, CP_ME_STATUS) +XE_GPU_REGISTER(0x01F8, kDword, CP_ME_RAM_WADDR) +XE_GPU_REGISTER(0x01F9, kDword, CP_ME_RAM_RADDR) +XE_GPU_REGISTER(0x01FA, kDword, CP_ME_RAM_DATA) +XE_GPU_REGISTER(0x01FB, kDword, CP_SNOOP_CNTL) +XE_GPU_REGISTER(0x01FC, kDword, CP_DEBUG) +XE_GPU_REGISTER(0x01FD, kDword, CP_CSQ_RB_STAT) +XE_GPU_REGISTER(0x01FE, kDword, CP_CSQ_IB1_STAT) +XE_GPU_REGISTER(0x01FF, kDword, CP_CSQ_IB2_STAT) +XE_GPU_REGISTER(0x0394, kDword, NQWAIT_UNTIL) XE_GPU_REGISTER(0x0395, kDword, RBBM_PERFCOUNTER0_SELECT) XE_GPU_REGISTER(0x0396, kDword, RBBM_PERFCOUNTER1_SELECT) XE_GPU_REGISTER(0x0397, kDword, RBBM_PERFCOUNTER0_LOW) @@ -36,23 +164,172 @@ XE_GPU_REGISTER(0x0398, kDword, RBBM_PERFCOUNTER0_HI) XE_GPU_REGISTER(0x0399, kDword, RBBM_PERFCOUNTER1_LOW) XE_GPU_REGISTER(0x039A, kDword, RBBM_PERFCOUNTER1_HI) -// XAM reads this directly and stores it to a struct, have not tracked where it -// goes from there PM4 command PM4_MEM_WRITE_CNTR is supposed to write this to -// memory XE_GPU_REGISTER(0x44b, kDword,CP_PROG_COUNTER ) -XE_GPU_REGISTER(0x045E, kDword, CALLBACK_ACK) - -XE_GPU_REGISTER(0x0578, kDword, SCRATCH_REG0) // interrupt sync -XE_GPU_REGISTER(0x0579, kDword, SCRATCH_REG1) // present interval +XE_GPU_REGISTER(0x039B, kDword, RBBM_DEBUG) +XE_GPU_REGISTER(0x039C, kDword, RBBM_STATUS2) +XE_GPU_REGISTER(0x039D, kDword, RBBM_CRC32) +XE_GPU_REGISTER(0x03A0, kDword, RBBM_DEBUG_OUT) +XE_GPU_REGISTER(0x03A1, kDword, RBBM_DEBUG_CNTL) +XE_GPU_REGISTER(0x03B2, kDword, RBBM_WAIT_IDLE_CLOCKS) +XE_GPU_REGISTER(0x03B3, kDword, RBBM_READ_ERROR) +XE_GPU_REGISTER(0x03B4, kDword, RBBM_INT_CNTL) +XE_GPU_REGISTER(0x03B5, kDword, RBBM_INT_STATUS) +XE_GPU_REGISTER(0x03B6, kDword, RBBM_INT_ACK) +XE_GPU_REGISTER(0x03B7, kDword, MASTER_INT_SIGNAL) +XE_GPU_REGISTER(0x03F9, kDword, RBBM_PERIPHID1) +XE_GPU_REGISTER(0x03FA, kDword, RBBM_PERIPHID2) +XE_GPU_REGISTER(0x0440, kDword, CP_NON_PREFETCH_CNTRS) +XE_GPU_REGISTER(0x0442, kDword, CP_STQ_RT_STAT) +XE_GPU_REGISTER(0x0443, kDword, CP_STQ_ST_STAT) +XE_GPU_REGISTER(0x0444, kDword, CP_STQ_RT_ST_STAT) +XE_GPU_REGISTER(0x0445, kDword, CP_RT_DMA_SRC_ADDR) +XE_GPU_REGISTER(0x0446, kDword, CP_RT_DMA_DST_ADDR) +XE_GPU_REGISTER(0x0447, kDword, CP_RT_DMA_COMMAND) +XE_GPU_REGISTER(0x0448, kDword, CP_RT_ME_RAM_WADDR) +XE_GPU_REGISTER(0x0449, kDword, CP_RT_ME_RAM_RADDR) +XE_GPU_REGISTER(0x044A, kDword, CP_RT_ME_RAM_DATA) +XE_GPU_REGISTER(0x044B, kDword, CP_PROG_COUNTER) +XE_GPU_REGISTER(0x044C, kDword, CP_RT_ME_RDADDR) +XE_GPU_REGISTER(0x044D, kDword, CP_ST_BASE) +XE_GPU_REGISTER(0x044E, kDword, CP_ST_BUFSZ) +XE_GPU_REGISTER(0x044F, kDword, CP_MEQ_STAT) +XE_GPU_REGISTER(0x0452, kDword, CP_MIU_TAG_STAT0) +XE_GPU_REGISTER(0x0453, kDword, CP_MIU_TAG_STAT1) +XE_GPU_REGISTER(0x0454, kDword, CP_BIN_MASK_LO) +XE_GPU_REGISTER(0x0455, kDword, CP_BIN_MASK_HI) +XE_GPU_REGISTER(0x0456, kDword, CP_BIN_SELECT_LO) +XE_GPU_REGISTER(0x0457, kDword, CP_BIN_SELECT_HI) +XE_GPU_REGISTER(0x0458, kDword, CP_RT_BIN_MASK_LO) +XE_GPU_REGISTER(0x0459, kDword, CP_RT_BIN_MASK_HI) +XE_GPU_REGISTER(0x045A, kDword, CP_RT_BIN_SELECT_LO) +XE_GPU_REGISTER(0x045B, kDword, CP_RT_BIN_SELECT_HI) +XE_GPU_REGISTER(0x045C, kDword, CP_CPU_INT_CNTL) +XE_GPU_REGISTER(0x045D, kDword, CP_CPU_INT_STATUS) +XE_GPU_REGISTER(0x045E, kDword, CP_CPU_INT_ACK) +XE_GPU_REGISTER(0x045F, kDword, CP_PFP_UCODE_ADDR) +XE_GPU_REGISTER(0x0460, kDword, CP_PFP_UCODE_DATA) +XE_GPU_REGISTER(0x0461, kDword, CP_PFP_RT_UCODE_ADDR) +XE_GPU_REGISTER(0x0462, kDword, CP_PFP_RT_UCODE_DATA) +XE_GPU_REGISTER(0x047E, kDword, CP_RT_STAT) +XE_GPU_REGISTER(0x047F, kDword, CP_STAT) +XE_GPU_REGISTER(0x04C0, kDword, CP_RT0_COMMAND) +XE_GPU_REGISTER(0x04C1, kDword, CP_RT0_POLL_ADDRESS) +XE_GPU_REGISTER(0x04C2, kDword, CP_RT0_REFERENCE) +XE_GPU_REGISTER(0x04C3, kDword, CP_RT0_MASK) +XE_GPU_REGISTER(0x04C4, kDword, CP_RT0_BADR) +XE_GPU_REGISTER(0x04C5, kDword, CP_RT0_SIZE) +XE_GPU_REGISTER(0x04C6, kDword, CP_RT1_COMMAND) +XE_GPU_REGISTER(0x04C7, kDword, CP_RT1_POLL_ADDRESS) +XE_GPU_REGISTER(0x04C8, kDword, CP_RT1_REFERENCE) +XE_GPU_REGISTER(0x04C9, kDword, CP_RT1_MASK) +XE_GPU_REGISTER(0x04CA, kDword, CP_RT1_BADR) +XE_GPU_REGISTER(0x04CB, kDword, CP_RT1_SIZE) +XE_GPU_REGISTER(0x04CC, kDword, CP_RT2_COMMAND) +XE_GPU_REGISTER(0x04CD, kDword, CP_RT2_POLL_ADDRESS) +XE_GPU_REGISTER(0x04CE, kDword, CP_RT2_REFERENCE) +XE_GPU_REGISTER(0x04CF, kDword, CP_RT2_MASK) +XE_GPU_REGISTER(0x04D0, kDword, CP_RT2_BADR) +XE_GPU_REGISTER(0x04D1, kDword, CP_RT2_SIZE) +XE_GPU_REGISTER(0x04D2, kDword, CP_RT3_COMMAND) +XE_GPU_REGISTER(0x04D3, kDword, CP_RT3_POLL_ADDRESS) +XE_GPU_REGISTER(0x04D4, kDword, CP_RT3_REFERENCE) +XE_GPU_REGISTER(0x04D5, kDword, CP_RT3_MASK) +XE_GPU_REGISTER(0x04D6, kDword, CP_RT3_BADR) +XE_GPU_REGISTER(0x04D7, kDword, CP_RT3_SIZE) +XE_GPU_REGISTER(0x04D8, kDword, CP_RT4_COMMAND) +XE_GPU_REGISTER(0x04D9, kDword, CP_RT4_POLL_ADDRESS) +XE_GPU_REGISTER(0x04DA, kDword, CP_RT4_REFERENCE) +XE_GPU_REGISTER(0x04DB, kDword, CP_RT4_MASK) +XE_GPU_REGISTER(0x04DC, kDword, CP_RT4_BADR) +XE_GPU_REGISTER(0x04DD, kDword, CP_RT4_SIZE) +XE_GPU_REGISTER(0x04DE, kDword, CP_RT5_COMMAND) +XE_GPU_REGISTER(0x04DF, kDword, CP_RT5_POLL_ADDRESS) +XE_GPU_REGISTER(0x04E0, kDword, CP_RT5_REFERENCE) +XE_GPU_REGISTER(0x04E1, kDword, CP_RT5_MASK) +XE_GPU_REGISTER(0x04E2, kDword, CP_RT5_BADR) +XE_GPU_REGISTER(0x04E3, kDword, CP_RT5_SIZE) +XE_GPU_REGISTER(0x04E4, kDword, CP_RT6_COMMAND) +XE_GPU_REGISTER(0x04E5, kDword, CP_RT6_POLL_ADDRESS) +XE_GPU_REGISTER(0x04E6, kDword, CP_RT6_REFERENCE) +XE_GPU_REGISTER(0x04E7, kDword, CP_RT6_MASK) +XE_GPU_REGISTER(0x04E8, kDword, CP_RT6_BADR) +XE_GPU_REGISTER(0x04E9, kDword, CP_RT6_SIZE) +XE_GPU_REGISTER(0x04EA, kDword, CP_RT7_COMMAND) +XE_GPU_REGISTER(0x04EB, kDword, CP_RT7_POLL_ADDRESS) +XE_GPU_REGISTER(0x04EC, kDword, CP_RT7_REFERENCE) +XE_GPU_REGISTER(0x04ED, kDword, CP_RT7_MASK) +XE_GPU_REGISTER(0x04EE, kDword, CP_RT7_BADR) +XE_GPU_REGISTER(0x04EF, kDword, CP_RT7_SIZE) +XE_GPU_REGISTER(0x04F0, kDword, CP_RT8_COMMAND) +XE_GPU_REGISTER(0x04F1, kDword, CP_RT8_POLL_ADDRESS) +XE_GPU_REGISTER(0x04F2, kDword, CP_RT8_REFERENCE) +XE_GPU_REGISTER(0x04F3, kDword, CP_RT8_MASK) +XE_GPU_REGISTER(0x04F4, kDword, CP_RT8_BADR) +XE_GPU_REGISTER(0x04F5, kDword, CP_RT8_SIZE) +XE_GPU_REGISTER(0x04F6, kDword, CP_RT9_COMMAND) +XE_GPU_REGISTER(0x04F7, kDword, CP_RT9_POLL_ADDRESS) +XE_GPU_REGISTER(0x04F8, kDword, CP_RT9_REFERENCE) +XE_GPU_REGISTER(0x04F9, kDword, CP_RT9_MASK) +XE_GPU_REGISTER(0x04FA, kDword, CP_RT9_BADR) +XE_GPU_REGISTER(0x04FB, kDword, CP_RT9_SIZE) +XE_GPU_REGISTER(0x04FC, kDword, CP_RT10_COMMAND) +XE_GPU_REGISTER(0x04FD, kDword, CP_RT10_POLL_ADDRESS) +XE_GPU_REGISTER(0x04FE, kDword, CP_RT10_REFERENCE) +XE_GPU_REGISTER(0x04FF, kDword, CP_RT10_MASK) +XE_GPU_REGISTER(0x0500, kDword, CP_RT10_BADR) +XE_GPU_REGISTER(0x0501, kDword, CP_RT10_SIZE) +XE_GPU_REGISTER(0x0502, kDword, CP_RT11_COMMAND) +XE_GPU_REGISTER(0x0503, kDword, CP_RT11_POLL_ADDRESS) +XE_GPU_REGISTER(0x0504, kDword, CP_RT11_REFERENCE) +XE_GPU_REGISTER(0x0505, kDword, CP_RT11_MASK) +XE_GPU_REGISTER(0x0506, kDword, CP_RT11_BADR) +XE_GPU_REGISTER(0x0507, kDword, CP_RT11_SIZE) +XE_GPU_REGISTER(0x0508, kDword, CP_RT12_COMMAND) +XE_GPU_REGISTER(0x0509, kDword, CP_RT12_POLL_ADDRESS) +XE_GPU_REGISTER(0x050A, kDword, CP_RT12_REFERENCE) +XE_GPU_REGISTER(0x050B, kDword, CP_RT12_MASK) +XE_GPU_REGISTER(0x050C, kDword, CP_RT12_BADR) +XE_GPU_REGISTER(0x050D, kDword, CP_RT12_SIZE) +XE_GPU_REGISTER(0x050E, kDword, CP_RT13_COMMAND) +XE_GPU_REGISTER(0x050F, kDword, CP_RT13_POLL_ADDRESS) +XE_GPU_REGISTER(0x0510, kDword, CP_RT13_REFERENCE) +XE_GPU_REGISTER(0x0511, kDword, CP_RT13_MASK) +XE_GPU_REGISTER(0x0512, kDword, CP_RT13_BADR) +XE_GPU_REGISTER(0x0513, kDword, CP_RT13_SIZE) +XE_GPU_REGISTER(0x0514, kDword, CP_RT14_COMMAND) +XE_GPU_REGISTER(0x0515, kDword, CP_RT14_POLL_ADDRESS) +XE_GPU_REGISTER(0x0516, kDword, CP_RT14_REFERENCE) +XE_GPU_REGISTER(0x0517, kDword, CP_RT14_MASK) +XE_GPU_REGISTER(0x0518, kDword, CP_RT14_RADR) +XE_GPU_REGISTER(0x0519, kDword, CP_RT14_SIZE) +XE_GPU_REGISTER(0x051A, kDword, CP_RT15_COMMAND) +XE_GPU_REGISTER(0x051B, kDword, CP_RT15_POLL_ADDRESS) +XE_GPU_REGISTER(0x051C, kDword, CP_RT15_REFERENCE) +XE_GPU_REGISTER(0x051D, kDword, CP_RT15_MASK) +XE_GPU_REGISTER(0x051E, kDword, CP_RT15_BADR) +XE_GPU_REGISTER(0x051F, kDword, CP_RT15_SIZE) +XE_GPU_REGISTER(0x0520, kDword, CP_RT_POLL_INTERVAL) +XE_GPU_REGISTER(0x0521, kDword, CP_VIP_EOL_EOF_COUNTER) +XE_GPU_REGISTER(0x0522, kDword, CP_D1_EOL_SOF_COUNTER) +XE_GPU_REGISTER(0x0523, kDword, CP_D2_EOL_SOF_COUNTER) +XE_GPU_REGISTER(0x0578, kDword, SCRATCH_REG0) +XE_GPU_REGISTER(0x0579, kDword, SCRATCH_REG1) XE_GPU_REGISTER(0x057A, kDword, SCRATCH_REG2) XE_GPU_REGISTER(0x057B, kDword, SCRATCH_REG3) -XE_GPU_REGISTER(0x057C, kDword, - SCRATCH_REG4) // originally this was named CALLBACK_ADDRESS, - // but that didnt make sense +XE_GPU_REGISTER(0x057C, kDword, SCRATCH_REG4) XE_GPU_REGISTER(0x057D, kDword, SCRATCH_REG5) XE_GPU_REGISTER(0x057E, kDword, SCRATCH_REG6) XE_GPU_REGISTER(0x057F, kDword, SCRATCH_REG7) +XE_GPU_REGISTER(0x0580, kDword, BIOS_8_SCRATCH) +XE_GPU_REGISTER(0x0581, kDword, BIOS_9_SCRATCH) +XE_GPU_REGISTER(0x0582, kDword, BIOS_10_SCRATCH) +XE_GPU_REGISTER(0x0583, kDword, BIOS_11_SCRATCH) +XE_GPU_REGISTER(0x0584, kDword, BIOS_12_SCRATCH) +XE_GPU_REGISTER(0x0585, kDword, BIOS_13_SCRATCH) +XE_GPU_REGISTER(0x0586, kDword, BIOS_14_SCRATCH) +XE_GPU_REGISTER(0x0587, kDword, BIOS_15_SCRATCH) XE_GPU_REGISTER(0x05C8, kDword, WAIT_UNTIL) +XE_GPU_REGISTER(0x05C9, kDword, RBBM_ISYNC_CNTL) // src is flash_xam.xex, i've seen it used by the kernel and aurora // seems to have a negative value while the gpu is busy @@ -66,38 +343,227 @@ XE_GPU_REGISTER(0x05C8, kDword, WAIT_UNTIL) // low 2 bits encode two different fields? // xboxkrnl just does addr |2 when assigning // XE_GPU_REGISTER(0x70C, kDword, CP_RB_RPTR_ADDR) -XE_GPU_REGISTER(0x0815, kDword, MC0_PERFCOUNTER0_SELECT) + +XE_GPU_REGISTER(0x05F0, kDword, CP_IB2D_BASE) +XE_GPU_REGISTER(0x05F1, kDword, CP_IB2D_BUFSZ) +XE_GPU_REGISTER(0x05F2, kDword, CP_DEFAULT_PITCH_OFFSET) +XE_GPU_REGISTER(0x05F3, kDword, CP_DEFAULT2_PITCH_OFFSET) +XE_GPU_REGISTER(0x05F4, kDword, CP_DEFAULT_SC_BOTTOM_RIGHT) +XE_GPU_REGISTER(0x05F5, kDword, CP_DEFAULT2_SC_BOTTOM_RIGHT) +XE_GPU_REGISTER(0x05F6, kDword, CP_2D_BRUSH_BASE) +XE_GPU_REGISTER(0x05F7, kDword, CP_2D_PALETTE_BASE) +XE_GPU_REGISTER(0x05F8, kDword, CP_2D_IMMD_BASE) +XE_GPU_REGISTER(0x05F9, kDword, CP_2D_BOOLEANS) +XE_GPU_REGISTER(0x0600, kDword, CP_ME_VS_EVENT_SRC) +XE_GPU_REGISTER(0x0601, kDword, CP_ME_VS_EVENT_ADDR) +XE_GPU_REGISTER(0x0602, kDword, CP_ME_VS_EVENT_DATA) +XE_GPU_REGISTER(0x0603, kDword, CP_ME_VS_EVENT_ADDR_SWM) +XE_GPU_REGISTER(0x0604, kDword, CP_ME_VS_EVENT_DATA_SWM) +XE_GPU_REGISTER(0x0605, kDword, CP_ME_PS_EVENT_SRC) +XE_GPU_REGISTER(0x0606, kDword, CP_ME_PS_EVENT_ADDR) +XE_GPU_REGISTER(0x0607, kDword, CP_ME_PS_EVENT_DATA) +XE_GPU_REGISTER(0x0608, kDword, CP_ME_PS_EVENT_ADDR_SWM) +XE_GPU_REGISTER(0x0609, kDword, CP_ME_PS_EVENT_DATA_SWM) +XE_GPU_REGISTER(0x060A, kDword, CP_ME_CF_EVENT_SRC) +XE_GPU_REGISTER(0x060B, kDword, CP_ME_CF_EVENT_ADDR) +XE_GPU_REGISTER(0x060C, kDword, CP_ME_CF_EVENT_DATA) +XE_GPU_REGISTER(0x060D, kDword, CP_ME_NRT_ADDR) +XE_GPU_REGISTER(0x060E, kDword, CP_ME_NRT_DATA) +XE_GPU_REGISTER(0x060F, kDword, CP_ME_RT_ADDR) +XE_GPU_REGISTER(0x0610, kDword, CP_ME_RT_DATA) +XE_GPU_REGISTER(0x0611, kDword, CP_ME_SCREEN_EXT_RPT_ADDR) +XE_GPU_REGISTER(0x0612, kDword, CP_ME_VS_FETCH_DONE_SRC) +XE_GPU_REGISTER(0x0613, kDword, CP_ME_VS_FETCH_DONE_ADDR) +XE_GPU_REGISTER(0x0614, kDword, CP_ME_VS_FETCH_DONE_DATA) +XE_GPU_REGISTER(0x0800, kDword, MC0_CNTL) +XE_GPU_REGISTER(0x0801, kDword, MC0_DRAM_CONFIG) +XE_GPU_REGISTER(0x0802, kDword, MC0_BSB_SNOOPED_TIMER_CNTL) +XE_GPU_REGISTER(0x0803, kDword, MC0_TUNING_0) +XE_GPU_REGISTER(0x0804, kDword, MC0_TUNING_1) +XE_GPU_REGISTER(0x0805, kDword, MC0_RD_BUFFER_CNTL_0) +XE_GPU_REGISTER(0x0806, kDword, MC0_ARBITRATION_CNTL) +XE_GPU_REGISTER(0x0807, kDword, MC0_TIMING_CNTL_0) +XE_GPU_REGISTER(0x0808, kDword, MC0_TIMING_CNTL_1) +XE_GPU_REGISTER(0x0809, kDword, MC0_TIMING_CNTL_2) +XE_GPU_REGISTER(0x080A, kDword, MC0_PAD_CAL_CNTL) +XE_GPU_REGISTER(0x080B, kDword, MC0_DRAM_CMD) +XE_GPU_REGISTER(0x080C, kDword, MC0_DRAM_DATA) +XE_GPU_REGISTER(0x080D, kDword, MC0_POINTER) +XE_GPU_REGISTER(0x080E, kDword, MC0_RDBUF_DATA) +XE_GPU_REGISTER(0x080F, kDword, MC0_DRAM_DQ) +XE_GPU_REGISTER(0x0810, kDword, MC0_STATUS_0) +XE_GPU_REGISTER(0x0811, kDword, MC0_STATUS_1) +XE_GPU_REGISTER(0x0812, kDword, MC0_CRC_CNTL) +XE_GPU_REGISTER(0x0813, kDword, MC0_DEBUG) +XE_GPU_REGISTER(0x0814, kDword, MC0_CRC_READ) +XE_GPU_REGISTER(0x0815, kDword, MC0_PERFCOUNTER0_CNTL) XE_GPU_REGISTER(0x0816, kDword, MC0_PERFCOUNTER0_HI) XE_GPU_REGISTER(0x0817, kDword, MC0_PERFCOUNTER0_LOW) -XE_GPU_REGISTER(0x0855, kDword, MC1_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0818, kDword, MC0_PERFCOUNTER1_CNTL) +XE_GPU_REGISTER(0x0819, kDword, MC0_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x081A, kDword, MC0_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x081B, kDword, MC0_INTERRUPT_MASK) +XE_GPU_REGISTER(0x081C, kDword, MC0_INTERRUPT_STATUS) +XE_GPU_REGISTER(0x081D, kDword, MC0_INTERRUPT_ACK) +XE_GPU_REGISTER(0x081E, kDword, MC0_SECURE_MEMORY_APERTURE_LOG_MH) +XE_GPU_REGISTER(0x081F, kDword, MC0_SECURE_MEMORY_APERTURE_LOG_BIU) +XE_GPU_REGISTER(0x0820, kDword, MC0_WR_STR_DLL_0) +XE_GPU_REGISTER(0x0821, kDword, MC0_WR_STR_DLL_1) +XE_GPU_REGISTER(0x0822, kDword, MC0_DLL_MASTER_ADJ_0) +XE_GPU_REGISTER(0x0823, kDword, MC0_DLL_MASTER_ADJ_1) +XE_GPU_REGISTER(0x0824, kDword, MC0_TERM_CNTL) +XE_GPU_REGISTER(0x0825, kDword, MC0_WR_DATA_DLY_0) +XE_GPU_REGISTER(0x0826, kDword, MC0_WR_DATA_DLY_1) +XE_GPU_REGISTER(0x0827, kDword, MC0_RD_STR_DLY_0) +XE_GPU_REGISTER(0x0828, kDword, MC0_RD_STR_DLY_1) +XE_GPU_REGISTER(0x0829, kDword, MC0_WR_STR_DLY) +XE_GPU_REGISTER(0x082A, kDword, MC0_PAD_CAL_STATUS) +XE_GPU_REGISTER(0x082B, kDword, MC0_RD_STR_DLY_CNTL) +XE_GPU_REGISTER(0x0830, kDword, MC0_PAD_IF_CNTL) +XE_GPU_REGISTER(0x0831, kDword, MC0_PAD_IF_CNTL_2) +XE_GPU_REGISTER(0x0832, kDword, MC0_RD_BUFFER_CNTL_1) +XE_GPU_REGISTER(0x0840, kDword, MC1_CNTL) +XE_GPU_REGISTER(0x0841, kDword, MC1_DRAM_CONFIG) +XE_GPU_REGISTER(0x0842, kDword, MC1_BSB_SNOOPED_TIMER_CNTL) +XE_GPU_REGISTER(0x0843, kDword, MC1_TUNING_0) +XE_GPU_REGISTER(0x0844, kDword, MC1_TUNING_1) +XE_GPU_REGISTER(0x0845, kDword, MC1_RD_BUFFER_CNTL_0) +XE_GPU_REGISTER(0x0846, kDword, MC1_ARBITRATION_CNTL) +XE_GPU_REGISTER(0x0847, kDword, MC1_TIMING_CNTL_0) +XE_GPU_REGISTER(0x0848, kDword, MC1_TIMING_CNTL_1) +XE_GPU_REGISTER(0x0849, kDword, MC1_TIMING_CNTL_2) +XE_GPU_REGISTER(0x084A, kDword, MC1_PAD_CAL_CNTL) +XE_GPU_REGISTER(0x084B, kDword, MC1_DRAM_CMD) +XE_GPU_REGISTER(0x084C, kDword, MC1_DRAM_DATA) +XE_GPU_REGISTER(0x084D, kDword, MC1_POINTER) +XE_GPU_REGISTER(0x084E, kDword, MC1_RDBUF_DATA) +XE_GPU_REGISTER(0x084F, kDword, MC1_DRAM_DQ) +XE_GPU_REGISTER(0x0850, kDword, MC1_STATUS_0) +XE_GPU_REGISTER(0x0851, kDword, MC1_STATUS_1) +XE_GPU_REGISTER(0x0852, kDword, MC1_CRC_CNTL) +XE_GPU_REGISTER(0x0853, kDword, MC1_DEBUG) +XE_GPU_REGISTER(0x0854, kDword, MC1_CRC_READ) +XE_GPU_REGISTER(0x0855, kDword, MC1_PERFCOUNTER0_CNTL) XE_GPU_REGISTER(0x0856, kDword, MC1_PERFCOUNTER0_HI) XE_GPU_REGISTER(0x0857, kDword, MC1_PERFCOUNTER0_LOW) -// base GPU virtual address of the xps region. Most guests write 0xC0100000 here -XE_GPU_REGISTER(0x0A02, kDword, XPS_BASE) -// will usually be set higher, but is effectively 0x700000 bytes long -XE_GPU_REGISTER(0x0A03, kDword, XPS_SIZE) -// usually 0xC0000000 -XE_GPU_REGISTER(0x0A04, kDword, WRITEBACK_BASE) -// usually 0x0100000 +XE_GPU_REGISTER(0x0858, kDword, MC1_PERFCOUNTER1_CNTL) +XE_GPU_REGISTER(0x0859, kDword, MC1_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x085A, kDword, MC1_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x085B, kDword, MC1_INTERRUPT_MASK) +XE_GPU_REGISTER(0x085C, kDword, MC1_INTERRUPT_STATUS) +XE_GPU_REGISTER(0x085D, kDword, MC1_INTERRUPT_ACK) +XE_GPU_REGISTER(0x085E, kDword, MC1_SECURE_MEMORY_APERTURE_LOG_MH) +XE_GPU_REGISTER(0x085F, kDword, MC1_SECURE_MEMORY_APERTURE_LOG_BIU) +XE_GPU_REGISTER(0x0860, kDword, MC1_WR_STR_DLL_0) +XE_GPU_REGISTER(0x0861, kDword, MC1_WR_STR_DLL_1) +XE_GPU_REGISTER(0x0862, kDword, MC1_DLL_MASTER_ADJ_0) +XE_GPU_REGISTER(0x0863, kDword, MC1_DLL_MASTER_ADJ_1) +XE_GPU_REGISTER(0x0864, kDword, MC1_TERM_CNTL) +XE_GPU_REGISTER(0x0865, kDword, MC1_WR_DATA_DLY_0) +XE_GPU_REGISTER(0x0866, kDword, MC1_WR_DATA_DLY_1) +XE_GPU_REGISTER(0x0867, kDword, MC1_RD_STR_DLY_0) +XE_GPU_REGISTER(0x0868, kDword, MC1_RD_STR_DLY_1) +XE_GPU_REGISTER(0x0869, kDword, MC1_WR_STR_DLY) +XE_GPU_REGISTER(0x086A, kDword, MC1_PAD_CAL_STATUS) +XE_GPU_REGISTER(0x086B, kDword, MC1_RD_STR_DLY_CNTL) +XE_GPU_REGISTER(0x0870, kDword, MC1_PAD_IF_CNTL) +XE_GPU_REGISTER(0x0871, kDword, MC1_PAD_IF_CNTL_2) +XE_GPU_REGISTER(0x0872, kDword, MC1_RD_BUFFER_CNTL_1) +XE_GPU_REGISTER(0x0A00, kDword, FB_START) +XE_GPU_REGISTER(0x0A01, kDword, FB_SIZE) +XE_GPU_REGISTER(0x0A02, kDword, PG_START) +XE_GPU_REGISTER(0x0A03, kDword, PG_SIZE) +XE_GPU_REGISTER(0x0A04, kDword, WRITEBACK_START) XE_GPU_REGISTER(0x0A05, kDword, WRITEBACK_SIZE) - -XE_GPU_REGISTER(0x0A18, kDword, MH_PERFCOUNTER0_SELECT) -XE_GPU_REGISTER(0x0A19, kDword, MH_PERFCOUNTER0_HI) -XE_GPU_REGISTER(0x0A1A, kDword, MH_PERFCOUNTER0_LOW) -XE_GPU_REGISTER(0x0A1B, kDword, MH_PERFCOUNTER1_SELECT) -XE_GPU_REGISTER(0x0A1C, kDword, MH_PERFCOUNTER1_HI) -XE_GPU_REGISTER(0x0A1D, kDword, MH_PERFCOUNTER1_LOW) -XE_GPU_REGISTER(0x0A1E, kDword, MH_PERFCOUNTER2_SELECT) -XE_GPU_REGISTER(0x0A1F, kDword, MH_PERFCOUNTER2_HI) -XE_GPU_REGISTER(0x0A20, kDword, MH_PERFCOUNTER2_LOW) - +XE_GPU_REGISTER(0x0A06, kDword, MH_CNTL) +XE_GPU_REGISTER(0x0A07, kDword, MH_STATUS) +XE_GPU_REGISTER(0x0A08, kDword, MH_INT_MASK) +XE_GPU_REGISTER(0x0A09, kDword, MH_INT_STATUS) +XE_GPU_REGISTER(0x0A0A, kDword, MH_INT_CLEAR) +XE_GPU_REGISTER(0x0A0B, kDword, MH_INT_SIGNAL) +XE_GPU_REGISTER(0x0A0C, kDword, PGL_CTL0) +XE_GPU_REGISTER(0x0A0D, kDword, PGL_CTL1) +XE_GPU_REGISTER(0x0A10, kDword, DC_SURFACE_0_BASE) +XE_GPU_REGISTER(0x0A11, kDword, DC_SURFACE_0_EXTENT) +XE_GPU_REGISTER(0x0A12, kDword, DC_SURFACE_0_INFO) +XE_GPU_REGISTER(0x0A13, kDword, DC_SURFACE_2_BASE) +XE_GPU_REGISTER(0x0A14, kDword, DC_SURFACE_2_EXTENT) +XE_GPU_REGISTER(0x0A15, kDword, DC_SURFACE_2_INFO) +XE_GPU_REGISTER(0x0A18, kDword, MH_PERFMON_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0A19, kDword, MH_PERFMON_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x0A1A, kDword, MH_PERFMON_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x0A1B, kDword, MH_PERFMON_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x0A1C, kDword, MH_PERFMON_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x0A1D, kDword, MH_PERFMON_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x0A1E, kDword, MH_PERFMON_PERFCOUNTER2_SELECT) +XE_GPU_REGISTER(0x0A1F, kDword, MH_PERFMON_PERFCOUNTER2_HI) +XE_GPU_REGISTER(0x0A20, kDword, MH_PERFMON_PERFCOUNTER2_LOW) +XE_GPU_REGISTER(0x0A21, kDword, DC_SURFACE_1_BASE) +XE_GPU_REGISTER(0x0A22, kDword, DC_SURFACE_1_EXTENT) +XE_GPU_REGISTER(0x0A23, kDword, DC_SURFACE_1_INFO) +XE_GPU_REGISTER(0x0A29, kDword, COHER_SIZE_PM4) +XE_GPU_REGISTER(0x0A2A, kDword, COHER_BASE_PM4) +XE_GPU_REGISTER(0x0A2B, kDword, COHER_STATUS_PM4) +XE_GPU_REGISTER(0x0A2C, kDword, COHER_SIZE_RT) +XE_GPU_REGISTER(0x0A2D, kDword, COHER_BASE_RT) +XE_GPU_REGISTER(0x0A2E, kDword, COHER_STATUS_RT) XE_GPU_REGISTER(0x0A2F, kDword, COHER_SIZE_HOST) XE_GPU_REGISTER(0x0A30, kDword, COHER_BASE_HOST) XE_GPU_REGISTER(0x0A31, kDword, COHER_STATUS_HOST) // Status flags of viz queries, doesn't seem to be read back by d3d // queries 0x00 to 0x1f (be), bit set when visible +XE_GPU_REGISTER(0x0A40, kDword, MH_ARBITER_CONFIG) +XE_GPU_REGISTER(0x0BFE, kDword, MH_DEBUG_INDEX) +XE_GPU_REGISTER(0x0BFF, kDword, MH_DEBUG_DATA) +XE_GPU_REGISTER(0x0C00, kDword, RTS_INITIATOR) +XE_GPU_REGISTER(0x0C01, kDword, RTS_BOUNDBOX_START) +XE_GPU_REGISTER(0x0C02, kDword, RTS_BOUNDBOX_END) +XE_GPU_REGISTER(0x0C03, kDword, RTS_BARYC_REF_VTX_X) +XE_GPU_REGISTER(0x0C04, kDword, RTS_BARYC_REF_VTX_Y) +XE_GPU_REGISTER(0x0C05, kDword, RTS_I_W_DX) +XE_GPU_REGISTER(0x0C06, kDword, RTS_J_W_DY) +XE_GPU_REGISTER(0x0C07, kDword, RTS_INV_W_REF) +XE_GPU_REGISTER(0x0C08, kDword, RTS_INV_W_DX) +XE_GPU_REGISTER(0x0C09, kDword, RTS_INV_W_DY) +XE_GPU_REGISTER(0x0C0A, kDword, RTS_I_W_REF) +XE_GPU_REGISTER(0x0C0B, kDword, RTS_I_W_DY) +XE_GPU_REGISTER(0x0C0C, kDword, RTS_J_W_REF) +XE_GPU_REGISTER(0x0C0D, kDword, RTS_J_W_DX) +XE_GPU_REGISTER(0x0C0E, kDword, RTS_Z_REF) +XE_GPU_REGISTER(0x0C0F, kDword, RTS_Z_DX_MSBS) +XE_GPU_REGISTER(0x0C10, kDword, RTS_Z_DY_MSBS) +XE_GPU_REGISTER(0x0C11, kDword, RTS_Z_DX_DY_LSBS) +XE_GPU_REGISTER(0x0C12, kDword, RTS_Z_MIN) +XE_GPU_REGISTER(0x0C13, kDword, RTS_Z_MAX) +XE_GPU_REGISTER(0x0C14, kDword, RTS_EDGE_0_DIST_LSBS) +XE_GPU_REGISTER(0x0C15, kDword, RTS_EDGE_1_DIST_LSBS) +XE_GPU_REGISTER(0x0C16, kDword, RTS_EDGE_2_DIST_LSBS) +XE_GPU_REGISTER(0x0C17, kDword, RTS_EDGE_DIST_MSBS) +XE_GPU_REGISTER(0x0C18, kDword, RTS_WD_EDGE_0_DIST_LSBS) +XE_GPU_REGISTER(0x0C19, kDword, RTS_WD_EDGE_1_DIST_LSBS) +XE_GPU_REGISTER(0x0C1A, kDword, RTS_WD_EDGE_2_DIST_LSBS) +XE_GPU_REGISTER(0x0C1B, kDword, RTS_WD_EDGE_DIST_MSBS) +XE_GPU_REGISTER(0x0C1C, kDword, RTS_EDGE_0_DX) +XE_GPU_REGISTER(0x0C1D, kDword, RTS_EDGE_0_DY) +XE_GPU_REGISTER(0x0C1E, kDword, RTS_EDGE_1_DX) +XE_GPU_REGISTER(0x0C1F, kDword, RTS_EDGE_1_DY) +XE_GPU_REGISTER(0x0C20, kDword, RTS_EDGE_2_DX) +XE_GPU_REGISTER(0x0C21, kDword, RTS_EDGE_2_DY) +XE_GPU_REGISTER(0x0C22, kDword, RTS_MISC) +XE_GPU_REGISTER(0x0C2C, kDword, VGT_VTX_VECT_EJECT_REG) +XE_GPU_REGISTER(0x0C2D, kDword, VGT_DMA_DATA_FIFO_DEPTH) +XE_GPU_REGISTER(0x0C2E, kDword, VGT_DMA_REQ_FIFO_DEPTH) +XE_GPU_REGISTER(0x0C2F, kDword, VGT_DRAW_INIT_FIFO_DEPTH) +XE_GPU_REGISTER(0x0C30, kDword, VGT_LAST_COPY_STATE) +XE_GPU_REGISTER(0x0C38, kDword, VGT_DEBUG_CNTL) +XE_GPU_REGISTER(0x0C39, kDword, VGT_DEBUG_DATA) +XE_GPU_REGISTER(0x0C3A, kDword, VGT_CRC_SQ_DATA) +XE_GPU_REGISTER(0x0C3B, kDword, VGT_CRC_SQ_CTRL) +XE_GPU_REGISTER(0x0C3C, kDword, VGT_CNTL_STATUS) +XE_GPU_REGISTER(0x0C40, kDword, PA_SC_LINE_STIPPLE_STATE) +XE_GPU_REGISTER(0x0C41, kDword, PA_SC_MULTI_CHIP_CNTL) XE_GPU_REGISTER(0x0C44, kDword, PA_SC_VIZ_QUERY_STATUS_0) // queries 0x20 to 0x3f (be) XE_GPU_REGISTER(0x0C45, kDword, PA_SC_VIZ_QUERY_STATUS_1) @@ -115,8 +581,14 @@ XE_GPU_REGISTER(0x0C51, kDword, VGT_PERFCOUNTER2_HI) XE_GPU_REGISTER(0x0C52, kDword, VGT_PERFCOUNTER3_LOW) XE_GPU_REGISTER(0x0C53, kDword, VGT_PERFCOUNTER3_HI) +XE_GPU_REGISTER(0x0C80, kDword, PA_SU_DEBUG_CNTL) +XE_GPU_REGISTER(0x0C81, kDword, PA_SU_DEBUG_DATA) +XE_GPU_REGISTER(0x0C82, kDword, PA_SC_DEBUG_CNTL) +XE_GPU_REGISTER(0x0C83, kDword, PA_SC_DEBUG_DATA) +XE_GPU_REGISTER(0x0C84, kDword, PA_CL_CNTL_STATUS) XE_GPU_REGISTER(0x0C85, kDword, PA_CL_ENHANCE) +XE_GPU_REGISTER(0x0C86, kDword, PA_SU_FACE_DATA) XE_GPU_REGISTER(0x0C88, kDword, PA_SU_PERFCOUNTER0_SELECT) XE_GPU_REGISTER(0x0C89, kDword, PA_SU_PERFCOUNTER1_SELECT) XE_GPU_REGISTER(0x0C8A, kDword, PA_SU_PERFCOUNTER2_SELECT) @@ -129,6 +601,7 @@ XE_GPU_REGISTER(0x0C90, kDword, PA_SU_PERFCOUNTER2_LOW) XE_GPU_REGISTER(0x0C91, kDword, PA_SU_PERFCOUNTER2_HI) XE_GPU_REGISTER(0x0C92, kDword, PA_SU_PERFCOUNTER3_LOW) XE_GPU_REGISTER(0x0C93, kDword, PA_SU_PERFCOUNTER3_HI) +XE_GPU_REGISTER(0x0C94, kDword, PA_SU_CNTL_STATUS) XE_GPU_REGISTER(0x0C98, kDword, PA_SC_PERFCOUNTER0_SELECT) XE_GPU_REGISTER(0x0C99, kDword, PA_SC_PERFCOUNTER1_SELECT) XE_GPU_REGISTER(0x0C9A, kDword, PA_SC_PERFCOUNTER2_SELECT) @@ -142,12 +615,43 @@ XE_GPU_REGISTER(0x0CA1, kDword, PA_SC_PERFCOUNTER2_HI) XE_GPU_REGISTER(0x0CA2, kDword, PA_SC_PERFCOUNTER3_LOW) XE_GPU_REGISTER(0x0CA3, kDword, PA_SC_PERFCOUNTER3_HI) +XE_GPU_REGISTER(0x0CA4, kDword, PA_SC_CNTL_STATUS) +XE_GPU_REGISTER(0x0CA5, kDword, PA_SC_ENHANCE) +XE_GPU_REGISTER(0x0CC0, kDword, PA_SC_FIFO_SIZE) XE_GPU_REGISTER(0x0D00, kDword, SQ_GPR_MANAGEMENT) -XE_GPU_REGISTER(0x0D01, kDword, SQ_FLOW_CONTROL) -XE_GPU_REGISTER(0x0D02, kDword, SQ_INST_STORE_MANAGMENT) - +XE_GPU_REGISTER(0x0D01, kDword, SQ_FLOW_CNTL) +XE_GPU_REGISTER(0x0D02, kDword, SQ_INST_STORE_MANAGEMENT) +XE_GPU_REGISTER(0x0D03, kDword, SQ_RESOURCE_MANAGMENT) XE_GPU_REGISTER(0x0D04, kDword, SQ_EO_RT) +XE_GPU_REGISTER(0x0D05, kDword, SQ_DEBUG_MISC) +XE_GPU_REGISTER(0x0D06, kDword, SQ_ACTIVITY_METER_CNTL) +XE_GPU_REGISTER(0x0D07, kDword, SQ_ACTIVITY_METER_STATUS) +XE_GPU_REGISTER(0x0D08, kDword, SQ_INPUT_ARB_PRIORITY) +XE_GPU_REGISTER(0x0D09, kDword, SQ_THREAD_ARB_PRIORITY) +XE_GPU_REGISTER(0x0D34, kDword, SQ_INT_CNTL) +XE_GPU_REGISTER(0x0D35, kDword, SQ_INT_STATUS) +XE_GPU_REGISTER(0x0D36, kDword, SQ_INT_ACK) +XE_GPU_REGISTER(0x0DAE, kDword, SQ_DEBUG_INPUT_FSM) +XE_GPU_REGISTER(0x0DAF, kDword, SQ_DEBUG_CONST_MGR_FSM) +XE_GPU_REGISTER(0x0DB0, kDword, SQ_DEBUG_TP_FSM) +XE_GPU_REGISTER(0x0DB1, kDword, SQ_DEBUG_FSM_ALU_0) +XE_GPU_REGISTER(0x0DB2, kDword, SQ_DEBUG_FSM_ALU_1) +XE_GPU_REGISTER(0x0DB3, kDword, SQ_DEBUG_EXP_ALLOC) +XE_GPU_REGISTER(0x0DB4, kDword, SQ_DEBUG_PTR_BUFF) +XE_GPU_REGISTER(0x0DB5, kDword, SQ_DEBUG_GPR_VTX) +XE_GPU_REGISTER(0x0DB6, kDword, SQ_DEBUG_GPR_PIX) +XE_GPU_REGISTER(0x0DB7, kDword, SQ_DEBUG_TB_STATUS_SEL) +XE_GPU_REGISTER(0x0DB8, kDword, SQ_DEBUG_VTX_TB_0) +XE_GPU_REGISTER(0x0DB9, kDword, SQ_DEBUG_VTX_TB_1) +XE_GPU_REGISTER(0x0DBA, kDword, SQ_DEBUG_VTX_TB_STATUS_REG) +XE_GPU_REGISTER(0x0DBB, kDword, SQ_DEBUG_VTX_TB_STATE_MEM) +XE_GPU_REGISTER(0x0DBC, kDword, SQ_DEBUG_PIX_TB_0) +XE_GPU_REGISTER(0x0DBD, kDword, SQ_DEBUG_PIX_TB_STATUS_REG_0) +XE_GPU_REGISTER(0x0DBE, kDword, SQ_DEBUG_PIX_TB_STATUS_REG_1) +XE_GPU_REGISTER(0x0DBF, kDword, SQ_DEBUG_PIX_TB_STATUS_REG_2) +XE_GPU_REGISTER(0x0DC0, kDword, SQ_DEBUG_PIX_TB_STATUS_REG_3) +XE_GPU_REGISTER(0x0DC1, kDword, SQ_DEBUG_PIX_TB_STATE_MEM) XE_GPU_REGISTER(0x0DC8, kDword, SQ_PERFCOUNTER0_SELECT) XE_GPU_REGISTER(0x0DC9, kDword, SQ_PERFCOUNTER1_SELECT) XE_GPU_REGISTER(0x0DCA, kDword, SQ_PERFCOUNTER2_SELECT) @@ -161,12 +665,25 @@ XE_GPU_REGISTER(0x0DD1, kDword, SQ_PERFCOUNTER2_HI) XE_GPU_REGISTER(0x0DD2, kDword, SQ_PERFCOUNTER3_LOW) XE_GPU_REGISTER(0x0DD3, kDword, SQ_PERFCOUNTER3_HI) XE_GPU_REGISTER(0x0DD4, kDword, SX_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x0DD5, kDword, SX_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x0DD6, kDword, SX_PERFCOUNTER2_SELECT) +XE_GPU_REGISTER(0x0DD7, kDword, SX_PERFCOUNTER3_SELECT) XE_GPU_REGISTER(0x0DD8, kDword, SX_PERFCOUNTER0_LOW) XE_GPU_REGISTER(0x0DD9, kDword, SX_PERFCOUNTER0_HI) // Set with WAIT_UNTIL = WAIT_3D_IDLECLEAN +XE_GPU_REGISTER(0x0DDA, kDword, SX_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x0DDB, kDword, SX_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x0DDC, kDword, SX_PERFCOUNTER2_LOW) +XE_GPU_REGISTER(0x0DDD, kDword, SX_PERFCOUNTER2_HI) +XE_GPU_REGISTER(0x0DDE, kDword, SX_PERFCOUNTER3_LOW) +XE_GPU_REGISTER(0x0DDF, kDword, SX_PERFCOUNTER3_HI) XE_GPU_REGISTER(0x0E00, kDword, TC_CNTL_STATUS) +XE_GPU_REGISTER(0x0E01, kDword, TP_DEBUG0) +XE_GPU_REGISTER(0x0E02, kDword, TCR_CHICKEN) +XE_GPU_REGISTER(0x0E03, kDword, TCF_CHICKEN) +XE_GPU_REGISTER(0x0E04, kDword, TCM_CHICKEN) XE_GPU_REGISTER(0x0E05, kDword, TCR_PERFCOUNTER0_SELECT) XE_GPU_REGISTER(0x0E06, kDword, TCR_PERFCOUNTER0_HI) XE_GPU_REGISTER(0x0E07, kDword, TCR_PERFCOUNTER0_LOW) @@ -174,6 +691,14 @@ XE_GPU_REGISTER(0x0E08, kDword, TCR_PERFCOUNTER1_SELECT) XE_GPU_REGISTER(0x0E09, kDword, TCR_PERFCOUNTER1_HI) XE_GPU_REGISTER(0x0E0A, kDword, TCR_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x0E17, kDword, TP_TC_CLKGATE_CNTL) +XE_GPU_REGISTER(0x0E18, kDword, TPC_CNTL_STATUS) +XE_GPU_REGISTER(0x0E19, kDword, TPC_DEBUG0) +XE_GPU_REGISTER(0x0E1A, kDword, TPC_DEBUG1) +XE_GPU_REGISTER(0x0E1B, kDword, TPC_CHICKEN) +XE_GPU_REGISTER(0x0E1C, kDword, TP0_CNTL_STATUS) +XE_GPU_REGISTER(0x0E1D, kDword, TP0_DEBUG) +XE_GPU_REGISTER(0x0E1E, kDword, TP0_CHICKEN) XE_GPU_REGISTER(0x0E1F, kDword, TP0_PERFCOUNTER0_SELECT) XE_GPU_REGISTER(0x0E20, kDword, TP0_PERFCOUNTER0_HI) XE_GPU_REGISTER(0x0E21, kDword, TP0_PERFCOUNTER0_LOW) @@ -181,6 +706,9 @@ XE_GPU_REGISTER(0x0E22, kDword, TP0_PERFCOUNTER1_SELECT) XE_GPU_REGISTER(0x0E23, kDword, TP0_PERFCOUNTER1_HI) XE_GPU_REGISTER(0x0E24, kDword, TP0_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x0E25, kDword, TP1_CNTL_STATUS) +XE_GPU_REGISTER(0x0E26, kDword, TP1_DEBUG) +XE_GPU_REGISTER(0x0E27, kDword, TP1_CHICKEN) XE_GPU_REGISTER(0x0E28, kDword, TP1_PERFCOUNTER0_SELECT) XE_GPU_REGISTER(0x0E29, kDword, TP1_PERFCOUNTER0_HI) XE_GPU_REGISTER(0x0E2A, kDword, TP1_PERFCOUNTER0_LOW) @@ -188,6 +716,9 @@ XE_GPU_REGISTER(0x0E2B, kDword, TP1_PERFCOUNTER1_SELECT) XE_GPU_REGISTER(0x0E2C, kDword, TP1_PERFCOUNTER1_HI) XE_GPU_REGISTER(0x0E2D, kDword, TP1_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x0E2E, kDword, TP2_CNTL_STATUS) +XE_GPU_REGISTER(0x0E2F, kDword, TP2_DEBUG) +XE_GPU_REGISTER(0x0E30, kDword, TP2_CHICKEN) XE_GPU_REGISTER(0x0E31, kDword, TP2_PERFCOUNTER0_SELECT) XE_GPU_REGISTER(0x0E32, kDword, TP2_PERFCOUNTER0_HI) XE_GPU_REGISTER(0x0E33, kDword, TP2_PERFCOUNTER0_LOW) @@ -195,19 +726,21 @@ XE_GPU_REGISTER(0x0E34, kDword, TP2_PERFCOUNTER1_SELECT) XE_GPU_REGISTER(0x0E35, kDword, TP2_PERFCOUNTER1_HI) XE_GPU_REGISTER(0x0E36, kDword, TP2_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x0E37, kDword, TP3_CNTL_STATUS) +XE_GPU_REGISTER(0x0E38, kDword, TP3_DEBUG) +XE_GPU_REGISTER(0x0E39, kDword, TP3_CHICKEN) XE_GPU_REGISTER(0x0E3A, kDword, TP3_PERFCOUNTER0_SELECT) XE_GPU_REGISTER(0x0E3B, kDword, TP3_PERFCOUNTER0_HI) XE_GPU_REGISTER(0x0E3C, kDword, TP3_PERFCOUNTER0_LOW) XE_GPU_REGISTER(0x0E3D, kDword, TP3_PERFCOUNTER1_SELECT) XE_GPU_REGISTER(0x0E3E, kDword, TP3_PERFCOUNTER1_HI) XE_GPU_REGISTER(0x0E3F, kDword, TP3_PERFCOUNTER1_LOW) - -// Set with WAIT_UNTIL = WAIT_3D_IDLECLEAN -XE_GPU_REGISTER(0x0E40, kDword, UNKNOWN_0E40) - -// Set during GPU initialization by D3D -XE_GPU_REGISTER(0x0E42, kDword, UNKNOWN_0E42) - +XE_GPU_REGISTER(0x0E40, kDword, VC_CNTL) +XE_GPU_REGISTER(0x0E41, kDword, VC_CNTL_STATUS) +XE_GPU_REGISTER(0x0E42, kDword, VC_FIFO_DEPTHS) +XE_GPU_REGISTER(0x0E43, kDword, VC_DEBUG_CNTL) +XE_GPU_REGISTER(0x0E44, kDword, VC_DEBUG_DATA) +XE_GPU_REGISTER(0x0E45, kDword, VC_ENHANCE) XE_GPU_REGISTER(0x0E48, kDword, VC_PERFCOUNTER0_SELECT) XE_GPU_REGISTER(0x0E49, kDword, VC_PERFCOUNTER0_HI) XE_GPU_REGISTER(0x0E4A, kDword, VC_PERFCOUNTER0_LOW) @@ -280,24 +813,79 @@ XE_GPU_REGISTER(0x0F0C, kDword, BC_PERFCOUNTER2_LOW) XE_GPU_REGISTER(0x0F0D, kDword, BC_PERFCOUNTER2_HI) XE_GPU_REGISTER(0x0F0E, kDword, BC_PERFCOUNTER3_LOW) XE_GPU_REGISTER(0x0F0F, kDword, BC_PERFCOUNTER3_HI) -// src is flash_xam.xex -// XE_GPU_REGISTER(0x0F12, RB_SIDEBAND_DATA, - +XE_GPU_REGISTER(0x0F10, kDword, RB_ZPASS_SAMPLES) +XE_GPU_REGISTER(0x0F11, kDword, RB_ZFAIL_SAMPLES) +XE_GPU_REGISTER(0x0F12, kDword, RB_SFAIL_SAMPLES) +XE_GPU_REGISTER(0x0F15, kDword, BC_DUMMY_CRAYRB_ENUMS) +XE_GPU_REGISTER(0x0F16, kDword, BC_DUMMY_CRAYRB_MOREENUMS) +XE_GPU_REGISTER(0x0F26, kDword, RB_DEBUG_CNTL) +XE_GPU_REGISTER(0x0F27, kDword, RB_DEBUG_DATA) +XE_GPU_REGISTER(0x0F28, kDword, RB_DEBUG_0) +XE_GPU_REGISTER(0x0F29, kDword, RB_DEBUG_1) +XE_GPU_REGISTER(0x0F2A, kDword, RB_DEBUG_2) +XE_GPU_REGISTER(0x0F2B, kDword, RB_FLAG_CONTROL) +XE_GPU_REGISTER(0x0F2C, kDword, RB_BC_SPARES) XE_GPU_REGISTER(0x1004, kDword, HZ_PERFCOUNTER0_SELECT) XE_GPU_REGISTER(0x1005, kDword, HZ_PERFCOUNTER0_HI) XE_GPU_REGISTER(0x1006, kDword, HZ_PERFCOUNTER0_LOW) XE_GPU_REGISTER(0x1007, kDword, HZ_PERFCOUNTER1_SELECT) XE_GPU_REGISTER(0x1008, kDword, HZ_PERFCOUNTER1_HI) XE_GPU_REGISTER(0x1009, kDword, HZ_PERFCOUNTER1_LOW) - -// D1*, LUT, and AVIVO registers taken from libxenon and -// https://www.x.org/docs/AMD/old/RRG-216M56-03oOEM.pdf +XE_GPU_REGISTER(0x1800, kDword, D1CRTC_H_TOTAL) +XE_GPU_REGISTER(0x1801, kDword, D1CRTC_H_BLANK_START_END) +XE_GPU_REGISTER(0x1802, kDword, D1CRTC_H_SYNC_A) +XE_GPU_REGISTER(0x1803, kDword, D1CRTC_H_SYNC_A_CNTL) +XE_GPU_REGISTER(0x1804, kDword, D1CRTC_V_TOTAL) +XE_GPU_REGISTER(0x1805, kDword, D1CRTC_V_BLANK_START_END) +XE_GPU_REGISTER(0x1806, kDword, D1CRTC_V_SYNC_A) +XE_GPU_REGISTER(0x1807, kDword, D1CRTC_V_SYNC_A_CNTL) +XE_GPU_REGISTER(0x1808, kDword, D1CRTC_FORCE_COUNT_NOW_CNTL) +XE_GPU_REGISTER(0x1809, kDword, D1CRTC_PIXEL_DATA_READBACK) +XE_GPU_REGISTER(0x180A, kDword, D1CRTC_CONTROL) +XE_GPU_REGISTER(0x180B, kDword, D1CRTC_BLANK_CONTROL) +XE_GPU_REGISTER(0x180C, kDword, D1CRTC_INTERLACE_CONTROL) +XE_GPU_REGISTER(0x180D, kDword, D1CRTC_INTERLACE_STATUS) +XE_GPU_REGISTER(0x180E, kDword, D1CRTC_BLANK_DATA_COLOR) +XE_GPU_REGISTER(0x180F, kDword, D1CRTC_OVERSCAN_COLOR) +XE_GPU_REGISTER(0x1810, kDword, D1CRTC_BLACK_COLOR) +XE_GPU_REGISTER(0x1811, kDword, D1CRTC_OVERSCAN_TOP) +XE_GPU_REGISTER(0x1812, kDword, D1CRTC_OVERSCAN_BOTTOM) +XE_GPU_REGISTER(0x1813, kDword, D1CRTC_OVERSCAN_LEFT) +XE_GPU_REGISTER(0x1814, kDword, D1CRTC_OVERSCAN_RIGHT) +XE_GPU_REGISTER(0x1815, kDword, D1CRTC_STATUS) +XE_GPU_REGISTER(0x1816, kDword, D1CRTC_STATUS_POSITION) +XE_GPU_REGISTER(0x1817, kDword, D1CRTC_FRAME_COUNT_CONTROL) +XE_GPU_REGISTER(0x1818, kDword, D1CRTC_STATUS_FRAME_COUNT) +XE_GPU_REGISTER(0x1819, kDword, D1CRTC_STATUS_VF_COUNT) +XE_GPU_REGISTER(0x181A, kDword, D1CRTC_STATUS_HV_COUNT) +XE_GPU_REGISTER(0x181B, kDword, D1CRTC_FRAME_COUNT_START) +XE_GPU_REGISTER(0x181C, kDword, D1CRTC_COUNT_CONTROL) +XE_GPU_REGISTER(0x181D, kDword, D1CRTC_STEREO_STATUS) +XE_GPU_REGISTER(0x181E, kDword, D1CRTC_STEREO_CONTROL) +XE_GPU_REGISTER(0x181F, kDword, D1CRTC_FRAME_RESET_CONTRO) XE_GPU_REGISTER(0x1838, kDword, D1MODE_MASTER_UPDATE_LOCK) +XE_GPU_REGISTER(0x1839, kDword, D1MODE_MASTER_UPDATE_MODE) +XE_GPU_REGISTER(0x183A, kDword, D1CRTC_UPDATE_LOCK) +XE_GPU_REGISTER(0x183B, kDword, D1CRTC_DOUBLE_BUFFER_CONTROL) +XE_GPU_REGISTER(0x183C, kDword, CRTC_DEBUG) +XE_GPU_REGISTER(0x1840, kDword, D1GRPH_ENABLE) XE_GPU_REGISTER(0x1841, kDword, D1GRPH_CONTROL) +XE_GPU_REGISTER(0x1842, kDword, D1GRPH_LUT_10BIT_BYPASS_CNTL) +XE_GPU_REGISTER(0x1843, kDword, D1GRPH_LUT_AFTER_CSC) XE_GPU_REGISTER(0x1844, kDword, D1GRPH_PRIMARY_SURFACE_ADDRESS) +XE_GPU_REGISTER(0x1846, kDword, D1GRPH_SECONDARY_SURFACE_ADDRESS) +XE_GPU_REGISTER(0x1848, kDword, D1GRPH_PITCH) +XE_GPU_REGISTER(0x1849, kDword, D1GRPH_SURFACE_OFFSET_X) +XE_GPU_REGISTER(0x184A, kDword, D1GRPH_SURFACE_OFFSET_Y) +XE_GPU_REGISTER(0x184B, kDword, D1GRPH_X_START) +XE_GPU_REGISTER(0x184C, kDword, D1GRPH_Y_START) +XE_GPU_REGISTER(0x184D, kDword, D1GRPH_X_END) +XE_GPU_REGISTER(0x184E, kDword, D1GRPH_Y_END) +XE_GPU_REGISTER(0x184F, kDword, D1COLOR_SUBSAMPLE_CRCB_CNTL) +XE_GPU_REGISTER(0x1851, kDword, D1GRPH_UPDATE) XE_GPU_REGISTER(0x1852, kDword, D1GRPH_FLIP_CONTROL) // In 4B4F07FE, the 256-entry gamma ramp for the 8bpc framebuffer is set to @@ -428,6 +1016,31 @@ XE_GPU_REGISTER(0x1852, kDword, D1GRPH_FLIP_CONTROL) // Read / write mode in bit 0: 0 - 256-entry table, 1 - PWL. // Default: 0x00000000. +XE_GPU_REGISTER(0x1860, kDword, D1OVL_ENABLE) +XE_GPU_REGISTER(0x1861, kDword, D1OVL_CONTROL1) +XE_GPU_REGISTER(0x1864, kDword, D1OVL_SURFACE_ADDRESS) +XE_GPU_REGISTER(0x1866, kDword, D1OVL_PITCH) +XE_GPU_REGISTER(0x1867, kDword, D1OVL_SURFACE_OFFSET_X) +XE_GPU_REGISTER(0x1868, kDword, D1OVL_SURFACE_OFFSET_Y) +XE_GPU_REGISTER(0x1869, kDword, D1OVL_START) +XE_GPU_REGISTER(0x186A, kDword, D1OVL_END) +XE_GPU_REGISTER(0x186B, kDword, D1OVL_UPDATE) +XE_GPU_REGISTER(0x18C1, kDword, D1OVL_ALPHA_OUTSIDE_OVL_WINDOW) +XE_GPU_REGISTER(0x18C2, kDword, D1OVL_ALPHA_INSIDE_OVL_WINDOW) +XE_GPU_REGISTER(0x18C3, kDword, D1OVL_ALPHA_CONTROL) +XE_GPU_REGISTER(0x18E0, kDword, D1GRPH_COLOR_MATRIX_CNTL) +XE_GPU_REGISTER(0x18E1, kDword, D1GRPH_COLOR_MATRIX_COEF_1_1) +XE_GPU_REGISTER(0x18E2, kDword, D1GRPH_COLOR_MATRIX_COEF_1_2) +XE_GPU_REGISTER(0x18E3, kDword, D1GRPH_COLOR_MATRIX_COEF_1_3) +XE_GPU_REGISTER(0x18E4, kDword, D1GRPH_COLOR_MATRIX_COEF_1_4) +XE_GPU_REGISTER(0x18E5, kDword, D1GRPH_COLOR_MATRIX_COEF_2_1) +XE_GPU_REGISTER(0x18E6, kDword, D1GRPH_COLOR_MATRIX_COEF_2_2) +XE_GPU_REGISTER(0x18E7, kDword, D1GRPH_COLOR_MATRIX_COEF_2_3) +XE_GPU_REGISTER(0x18E8, kDword, D1GRPH_COLOR_MATRIX_COEF_2_4) +XE_GPU_REGISTER(0x18E9, kDword, D1GRPH_COLOR_MATRIX_COEF_3_1) +XE_GPU_REGISTER(0x18EA, kDword, D1GRPH_COLOR_MATRIX_COEF_3_2) +XE_GPU_REGISTER(0x18EB, kDword, D1GRPH_COLOR_MATRIX_COEF_3_3) +XE_GPU_REGISTER(0x18EC, kDword, D1GRPH_COLOR_MATRIX_COEF_3_4) XE_GPU_REGISTER(0x1921, kDword, DC_LUT_RW_MODE) // Read / write index. No lower and upper halves on the Xenos apparently, for // the 256-entry table, the bits 0:7 are the index directly (unlike on the M56, @@ -479,14 +1092,125 @@ XE_GPU_REGISTER(0x1927, kDword, DC_LUT_WRITE_EN_MASK) // Default: 0x00000000. XE_GPU_REGISTER(0x1930, kDword, DC_LUTA_CONTROL) +XE_GPU_REGISTER(0x1931, kDword, DC_LUTA_BLACK_OFFSET_BLUE) +XE_GPU_REGISTER(0x1932, kDword, DC_LUTA_BLACK_OFFSET_GREEN) +XE_GPU_REGISTER(0x1933, kDword, DC_LUTA_BLACK_OFFSET_RED) +XE_GPU_REGISTER(0x1934, kDword, DC_LUTA_WHITE_OFFSET_BLUE) +XE_GPU_REGISTER(0x1935, kDword, DC_LUTA_WHITE_OFFSET_GREEN) +XE_GPU_REGISTER(0x1936, kDword, DC_LUTA_WHITE_OFFSET_RED) +XE_GPU_REGISTER(0x1949, kDword, D1MODE_UNDERFLOW_STATUS) +XE_GPU_REGISTER(0x194A, kDword, D1MODE_DATA_FORMAT) +XE_GPU_REGISTER(0x194B, kDword, D1MODE_DESKTOP_HEIGHT) XE_GPU_REGISTER(0x194C, kDword, D1MODE_V_COUNTER) - -XE_GPU_REGISTER(0x1961, kDword, AVIVO_D1MODE_VIEWPORT_SIZE) - -XE_GPU_REGISTER(0x1964, kDword, AVIVO_D1SCL_SCALER_ENABLE) - -XE_GPU_REGISTER(0x1973, kDword, AVIVO_D1SCL_UPDATE) - +XE_GPU_REGISTER(0x194D, kDword, D1MODE_VBLANK_STATUS) +XE_GPU_REGISTER(0x194E, kDword, D1MODE_VLINE_START_END) +XE_GPU_REGISTER(0x194F, kDword, D1MODE_VLINE_STATUS) +XE_GPU_REGISTER(0x1950, kDword, D1MODE_INT_MASK) +XE_GPU_REGISTER(0x1951, kDword, D1MODE_VBLANK_VLINE_STATUS) +XE_GPU_REGISTER(0x1952, kDword, D1MODE_MAX_CHUNK_SIZE) +XE_GPU_REGISTER(0x1953, kDword, D1MODE_CHUNK_SIZE_DEBUG) +XE_GPU_REGISTER(0x1954, kDword, D1MODE_PRIORITY_A_CNT) +XE_GPU_REGISTER(0x1955, kDword, D1MODE_URGENCY_STAT) +XE_GPU_REGISTER(0x195E, kDword, D1SCL_COEF_RAM_SELECT) +XE_GPU_REGISTER(0x195F, kDword, D1SCL_COEF_RAM_TAP_DATA) +XE_GPU_REGISTER(0x1960, kDword, D1MODE_VIEWPORT_START) +XE_GPU_REGISTER(0x1961, kDword, D1MODE_VIEWPORT_SIZE) +XE_GPU_REGISTER(0x1964, kDword, D1SCL_SCALER_ENABLE) +XE_GPU_REGISTER(0x1965, kDword, D1SCL_TAP_CONTROL) +XE_GPU_REGISTER(0x1968, kDword, D1SCL_MANUAL_REPLICATE_CONTROL) +XE_GPU_REGISTER(0x196C, kDword, D1SCL_HORZ_FILTER_CONTROL) +XE_GPU_REGISTER(0x196D, kDword, D1SCL_HORZ_FILTER_SCALE_RATIO) +XE_GPU_REGISTER(0x196E, kDword, D1SCL_HORZ_FILTER_INIT_RGB_LUMA) +XE_GPU_REGISTER(0x196F, kDword, D1SCL_HORZ_FILTER_INIT_CHROMA) +XE_GPU_REGISTER(0x1970, kDword, D1SCL_VERT_FILTER_CONTROL) +XE_GPU_REGISTER(0x1971, kDword, D1SCL_VERT_FILTER_SCALE_RATIO) +XE_GPU_REGISTER(0x1972, kDword, D1SCL_VERT_FILTER_INIT) +XE_GPU_REGISTER(0x1973, kDword, D1SCL_UPDATE) +XE_GPU_REGISTER(0x1974, kDword, D1SCL_UNDERFLOW_STATUS) +XE_GPU_REGISTER(0x1977, kDword, D1SCL_VERT_FILTER_INIT_BOT) +XE_GPU_REGISTER(0x1978, kDword, D1SCL_COEF_RAM_CONFLICT_STATUS) +XE_GPU_REGISTER(0x1979, kDword, D1SCL_ONE_SHOT_WATERMARK) +XE_GPU_REGISTER(0x197A, kDword, D1MODE_LB_PITCH_IN_WORDS) +XE_GPU_REGISTER(0x198C, kDword, DISP_RBBMIF_RDWR_TIMEOUT) +XE_GPU_REGISTER(0x19BA, kDword, D1SCL_CRC_ENABLE) +XE_GPU_REGISTER(0x19BC, kDword, D1SCL_CRC_SOURCE_SEL) +XE_GPU_REGISTER(0x19BD, kDword, D1SCL_CRC_MAS) +XE_GPU_REGISTER(0x19BE, kDword, D1SCL_CRC_CURRENT) +XE_GPU_REGISTER(0x19BF, kDword, D1SCL_CRC_LAST) +XE_GPU_REGISTER(0x1B20, kDword, DCP_CRC_CONTROL) +XE_GPU_REGISTER(0x1B21, kDword, DCP_CRC_MASK) +XE_GPU_REGISTER(0x1B22, kDword, DCP_CRC_P0_CURRENT) +XE_GPU_REGISTER(0x1B24, kDword, DCP_CRC_P0_LAST) +XE_GPU_REGISTER(0x1B25, kDword, DCP_DEBUG) +XE_GPU_REGISTER(0x1B2E, kDword, DMIF_STATUS) +XE_GPU_REGISTER(0x1B2F, kDword, DCP_LB_DATA_GAP_BETWEEN_CHUNK) +XE_GPU_REGISTER(0x1C46, kDword, DC_LB_MEM_SIZE) +XE_GPU_REGISTER(0x1E40, kDword, XDVO_ENABLE) +XE_GPU_REGISTER(0x1E43, kDword, XDVO_BIT_DEPTH_CONTROL) +XE_GPU_REGISTER(0x1E44, kDword, XDVO_CLOCK_INV) +XE_GPU_REGISTER(0x1E45, kDword, XDVO_CONTROL) +XE_GPU_REGISTER(0x1E46, kDword, XDVO_CRC_EN) +XE_GPU_REGISTER(0x1E47, kDword, XDVO_CRC_CNTL) +XE_GPU_REGISTER(0x1E48, kDword, XDVO_CRC_MASK_SIG_RGB) +XE_GPU_REGISTER(0x1E49, kDword, XDVO_CRC_MASK_SIG_CNTL) +XE_GPU_REGISTER(0x1E4A, kDword, XDVO_CRC_SIG_RGB) +XE_GPU_REGISTER(0x1E4B, kDword, XDVO_CRC_SIG_CNTL) +XE_GPU_REGISTER(0x1E4C, kDword, XDVO_STRENGTH_CONTROL) +XE_GPU_REGISTER(0x1E4D, kDword, XDVO_DATA_STRENGTH_CONTROL) +XE_GPU_REGISTER(0x1E4E, kDword, XDVO_FORCE_OUTPUT_CNTL) +XE_GPU_REGISTER(0x1E4F, kDword, XDVO_FORCE_DATA) +XE_GPU_REGISTER(0x1E50, kDword, XDVO_2ND_CRC_EN) +XE_GPU_REGISTER(0x1E51, kDword, XDVO_2ND_CRC_CNTL) +XE_GPU_REGISTER(0x1E52, kDword, XDVO_2ND_CRC_MASK_SIG) +XE_GPU_REGISTER(0x1E53, kDword, XDVO_2ND_CRC_SIG) +XE_GPU_REGISTER(0x1E54, kDword, XDVO_REGISTER_INDEX) +XE_GPU_REGISTER(0x1E55, kDword, XDVO_REGISTER_DATA) +XE_GPU_REGISTER(0x1F98, kDword, DC_GPIO_XDVODATA_MASK) +XE_GPU_REGISTER(0x1F99, kDword, DC_GPIO_XDVODATA_A) +XE_GPU_REGISTER(0x1F9A, kDword, DC_GPIO_XDVODATA_EN) +XE_GPU_REGISTER(0x1F9B, kDword, DC_GPIO_XDVODATA_Y) +XE_GPU_REGISTER(0x1F9C, kDword, DC_HSYNC_DEBUG_TEST) +XE_GPU_REGISTER(0x1FB4, kDword, CAPTURE_START_STATUS) +XE_GPU_REGISTER(0x1FB7, kDword, DISP_INTERRUPT_STATUS) +XE_GPU_REGISTER(0x1FB8, kDword, DOUT_DEBUG) +XE_GPU_REGISTER(0x1FC0, kDword, DO_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x1FC1, kDword, DO_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x1FC2, kDword, DO_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x1FC3, kDword, DO_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x1FC4, kDword, DO_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x1FC5, kDword, DO_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x1FC8, kDword, DC_PERFCOUNTER0_SELECT) +XE_GPU_REGISTER(0x1FC9, kDword, DC_PERFCOUNTER0_HI) +XE_GPU_REGISTER(0x1FCA, kDword, DC_PERFCOUNTER0_LOW) +XE_GPU_REGISTER(0x1FCB, kDword, DC_PERFCOUNTER1_SELECT) +XE_GPU_REGISTER(0x1FCC, kDword, DC_PERFCOUNTER1_HI) +XE_GPU_REGISTER(0x1FCD, kDword, DC_PERFCOUNTER1_LOW) +XE_GPU_REGISTER(0x1FCE, kDword, DC_PERFMON_CNTL) +XE_GPU_REGISTER(0x1FD0, kDword, DC_DOUT_DEBUG_MUX_CNTL) +XE_GPU_REGISTER(0x1FE6, kDword, DC_TEST_DEBUG_BUS_CLK1_SEL) +XE_GPU_REGISTER(0x1FE7, kDword, DC_TEST_DEBUG_OUT_PIN_MASK) +XE_GPU_REGISTER(0x1FE8, kDword, DC_TEST_DEBUG_TRIGGER_CNTL) +XE_GPU_REGISTER(0x1FE9, kDword, DC_TEST_DEBUG_TRIGGER_STAT) +XE_GPU_REGISTER(0x1FEA, kDword, DC_TEST_DEBUG_EDGE_TRIGGER_MASK) +XE_GPU_REGISTER(0x1FEB, kDword, DC_TEST_DEBUG_EDGE_TRIGGER_PATTERN) +XE_GPU_REGISTER(0x1FEC, kDword, DC_TEST_DEBUG_DATA_TRIGGER_MASK) +XE_GPU_REGISTER(0x1FED, kDword, DC_TEST_DEBUG_DATA_TRIGGER_PATTERN) +XE_GPU_REGISTER(0x1FEE, kDword, DC_TEST_DEBUG_OUT_TEST_DATA) +XE_GPU_REGISTER(0x1FEF, kDword, DC_TEST_DEBUG_OUT_CNTL) +XE_GPU_REGISTER(0x1FF2, kDword, DO_TEST_DEBUG_BUS_CLK1_SEL) +XE_GPU_REGISTER(0x1FF3, kDword, DO_TEST_DEBUG_OUT_PIN_MASK) +XE_GPU_REGISTER(0x1FF4, kDword, DO_TEST_DEBUG_TRIGGER_CNTL) +XE_GPU_REGISTER(0x1FF5, kDword, DO_TEST_DEBUG_TRIGGER_STAT) +XE_GPU_REGISTER(0x1FF6, kDword, DO_TEST_DEBUG_EDGE_TRIGGER_MASK) +XE_GPU_REGISTER(0x1FF7, kDword, DO_TEST_DEBUG_EDGE_TRIGGER_PATTERN) +XE_GPU_REGISTER(0x1FF8, kDword, DO_TEST_DEBUG_DATA_TRIGGER_MASK) +XE_GPU_REGISTER(0x1FF9, kDword, DO_TEST_DEBUG_DATA_TRIGGER_PATTERN) +XE_GPU_REGISTER(0x1FFA, kDword, DO_TEST_DEBUG_OUT_TEST_DATA) +XE_GPU_REGISTER(0x1FFB, kDword, DO_TEST_DEBUG_OUT_CNTL) +XE_GPU_REGISTER(0x1FFC, kDword, DC_TEST_DEBUG_INDEX) +XE_GPU_REGISTER(0x1FFD, kDword, DC_TEST_DEBUG_DATA) +XE_GPU_REGISTER(0x1FFE, kDword, DO_TEST_DEBUG_INDEX) +XE_GPU_REGISTER(0x1FFF, kDword, DO_TEST_DEBUG_DATA) XE_GPU_REGISTER(0x2000, kDword, RB_SURFACE_INFO) XE_GPU_REGISTER(0x2001, kDword, RB_COLOR_INFO) XE_GPU_REGISTER(0x2002, kDword, RB_DEPTH_INFO) @@ -508,6 +1232,15 @@ XE_GPU_REGISTER(0x2080, kDword, PA_SC_WINDOW_OFFSET) XE_GPU_REGISTER(0x2081, kDword, PA_SC_WINDOW_SCISSOR_TL) XE_GPU_REGISTER(0x2082, kDword, PA_SC_WINDOW_SCISSOR_BR) +XE_GPU_REGISTER(0x2083, kDword, PA_SC_CLIPRECT_RULE) +XE_GPU_REGISTER(0x2084, kDword, PA_SC_CLIPRECT_0_TL) +XE_GPU_REGISTER(0x2085, kDword, PA_SC_CLIPRECT_0_BR) +XE_GPU_REGISTER(0x2086, kDword, PA_SC_CLIPRECT_1_TL) +XE_GPU_REGISTER(0x2087, kDword, PA_SC_CLIPRECT_1_BR) +XE_GPU_REGISTER(0x2088, kDword, PA_SC_CLIPRECT_2_TL) +XE_GPU_REGISTER(0x2089, kDword, PA_SC_CLIPRECT_2_BR) +XE_GPU_REGISTER(0x208A, kDword, PA_SC_CLIPRECT_3_TL) +XE_GPU_REGISTER(0x208B, kDword, PA_SC_CLIPRECT_3_BR) XE_GPU_REGISTER(0x2100, kDword, VGT_MAX_VTX_INDX) XE_GPU_REGISTER(0x2101, kDword, VGT_MIN_VTX_INDX) XE_GPU_REGISTER(0x2102, kDword, VGT_INDX_OFFSET) @@ -535,8 +1268,10 @@ XE_GPU_REGISTER(0x2181, kDword, SQ_CONTEXT_MISC) XE_GPU_REGISTER(0x2182, kDword, SQ_INTERPOLATOR_CNTL) XE_GPU_REGISTER(0x2183, kDword, SQ_WRAPPING_0) XE_GPU_REGISTER(0x2184, kDword, SQ_WRAPPING_1) - -// These three registers are set by the command processor. +XE_GPU_REGISTER(0x21F4, kDword, GFX_COPY_STATE) +XE_GPU_REGISTER(0x21F5, kDword, SQ_CF_RD_BASE) +XE_GPU_REGISTER(0x21F6, kDword, SQ_PS_PROGRAM) +XE_GPU_REGISTER(0x21F7, kDword, SQ_VS_PROGRAM) XE_GPU_REGISTER(0x21F9, kDword, VGT_EVENT_INITIATOR) XE_GPU_REGISTER(0x21FA, kDword, VGT_DMA_BASE) XE_GPU_REGISTER(0x21FB, kDword, VGT_DMA_SIZE) @@ -556,6 +1291,7 @@ XE_GPU_REGISTER(0x2209, kDword, RB_BLENDCONTROL1) XE_GPU_REGISTER(0x220A, kDword, RB_BLENDCONTROL2) XE_GPU_REGISTER(0x220B, kDword, RB_BLENDCONTROL3) +XE_GPU_REGISTER(0x2210, kDword, GRAS_CONTROL) XE_GPU_REGISTER(0x2280, kDword, PA_SU_POINT_SIZE) XE_GPU_REGISTER(0x2281, kDword, PA_SU_POINT_MINMAX) XE_GPU_REGISTER(0x2282, kDword, PA_SU_LINE_CNTL) @@ -616,12 +1352,10 @@ XE_GPU_REGISTER(0x2322, kDword, RB_COPY_MASK) XE_GPU_REGISTER(0x2323, kDword, RB_COPY_SURFACE_SLICE) XE_GPU_REGISTER(0x2324, kDword, RB_SAMPLE_COUNT_CTL) XE_GPU_REGISTER(0x2325, kDword, RB_SAMPLE_COUNT_ADDR) - -// Polygon offset scales and offsets are 32-bit floating-point. -// "slope computed in subpixels (1/12 or 1/16)" - R5xx Acceleration. -// But the correct scale for conversion of the slope scale (FRONT_BACK/SCALE) -// from subpixels to pixels is likely 1/16 according to: -// https://github.com/mesa3d/mesa/blob/54ad9b444c8e73da498211870e785239ad3ff1aa/src/gallium/drivers/radeonsi/si_state.c#L946 +XE_GPU_REGISTER(0x2326, kFloat, RB_COLOR_DEST_MASK) +XE_GPU_REGISTER(0x2340, kFloat, GRAS_UCP0X) +XE_GPU_REGISTER(0x2357, kFloat, GRAS_UCP5W) +XE_GPU_REGISTER(0x2360, kFloat, GRAS_UCP_ENABLED) XE_GPU_REGISTER(0x2380, kFloat, PA_SU_POLY_OFFSET_FRONT_SCALE) XE_GPU_REGISTER(0x2381, kFloat, PA_SU_POLY_OFFSET_FRONT_OFFSET) XE_GPU_REGISTER(0x2382, kFloat, PA_SU_POLY_OFFSET_BACK_SCALE) From 56703e52e2805bd05752683337343c42eaa10727 Mon Sep 17 00:00:00 2001 From: Gliniak Date: Wed, 26 Mar 2025 20:52:11 +0100 Subject: [PATCH 9/9] [UI] Redesigned "Install Content" window - Added ID for each ImGui window - Added filesystem::CreateFolder function --- src/xenia/app/emulator_window.cc | 150 ++++++++++++------ src/xenia/app/emulator_window.h | 28 ++++ src/xenia/base/filesystem.cc | 13 ++ src/xenia/base/filesystem.h | 4 + src/xenia/emulator.cc | 118 +++++++++----- src/xenia/emulator.h | 25 ++- src/xenia/kernel/xam/xam_content.cc | 7 +- src/xenia/kernel/xam/xam_ui.cc | 44 ++--- src/xenia/ui/imgui_dialog.cc | 3 + src/xenia/ui/imgui_dialog.h | 3 + src/xenia/ui/imgui_drawer.cc | 33 ++-- src/xenia/ui/imgui_drawer.h | 4 + .../vfs/devices/xcontent_container_device.cc | 3 +- .../vfs/devices/xcontent_container_device.h | 10 +- src/xenia/vfs/vfs_dump.cc | 5 +- src/xenia/vfs/virtual_file_system.cc | 42 +++-- src/xenia/vfs/virtual_file_system.h | 4 +- src/xenia/xbox.h | 1 + 18 files changed, 346 insertions(+), 151 deletions(-) diff --git a/src/xenia/app/emulator_window.cc b/src/xenia/app/emulator_window.cc index 46558d25f..15aa29daa 100644 --- a/src/xenia/app/emulator_window.cc +++ b/src/xenia/app/emulator_window.cc @@ -569,6 +569,93 @@ 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(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()); + } + + if (entry.installation_result_ != X_ERROR_SUCCESS) { + ImGui::Text("Status: %s (0x%08X)", + entry.installation_error_message_.c_str(), + entry.installation_result_); + } else if (entry.currently_installed_size_ == entry.content_size_ && + entry.installation_result_ == X_ERROR_SUCCESS) { + ImGui::Text("Status: Success"); + } + ImGui::EndTable(); + + if (entry.content_size_ > 0) { + ImGui::ProgressBar(static_cast(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); @@ -1088,62 +1175,27 @@ void EmulatorWindow::InstallContent() { return; } - using content_installation_data = - std::tuple; - std::map> - content_installation_details; + std::shared_ptr> + content_installation_status = + std::make_shared>(); for (const auto& path : paths) { - // 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}); + content_installation_status->push_back({path}); } - // Prepare installation process summary message - std::string summary = "Installation result: \n"; + for (auto& entry : *content_installation_status) { + emulator_->ProcessContentPackageHeader(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"; + auto installationThread = std::thread([this, content_installation_status] { + for (auto& entry : *content_installation_status) { + emulator_->InstallContentPackage(entry.path_, entry); } + }); + installationThread.detach(); - 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); + new ContentInstallDialog(imgui_drawer_.get(), *this, + content_installation_status); } void EmulatorWindow::ExtractZarchive() { diff --git a/src/xenia/app/emulator_window.h b/src/xenia/app/emulator_window.h index 7e58a3372..5b25b92a9 100644 --- a/src/xenia/app/emulator_window.h +++ b/src/xenia/app/emulator_window.h @@ -167,6 +167,34 @@ class EmulatorWindow { EmulatorWindow& emulator_window_; }; + class ContentInstallDialog final : public ui::ImGuiDialog { + public: + ContentInstallDialog( + ui::ImGuiDrawer* imgui_drawer, EmulatorWindow& emulator_window, + std::shared_ptr> 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> + installation_entries_; + }; + class DisplayConfigDialog final : public ui::ImGuiDialog { public: DisplayConfigDialog(ui::ImGuiDrawer* imgui_drawer, diff --git a/src/xenia/base/filesystem.cc b/src/xenia/base/filesystem.cc index d8c61935d..408801f28 100644 --- a/src/xenia/base/filesystem.cc +++ b/src/xenia/base/filesystem.cc @@ -24,6 +24,19 @@ 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 ListDirectories(const std::filesystem::path& path) { std::vector files = ListFiles(path); std::vector directories = {}; diff --git a/src/xenia/base/filesystem.h b/src/xenia/base/filesystem.h index 3596c374c..5dc3de7e7 100644 --- a/src/xenia/base/filesystem.h +++ b/src/xenia/base/filesystem.h @@ -45,6 +45,10 @@ 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); diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index 82ca8f1e9..8f5d17074 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -785,53 +785,85 @@ X_STATUS Emulator::DataMigration(const uint64_t xuid) { return X_STATUS_SUCCESS; } -X_STATUS Emulator::InstallContentPackage( - const std::filesystem::path& path, - ContentInstallationInfo& installation_info) { - std::unique_ptr device = +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()); + + std::unique_ptr device = vfs::XContentContainerDevice::CreateContentDevice("", path); - installation_info.content_name = "Invalid Content Package!"; - installation_info.content_type = static_cast(0); - installation_info.installation_path = xe::path_to_utf8(path.filename()); + if (!device || !device->Initialize()) { + 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(0)); + + uint64_t xuid = device->xuid(); + if (device->content_type() == + static_cast(XContentType::kSavedGame) && + profile) { + xuid = profile->xuid(); + } + + installation_info.data_installation_path_ = + fmt::format("{:016X}/{:08X}/{:08X}/{}", xuid, device->title_id(), + device->content_type(), path.filename()); + + installation_info.header_installation_path_ = + fmt::format("{:016X}/{:08X}/Headers/{:08X}/{}", xuid, device->title_id(), + device->content_type(), path.filename()); + + installation_info.name_ = + xe::to_utf8(device->content_header().display_name()); + installation_info.content_type_ = + static_cast(device->content_type()); + installation_info.content_size_ = device->data_size(); + + installation_info.icon_ = + imgui_drawer_->LoadImGuiIcon(std::span( + device->GetContainerHeader()->content_metadata.title_thumbnail, + device->GetContainerHeader()->content_metadata.title_thumbnail_size)); + return X_STATUS_SUCCESS; +} + +X_STATUS Emulator::InstallContentPackage( + const std::filesystem::path& path, ContentInstallEntry& installation_info) { + std::unique_ptr device = + vfs::XContentContainerDevice::CreateContentDevice("", path); if (!device || !device->Initialize()) { XELOGE("Failed to initialize device"); return X_STATUS_INVALID_PARAMETER; } - const vfs::XContentContainerDevice* dev = - (vfs::XContentContainerDevice*)device.get(); + const std::filesystem::path installation_path = + content_root() / installation_info.data_installation_path_; - // Always install savefiles to user signed to slot 0. - const auto profile = - kernel_state_->xam_state()->profile_manager()->GetProfile( - static_cast(0)); + const std::filesystem::path header_path = + content_root() / installation_info.header_installation_path_; - uint64_t xuid = dev->xuid(); - if (dev->content_type() == static_cast(XContentType::kSavedGame) && - profile) { - xuid = profile->xuid(); + if (!std::filesystem::exists(content_root())) { + const std::error_code ec = xe::filesystem::CreateFolder(content_root()); + if (ec) { + installation_info.installation_error_message_ = ec.message(); + installation_info.installation_result_ = X_STATUS_ACCESS_DENIED; + return X_STATUS_ACCESS_DENIED; + } } - 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(dev->content_type()); + const auto disk_space = std::filesystem::space(content_root()); + if (disk_space.available < installation_info.content_size_ * 1.1f) { + installation_info.installation_error_message_ = "Insufficient disk space!"; + installation_info.installation_result_ = X_STATUS_DISK_FULL; + return X_STATUS_DISK_FULL; + } if (std::filesystem::exists(installation_path)) { // TODO(Gliniak): Popup @@ -840,7 +872,9 @@ X_STATUS Emulator::InstallContentPackage( std::error_code error_code; std::filesystem::create_directories(installation_path, error_code); if (error_code) { - installation_info.content_name = "Cannot Create Content Directory!"; + installation_info.installation_error_message_ = + "Cannot Create Content Directory!"; + installation_info.installation_result_ = error_code.value(); return error_code.value(); } } @@ -848,13 +882,19 @@ X_STATUS Emulator::InstallContentPackage( vfs::VirtualFileSystem::ExtractContentHeader(device.get(), header_path); X_STATUS error_code = vfs::VirtualFileSystem::ExtractContentFiles( - device.get(), installation_path); + device.get(), installation_path, + installation_info.currently_installed_size_); if (error_code != X_ERROR_SUCCESS) { return error_code; } + 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; } @@ -879,7 +919,9 @@ X_STATUS Emulator::ExtractZarchivePackage( } } - return vfs::VirtualFileSystem::ExtractContentFiles(device.get(), extract_dir); + uint64_t progress = 0; + return vfs::VirtualFileSystem::ExtractContentFiles(device.get(), extract_dir, + progress); } X_STATUS Emulator::CreateZarchivePackage( diff --git a/src/xenia/emulator.h b/src/xenia/emulator.h index 1837f364d..c19328c7c 100644 --- a/src/xenia/emulator.h +++ b/src/xenia/emulator.h @@ -26,6 +26,7 @@ #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" @@ -234,18 +235,32 @@ class Emulator { X_STATUS LaunchDefaultModule(const std::filesystem::path& path); - struct ContentInstallationInfo { - XContentType content_type; - std::string installation_path; - std::string content_name; + 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; + X_STATUS installation_result_{}; + std::string installation_error_message_{}; + XContentType content_type_{}; + + std::unique_ptr icon_; }; // 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, - ContentInstallationInfo& installation_info); + ContentInstallEntry& installation_info); // Extract content of zar package to desired directory. X_STATUS ExtractZarchivePackage(const std::filesystem::path& path, diff --git a/src/xenia/kernel/xam/xam_content.cc b/src/xenia/kernel/xam/xam_content.cc index a5ea05144..693033a6d 100644 --- a/src/xenia/kernel/xam/xam_content.cc +++ b/src/xenia/kernel/xam/xam_content.cc @@ -661,8 +661,10 @@ dword_result_t XamContentLaunchImageFromFileInternal_entry( const std::filesystem::path host_path = kernel_state()->emulator()->content_root() / entry->name(); if (!std::filesystem::exists(host_path)) { + uint64_t progress = 0; + vfs::VirtualFileSystem::ExtractContentFile( - entry, kernel_state()->emulator()->content_root(), true); + entry, kernel_state()->emulator()->content_root(), progress, true); } auto xam = kernel_state()->GetKernelModule("xam.xex"); @@ -716,8 +718,9 @@ dword_result_t XamContentLaunchImageInternal_entry(lpvoid_t content_data_ptr, kernel_state()->emulator()->content_root() / entry->name(); if (!std::filesystem::exists(host_path)) { + uint64_t progress = 0; kernel_state()->file_system()->ExtractContentFile( - entry, kernel_state()->emulator()->content_root(), true); + entry, kernel_state()->emulator()->content_root(), progress, true); } auto xam = kernel_state()->GetKernelModule("xam.xex"); diff --git a/src/xenia/kernel/xam/xam_ui.cc b/src/xenia/kernel/xam/xam_ui.cc index 1f81de2a6..9e11ff3e2 100644 --- a/src/xenia/kernel/xam/xam_ui.cc +++ b/src/xenia/kernel/xam/xam_ui.cc @@ -58,8 +58,6 @@ namespace xam { extern std::atomic xam_dialogs_shown_; -constexpr ImVec2 default_image_icon_size = ImVec2(75.f, 75.f); - class XamDialog : public xe::ui::ImGuiDialog { public: void set_close_callback(std::function close_callback) { @@ -509,7 +507,8 @@ class GameAchievementsDialog final : public XamDialog { : XamDialog(imgui_drawer), drawing_position_(drawing_position), title_info_(*title_info), - profile_(profile) { + profile_(profile), + window_id_(GetWindowId()) { LoadAchievementsData(); } @@ -616,9 +615,9 @@ class GameAchievementsDialog final : public XamDialog { const auto icon = GetIcon(achievement_entry); if (icon) { ImGui::Image(reinterpret_cast(GetIcon(achievement_entry)), - default_image_icon_size); + ui::default_image_icon_size); } else { - ImGui::Dummy(default_image_icon_size); + ImGui::Dummy(ui::default_image_icon_size); } ImGui::TableNextColumn(); @@ -632,7 +631,7 @@ class GameAchievementsDialog final : public XamDialog { GetAchievementDescription(achievement_entry).c_str()); ImGui::PopTextWrapPos(); - ImGui::SetCursorPosY(start_drawing_pos.y + default_image_icon_size.x - + ImGui::SetCursorPosY(start_drawing_pos.y + ui::default_image_icon_size.x - ImGui::GetTextLineHeight()); if (achievement_entry.IsUnlocked()) { @@ -644,7 +643,8 @@ class GameAchievementsDialog final : public XamDialog { // TODO(Gliniak): There is no easy way to align text to middle, so I have to // do it manually. const float achievement_row_middle_alignment = - ((default_image_icon_size.x / 2.f) - ImGui::GetTextLineHeight() / 2.f) * + ((ui::default_image_icon_size.x / 2.f) - + ImGui::GetTextLineHeight() / 2.f) * 0.85f; ImGui::SetCursorPosY(ImGui::GetCursorPosY() + @@ -667,10 +667,13 @@ class GameAchievementsDialog final : public XamDialog { bool dialog_open = true; - if (!ImGui::Begin(fmt::format("{} Achievements List", - xe::to_utf8(title_info_.title_name)) - .c_str(), - &dialog_open, + std::string title_name = xe::to_utf8(title_info_.title_name); + title_name.erase(std::remove(title_name.begin(), title_name.end(), '\0'), + title_name.end()); + + const std::string window_name = + fmt::format("{} Achievements###{}", title_name, window_id_); + if (!ImGui::Begin(window_name.c_str(), &dialog_open, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_HorizontalScrollbar)) { @@ -688,7 +691,7 @@ class GameAchievementsDialog final : public XamDialog { if (ImGui::BeginTable("", 3, ImGuiTableFlags_::ImGuiTableFlags_BordersInnerH)) { for (const auto& entry : achievements_info_) { - ImGui::TableNextRow(0, default_image_icon_size.y); + ImGui::TableNextRow(0, ui::default_image_icon_size.y); DrawTitleAchievementInfo(io, entry); } @@ -707,6 +710,7 @@ class GameAchievementsDialog final : public XamDialog { bool show_locked_info_ = false; + uint64_t window_id_; const ImVec2 drawing_position_ = {}; const TitleInfo title_info_; @@ -724,7 +728,8 @@ class GamesInfoDialog final : public XamDialog { drawing_position_(drawing_position), profile_(profile), profile_manager_(kernel_state()->xam_state()->profile_manager()), - dialog_name_(fmt::format("{}'s Games List", profile->name())) { + dialog_name_(fmt::format("{}'s Games List###{}", profile->name(), + GetWindowId())) { LoadProfileGameInfo(imgui_drawer, profile); } @@ -762,9 +767,9 @@ class GamesInfoDialog final : public XamDialog { if (title_icon.count(entry.id)) { ImGui::Image(reinterpret_cast(title_icon.at(entry.id).get()), - default_image_icon_size); + ui::default_image_icon_size); } else { - ImGui::Dummy(default_image_icon_size); + ImGui::Dummy(ui::default_image_icon_size); } // Second Column @@ -779,7 +784,7 @@ class GamesInfoDialog final : public XamDialog { entry.title_earned_gamerscore) .c_str()); - ImGui::SetCursorPosY(start_position.y + default_image_icon_size.y - + ImGui::SetCursorPosY(start_position.y + ui::default_image_icon_size.y - ImGui::GetTextLineHeight()); if (entry.WasTitlePlayed()) { @@ -881,7 +886,7 @@ class GamesInfoDialog final : public XamDialog { if (ImGui::BeginTable("", 2, ImGuiTableFlags_::ImGuiTableFlags_BordersInnerH)) { - ImGui::TableNextRow(0, default_image_icon_size.y); + ImGui::TableNextRow(0, ui::default_image_icon_size.y); for (auto& entry : info_) { std::string filter(title_name_filter_); if (!filter.empty()) { @@ -1564,9 +1569,10 @@ bool xeDrawProfileContent(ui::ImGuiDrawer* imgui_drawer, const uint64_t xuid, // In the future it can be replaced with profile icon. const auto icon = imgui_drawer->GetNotificationIcon(user_index); if (icon && user_index < XUserMaxUserCount) { - ImGui::Image(reinterpret_cast(icon), default_image_icon_size); + ImGui::Image(reinterpret_cast(icon), + ui::default_image_icon_size); } else { - ImGui::Dummy(default_image_icon_size); + ImGui::Dummy(ui::default_image_icon_size); } ImGui::SameLine(); diff --git a/src/xenia/ui/imgui_dialog.cc b/src/xenia/ui/imgui_dialog.cc index 4e940e798..e3e09df53 100644 --- a/src/xenia/ui/imgui_dialog.cc +++ b/src/xenia/ui/imgui_dialog.cc @@ -16,9 +16,12 @@ namespace xe { namespace ui { +uint64_t ImGuiDialog::next_window_id_ = 0; + ImGuiDialog::ImGuiDialog(ImGuiDrawer* imgui_drawer) : imgui_drawer_(imgui_drawer) { imgui_drawer_->AddDialog(this); + next_window_id_++; } ImGuiDialog::~ImGuiDialog() { diff --git a/src/xenia/ui/imgui_dialog.h b/src/xenia/ui/imgui_dialog.h index 976fd1d26..aefa2658c 100644 --- a/src/xenia/ui/imgui_dialog.h +++ b/src/xenia/ui/imgui_dialog.h @@ -40,6 +40,7 @@ class ImGuiDialog { ImGuiDrawer* imgui_drawer() const { return imgui_drawer_; } ImGuiIO& GetIO(); + uint64_t GetWindowId() const { return next_window_id_; } // Closes the dialog and returns to any waiters. void Close(); @@ -48,6 +49,8 @@ class ImGuiDialog { virtual void OnDraw(ImGuiIO& io) {} private: + static uint64_t next_window_id_; + ImGuiDrawer* imgui_drawer_ = nullptr; bool has_close_pending_ = false; std::vector waiting_fences_; diff --git a/src/xenia/ui/imgui_drawer.cc b/src/xenia/ui/imgui_drawer.cc index 70c5d4698..45afc24a0 100644 --- a/src/xenia/ui/imgui_drawer.cc +++ b/src/xenia/ui/imgui_drawer.cc @@ -234,6 +234,25 @@ std::optional ImGuiDrawer::VirtualKeyToImGuiKey(VirtualKey vkey) { } } +std::unique_ptr ImGuiDrawer::LoadImGuiIcon( + std::span data) { + if (!immediate_drawer_) { + return {}; + } + + int width, height, channels; + unsigned char* image_data = + stbi_load_from_memory(data.data(), static_cast(data.size()), &width, + &height, &channels, STBI_rgb_alpha); + if (!image_data) { + return {}; + } + + return immediate_drawer_->CreateTexture( + width, height, ImmediateTextureFilter::kLinear, true, + reinterpret_cast(image_data)); +} + std::map> ImGuiDrawer::LoadIcons( IconsData data) { std::map> icons_; @@ -242,21 +261,9 @@ std::map> ImGuiDrawer::LoadIcons( return icons_; } - int width, height, channels; - for (const auto& icon : data) { - unsigned char* image_data = stbi_load_from_memory( - icon.second.data(), static_cast(icon.second.size()), &width, - &height, &channels, STBI_rgb_alpha); - - if (!image_data) { - continue; - } - icons_[icon.first] = (immediate_drawer_->CreateTexture( - width, height, ImmediateTextureFilter::kLinear, true, - reinterpret_cast(image_data))); + icons_[icon.first] = LoadImGuiIcon(icon.second); } - return icons_; } diff --git a/src/xenia/ui/imgui_drawer.h b/src/xenia/ui/imgui_drawer.h index 08cbf3745..099dfb454 100644 --- a/src/xenia/ui/imgui_drawer.h +++ b/src/xenia/ui/imgui_drawer.h @@ -37,6 +37,8 @@ class Window; using IconsData = std::map>; +constexpr ImVec2 default_image_icon_size = ImVec2(75.f, 75.f); + class ImGuiDrawer : public WindowInputListener, public UIDrawer { public: ImGuiDrawer(Window* window, size_t z_order); @@ -64,6 +66,8 @@ class ImGuiDrawer : public WindowInputListener, public UIDrawer { void ClearDialogs(); void EnableNotifications(bool enable) { are_notifications_enabled_ = enable; } + std::unique_ptr LoadImGuiIcon( + std::span data); std::map> LoadIcons( IconsData data); diff --git a/src/xenia/vfs/devices/xcontent_container_device.cc b/src/xenia/vfs/devices/xcontent_container_device.cc index 9501f425d..7da3fd860 100644 --- a/src/xenia/vfs/devices/xcontent_container_device.cc +++ b/src/xenia/vfs/devices/xcontent_container_device.cc @@ -15,7 +15,8 @@ namespace xe { namespace vfs { -std::unique_ptr XContentContainerDevice::CreateContentDevice( +std::unique_ptr +XContentContainerDevice::CreateContentDevice( const std::string_view mount_path, const std::filesystem::path& host_path) { if (!std::filesystem::exists(host_path)) { XELOGE("Path to XContent container does not exist: {}", host_path); diff --git a/src/xenia/vfs/devices/xcontent_container_device.h b/src/xenia/vfs/devices/xcontent_container_device.h index 124715056..c44801a43 100644 --- a/src/xenia/vfs/devices/xcontent_container_device.h +++ b/src/xenia/vfs/devices/xcontent_container_device.h @@ -31,7 +31,7 @@ class XContentContainerDevice : public Device { public: constexpr static uint32_t kBlockSize = 0x1000; - static std::unique_ptr CreateContentDevice( + static std::unique_ptr CreateContentDevice( const std::string_view mount_path, const std::filesystem::path& host_path); @@ -74,6 +74,10 @@ class XContentContainerDevice : public Device { return final_license; } + const XContentContainerHeader* GetContainerHeader() const { + return header_.get(); + } + protected: XContentContainerDevice(const std::string_view mount_path, const std::filesystem::path& host_path); @@ -106,10 +110,6 @@ class XContentContainerDevice : public Device { const std::filesystem::path& GetHostPath() const { return host_path_; } - const XContentContainerHeader* GetContainerHeader() const { - return header_.get(); - } - std::string name_; std::filesystem::path host_path_; diff --git a/src/xenia/vfs/vfs_dump.cc b/src/xenia/vfs/vfs_dump.cc index 6aadfb159..552edd1bf 100644 --- a/src/xenia/vfs/vfs_dump.cc +++ b/src/xenia/vfs/vfs_dump.cc @@ -44,7 +44,10 @@ int vfs_dump_main(const std::vector& args) { XELOGE("Failed to initialize device"); return 1; } - return VirtualFileSystem::ExtractContentFiles(device.get(), base_path); + + uint64_t progress = 0; + return VirtualFileSystem::ExtractContentFiles(device.get(), base_path, + progress); } } // namespace vfs diff --git a/src/xenia/vfs/virtual_file_system.cc b/src/xenia/vfs/virtual_file_system.cc index 985031ea8..b3b6b00cf 100644 --- a/src/xenia/vfs/virtual_file_system.cc +++ b/src/xenia/vfs/virtual_file_system.cc @@ -335,6 +335,7 @@ X_STATUS VirtualFileSystem::OpenFile(Entry* root_entry, X_STATUS VirtualFileSystem::ExtractContentFile(Entry* entry, std::filesystem::path base_path, + uint64_t& progress, bool extract_to_root) { // Allocate a buffer when needed. size_t buffer_size = 0; @@ -369,27 +370,33 @@ X_STATUS VirtualFileSystem::ExtractContentFile(Entry* entry, in_file->Destroy(); return 1; } + constexpr size_t write_buffer_size = 4_MiB; if (entry->can_map()) { auto map = entry->OpenMapped(xe::MappedMemory::Mode::kRead); - fwrite(map->data(), map->size(), 1, file); + + auto remaining_size = map->size(); + auto offset = 0; + + while (remaining_size > 0) { + fwrite(map->data() + offset, write_buffer_size, 1, file); + offset += write_buffer_size; + remaining_size -= write_buffer_size; + } map->Close(); } else { - // Can't map the file into memory. Read it into a temporary buffer. - if (!buffer || entry->size() > buffer_size) { - // Resize the buffer. - if (buffer) { - delete[] buffer; - } + auto remaining_size = entry->size(); + size_t offset = 0; + buffer = new uint8_t[write_buffer_size]; - // Allocate a buffer rounded up to the nearest 512MB. - buffer_size = xe::round_up(entry->size(), 512_MiB); - buffer = new uint8_t[buffer_size]; + while (remaining_size > 0) { + size_t bytes_read = 0; + in_file->ReadSync(buffer, write_buffer_size, offset, &bytes_read); + fwrite(buffer, bytes_read, 1, file); + offset += bytes_read; + remaining_size -= bytes_read; + progress += bytes_read; } - - size_t bytes_read = 0; - in_file->ReadSync(buffer, entry->size(), 0, &bytes_read); - fwrite(buffer, bytes_read, 1, file); } fclose(file); @@ -401,8 +408,9 @@ X_STATUS VirtualFileSystem::ExtractContentFile(Entry* entry, return 0; } -X_STATUS VirtualFileSystem::ExtractContentFiles( - Device* device, std::filesystem::path base_path) { +X_STATUS VirtualFileSystem::ExtractContentFiles(Device* device, + std::filesystem::path base_path, + uint64_t& progress) { // Run through all the files, breadth-first style. std::queue queue; auto root = device->ResolvePath("/"); @@ -415,7 +423,7 @@ X_STATUS VirtualFileSystem::ExtractContentFiles( queue.push(entry.get()); } - ExtractContentFile(entry, base_path); + ExtractContentFile(entry, base_path, progress); } return X_STATUS_SUCCESS; } diff --git a/src/xenia/vfs/virtual_file_system.h b/src/xenia/vfs/virtual_file_system.h index 46c42c0c1..df3271b59 100644 --- a/src/xenia/vfs/virtual_file_system.h +++ b/src/xenia/vfs/virtual_file_system.h @@ -51,9 +51,11 @@ class VirtualFileSystem { static X_STATUS ExtractContentFile(Entry* entry, std::filesystem::path base_path, + uint64_t& progress, bool extract_to_root = false); static X_STATUS ExtractContentFiles(Device* device, - std::filesystem::path base_path); + std::filesystem::path base_path, + uint64_t& progress); static void ExtractContentHeader(Device* device, std::filesystem::path base_path); diff --git a/src/xenia/xbox.h b/src/xenia/xbox.h index 7a206d56d..05abe803e 100644 --- a/src/xenia/xbox.h +++ b/src/xenia/xbox.h @@ -67,6 +67,7 @@ typedef uint32_t X_STATUS; #define X_STATUS_THREAD_IS_TERMINATING ((X_STATUS)0xC000004BL) #define X_STATUS_PROCEDURE_NOT_FOUND ((X_STATUS)0xC000007AL) #define X_STATUS_INVALID_IMAGE_FORMAT ((X_STATUS)0xC000007BL) +#define X_STATUS_DISK_FULL ((X_STATUS)0xC000007FL) #define X_STATUS_INSUFFICIENT_RESOURCES ((X_STATUS)0xC000009AL) #define X_STATUS_MEMORY_NOT_ALLOCATED ((X_STATUS)0xC00000A0L) #define X_STATUS_FILE_IS_A_DIRECTORY ((X_STATUS)0xC00000BAL)