diff options
Diffstat (limited to 'src')
65 files changed, 490 insertions, 261 deletions
diff --git a/src/common/scratch_buffer.h b/src/common/scratch_buffer.h index 26d4e76dc..a69a5a7af 100644 --- a/src/common/scratch_buffer.h +++ b/src/common/scratch_buffer.h | |||
| @@ -23,7 +23,10 @@ public: | |||
| 23 | buffer{Common::make_unique_for_overwrite<T[]>(initial_capacity)} {} | 23 | buffer{Common::make_unique_for_overwrite<T[]>(initial_capacity)} {} |
| 24 | 24 | ||
| 25 | ~ScratchBuffer() = default; | 25 | ~ScratchBuffer() = default; |
| 26 | ScratchBuffer(const ScratchBuffer&) = delete; | ||
| 27 | ScratchBuffer& operator=(const ScratchBuffer&) = delete; | ||
| 26 | ScratchBuffer(ScratchBuffer&&) = default; | 28 | ScratchBuffer(ScratchBuffer&&) = default; |
| 29 | ScratchBuffer& operator=(ScratchBuffer&&) = default; | ||
| 27 | 30 | ||
| 28 | /// This will only grow the buffer's capacity if size is greater than the current capacity. | 31 | /// This will only grow the buffer's capacity if size is greater than the current capacity. |
| 29 | /// The previously held data will remain intact. | 32 | /// The previously held data will remain intact. |
| @@ -87,6 +90,12 @@ public: | |||
| 87 | return buffer_capacity; | 90 | return buffer_capacity; |
| 88 | } | 91 | } |
| 89 | 92 | ||
| 93 | void swap(ScratchBuffer& other) noexcept { | ||
| 94 | std::swap(last_requested_size, other.last_requested_size); | ||
| 95 | std::swap(buffer_capacity, other.buffer_capacity); | ||
| 96 | std::swap(buffer, other.buffer); | ||
| 97 | } | ||
| 98 | |||
| 90 | private: | 99 | private: |
| 91 | size_t last_requested_size{}; | 100 | size_t last_requested_size{}; |
| 92 | size_t buffer_capacity{}; | 101 | size_t buffer_capacity{}; |
diff --git a/src/common/settings.cpp b/src/common/settings.cpp index db1774c71..ba617aea1 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp | |||
| @@ -232,6 +232,7 @@ void RestoreGlobalState(bool is_powered_on) { | |||
| 232 | values.bg_red.SetGlobal(true); | 232 | values.bg_red.SetGlobal(true); |
| 233 | values.bg_green.SetGlobal(true); | 233 | values.bg_green.SetGlobal(true); |
| 234 | values.bg_blue.SetGlobal(true); | 234 | values.bg_blue.SetGlobal(true); |
| 235 | values.enable_compute_pipelines.SetGlobal(true); | ||
| 235 | 236 | ||
| 236 | // System | 237 | // System |
| 237 | values.language_index.SetGlobal(true); | 238 | values.language_index.SetGlobal(true); |
diff --git a/src/common/settings.h b/src/common/settings.h index f4eb4e3cd..36ffcd693 100644 --- a/src/common/settings.h +++ b/src/common/settings.h | |||
| @@ -472,6 +472,7 @@ struct Values { | |||
| 472 | SwitchableSetting<bool> use_fast_gpu_time{true, "use_fast_gpu_time"}; | 472 | SwitchableSetting<bool> use_fast_gpu_time{true, "use_fast_gpu_time"}; |
| 473 | SwitchableSetting<bool> use_vulkan_driver_pipeline_cache{true, | 473 | SwitchableSetting<bool> use_vulkan_driver_pipeline_cache{true, |
| 474 | "use_vulkan_driver_pipeline_cache"}; | 474 | "use_vulkan_driver_pipeline_cache"}; |
| 475 | SwitchableSetting<bool> enable_compute_pipelines{false, "enable_compute_pipelines"}; | ||
| 475 | 476 | ||
| 476 | SwitchableSetting<u8> bg_red{0, "bg_red"}; | 477 | SwitchableSetting<u8> bg_red{0, "bg_red"}; |
| 477 | SwitchableSetting<u8> bg_green{0, "bg_green"}; | 478 | SwitchableSetting<u8> bg_green{0, "bg_green"}; |
| @@ -535,6 +536,8 @@ struct Values { | |||
| 535 | Setting<bool> enable_ir_sensor{false, "enable_ir_sensor"}; | 536 | Setting<bool> enable_ir_sensor{false, "enable_ir_sensor"}; |
| 536 | Setting<std::string> ir_sensor_device{"auto", "ir_sensor_device"}; | 537 | Setting<std::string> ir_sensor_device{"auto", "ir_sensor_device"}; |
| 537 | 538 | ||
| 539 | Setting<bool> random_amiibo_id{false, "random_amiibo_id"}; | ||
| 540 | |||
| 538 | // Data Storage | 541 | // Data Storage |
| 539 | Setting<bool> use_virtual_sd{true, "use_virtual_sd"}; | 542 | Setting<bool> use_virtual_sd{true, "use_virtual_sd"}; |
| 540 | Setting<bool> gamecard_inserted{false, "gamecard_inserted"}; | 543 | Setting<bool> gamecard_inserted{false, "gamecard_inserted"}; |
diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index 769065b6f..70b36f170 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp | |||
| @@ -82,9 +82,9 @@ std::string GetFutureSaveDataPath(SaveDataSpaceId space_id, SaveDataType type, u | |||
| 82 | // Only detect account/device saves from the future location. | 82 | // Only detect account/device saves from the future location. |
| 83 | switch (type) { | 83 | switch (type) { |
| 84 | case SaveDataType::SaveData: | 84 | case SaveDataType::SaveData: |
| 85 | return fmt::format("{}/account/{}/{:016X}/1", space_id_path, uuid.RawString(), title_id); | 85 | return fmt::format("{}/account/{}/{:016X}/0", space_id_path, uuid.RawString(), title_id); |
| 86 | case SaveDataType::DeviceSaveData: | 86 | case SaveDataType::DeviceSaveData: |
| 87 | return fmt::format("{}/device/{:016X}/1", space_id_path, title_id); | 87 | return fmt::format("{}/device/{:016X}/0", space_id_path, title_id); |
| 88 | default: | 88 | default: |
| 89 | return ""; | 89 | return ""; |
| 90 | } | 90 | } |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index e59de844c..a2375508a 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include "core/file_sys/savedata_factory.h" | 13 | #include "core/file_sys/savedata_factory.h" |
| 14 | #include "core/hle/kernel/k_event.h" | 14 | #include "core/hle/kernel/k_event.h" |
| 15 | #include "core/hle/kernel/k_transfer_memory.h" | 15 | #include "core/hle/kernel/k_transfer_memory.h" |
| 16 | #include "core/hle/result.h" | ||
| 16 | #include "core/hle/service/acc/profile_manager.h" | 17 | #include "core/hle/service/acc/profile_manager.h" |
| 17 | #include "core/hle/service/am/am.h" | 18 | #include "core/hle/service/am/am.h" |
| 18 | #include "core/hle/service/am/applet_ae.h" | 19 | #include "core/hle/service/am/applet_ae.h" |
| @@ -1335,7 +1336,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_) | |||
| 1335 | {24, nullptr, "GetLaunchStorageInfoForDebug"}, | 1336 | {24, nullptr, "GetLaunchStorageInfoForDebug"}, |
| 1336 | {25, &IApplicationFunctions::ExtendSaveData, "ExtendSaveData"}, | 1337 | {25, &IApplicationFunctions::ExtendSaveData, "ExtendSaveData"}, |
| 1337 | {26, &IApplicationFunctions::GetSaveDataSize, "GetSaveDataSize"}, | 1338 | {26, &IApplicationFunctions::GetSaveDataSize, "GetSaveDataSize"}, |
| 1338 | {27, nullptr, "CreateCacheStorage"}, | 1339 | {27, &IApplicationFunctions::CreateCacheStorage, "CreateCacheStorage"}, |
| 1339 | {28, nullptr, "GetSaveDataSizeMax"}, | 1340 | {28, nullptr, "GetSaveDataSizeMax"}, |
| 1340 | {29, nullptr, "GetCacheStorageMax"}, | 1341 | {29, nullptr, "GetCacheStorageMax"}, |
| 1341 | {30, &IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed, "BeginBlockingHomeButtonShortAndLongPressed"}, | 1342 | {30, &IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed, "BeginBlockingHomeButtonShortAndLongPressed"}, |
| @@ -1738,6 +1739,36 @@ void IApplicationFunctions::GetSaveDataSize(HLERequestContext& ctx) { | |||
| 1738 | rb.Push(size.journal); | 1739 | rb.Push(size.journal); |
| 1739 | } | 1740 | } |
| 1740 | 1741 | ||
| 1742 | void IApplicationFunctions::CreateCacheStorage(HLERequestContext& ctx) { | ||
| 1743 | struct InputParameters { | ||
| 1744 | u16 index; | ||
| 1745 | s64 size; | ||
| 1746 | s64 journal_size; | ||
| 1747 | }; | ||
| 1748 | static_assert(sizeof(InputParameters) == 24); | ||
| 1749 | |||
| 1750 | struct OutputParameters { | ||
| 1751 | u32 storage_target; | ||
| 1752 | u64 required_size; | ||
| 1753 | }; | ||
| 1754 | static_assert(sizeof(OutputParameters) == 16); | ||
| 1755 | |||
| 1756 | IPC::RequestParser rp{ctx}; | ||
| 1757 | const auto params = rp.PopRaw<InputParameters>(); | ||
| 1758 | |||
| 1759 | LOG_WARNING(Service_AM, "(STUBBED) called with index={}, size={:#x}, journal_size={:#x}", | ||
| 1760 | params.index, params.size, params.journal_size); | ||
| 1761 | |||
| 1762 | const OutputParameters resp{ | ||
| 1763 | .storage_target = 1, | ||
| 1764 | .required_size = 0, | ||
| 1765 | }; | ||
| 1766 | |||
| 1767 | IPC::ResponseBuilder rb{ctx, 6}; | ||
| 1768 | rb.Push(ResultSuccess); | ||
| 1769 | rb.PushRaw(resp); | ||
| 1770 | } | ||
| 1771 | |||
| 1741 | void IApplicationFunctions::QueryApplicationPlayStatistics(HLERequestContext& ctx) { | 1772 | void IApplicationFunctions::QueryApplicationPlayStatistics(HLERequestContext& ctx) { |
| 1742 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 1773 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 1743 | 1774 | ||
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 0dbc6485e..d4fd163da 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h | |||
| @@ -333,6 +333,7 @@ private: | |||
| 333 | void GetPseudoDeviceId(HLERequestContext& ctx); | 333 | void GetPseudoDeviceId(HLERequestContext& ctx); |
| 334 | void ExtendSaveData(HLERequestContext& ctx); | 334 | void ExtendSaveData(HLERequestContext& ctx); |
| 335 | void GetSaveDataSize(HLERequestContext& ctx); | 335 | void GetSaveDataSize(HLERequestContext& ctx); |
| 336 | void CreateCacheStorage(HLERequestContext& ctx); | ||
| 336 | void BeginBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx); | 337 | void BeginBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx); |
| 337 | void EndBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx); | 338 | void EndBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx); |
| 338 | void BeginBlockingHomeButton(HLERequestContext& ctx); | 339 | void BeginBlockingHomeButton(HLERequestContext& ctx); |
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 9e559d97e..f73a864c3 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp | |||
| @@ -24,8 +24,10 @@ | |||
| 24 | #include "core/file_sys/savedata_factory.h" | 24 | #include "core/file_sys/savedata_factory.h" |
| 25 | #include "core/file_sys/system_archive/system_archive.h" | 25 | #include "core/file_sys/system_archive/system_archive.h" |
| 26 | #include "core/file_sys/vfs.h" | 26 | #include "core/file_sys/vfs.h" |
| 27 | #include "core/hle/result.h" | ||
| 27 | #include "core/hle/service/filesystem/filesystem.h" | 28 | #include "core/hle/service/filesystem/filesystem.h" |
| 28 | #include "core/hle/service/filesystem/fsp_srv.h" | 29 | #include "core/hle/service/filesystem/fsp_srv.h" |
| 30 | #include "core/hle/service/hle_ipc.h" | ||
| 29 | #include "core/hle/service/ipc_helpers.h" | 31 | #include "core/hle/service/ipc_helpers.h" |
| 30 | #include "core/reporter.h" | 32 | #include "core/reporter.h" |
| 31 | 33 | ||
| @@ -552,9 +554,9 @@ public: | |||
| 552 | // Write the data to memory | 554 | // Write the data to memory |
| 553 | ctx.WriteBuffer(begin, range_size); | 555 | ctx.WriteBuffer(begin, range_size); |
| 554 | 556 | ||
| 555 | IPC::ResponseBuilder rb{ctx, 3}; | 557 | IPC::ResponseBuilder rb{ctx, 4}; |
| 556 | rb.Push(ResultSuccess); | 558 | rb.Push(ResultSuccess); |
| 557 | rb.Push<u32>(static_cast<u32>(actual_entries)); | 559 | rb.Push<u64>(actual_entries); |
| 558 | } | 560 | } |
| 559 | 561 | ||
| 560 | private: | 562 | private: |
| @@ -712,7 +714,7 @@ FSP_SRV::FSP_SRV(Core::System& system_) | |||
| 712 | {59, nullptr, "WriteSaveDataFileSystemExtraData"}, | 714 | {59, nullptr, "WriteSaveDataFileSystemExtraData"}, |
| 713 | {60, nullptr, "OpenSaveDataInfoReader"}, | 715 | {60, nullptr, "OpenSaveDataInfoReader"}, |
| 714 | {61, &FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId, "OpenSaveDataInfoReaderBySaveDataSpaceId"}, | 716 | {61, &FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId, "OpenSaveDataInfoReaderBySaveDataSpaceId"}, |
| 715 | {62, nullptr, "OpenCacheStorageList"}, | 717 | {62, &FSP_SRV::OpenSaveDataInfoReaderOnlyCacheStorage, "OpenSaveDataInfoReaderOnlyCacheStorage"}, |
| 716 | {64, nullptr, "OpenSaveDataInternalStorageFileSystem"}, | 718 | {64, nullptr, "OpenSaveDataInternalStorageFileSystem"}, |
| 717 | {65, nullptr, "UpdateSaveDataMacForDebug"}, | 719 | {65, nullptr, "UpdateSaveDataMacForDebug"}, |
| 718 | {66, nullptr, "WriteSaveDataFileSystemExtraData2"}, | 720 | {66, nullptr, "WriteSaveDataFileSystemExtraData2"}, |
| @@ -921,6 +923,15 @@ void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(HLERequestContext& ctx) { | |||
| 921 | std::make_shared<ISaveDataInfoReader>(system, space, fsc)); | 923 | std::make_shared<ISaveDataInfoReader>(system, space, fsc)); |
| 922 | } | 924 | } |
| 923 | 925 | ||
| 926 | void FSP_SRV::OpenSaveDataInfoReaderOnlyCacheStorage(HLERequestContext& ctx) { | ||
| 927 | LOG_WARNING(Service_FS, "(STUBBED) called"); | ||
| 928 | |||
| 929 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 930 | rb.Push(ResultSuccess); | ||
| 931 | rb.PushIpcInterface<ISaveDataInfoReader>(system, FileSys::SaveDataSpaceId::TemporaryStorage, | ||
| 932 | fsc); | ||
| 933 | } | ||
| 934 | |||
| 924 | void FSP_SRV::WriteSaveDataFileSystemExtraDataBySaveDataAttribute(HLERequestContext& ctx) { | 935 | void FSP_SRV::WriteSaveDataFileSystemExtraDataBySaveDataAttribute(HLERequestContext& ctx) { |
| 925 | LOG_WARNING(Service_FS, "(STUBBED) called."); | 936 | LOG_WARNING(Service_FS, "(STUBBED) called."); |
| 926 | 937 | ||
diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h index 49f17c7c3..4f3c2f6de 100644 --- a/src/core/hle/service/filesystem/fsp_srv.h +++ b/src/core/hle/service/filesystem/fsp_srv.h | |||
| @@ -42,6 +42,7 @@ private: | |||
| 42 | void OpenSaveDataFileSystem(HLERequestContext& ctx); | 42 | void OpenSaveDataFileSystem(HLERequestContext& ctx); |
| 43 | void OpenReadOnlySaveDataFileSystem(HLERequestContext& ctx); | 43 | void OpenReadOnlySaveDataFileSystem(HLERequestContext& ctx); |
| 44 | void OpenSaveDataInfoReaderBySaveDataSpaceId(HLERequestContext& ctx); | 44 | void OpenSaveDataInfoReaderBySaveDataSpaceId(HLERequestContext& ctx); |
| 45 | void OpenSaveDataInfoReaderOnlyCacheStorage(HLERequestContext& ctx); | ||
| 45 | void WriteSaveDataFileSystemExtraDataBySaveDataAttribute(HLERequestContext& ctx); | 46 | void WriteSaveDataFileSystemExtraDataBySaveDataAttribute(HLERequestContext& ctx); |
| 46 | void ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute(HLERequestContext& ctx); | 47 | void ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute(HLERequestContext& ctx); |
| 47 | void OpenDataStorageByCurrentProcess(HLERequestContext& ctx); | 48 | void OpenDataStorageByCurrentProcess(HLERequestContext& ctx); |
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index ef4aec4ea..28818c813 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -979,8 +979,8 @@ void Controller_NPad::VibrateController( | |||
| 979 | } | 979 | } |
| 980 | 980 | ||
| 981 | void Controller_NPad::VibrateControllers( | 981 | void Controller_NPad::VibrateControllers( |
| 982 | const std::vector<Core::HID::VibrationDeviceHandle>& vibration_device_handles, | 982 | std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles, |
| 983 | const std::vector<Core::HID::VibrationValue>& vibration_values) { | 983 | std::span<const Core::HID::VibrationValue> vibration_values) { |
| 984 | if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) { | 984 | if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) { |
| 985 | return; | 985 | return; |
| 986 | } | 986 | } |
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 9cfe298f1..776411261 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -112,8 +112,8 @@ public: | |||
| 112 | const Core::HID::VibrationValue& vibration_value); | 112 | const Core::HID::VibrationValue& vibration_value); |
| 113 | 113 | ||
| 114 | void VibrateControllers( | 114 | void VibrateControllers( |
| 115 | const std::vector<Core::HID::VibrationDeviceHandle>& vibration_device_handles, | 115 | std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles, |
| 116 | const std::vector<Core::HID::VibrationValue>& vibration_values); | 116 | std::span<const Core::HID::VibrationValue> vibration_values); |
| 117 | 117 | ||
| 118 | Core::HID::VibrationValue GetLastVibration( | 118 | Core::HID::VibrationValue GetLastVibration( |
| 119 | const Core::HID::VibrationDeviceHandle& vibration_device_handle) const; | 119 | const Core::HID::VibrationDeviceHandle& vibration_device_handle) const; |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 87e7b864a..2bf1d8a27 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -1601,16 +1601,16 @@ void Hid::SendVibrationValues(HLERequestContext& ctx) { | |||
| 1601 | IPC::RequestParser rp{ctx}; | 1601 | IPC::RequestParser rp{ctx}; |
| 1602 | const auto applet_resource_user_id{rp.Pop<u64>()}; | 1602 | const auto applet_resource_user_id{rp.Pop<u64>()}; |
| 1603 | 1603 | ||
| 1604 | const auto handles = ctx.ReadBuffer(0); | 1604 | const auto handle_data = ctx.ReadBuffer(0); |
| 1605 | const auto vibrations = ctx.ReadBuffer(1); | 1605 | const auto handle_count = ctx.GetReadBufferNumElements<Core::HID::VibrationDeviceHandle>(0); |
| 1606 | 1606 | const auto vibration_data = ctx.ReadBuffer(1); | |
| 1607 | std::vector<Core::HID::VibrationDeviceHandle> vibration_device_handles( | 1607 | const auto vibration_count = ctx.GetReadBufferNumElements<Core::HID::VibrationValue>(1); |
| 1608 | handles.size() / sizeof(Core::HID::VibrationDeviceHandle)); | 1608 | |
| 1609 | std::vector<Core::HID::VibrationValue> vibration_values(vibrations.size() / | 1609 | auto vibration_device_handles = |
| 1610 | sizeof(Core::HID::VibrationValue)); | 1610 | std::span(reinterpret_cast<const Core::HID::VibrationDeviceHandle*>(handle_data.data()), |
| 1611 | 1611 | handle_count); | |
| 1612 | std::memcpy(vibration_device_handles.data(), handles.data(), handles.size()); | 1612 | auto vibration_values = std::span( |
| 1613 | std::memcpy(vibration_values.data(), vibrations.data(), vibrations.size()); | 1613 | reinterpret_cast<const Core::HID::VibrationValue*>(vibration_data.data()), vibration_count); |
| 1614 | 1614 | ||
| 1615 | applet_resource->GetController<Controller_NPad>(HidController::NPad) | 1615 | applet_resource->GetController<Controller_NPad>(HidController::NPad) |
| 1616 | .VibrateControllers(vibration_device_handles, vibration_values); | 1616 | .VibrateControllers(vibration_device_handles, vibration_values); |
diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index e5de65ce0..322bde2ed 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp | |||
| @@ -48,9 +48,6 @@ NfcDevice::NfcDevice(Core::HID::NpadIdType npad_id_, Core::System& system_, | |||
| 48 | }; | 48 | }; |
| 49 | is_controller_set = true; | 49 | is_controller_set = true; |
| 50 | callback_key = npad_device->SetCallback(engine_callback); | 50 | callback_key = npad_device->SetCallback(engine_callback); |
| 51 | |||
| 52 | auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()}; | ||
| 53 | current_posix_time = standard_steady_clock.GetCurrentTimePoint(system).time_point; | ||
| 54 | } | 51 | } |
| 55 | 52 | ||
| 56 | NfcDevice::~NfcDevice() { | 53 | NfcDevice::~NfcDevice() { |
| @@ -227,11 +224,21 @@ Result NfcDevice::GetTagInfo(NFP::TagInfo& tag_info, bool is_mifare) const { | |||
| 227 | return ResultWrongDeviceState; | 224 | return ResultWrongDeviceState; |
| 228 | } | 225 | } |
| 229 | 226 | ||
| 227 | UniqueSerialNumber uuid = encrypted_tag_data.uuid.uid; | ||
| 228 | |||
| 229 | // Generate random UUID to bypass amiibo load limits | ||
| 230 | if (Settings::values.random_amiibo_id) { | ||
| 231 | Common::TinyMT rng{}; | ||
| 232 | rng.Initialize(static_cast<u32>(GetCurrentPosixTime())); | ||
| 233 | rng.GenerateRandomBytes(uuid.data(), sizeof(UniqueSerialNumber)); | ||
| 234 | uuid[3] = 0x88 ^ uuid[0] ^ uuid[1] ^ uuid[2]; | ||
| 235 | } | ||
| 236 | |||
| 230 | if (is_mifare) { | 237 | if (is_mifare) { |
| 231 | tag_info = { | 238 | tag_info = { |
| 232 | .uuid = encrypted_tag_data.uuid.uid, | 239 | .uuid = uuid, |
| 233 | .uuid_extension = {}, | 240 | .uuid_extension = {}, |
| 234 | .uuid_length = static_cast<u8>(encrypted_tag_data.uuid.uid.size()), | 241 | .uuid_length = static_cast<u8>(uuid.size()), |
| 235 | .protocol = NfcProtocol::TypeA, | 242 | .protocol = NfcProtocol::TypeA, |
| 236 | .tag_type = TagType::Type4, | 243 | .tag_type = TagType::Type4, |
| 237 | }; | 244 | }; |
| @@ -240,9 +247,9 @@ Result NfcDevice::GetTagInfo(NFP::TagInfo& tag_info, bool is_mifare) const { | |||
| 240 | 247 | ||
| 241 | // Protocol and tag type may change here | 248 | // Protocol and tag type may change here |
| 242 | tag_info = { | 249 | tag_info = { |
| 243 | .uuid = encrypted_tag_data.uuid.uid, | 250 | .uuid = uuid, |
| 244 | .uuid_extension = {}, | 251 | .uuid_extension = {}, |
| 245 | .uuid_length = static_cast<u8>(encrypted_tag_data.uuid.uid.size()), | 252 | .uuid_length = static_cast<u8>(uuid.size()), |
| 246 | .protocol = NfcProtocol::TypeA, | 253 | .protocol = NfcProtocol::TypeA, |
| 247 | .tag_type = TagType::Type2, | 254 | .tag_type = TagType::Type2, |
| 248 | }; | 255 | }; |
| @@ -406,7 +413,7 @@ Result NfcDevice::Flush() { | |||
| 406 | 413 | ||
| 407 | auto& settings = tag_data.settings; | 414 | auto& settings = tag_data.settings; |
| 408 | 415 | ||
| 409 | const auto& current_date = GetAmiiboDate(current_posix_time); | 416 | const auto& current_date = GetAmiiboDate(GetCurrentPosixTime()); |
| 410 | if (settings.write_date.raw_date != current_date.raw_date) { | 417 | if (settings.write_date.raw_date != current_date.raw_date) { |
| 411 | settings.write_date = current_date; | 418 | settings.write_date = current_date; |
| 412 | UpdateSettingsCrc(); | 419 | UpdateSettingsCrc(); |
| @@ -525,6 +532,7 @@ Result NfcDevice::GetModelInfo(NFP::ModelInfo& model_info) const { | |||
| 525 | } | 532 | } |
| 526 | 533 | ||
| 527 | const auto& model_info_data = encrypted_tag_data.user_memory.model_info; | 534 | const auto& model_info_data = encrypted_tag_data.user_memory.model_info; |
| 535 | |||
| 528 | model_info = { | 536 | model_info = { |
| 529 | .character_id = model_info_data.character_id, | 537 | .character_id = model_info_data.character_id, |
| 530 | .character_variant = model_info_data.character_variant, | 538 | .character_variant = model_info_data.character_variant, |
| @@ -669,6 +677,7 @@ Result NfcDevice::DeleteRegisterInfo() { | |||
| 669 | } | 677 | } |
| 670 | 678 | ||
| 671 | Common::TinyMT rng{}; | 679 | Common::TinyMT rng{}; |
| 680 | rng.Initialize(static_cast<u32>(GetCurrentPosixTime())); | ||
| 672 | rng.GenerateRandomBytes(&tag_data.owner_mii, sizeof(tag_data.owner_mii)); | 681 | rng.GenerateRandomBytes(&tag_data.owner_mii, sizeof(tag_data.owner_mii)); |
| 673 | rng.GenerateRandomBytes(&tag_data.settings.amiibo_name, sizeof(tag_data.settings.amiibo_name)); | 682 | rng.GenerateRandomBytes(&tag_data.settings.amiibo_name, sizeof(tag_data.settings.amiibo_name)); |
| 674 | rng.GenerateRandomBytes(&tag_data.unknown, sizeof(u8)); | 683 | rng.GenerateRandomBytes(&tag_data.unknown, sizeof(u8)); |
| @@ -701,7 +710,7 @@ Result NfcDevice::SetRegisterInfoPrivate(const NFP::RegisterInfoPrivate& registe | |||
| 701 | auto& settings = tag_data.settings; | 710 | auto& settings = tag_data.settings; |
| 702 | 711 | ||
| 703 | if (tag_data.settings.settings.amiibo_initialized == 0) { | 712 | if (tag_data.settings.settings.amiibo_initialized == 0) { |
| 704 | settings.init_date = GetAmiiboDate(current_posix_time); | 713 | settings.init_date = GetAmiiboDate(GetCurrentPosixTime()); |
| 705 | settings.write_date.raw_date = 0; | 714 | settings.write_date.raw_date = 0; |
| 706 | } | 715 | } |
| 707 | 716 | ||
| @@ -868,6 +877,7 @@ Result NfcDevice::SetApplicationArea(std::span<const u8> data) { | |||
| 868 | } | 877 | } |
| 869 | 878 | ||
| 870 | Common::TinyMT rng{}; | 879 | Common::TinyMT rng{}; |
| 880 | rng.Initialize(static_cast<u32>(GetCurrentPosixTime())); | ||
| 871 | std::memcpy(tag_data.application_area.data(), data.data(), data.size()); | 881 | std::memcpy(tag_data.application_area.data(), data.data(), data.size()); |
| 872 | // Fill remaining data with random numbers | 882 | // Fill remaining data with random numbers |
| 873 | rng.GenerateRandomBytes(tag_data.application_area.data() + data.size(), | 883 | rng.GenerateRandomBytes(tag_data.application_area.data() + data.size(), |
| @@ -924,6 +934,7 @@ Result NfcDevice::RecreateApplicationArea(u32 access_id, std::span<const u8> dat | |||
| 924 | } | 934 | } |
| 925 | 935 | ||
| 926 | Common::TinyMT rng{}; | 936 | Common::TinyMT rng{}; |
| 937 | rng.Initialize(static_cast<u32>(GetCurrentPosixTime())); | ||
| 927 | std::memcpy(tag_data.application_area.data(), data.data(), data.size()); | 938 | std::memcpy(tag_data.application_area.data(), data.data(), data.size()); |
| 928 | // Fill remaining data with random numbers | 939 | // Fill remaining data with random numbers |
| 929 | rng.GenerateRandomBytes(tag_data.application_area.data() + data.size(), | 940 | rng.GenerateRandomBytes(tag_data.application_area.data() + data.size(), |
| @@ -973,6 +984,7 @@ Result NfcDevice::DeleteApplicationArea() { | |||
| 973 | } | 984 | } |
| 974 | 985 | ||
| 975 | Common::TinyMT rng{}; | 986 | Common::TinyMT rng{}; |
| 987 | rng.Initialize(static_cast<u32>(GetCurrentPosixTime())); | ||
| 976 | rng.GenerateRandomBytes(tag_data.application_area.data(), sizeof(NFP::ApplicationArea)); | 988 | rng.GenerateRandomBytes(tag_data.application_area.data(), sizeof(NFP::ApplicationArea)); |
| 977 | rng.GenerateRandomBytes(&tag_data.application_id, sizeof(u64)); | 989 | rng.GenerateRandomBytes(&tag_data.application_id, sizeof(u64)); |
| 978 | rng.GenerateRandomBytes(&tag_data.application_area_id, sizeof(u32)); | 990 | rng.GenerateRandomBytes(&tag_data.application_area_id, sizeof(u32)); |
| @@ -1189,6 +1201,11 @@ NFP::AmiiboDate NfcDevice::GetAmiiboDate(s64 posix_time) const { | |||
| 1189 | return amiibo_date; | 1201 | return amiibo_date; |
| 1190 | } | 1202 | } |
| 1191 | 1203 | ||
| 1204 | u64 NfcDevice::GetCurrentPosixTime() const { | ||
| 1205 | auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()}; | ||
| 1206 | return standard_steady_clock.GetCurrentTimePoint(system).time_point; | ||
| 1207 | } | ||
| 1208 | |||
| 1192 | u64 NfcDevice::RemoveVersionByte(u64 application_id) const { | 1209 | u64 NfcDevice::RemoveVersionByte(u64 application_id) const { |
| 1193 | return application_id & ~(0xfULL << NFP::application_id_version_offset); | 1210 | return application_id & ~(0xfULL << NFP::application_id_version_offset); |
| 1194 | } | 1211 | } |
diff --git a/src/core/hle/service/nfc/common/device.h b/src/core/hle/service/nfc/common/device.h index 654eda98e..98e1945c1 100644 --- a/src/core/hle/service/nfc/common/device.h +++ b/src/core/hle/service/nfc/common/device.h | |||
| @@ -105,6 +105,7 @@ private: | |||
| 105 | NFP::AmiiboName GetAmiiboName(const NFP::AmiiboSettings& settings) const; | 105 | NFP::AmiiboName GetAmiiboName(const NFP::AmiiboSettings& settings) const; |
| 106 | void SetAmiiboName(NFP::AmiiboSettings& settings, const NFP::AmiiboName& amiibo_name); | 106 | void SetAmiiboName(NFP::AmiiboSettings& settings, const NFP::AmiiboName& amiibo_name); |
| 107 | NFP::AmiiboDate GetAmiiboDate(s64 posix_time) const; | 107 | NFP::AmiiboDate GetAmiiboDate(s64 posix_time) const; |
| 108 | u64 GetCurrentPosixTime() const; | ||
| 108 | u64 RemoveVersionByte(u64 application_id) const; | 109 | u64 RemoveVersionByte(u64 application_id) const; |
| 109 | void UpdateSettingsCrc(); | 110 | void UpdateSettingsCrc(); |
| 110 | void UpdateRegisterInfoCrc(); | 111 | void UpdateRegisterInfoCrc(); |
| @@ -127,7 +128,6 @@ private: | |||
| 127 | bool is_data_moddified{}; | 128 | bool is_data_moddified{}; |
| 128 | bool is_app_area_open{}; | 129 | bool is_app_area_open{}; |
| 129 | bool is_plain_amiibo{}; | 130 | bool is_plain_amiibo{}; |
| 130 | s64 current_posix_time{}; | ||
| 131 | NFP::MountTarget mount_target{NFP::MountTarget::None}; | 131 | NFP::MountTarget mount_target{NFP::MountTarget::None}; |
| 132 | 132 | ||
| 133 | NFP::NTAG215File tag_data{}; | 133 | NFP::NTAG215File tag_data{}; |
diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp index cd0a13094..b16f9933f 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp | |||
| @@ -793,6 +793,7 @@ Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot, | |||
| 793 | std::scoped_lock lock{core->mutex}; | 793 | std::scoped_lock lock{core->mutex}; |
| 794 | 794 | ||
| 795 | slots[slot] = {}; | 795 | slots[slot] = {}; |
| 796 | slots[slot].fence = Fence::NoFence(); | ||
| 796 | slots[slot].graphic_buffer = buffer; | 797 | slots[slot].graphic_buffer = buffer; |
| 797 | slots[slot].frame_number = 0; | 798 | slots[slot].frame_number = 0; |
| 798 | 799 | ||
| @@ -854,7 +855,7 @@ void BufferQueueProducer::Transact(HLERequestContext& ctx, TransactionId code, u | |||
| 854 | status = DequeueBuffer(&slot, &fence, is_async, width, height, pixel_format, usage); | 855 | status = DequeueBuffer(&slot, &fence, is_async, width, height, pixel_format, usage); |
| 855 | 856 | ||
| 856 | parcel_out.Write(slot); | 857 | parcel_out.Write(slot); |
| 857 | parcel_out.WriteObject(&fence); | 858 | parcel_out.WriteFlattenedObject(&fence); |
| 858 | break; | 859 | break; |
| 859 | } | 860 | } |
| 860 | case TransactionId::RequestBuffer: { | 861 | case TransactionId::RequestBuffer: { |
| @@ -864,7 +865,7 @@ void BufferQueueProducer::Transact(HLERequestContext& ctx, TransactionId code, u | |||
| 864 | 865 | ||
| 865 | status = RequestBuffer(slot, &buf); | 866 | status = RequestBuffer(slot, &buf); |
| 866 | 867 | ||
| 867 | parcel_out.WriteObject(buf); | 868 | parcel_out.WriteFlattenedObject(buf); |
| 868 | break; | 869 | break; |
| 869 | } | 870 | } |
| 870 | case TransactionId::QueueBuffer: { | 871 | case TransactionId::QueueBuffer: { |
diff --git a/src/core/hle/service/nvnflinger/parcel.h b/src/core/hle/service/nvnflinger/parcel.h index d1b6201e0..fb56d75d7 100644 --- a/src/core/hle/service/nvnflinger/parcel.h +++ b/src/core/hle/service/nvnflinger/parcel.h | |||
| @@ -117,61 +117,67 @@ private: | |||
| 117 | 117 | ||
| 118 | class OutputParcel final { | 118 | class OutputParcel final { |
| 119 | public: | 119 | public: |
| 120 | static constexpr std::size_t DefaultBufferSize = 0x40; | 120 | OutputParcel() = default; |
| 121 | |||
| 122 | OutputParcel() : buffer(DefaultBufferSize) {} | ||
| 123 | |||
| 124 | template <typename T> | ||
| 125 | explicit OutputParcel(const T& out_data) : buffer(DefaultBufferSize) { | ||
| 126 | Write(out_data); | ||
| 127 | } | ||
| 128 | 121 | ||
| 129 | template <typename T> | 122 | template <typename T> |
| 130 | void Write(const T& val) { | 123 | void Write(const T& val) { |
| 131 | static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable."); | 124 | this->WriteImpl(val, m_data_buffer); |
| 132 | |||
| 133 | if (buffer.size() < write_index + sizeof(T)) { | ||
| 134 | buffer.resize(buffer.size() + sizeof(T) + DefaultBufferSize); | ||
| 135 | } | ||
| 136 | |||
| 137 | std::memcpy(buffer.data() + write_index, &val, sizeof(T)); | ||
| 138 | write_index += sizeof(T); | ||
| 139 | write_index = Common::AlignUp(write_index, 4); | ||
| 140 | } | 125 | } |
| 141 | 126 | ||
| 142 | template <typename T> | 127 | template <typename T> |
| 143 | void WriteObject(const T* ptr) { | 128 | void WriteFlattenedObject(const T* ptr) { |
| 144 | static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable."); | ||
| 145 | |||
| 146 | if (!ptr) { | 129 | if (!ptr) { |
| 147 | Write<u32>(0); | 130 | this->Write<u32>(0); |
| 148 | return; | 131 | return; |
| 149 | } | 132 | } |
| 150 | 133 | ||
| 151 | Write<u32>(1); | 134 | this->Write<u32>(1); |
| 152 | Write<s64>(sizeof(T)); | 135 | this->Write<s64>(sizeof(T)); |
| 153 | Write(*ptr); | 136 | this->Write(*ptr); |
| 154 | } | 137 | } |
| 155 | 138 | ||
| 156 | template <typename T> | 139 | template <typename T> |
| 157 | void WriteObject(const std::shared_ptr<T> ptr) { | 140 | void WriteFlattenedObject(const std::shared_ptr<T> ptr) { |
| 158 | WriteObject(ptr.get()); | 141 | this->WriteFlattenedObject(ptr.get()); |
| 142 | } | ||
| 143 | |||
| 144 | template <typename T> | ||
| 145 | void WriteInterface(const T& val) { | ||
| 146 | this->WriteImpl(val, m_data_buffer); | ||
| 147 | this->WriteImpl(0U, m_object_buffer); | ||
| 159 | } | 148 | } |
| 160 | 149 | ||
| 161 | std::vector<u8> Serialize() const { | 150 | std::vector<u8> Serialize() const { |
| 151 | std::vector<u8> output_buffer(sizeof(ParcelHeader) + m_data_buffer.size() + | ||
| 152 | m_object_buffer.size()); | ||
| 153 | |||
| 162 | ParcelHeader header{}; | 154 | ParcelHeader header{}; |
| 163 | header.data_size = static_cast<u32>(write_index - sizeof(ParcelHeader)); | 155 | header.data_size = static_cast<u32>(m_data_buffer.size()); |
| 164 | header.data_offset = sizeof(ParcelHeader); | 156 | header.data_offset = sizeof(ParcelHeader); |
| 165 | header.objects_size = 4; | 157 | header.objects_size = static_cast<u32>(m_object_buffer.size()); |
| 166 | header.objects_offset = static_cast<u32>(sizeof(ParcelHeader) + header.data_size); | 158 | header.objects_offset = header.data_offset + header.data_size; |
| 167 | std::memcpy(buffer.data(), &header, sizeof(ParcelHeader)); | 159 | |
| 160 | std::memcpy(output_buffer.data(), &header, sizeof(header)); | ||
| 161 | std::ranges::copy(m_data_buffer, output_buffer.data() + header.data_offset); | ||
| 162 | std::ranges::copy(m_object_buffer, output_buffer.data() + header.objects_offset); | ||
| 163 | |||
| 164 | return output_buffer; | ||
| 165 | } | ||
| 166 | |||
| 167 | private: | ||
| 168 | template <typename T> | ||
| 169 | requires(std::is_trivially_copyable_v<T>) | ||
| 170 | void WriteImpl(const T& val, std::vector<u8>& buffer) { | ||
| 171 | const size_t aligned_size = Common::AlignUp(sizeof(T), 4); | ||
| 172 | const size_t old_size = buffer.size(); | ||
| 173 | buffer.resize(old_size + aligned_size); | ||
| 168 | 174 | ||
| 169 | return buffer; | 175 | std::memcpy(buffer.data() + old_size, &val, sizeof(T)); |
| 170 | } | 176 | } |
| 171 | 177 | ||
| 172 | private: | 178 | private: |
| 173 | mutable std::vector<u8> buffer; | 179 | std::vector<u8> m_data_buffer; |
| 174 | std::size_t write_index = sizeof(ParcelHeader); | 180 | std::vector<u8> m_object_buffer; |
| 175 | }; | 181 | }; |
| 176 | 182 | ||
| 177 | } // namespace Service::android | 183 | } // namespace Service::android |
diff --git a/src/core/hle/service/time/clock_types.h b/src/core/hle/service/time/clock_types.h index ed1eb5b2d..e6293ffb9 100644 --- a/src/core/hle/service/time/clock_types.h +++ b/src/core/hle/service/time/clock_types.h | |||
| @@ -59,6 +59,18 @@ static_assert(sizeof(SystemClockContext) == 0x20, "SystemClockContext is incorre | |||
| 59 | static_assert(std::is_trivially_copyable_v<SystemClockContext>, | 59 | static_assert(std::is_trivially_copyable_v<SystemClockContext>, |
| 60 | "SystemClockContext must be trivially copyable"); | 60 | "SystemClockContext must be trivially copyable"); |
| 61 | 61 | ||
| 62 | struct ContinuousAdjustmentTimePoint { | ||
| 63 | s64 measurement_offset; | ||
| 64 | s64 diff_scale; | ||
| 65 | u32 shift_amount; | ||
| 66 | s64 lower; | ||
| 67 | s64 upper; | ||
| 68 | Common::UUID clock_source_id; | ||
| 69 | }; | ||
| 70 | static_assert(sizeof(ContinuousAdjustmentTimePoint) == 0x38); | ||
| 71 | static_assert(std::is_trivially_copyable_v<ContinuousAdjustmentTimePoint>, | ||
| 72 | "ContinuousAdjustmentTimePoint must be trivially copyable"); | ||
| 73 | |||
| 62 | /// https://switchbrew.org/wiki/Glue_services#TimeSpanType | 74 | /// https://switchbrew.org/wiki/Glue_services#TimeSpanType |
| 63 | struct TimeSpanType { | 75 | struct TimeSpanType { |
| 64 | s64 nanoseconds{}; | 76 | s64 nanoseconds{}; |
diff --git a/src/core/hle/service/time/time_sharedmemory.cpp b/src/core/hle/service/time/time_sharedmemory.cpp index ff53a7d6f..ce1c85bcc 100644 --- a/src/core/hle/service/time/time_sharedmemory.cpp +++ b/src/core/hle/service/time/time_sharedmemory.cpp | |||
| @@ -30,6 +30,25 @@ void SharedMemory::SetupStandardSteadyClock(const Common::UUID& clock_source_id, | |||
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | void SharedMemory::UpdateLocalSystemClockContext(const Clock::SystemClockContext& context) { | 32 | void SharedMemory::UpdateLocalSystemClockContext(const Clock::SystemClockContext& context) { |
| 33 | // lower and upper are related to the measurement point for the steady time point, | ||
| 34 | // and compare equal on boot | ||
| 35 | const s64 time_point_ns = context.steady_time_point.time_point * 1'000'000'000LL; | ||
| 36 | |||
| 37 | // This adjusts for some sort of time skew | ||
| 38 | // Both 0 on boot | ||
| 39 | const s64 diff_scale = 0; | ||
| 40 | const u32 shift_amount = 0; | ||
| 41 | |||
| 42 | const Clock::ContinuousAdjustmentTimePoint adjustment{ | ||
| 43 | .measurement_offset = system.CoreTiming().GetGlobalTimeNs().count(), | ||
| 44 | .diff_scale = diff_scale, | ||
| 45 | .shift_amount = shift_amount, | ||
| 46 | .lower = time_point_ns, | ||
| 47 | .upper = time_point_ns, | ||
| 48 | .clock_source_id = context.steady_time_point.clock_source_id, | ||
| 49 | }; | ||
| 50 | |||
| 51 | StoreToLockFreeAtomicType(&GetFormat()->continuous_adjustment_timepoint, adjustment); | ||
| 33 | StoreToLockFreeAtomicType(&GetFormat()->standard_local_system_clock_context, context); | 52 | StoreToLockFreeAtomicType(&GetFormat()->standard_local_system_clock_context, context); |
| 34 | } | 53 | } |
| 35 | 54 | ||
diff --git a/src/core/hle/service/time/time_sharedmemory.h b/src/core/hle/service/time/time_sharedmemory.h index 044a4d24e..c89be9765 100644 --- a/src/core/hle/service/time/time_sharedmemory.h +++ b/src/core/hle/service/time/time_sharedmemory.h | |||
| @@ -65,14 +65,15 @@ public: | |||
| 65 | LockFreeAtomicType<Clock::SystemClockContext> standard_local_system_clock_context; | 65 | LockFreeAtomicType<Clock::SystemClockContext> standard_local_system_clock_context; |
| 66 | LockFreeAtomicType<Clock::SystemClockContext> standard_network_system_clock_context; | 66 | LockFreeAtomicType<Clock::SystemClockContext> standard_network_system_clock_context; |
| 67 | LockFreeAtomicType<bool> is_standard_user_system_clock_automatic_correction_enabled; | 67 | LockFreeAtomicType<bool> is_standard_user_system_clock_automatic_correction_enabled; |
| 68 | u32 format_version; | 68 | LockFreeAtomicType<Clock::ContinuousAdjustmentTimePoint> continuous_adjustment_timepoint; |
| 69 | }; | 69 | }; |
| 70 | static_assert(offsetof(Format, standard_steady_clock_timepoint) == 0x0); | 70 | static_assert(offsetof(Format, standard_steady_clock_timepoint) == 0x0); |
| 71 | static_assert(offsetof(Format, standard_local_system_clock_context) == 0x38); | 71 | static_assert(offsetof(Format, standard_local_system_clock_context) == 0x38); |
| 72 | static_assert(offsetof(Format, standard_network_system_clock_context) == 0x80); | 72 | static_assert(offsetof(Format, standard_network_system_clock_context) == 0x80); |
| 73 | static_assert(offsetof(Format, is_standard_user_system_clock_automatic_correction_enabled) == | 73 | static_assert(offsetof(Format, is_standard_user_system_clock_automatic_correction_enabled) == |
| 74 | 0xc8); | 74 | 0xc8); |
| 75 | static_assert(sizeof(Format) == 0xd8, "Format is an invalid size"); | 75 | static_assert(offsetof(Format, continuous_adjustment_timepoint) == 0xd0); |
| 76 | static_assert(sizeof(Format) == 0x148, "Format is an invalid size"); | ||
| 76 | 77 | ||
| 77 | void SetupStandardSteadyClock(const Common::UUID& clock_source_id, | 78 | void SetupStandardSteadyClock(const Common::UUID& clock_source_id, |
| 78 | Clock::TimeSpanType current_time_point); | 79 | Clock::TimeSpanType current_time_point); |
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 68eab5133..1b193f00c 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -64,8 +64,8 @@ public: | |||
| 64 | private: | 64 | private: |
| 65 | const u32 magic = 2; | 65 | const u32 magic = 2; |
| 66 | const u32 process_id = 1; | 66 | const u32 process_id = 1; |
| 67 | const u32 id; | 67 | const u64 id; |
| 68 | INSERT_PADDING_WORDS(3); | 68 | INSERT_PADDING_WORDS(2); |
| 69 | std::array<u8, 8> dispdrv = {'d', 'i', 's', 'p', 'd', 'r', 'v', '\0'}; | 69 | std::array<u8, 8> dispdrv = {'d', 'i', 's', 'p', 'd', 'r', 'v', '\0'}; |
| 70 | INSERT_PADDING_WORDS(2); | 70 | INSERT_PADDING_WORDS(2); |
| 71 | }; | 71 | }; |
| @@ -608,7 +608,9 @@ private: | |||
| 608 | return; | 608 | return; |
| 609 | } | 609 | } |
| 610 | 610 | ||
| 611 | const auto parcel = android::OutputParcel{NativeWindow{*buffer_queue_id}}; | 611 | android::OutputParcel parcel; |
| 612 | parcel.WriteInterface(NativeWindow{*buffer_queue_id}); | ||
| 613 | |||
| 612 | const auto buffer_size = ctx.WriteBuffer(parcel.Serialize()); | 614 | const auto buffer_size = ctx.WriteBuffer(parcel.Serialize()); |
| 613 | 615 | ||
| 614 | IPC::ResponseBuilder rb{ctx, 4}; | 616 | IPC::ResponseBuilder rb{ctx, 4}; |
| @@ -654,7 +656,9 @@ private: | |||
| 654 | return; | 656 | return; |
| 655 | } | 657 | } |
| 656 | 658 | ||
| 657 | const auto parcel = android::OutputParcel{NativeWindow{*buffer_queue_id}}; | 659 | android::OutputParcel parcel; |
| 660 | parcel.WriteInterface(NativeWindow{*buffer_queue_id}); | ||
| 661 | |||
| 658 | const auto buffer_size = ctx.WriteBuffer(parcel.Serialize()); | 662 | const auto buffer_size = ctx.WriteBuffer(parcel.Serialize()); |
| 659 | 663 | ||
| 660 | IPC::ResponseBuilder rb{ctx, 6}; | 664 | IPC::ResponseBuilder rb{ctx, 6}; |
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp index 7f9e8dbb9..9a0439bb5 100644 --- a/src/input_common/drivers/sdl_driver.cpp +++ b/src/input_common/drivers/sdl_driver.cpp | |||
| @@ -109,14 +109,37 @@ public: | |||
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | bool RumblePlay(const Common::Input::VibrationStatus vibration) { | 111 | bool RumblePlay(const Common::Input::VibrationStatus vibration) { |
| 112 | constexpr u32 rumble_max_duration_ms = 1000; | 112 | constexpr u32 rumble_max_duration_ms = 2000; |
| 113 | constexpr f32 low_start_sensitivity_limit = 140.0; | ||
| 114 | constexpr f32 low_width_sensitivity_limit = 400.0; | ||
| 115 | constexpr f32 high_start_sensitivity_limit = 200.0; | ||
| 116 | constexpr f32 high_width_sensitivity_limit = 700.0; | ||
| 117 | // Try to provide some feeling of the frequency by reducing the amplitude depending on it. | ||
| 118 | f32 low_frequency_scale = 1.0; | ||
| 119 | if (vibration.low_frequency > low_start_sensitivity_limit) { | ||
| 120 | low_frequency_scale = | ||
| 121 | std::max(1.0f - (vibration.low_frequency - low_start_sensitivity_limit) / | ||
| 122 | low_width_sensitivity_limit, | ||
| 123 | 0.3f); | ||
| 124 | } | ||
| 125 | f32 low_amplitude = vibration.low_amplitude * low_frequency_scale; | ||
| 126 | |||
| 127 | f32 high_frequency_scale = 1.0; | ||
| 128 | if (vibration.high_frequency > high_start_sensitivity_limit) { | ||
| 129 | high_frequency_scale = | ||
| 130 | std::max(1.0f - (vibration.high_frequency - high_start_sensitivity_limit) / | ||
| 131 | high_width_sensitivity_limit, | ||
| 132 | 0.3f); | ||
| 133 | } | ||
| 134 | f32 high_amplitude = vibration.high_amplitude * high_frequency_scale; | ||
| 135 | |||
| 113 | if (sdl_controller) { | 136 | if (sdl_controller) { |
| 114 | return SDL_GameControllerRumble( | 137 | return SDL_GameControllerRumble(sdl_controller.get(), static_cast<u16>(low_amplitude), |
| 115 | sdl_controller.get(), static_cast<u16>(vibration.low_amplitude), | 138 | static_cast<u16>(high_amplitude), |
| 116 | static_cast<u16>(vibration.high_amplitude), rumble_max_duration_ms) != -1; | 139 | rumble_max_duration_ms) != -1; |
| 117 | } else if (sdl_joystick) { | 140 | } else if (sdl_joystick) { |
| 118 | return SDL_JoystickRumble(sdl_joystick.get(), static_cast<u16>(vibration.low_amplitude), | 141 | return SDL_JoystickRumble(sdl_joystick.get(), static_cast<u16>(low_amplitude), |
| 119 | static_cast<u16>(vibration.high_amplitude), | 142 | static_cast<u16>(high_amplitude), |
| 120 | rumble_max_duration_ms) != -1; | 143 | rumble_max_duration_ms) != -1; |
| 121 | } | 144 | } |
| 122 | 145 | ||
diff --git a/src/input_common/helpers/joycon_protocol/joycon_types.h b/src/input_common/helpers/joycon_protocol/joycon_types.h index b03143e04..1c8d294b0 100644 --- a/src/input_common/helpers/joycon_protocol/joycon_types.h +++ b/src/input_common/helpers/joycon_protocol/joycon_types.h | |||
| @@ -394,6 +394,7 @@ enum class DriverResult { | |||
| 394 | InvalidHandle, | 394 | InvalidHandle, |
| 395 | NotSupported, | 395 | NotSupported, |
| 396 | Disabled, | 396 | Disabled, |
| 397 | Delayed, | ||
| 397 | Unknown, | 398 | Unknown, |
| 398 | }; | 399 | }; |
| 399 | 400 | ||
diff --git a/src/input_common/helpers/joycon_protocol/nfc.cpp b/src/input_common/helpers/joycon_protocol/nfc.cpp index 77ea6d5cf..14818ae33 100644 --- a/src/input_common/helpers/joycon_protocol/nfc.cpp +++ b/src/input_common/helpers/joycon_protocol/nfc.cpp | |||
| @@ -72,6 +72,11 @@ DriverResult NfcProtocol::StartNFCPollingMode() { | |||
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | DriverResult NfcProtocol::ScanAmiibo(std::vector<u8>& data) { | 74 | DriverResult NfcProtocol::ScanAmiibo(std::vector<u8>& data) { |
| 75 | if (update_counter++ < AMIIBO_UPDATE_DELAY) { | ||
| 76 | return DriverResult::Delayed; | ||
| 77 | } | ||
| 78 | update_counter = 0; | ||
| 79 | |||
| 75 | LOG_DEBUG(Input, "Start NFC pooling Mode"); | 80 | LOG_DEBUG(Input, "Start NFC pooling Mode"); |
| 76 | ScopedSetBlocking sb(this); | 81 | ScopedSetBlocking sb(this); |
| 77 | DriverResult result{DriverResult::Success}; | 82 | DriverResult result{DriverResult::Success}; |
| @@ -87,7 +92,7 @@ DriverResult NfcProtocol::ScanAmiibo(std::vector<u8>& data) { | |||
| 87 | result = WaitUntilNfcIsReady(); | 92 | result = WaitUntilNfcIsReady(); |
| 88 | } | 93 | } |
| 89 | if (result == DriverResult::Success) { | 94 | if (result == DriverResult::Success) { |
| 90 | result = StartPolling(tag_data); | 95 | result = StartPolling(tag_data, 7); |
| 91 | } | 96 | } |
| 92 | if (result == DriverResult::Success) { | 97 | if (result == DriverResult::Success) { |
| 93 | result = GetAmiiboData(data); | 98 | result = GetAmiiboData(data); |
| @@ -129,9 +134,8 @@ DriverResult NfcProtocol::WaitUntilNfcIsReady() { | |||
| 129 | return DriverResult::Success; | 134 | return DriverResult::Success; |
| 130 | } | 135 | } |
| 131 | 136 | ||
| 132 | DriverResult NfcProtocol::StartPolling(TagFoundData& data) { | 137 | DriverResult NfcProtocol::StartPolling(TagFoundData& data, std::size_t timeout_limit) { |
| 133 | LOG_DEBUG(Input, "Start Polling for tag"); | 138 | LOG_DEBUG(Input, "Start Polling for tag"); |
| 134 | constexpr std::size_t timeout_limit = 7; | ||
| 135 | MCUCommandResponse output{}; | 139 | MCUCommandResponse output{}; |
| 136 | std::size_t tries = 0; | 140 | std::size_t tries = 0; |
| 137 | 141 | ||
diff --git a/src/input_common/helpers/joycon_protocol/nfc.h b/src/input_common/helpers/joycon_protocol/nfc.h index 11e263e07..4cb992d1d 100644 --- a/src/input_common/helpers/joycon_protocol/nfc.h +++ b/src/input_common/helpers/joycon_protocol/nfc.h | |||
| @@ -32,6 +32,9 @@ public: | |||
| 32 | bool IsEnabled() const; | 32 | bool IsEnabled() const; |
| 33 | 33 | ||
| 34 | private: | 34 | private: |
| 35 | // Number of times the function will be delayed until it outputs valid data | ||
| 36 | static constexpr std::size_t AMIIBO_UPDATE_DELAY = 15; | ||
| 37 | |||
| 35 | struct TagFoundData { | 38 | struct TagFoundData { |
| 36 | u8 type; | 39 | u8 type; |
| 37 | std::vector<u8> uuid; | 40 | std::vector<u8> uuid; |
| @@ -39,7 +42,7 @@ private: | |||
| 39 | 42 | ||
| 40 | DriverResult WaitUntilNfcIsReady(); | 43 | DriverResult WaitUntilNfcIsReady(); |
| 41 | 44 | ||
| 42 | DriverResult StartPolling(TagFoundData& data); | 45 | DriverResult StartPolling(TagFoundData& data, std::size_t timeout_limit = 1); |
| 43 | 46 | ||
| 44 | DriverResult ReadTag(const TagFoundData& data); | 47 | DriverResult ReadTag(const TagFoundData& data); |
| 45 | 48 | ||
| @@ -56,6 +59,7 @@ private: | |||
| 56 | NFCReadBlockCommand GetReadBlockCommand(NFCPages pages) const; | 59 | NFCReadBlockCommand GetReadBlockCommand(NFCPages pages) const; |
| 57 | 60 | ||
| 58 | bool is_enabled{}; | 61 | bool is_enabled{}; |
| 62 | std::size_t update_counter{}; | ||
| 59 | }; | 63 | }; |
| 60 | 64 | ||
| 61 | } // namespace InputCommon::Joycon | 65 | } // namespace InputCommon::Joycon |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index fee510f7b..07c2b7b8a 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp | |||
| @@ -339,9 +339,7 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, Id vertex) { | |||
| 339 | if (ctx.profile.support_vertex_instance_id) { | 339 | if (ctx.profile.support_vertex_instance_id) { |
| 340 | return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.vertex_id)); | 340 | return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.vertex_id)); |
| 341 | } else { | 341 | } else { |
| 342 | const Id index{ctx.OpLoad(ctx.U32[1], ctx.vertex_index)}; | 342 | return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.vertex_index)); |
| 343 | const Id base{ctx.OpLoad(ctx.U32[1], ctx.base_vertex)}; | ||
| 344 | return ctx.OpBitcast(ctx.F32[1], ctx.OpISub(ctx.U32[1], index, base)); | ||
| 345 | } | 343 | } |
| 346 | case IR::Attribute::BaseInstance: | 344 | case IR::Attribute::BaseInstance: |
| 347 | return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.base_instance)); | 345 | return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.base_instance)); |
| @@ -386,9 +384,7 @@ Id EmitGetAttributeU32(EmitContext& ctx, IR::Attribute attr, Id) { | |||
| 386 | if (ctx.profile.support_vertex_instance_id) { | 384 | if (ctx.profile.support_vertex_instance_id) { |
| 387 | return ctx.OpLoad(ctx.U32[1], ctx.vertex_id); | 385 | return ctx.OpLoad(ctx.U32[1], ctx.vertex_id); |
| 388 | } else { | 386 | } else { |
| 389 | const Id index{ctx.OpLoad(ctx.U32[1], ctx.vertex_index)}; | 387 | return ctx.OpLoad(ctx.U32[1], ctx.vertex_index); |
| 390 | const Id base{ctx.OpLoad(ctx.U32[1], ctx.base_vertex)}; | ||
| 391 | return ctx.OpISub(ctx.U32[1], index, base); | ||
| 392 | } | 388 | } |
| 393 | case IR::Attribute::BaseInstance: | 389 | case IR::Attribute::BaseInstance: |
| 394 | return ctx.OpLoad(ctx.U32[1], ctx.base_instance); | 390 | return ctx.OpLoad(ctx.U32[1], ctx.base_instance); |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_mipmap_level.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_mipmap_level.cpp index 639da1e9c..eeb49444f 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_mipmap_level.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_mipmap_level.cpp | |||
| @@ -102,12 +102,7 @@ void Impl(TranslatorVisitor& v, u64 insn, bool is_bindless) { | |||
| 102 | } | 102 | } |
| 103 | IR::F32 value{v.ir.CompositeExtract(sample, element)}; | 103 | IR::F32 value{v.ir.CompositeExtract(sample, element)}; |
| 104 | if (element < 2) { | 104 | if (element < 2) { |
| 105 | IR::U32 casted_value; | 105 | IR::U32 casted_value = v.ir.ConvertFToU(32, value); |
| 106 | if (element == 0) { | ||
| 107 | casted_value = v.ir.ConvertFToU(32, value); | ||
| 108 | } else { | ||
| 109 | casted_value = v.ir.ConvertFToS(16, value); | ||
| 110 | } | ||
| 111 | v.X(dest_reg, v.ir.ShiftLeftLogical(casted_value, v.ir.Imm32(8))); | 106 | v.X(dest_reg, v.ir.ShiftLeftLogical(casted_value, v.ir.Imm32(8))); |
| 112 | } else { | 107 | } else { |
| 113 | v.F(dest_reg, value); | 108 | v.F(dest_reg, value); |
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 6624919a4..98756e4da 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -96,12 +96,12 @@ void BufferCache<P>::TickFrame() { | |||
| 96 | 96 | ||
| 97 | template <class P> | 97 | template <class P> |
| 98 | void BufferCache<P>::WriteMemory(VAddr cpu_addr, u64 size) { | 98 | void BufferCache<P>::WriteMemory(VAddr cpu_addr, u64 size) { |
| 99 | memory_tracker.MarkRegionAsCpuModified(cpu_addr, size); | ||
| 100 | if (memory_tracker.IsRegionGpuModified(cpu_addr, size)) { | 99 | if (memory_tracker.IsRegionGpuModified(cpu_addr, size)) { |
| 101 | const IntervalType subtract_interval{cpu_addr, cpu_addr + size}; | 100 | const IntervalType subtract_interval{cpu_addr, cpu_addr + size}; |
| 102 | ClearDownload(subtract_interval); | 101 | ClearDownload(subtract_interval); |
| 103 | common_ranges.subtract(subtract_interval); | 102 | common_ranges.subtract(subtract_interval); |
| 104 | } | 103 | } |
| 104 | memory_tracker.MarkRegionAsCpuModified(cpu_addr, size); | ||
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | template <class P> | 107 | template <class P> |
| @@ -122,41 +122,24 @@ std::optional<VideoCore::RasterizerDownloadArea> BufferCache<P>::GetFlushArea(VA | |||
| 122 | area->preemtive = true; | 122 | area->preemtive = true; |
| 123 | return area; | 123 | return area; |
| 124 | }; | 124 | }; |
| 125 | area->preemtive = | ||
| 126 | !IsRegionGpuModified(cpu_addr_start_aligned, cpu_addr_end_aligned - cpu_addr_start_aligned); | ||
| 125 | memory_tracker.MarkRegionAsPreflushable(cpu_addr_start_aligned, | 127 | memory_tracker.MarkRegionAsPreflushable(cpu_addr_start_aligned, |
| 126 | cpu_addr_end_aligned - cpu_addr_start_aligned); | 128 | cpu_addr_end_aligned - cpu_addr_start_aligned); |
| 127 | area->preemtive = !IsRegionGpuModified(cpu_addr, size); | ||
| 128 | return area; | 129 | return area; |
| 129 | } | 130 | } |
| 130 | 131 | ||
| 131 | template <class P> | 132 | template <class P> |
| 132 | void BufferCache<P>::DownloadMemory(VAddr cpu_addr, u64 size) { | 133 | void BufferCache<P>::DownloadMemory(VAddr cpu_addr, u64 size) { |
| 133 | WaitOnAsyncFlushes(cpu_addr, size); | ||
| 134 | ForEachBufferInRange(cpu_addr, size, [&](BufferId, Buffer& buffer) { | 134 | ForEachBufferInRange(cpu_addr, size, [&](BufferId, Buffer& buffer) { |
| 135 | DownloadBufferMemory(buffer, cpu_addr, size); | 135 | DownloadBufferMemory(buffer, cpu_addr, size); |
| 136 | }); | 136 | }); |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | template <class P> | 139 | template <class P> |
| 140 | void BufferCache<P>::WaitOnAsyncFlushes(VAddr cpu_addr, u64 size) { | ||
| 141 | bool must_wait = false; | ||
| 142 | ForEachInOverlapCounter(async_downloads, cpu_addr, size, | ||
| 143 | [&](VAddr, VAddr, int) { must_wait = true; }); | ||
| 144 | bool must_release = false; | ||
| 145 | ForEachInRangeSet(pending_ranges, cpu_addr, size, [&](VAddr, VAddr) { must_release = true; }); | ||
| 146 | if (must_release) { | ||
| 147 | std::function<void()> tmp([]() {}); | ||
| 148 | rasterizer.SignalFence(std::move(tmp)); | ||
| 149 | } | ||
| 150 | if (must_wait || must_release) { | ||
| 151 | rasterizer.ReleaseFences(); | ||
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | template <class P> | ||
| 156 | void BufferCache<P>::ClearDownload(IntervalType subtract_interval) { | 140 | void BufferCache<P>::ClearDownload(IntervalType subtract_interval) { |
| 157 | RemoveEachInOverlapCounter(async_downloads, subtract_interval, -1024); | 141 | RemoveEachInOverlapCounter(async_downloads, subtract_interval, -1024); |
| 158 | uncommitted_ranges.subtract(subtract_interval); | 142 | uncommitted_ranges.subtract(subtract_interval); |
| 159 | pending_ranges.subtract(subtract_interval); | ||
| 160 | for (auto& interval_set : committed_ranges) { | 143 | for (auto& interval_set : committed_ranges) { |
| 161 | interval_set.subtract(subtract_interval); | 144 | interval_set.subtract(subtract_interval); |
| 162 | } | 145 | } |
| @@ -176,7 +159,6 @@ bool BufferCache<P>::DMACopy(GPUVAddr src_address, GPUVAddr dest_address, u64 am | |||
| 176 | } | 159 | } |
| 177 | 160 | ||
| 178 | const IntervalType subtract_interval{*cpu_dest_address, *cpu_dest_address + amount}; | 161 | const IntervalType subtract_interval{*cpu_dest_address, *cpu_dest_address + amount}; |
| 179 | WaitOnAsyncFlushes(*cpu_src_address, static_cast<u32>(amount)); | ||
| 180 | ClearDownload(subtract_interval); | 162 | ClearDownload(subtract_interval); |
| 181 | 163 | ||
| 182 | BufferId buffer_a; | 164 | BufferId buffer_a; |
| @@ -204,7 +186,6 @@ bool BufferCache<P>::DMACopy(GPUVAddr src_address, GPUVAddr dest_address, u64 am | |||
| 204 | const IntervalType add_interval{new_base_address, new_base_address + size}; | 186 | const IntervalType add_interval{new_base_address, new_base_address + size}; |
| 205 | tmp_intervals.push_back(add_interval); | 187 | tmp_intervals.push_back(add_interval); |
| 206 | uncommitted_ranges.add(add_interval); | 188 | uncommitted_ranges.add(add_interval); |
| 207 | pending_ranges.add(add_interval); | ||
| 208 | }; | 189 | }; |
| 209 | ForEachInRangeSet(common_ranges, *cpu_src_address, amount, mirror); | 190 | ForEachInRangeSet(common_ranges, *cpu_src_address, amount, mirror); |
| 210 | // This subtraction in this order is important for overlapping copies. | 191 | // This subtraction in this order is important for overlapping copies. |
| @@ -491,7 +472,6 @@ void BufferCache<P>::CommitAsyncFlushesHigh() { | |||
| 491 | } | 472 | } |
| 492 | MICROPROFILE_SCOPE(GPU_DownloadMemory); | 473 | MICROPROFILE_SCOPE(GPU_DownloadMemory); |
| 493 | 474 | ||
| 494 | pending_ranges.clear(); | ||
| 495 | auto it = committed_ranges.begin(); | 475 | auto it = committed_ranges.begin(); |
| 496 | while (it != committed_ranges.end()) { | 476 | while (it != committed_ranges.end()) { |
| 497 | auto& current_intervals = *it; | 477 | auto& current_intervals = *it; |
| @@ -1223,16 +1203,14 @@ void BufferCache<P>::UpdateComputeTextureBuffers() { | |||
| 1223 | 1203 | ||
| 1224 | template <class P> | 1204 | template <class P> |
| 1225 | void BufferCache<P>::MarkWrittenBuffer(BufferId buffer_id, VAddr cpu_addr, u32 size) { | 1205 | void BufferCache<P>::MarkWrittenBuffer(BufferId buffer_id, VAddr cpu_addr, u32 size) { |
| 1226 | memory_tracker.MarkRegionAsGpuModified(cpu_addr, size); | ||
| 1227 | |||
| 1228 | if (memory_tracker.IsRegionCpuModified(cpu_addr, size)) { | 1206 | if (memory_tracker.IsRegionCpuModified(cpu_addr, size)) { |
| 1229 | SynchronizeBuffer(slot_buffers[buffer_id], cpu_addr, size); | 1207 | SynchronizeBuffer(slot_buffers[buffer_id], cpu_addr, size); |
| 1230 | } | 1208 | } |
| 1209 | memory_tracker.MarkRegionAsGpuModified(cpu_addr, size); | ||
| 1231 | 1210 | ||
| 1232 | const IntervalType base_interval{cpu_addr, cpu_addr + size}; | 1211 | const IntervalType base_interval{cpu_addr, cpu_addr + size}; |
| 1233 | common_ranges.add(base_interval); | 1212 | common_ranges.add(base_interval); |
| 1234 | uncommitted_ranges.add(base_interval); | 1213 | uncommitted_ranges.add(base_interval); |
| 1235 | pending_ranges.add(base_interval); | ||
| 1236 | } | 1214 | } |
| 1237 | 1215 | ||
| 1238 | template <class P> | 1216 | template <class P> |
| @@ -1677,14 +1655,15 @@ typename BufferCache<P>::Binding BufferCache<P>::StorageBufferBinding(GPUVAddr s | |||
| 1677 | const bool is_nvn_cbuf = cbuf_index == 0; | 1655 | const bool is_nvn_cbuf = cbuf_index == 0; |
| 1678 | // The NVN driver buffer (index 0) is known to pack the SSBO address followed by its size. | 1656 | // The NVN driver buffer (index 0) is known to pack the SSBO address followed by its size. |
| 1679 | if (is_nvn_cbuf) { | 1657 | if (is_nvn_cbuf) { |
| 1680 | return gpu_memory->Read<u32>(ssbo_addr + 8); | 1658 | const u32 ssbo_size = gpu_memory->Read<u32>(ssbo_addr + 8); |
| 1659 | if (ssbo_size != 0) { | ||
| 1660 | return ssbo_size; | ||
| 1661 | } | ||
| 1681 | } | 1662 | } |
| 1682 | // Other titles (notably Doom Eternal) may use STG/LDG on buffer addresses in custom defined | 1663 | // Other titles (notably Doom Eternal) may use STG/LDG on buffer addresses in custom defined |
| 1683 | // cbufs, which do not store the sizes adjacent to the addresses, so use the fully | 1664 | // cbufs, which do not store the sizes adjacent to the addresses, so use the fully |
| 1684 | // mapped buffer size for now. | 1665 | // mapped buffer size for now. |
| 1685 | const u32 memory_layout_size = static_cast<u32>(gpu_memory->GetMemoryLayoutSize(gpu_addr)); | 1666 | const u32 memory_layout_size = static_cast<u32>(gpu_memory->GetMemoryLayoutSize(gpu_addr)); |
| 1686 | LOG_INFO(HW_GPU, "Binding storage buffer for cbuf index {}, MemoryLayoutSize 0x{:X}", | ||
| 1687 | cbuf_index, memory_layout_size); | ||
| 1688 | return memory_layout_size; | 1667 | return memory_layout_size; |
| 1689 | }(); | 1668 | }(); |
| 1690 | const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr); | 1669 | const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr); |
diff --git a/src/video_core/buffer_cache/buffer_cache_base.h b/src/video_core/buffer_cache/buffer_cache_base.h index 0445ec47f..ac00d4d9d 100644 --- a/src/video_core/buffer_cache/buffer_cache_base.h +++ b/src/video_core/buffer_cache/buffer_cache_base.h | |||
| @@ -381,8 +381,6 @@ private: | |||
| 381 | 381 | ||
| 382 | void RunGarbageCollector(); | 382 | void RunGarbageCollector(); |
| 383 | 383 | ||
| 384 | void WaitOnAsyncFlushes(VAddr cpu_addr, u64 size); | ||
| 385 | |||
| 386 | void BindHostIndexBuffer(); | 384 | void BindHostIndexBuffer(); |
| 387 | 385 | ||
| 388 | void BindHostVertexBuffers(); | 386 | void BindHostVertexBuffers(); |
| @@ -547,7 +545,6 @@ private: | |||
| 547 | IntervalSet uncommitted_ranges; | 545 | IntervalSet uncommitted_ranges; |
| 548 | IntervalSet common_ranges; | 546 | IntervalSet common_ranges; |
| 549 | IntervalSet cached_ranges; | 547 | IntervalSet cached_ranges; |
| 550 | IntervalSet pending_ranges; | ||
| 551 | std::deque<IntervalSet> committed_ranges; | 548 | std::deque<IntervalSet> committed_ranges; |
| 552 | 549 | ||
| 553 | // Async Buffers | 550 | // Async Buffers |
diff --git a/src/video_core/engines/sw_blitter/blitter.cpp b/src/video_core/engines/sw_blitter/blitter.cpp index 3c9f38559..ff88cd03d 100644 --- a/src/video_core/engines/sw_blitter/blitter.cpp +++ b/src/video_core/engines/sw_blitter/blitter.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <cmath> | 5 | #include <cmath> |
| 6 | #include <vector> | 6 | #include <vector> |
| 7 | 7 | ||
| 8 | #include "common/scratch_buffer.h" | ||
| 8 | #include "video_core/engines/sw_blitter/blitter.h" | 9 | #include "video_core/engines/sw_blitter/blitter.h" |
| 9 | #include "video_core/engines/sw_blitter/converter.h" | 10 | #include "video_core/engines/sw_blitter/converter.h" |
| 10 | #include "video_core/memory_manager.h" | 11 | #include "video_core/memory_manager.h" |
| @@ -112,11 +113,11 @@ void Bilinear(std::span<const f32> input, std::span<f32> output, size_t src_widt | |||
| 112 | } // namespace | 113 | } // namespace |
| 113 | 114 | ||
| 114 | struct SoftwareBlitEngine::BlitEngineImpl { | 115 | struct SoftwareBlitEngine::BlitEngineImpl { |
| 115 | std::vector<u8> tmp_buffer; | 116 | Common::ScratchBuffer<u8> tmp_buffer; |
| 116 | std::vector<u8> src_buffer; | 117 | Common::ScratchBuffer<u8> src_buffer; |
| 117 | std::vector<u8> dst_buffer; | 118 | Common::ScratchBuffer<u8> dst_buffer; |
| 118 | std::vector<f32> intermediate_src; | 119 | Common::ScratchBuffer<f32> intermediate_src; |
| 119 | std::vector<f32> intermediate_dst; | 120 | Common::ScratchBuffer<f32> intermediate_dst; |
| 120 | ConverterFactory converter_factory; | 121 | ConverterFactory converter_factory; |
| 121 | }; | 122 | }; |
| 122 | 123 | ||
| @@ -158,14 +159,14 @@ bool SoftwareBlitEngine::Blit(Fermi2D::Surface& src, Fermi2D::Surface& dst, | |||
| 158 | const auto src_bytes_per_pixel = BytesPerBlock(PixelFormatFromRenderTargetFormat(src.format)); | 159 | const auto src_bytes_per_pixel = BytesPerBlock(PixelFormatFromRenderTargetFormat(src.format)); |
| 159 | const auto dst_bytes_per_pixel = BytesPerBlock(PixelFormatFromRenderTargetFormat(dst.format)); | 160 | const auto dst_bytes_per_pixel = BytesPerBlock(PixelFormatFromRenderTargetFormat(dst.format)); |
| 160 | const size_t src_size = get_surface_size(src, src_bytes_per_pixel); | 161 | const size_t src_size = get_surface_size(src, src_bytes_per_pixel); |
| 161 | impl->tmp_buffer.resize(src_size); | 162 | impl->tmp_buffer.resize_destructive(src_size); |
| 162 | memory_manager.ReadBlock(src.Address(), impl->tmp_buffer.data(), src_size); | 163 | memory_manager.ReadBlock(src.Address(), impl->tmp_buffer.data(), src_size); |
| 163 | 164 | ||
| 164 | const size_t src_copy_size = src_extent_x * src_extent_y * src_bytes_per_pixel; | 165 | const size_t src_copy_size = src_extent_x * src_extent_y * src_bytes_per_pixel; |
| 165 | 166 | ||
| 166 | const size_t dst_copy_size = dst_extent_x * dst_extent_y * dst_bytes_per_pixel; | 167 | const size_t dst_copy_size = dst_extent_x * dst_extent_y * dst_bytes_per_pixel; |
| 167 | 168 | ||
| 168 | impl->src_buffer.resize(src_copy_size); | 169 | impl->src_buffer.resize_destructive(src_copy_size); |
| 169 | 170 | ||
| 170 | const bool no_passthrough = | 171 | const bool no_passthrough = |
| 171 | src.format != dst.format || src_extent_x != dst_extent_x || src_extent_y != dst_extent_y; | 172 | src.format != dst.format || src_extent_x != dst_extent_x || src_extent_y != dst_extent_y; |
| @@ -177,8 +178,10 @@ bool SoftwareBlitEngine::Blit(Fermi2D::Surface& src, Fermi2D::Surface& dst, | |||
| 177 | 178 | ||
| 178 | const auto convertion_phase_ir = [&]() { | 179 | const auto convertion_phase_ir = [&]() { |
| 179 | auto* input_converter = impl->converter_factory.GetFormatConverter(src.format); | 180 | auto* input_converter = impl->converter_factory.GetFormatConverter(src.format); |
| 180 | impl->intermediate_src.resize((src_copy_size / src_bytes_per_pixel) * ir_components); | 181 | impl->intermediate_src.resize_destructive((src_copy_size / src_bytes_per_pixel) * |
| 181 | impl->intermediate_dst.resize((dst_copy_size / dst_bytes_per_pixel) * ir_components); | 182 | ir_components); |
| 183 | impl->intermediate_dst.resize_destructive((dst_copy_size / dst_bytes_per_pixel) * | ||
| 184 | ir_components); | ||
| 182 | input_converter->ConvertTo(impl->src_buffer, impl->intermediate_src); | 185 | input_converter->ConvertTo(impl->src_buffer, impl->intermediate_src); |
| 183 | 186 | ||
| 184 | if (config.filter != Fermi2D::Filter::Bilinear) { | 187 | if (config.filter != Fermi2D::Filter::Bilinear) { |
| @@ -195,7 +198,7 @@ bool SoftwareBlitEngine::Blit(Fermi2D::Surface& src, Fermi2D::Surface& dst, | |||
| 195 | 198 | ||
| 196 | // Do actual Blit | 199 | // Do actual Blit |
| 197 | 200 | ||
| 198 | impl->dst_buffer.resize(dst_copy_size); | 201 | impl->dst_buffer.resize_destructive(dst_copy_size); |
| 199 | if (src.linear == Fermi2D::MemoryLayout::BlockLinear) { | 202 | if (src.linear == Fermi2D::MemoryLayout::BlockLinear) { |
| 200 | UnswizzleSubrect(impl->src_buffer, impl->tmp_buffer, src_bytes_per_pixel, src.width, | 203 | UnswizzleSubrect(impl->src_buffer, impl->tmp_buffer, src_bytes_per_pixel, src.width, |
| 201 | src.height, src.depth, config.src_x0, config.src_y0, src_extent_x, | 204 | src.height, src.depth, config.src_x0, config.src_y0, src_extent_x, |
| @@ -218,7 +221,7 @@ bool SoftwareBlitEngine::Blit(Fermi2D::Surface& src, Fermi2D::Surface& dst, | |||
| 218 | } | 221 | } |
| 219 | 222 | ||
| 220 | const size_t dst_size = get_surface_size(dst, dst_bytes_per_pixel); | 223 | const size_t dst_size = get_surface_size(dst, dst_bytes_per_pixel); |
| 221 | impl->tmp_buffer.resize(dst_size); | 224 | impl->tmp_buffer.resize_destructive(dst_size); |
| 222 | memory_manager.ReadBlock(dst.Address(), impl->tmp_buffer.data(), dst_size); | 225 | memory_manager.ReadBlock(dst.Address(), impl->tmp_buffer.data(), dst_size); |
| 223 | 226 | ||
| 224 | if (dst.linear == Fermi2D::MemoryLayout::BlockLinear) { | 227 | if (dst.linear == Fermi2D::MemoryLayout::BlockLinear) { |
diff --git a/src/video_core/host1x/codecs/h264.cpp b/src/video_core/host1x/codecs/h264.cpp index e87bd65fa..6ce179167 100644 --- a/src/video_core/host1x/codecs/h264.cpp +++ b/src/video_core/host1x/codecs/h264.cpp | |||
| @@ -111,7 +111,7 @@ const std::vector<u8>& H264::ComposeFrame(const Host1x::NvdecCommon::NvdecRegist | |||
| 111 | writer.WriteUe(0); | 111 | writer.WriteUe(0); |
| 112 | 112 | ||
| 113 | writer.WriteBit(context.h264_parameter_set.entropy_coding_mode_flag != 0); | 113 | writer.WriteBit(context.h264_parameter_set.entropy_coding_mode_flag != 0); |
| 114 | writer.WriteBit(false); | 114 | writer.WriteBit(context.h264_parameter_set.pic_order_present_flag != 0); |
| 115 | writer.WriteUe(0); | 115 | writer.WriteUe(0); |
| 116 | writer.WriteUe(context.h264_parameter_set.num_refidx_l0_default_active); | 116 | writer.WriteUe(context.h264_parameter_set.num_refidx_l0_default_active); |
| 117 | writer.WriteUe(context.h264_parameter_set.num_refidx_l1_default_active); | 117 | writer.WriteUe(context.h264_parameter_set.num_refidx_l1_default_active); |
| @@ -129,7 +129,7 @@ const std::vector<u8>& H264::ComposeFrame(const Host1x::NvdecCommon::NvdecRegist | |||
| 129 | writer.WriteBit(context.h264_parameter_set.redundant_pic_cnt_present_flag != 0); | 129 | writer.WriteBit(context.h264_parameter_set.redundant_pic_cnt_present_flag != 0); |
| 130 | writer.WriteBit(context.h264_parameter_set.transform_8x8_mode_flag != 0); | 130 | writer.WriteBit(context.h264_parameter_set.transform_8x8_mode_flag != 0); |
| 131 | 131 | ||
| 132 | writer.WriteBit(true); | 132 | writer.WriteBit(true); // pic_scaling_matrix_present_flag |
| 133 | 133 | ||
| 134 | for (s32 index = 0; index < 6; index++) { | 134 | for (s32 index = 0; index < 6; index++) { |
| 135 | writer.WriteBit(true); | 135 | writer.WriteBit(true); |
diff --git a/src/video_core/renderer_vulkan/pipeline_helper.h b/src/video_core/renderer_vulkan/pipeline_helper.h index 28b893e25..983e1c2e1 100644 --- a/src/video_core/renderer_vulkan/pipeline_helper.h +++ b/src/video_core/renderer_vulkan/pipeline_helper.h | |||
| @@ -176,7 +176,7 @@ public: | |||
| 176 | }; | 176 | }; |
| 177 | 177 | ||
| 178 | inline void PushImageDescriptors(TextureCache& texture_cache, | 178 | inline void PushImageDescriptors(TextureCache& texture_cache, |
| 179 | UpdateDescriptorQueue& update_descriptor_queue, | 179 | GuestDescriptorQueue& guest_descriptor_queue, |
| 180 | const Shader::Info& info, RescalingPushConstant& rescaling, | 180 | const Shader::Info& info, RescalingPushConstant& rescaling, |
| 181 | const VkSampler*& samplers, | 181 | const VkSampler*& samplers, |
| 182 | const VideoCommon::ImageViewInOut*& views) { | 182 | const VideoCommon::ImageViewInOut*& views) { |
| @@ -190,7 +190,7 @@ inline void PushImageDescriptors(TextureCache& texture_cache, | |||
| 190 | const VkSampler sampler{*(samplers++)}; | 190 | const VkSampler sampler{*(samplers++)}; |
| 191 | ImageView& image_view{texture_cache.GetImageView(image_view_id)}; | 191 | ImageView& image_view{texture_cache.GetImageView(image_view_id)}; |
| 192 | const VkImageView vk_image_view{image_view.Handle(desc.type)}; | 192 | const VkImageView vk_image_view{image_view.Handle(desc.type)}; |
| 193 | update_descriptor_queue.AddSampledImage(vk_image_view, sampler); | 193 | guest_descriptor_queue.AddSampledImage(vk_image_view, sampler); |
| 194 | rescaling.PushTexture(texture_cache.IsRescaling(image_view)); | 194 | rescaling.PushTexture(texture_cache.IsRescaling(image_view)); |
| 195 | } | 195 | } |
| 196 | } | 196 | } |
| @@ -201,7 +201,7 @@ inline void PushImageDescriptors(TextureCache& texture_cache, | |||
| 201 | texture_cache.MarkModification(image_view.image_id); | 201 | texture_cache.MarkModification(image_view.image_id); |
| 202 | } | 202 | } |
| 203 | const VkImageView vk_image_view{image_view.StorageView(desc.type, desc.format)}; | 203 | const VkImageView vk_image_view{image_view.StorageView(desc.type, desc.format)}; |
| 204 | update_descriptor_queue.AddImage(vk_image_view); | 204 | guest_descriptor_queue.AddImage(vk_image_view); |
| 205 | rescaling.PushImage(texture_cache.IsRescaling(image_view)); | 205 | rescaling.PushImage(texture_cache.IsRescaling(image_view)); |
| 206 | } | 206 | } |
| 207 | } | 207 | } |
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index 510602e8e..9627eb129 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp | |||
| @@ -298,12 +298,14 @@ private: | |||
| 298 | 298 | ||
| 299 | BufferCacheRuntime::BufferCacheRuntime(const Device& device_, MemoryAllocator& memory_allocator_, | 299 | BufferCacheRuntime::BufferCacheRuntime(const Device& device_, MemoryAllocator& memory_allocator_, |
| 300 | Scheduler& scheduler_, StagingBufferPool& staging_pool_, | 300 | Scheduler& scheduler_, StagingBufferPool& staging_pool_, |
| 301 | UpdateDescriptorQueue& update_descriptor_queue_, | 301 | GuestDescriptorQueue& guest_descriptor_queue_, |
| 302 | ComputePassDescriptorQueue& compute_pass_descriptor_queue, | ||
| 302 | DescriptorPool& descriptor_pool) | 303 | DescriptorPool& descriptor_pool) |
| 303 | : device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_}, | 304 | : device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_}, |
| 304 | staging_pool{staging_pool_}, update_descriptor_queue{update_descriptor_queue_}, | 305 | staging_pool{staging_pool_}, guest_descriptor_queue{guest_descriptor_queue_}, |
| 305 | uint8_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), | 306 | uint8_pass(device, scheduler, descriptor_pool, staging_pool, compute_pass_descriptor_queue), |
| 306 | quad_index_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue) { | 307 | quad_index_pass(device, scheduler, descriptor_pool, staging_pool, |
| 308 | compute_pass_descriptor_queue) { | ||
| 307 | quad_array_index_buffer = std::make_shared<QuadArrayIndexBuffer>(device_, memory_allocator_, | 309 | quad_array_index_buffer = std::make_shared<QuadArrayIndexBuffer>(device_, memory_allocator_, |
| 308 | scheduler_, staging_pool_); | 310 | scheduler_, staging_pool_); |
| 309 | quad_strip_index_buffer = std::make_shared<QuadStripIndexBuffer>(device_, memory_allocator_, | 311 | quad_strip_index_buffer = std::make_shared<QuadStripIndexBuffer>(device_, memory_allocator_, |
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h index 879f1ed94..5e9602905 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.h +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h | |||
| @@ -63,7 +63,8 @@ class BufferCacheRuntime { | |||
| 63 | public: | 63 | public: |
| 64 | explicit BufferCacheRuntime(const Device& device_, MemoryAllocator& memory_manager_, | 64 | explicit BufferCacheRuntime(const Device& device_, MemoryAllocator& memory_manager_, |
| 65 | Scheduler& scheduler_, StagingBufferPool& staging_pool_, | 65 | Scheduler& scheduler_, StagingBufferPool& staging_pool_, |
| 66 | UpdateDescriptorQueue& update_descriptor_queue_, | 66 | GuestDescriptorQueue& guest_descriptor_queue, |
| 67 | ComputePassDescriptorQueue& compute_pass_descriptor_queue, | ||
| 67 | DescriptorPool& descriptor_pool); | 68 | DescriptorPool& descriptor_pool); |
| 68 | 69 | ||
| 69 | void Finish(); | 70 | void Finish(); |
| @@ -116,12 +117,12 @@ public: | |||
| 116 | 117 | ||
| 117 | void BindTextureBuffer(Buffer& buffer, u32 offset, u32 size, | 118 | void BindTextureBuffer(Buffer& buffer, u32 offset, u32 size, |
| 118 | VideoCore::Surface::PixelFormat format) { | 119 | VideoCore::Surface::PixelFormat format) { |
| 119 | update_descriptor_queue.AddTexelBuffer(buffer.View(offset, size, format)); | 120 | guest_descriptor_queue.AddTexelBuffer(buffer.View(offset, size, format)); |
| 120 | } | 121 | } |
| 121 | 122 | ||
| 122 | private: | 123 | private: |
| 123 | void BindBuffer(VkBuffer buffer, u32 offset, u32 size) { | 124 | void BindBuffer(VkBuffer buffer, u32 offset, u32 size) { |
| 124 | update_descriptor_queue.AddBuffer(buffer, offset, size); | 125 | guest_descriptor_queue.AddBuffer(buffer, offset, size); |
| 125 | } | 126 | } |
| 126 | 127 | ||
| 127 | void ReserveNullBuffer(); | 128 | void ReserveNullBuffer(); |
| @@ -130,7 +131,7 @@ private: | |||
| 130 | MemoryAllocator& memory_allocator; | 131 | MemoryAllocator& memory_allocator; |
| 131 | Scheduler& scheduler; | 132 | Scheduler& scheduler; |
| 132 | StagingBufferPool& staging_pool; | 133 | StagingBufferPool& staging_pool; |
| 133 | UpdateDescriptorQueue& update_descriptor_queue; | 134 | GuestDescriptorQueue& guest_descriptor_queue; |
| 134 | 135 | ||
| 135 | std::shared_ptr<QuadArrayIndexBuffer> quad_array_index_buffer; | 136 | std::shared_ptr<QuadArrayIndexBuffer> quad_array_index_buffer; |
| 136 | std::shared_ptr<QuadStripIndexBuffer> quad_strip_index_buffer; | 137 | std::shared_ptr<QuadStripIndexBuffer> quad_strip_index_buffer; |
diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp index 1a316b6eb..3bc8553e1 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp | |||
| @@ -200,12 +200,12 @@ ComputePass::~ComputePass() = default; | |||
| 200 | 200 | ||
| 201 | Uint8Pass::Uint8Pass(const Device& device_, Scheduler& scheduler_, DescriptorPool& descriptor_pool, | 201 | Uint8Pass::Uint8Pass(const Device& device_, Scheduler& scheduler_, DescriptorPool& descriptor_pool, |
| 202 | StagingBufferPool& staging_buffer_pool_, | 202 | StagingBufferPool& staging_buffer_pool_, |
| 203 | UpdateDescriptorQueue& update_descriptor_queue_) | 203 | ComputePassDescriptorQueue& compute_pass_descriptor_queue_) |
| 204 | : ComputePass(device_, descriptor_pool, INPUT_OUTPUT_DESCRIPTOR_SET_BINDINGS, | 204 | : ComputePass(device_, descriptor_pool, INPUT_OUTPUT_DESCRIPTOR_SET_BINDINGS, |
| 205 | INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE, INPUT_OUTPUT_BANK_INFO, {}, | 205 | INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE, INPUT_OUTPUT_BANK_INFO, {}, |
| 206 | VULKAN_UINT8_COMP_SPV), | 206 | VULKAN_UINT8_COMP_SPV), |
| 207 | scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_}, | 207 | scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_}, |
| 208 | update_descriptor_queue{update_descriptor_queue_} {} | 208 | compute_pass_descriptor_queue{compute_pass_descriptor_queue_} {} |
| 209 | 209 | ||
| 210 | Uint8Pass::~Uint8Pass() = default; | 210 | Uint8Pass::~Uint8Pass() = default; |
| 211 | 211 | ||
| @@ -214,10 +214,10 @@ std::pair<VkBuffer, VkDeviceSize> Uint8Pass::Assemble(u32 num_vertices, VkBuffer | |||
| 214 | const u32 staging_size = static_cast<u32>(num_vertices * sizeof(u16)); | 214 | const u32 staging_size = static_cast<u32>(num_vertices * sizeof(u16)); |
| 215 | const auto staging = staging_buffer_pool.Request(staging_size, MemoryUsage::DeviceLocal); | 215 | const auto staging = staging_buffer_pool.Request(staging_size, MemoryUsage::DeviceLocal); |
| 216 | 216 | ||
| 217 | update_descriptor_queue.Acquire(); | 217 | compute_pass_descriptor_queue.Acquire(); |
| 218 | update_descriptor_queue.AddBuffer(src_buffer, src_offset, num_vertices); | 218 | compute_pass_descriptor_queue.AddBuffer(src_buffer, src_offset, num_vertices); |
| 219 | update_descriptor_queue.AddBuffer(staging.buffer, staging.offset, staging_size); | 219 | compute_pass_descriptor_queue.AddBuffer(staging.buffer, staging.offset, staging_size); |
| 220 | const void* const descriptor_data{update_descriptor_queue.UpdateData()}; | 220 | const void* const descriptor_data{compute_pass_descriptor_queue.UpdateData()}; |
| 221 | 221 | ||
| 222 | scheduler.RequestOutsideRenderPassOperationContext(); | 222 | scheduler.RequestOutsideRenderPassOperationContext(); |
| 223 | scheduler.Record([this, descriptor_data, num_vertices](vk::CommandBuffer cmdbuf) { | 223 | scheduler.Record([this, descriptor_data, num_vertices](vk::CommandBuffer cmdbuf) { |
| @@ -242,12 +242,12 @@ std::pair<VkBuffer, VkDeviceSize> Uint8Pass::Assemble(u32 num_vertices, VkBuffer | |||
| 242 | QuadIndexedPass::QuadIndexedPass(const Device& device_, Scheduler& scheduler_, | 242 | QuadIndexedPass::QuadIndexedPass(const Device& device_, Scheduler& scheduler_, |
| 243 | DescriptorPool& descriptor_pool_, | 243 | DescriptorPool& descriptor_pool_, |
| 244 | StagingBufferPool& staging_buffer_pool_, | 244 | StagingBufferPool& staging_buffer_pool_, |
| 245 | UpdateDescriptorQueue& update_descriptor_queue_) | 245 | ComputePassDescriptorQueue& compute_pass_descriptor_queue_) |
| 246 | : ComputePass(device_, descriptor_pool_, INPUT_OUTPUT_DESCRIPTOR_SET_BINDINGS, | 246 | : ComputePass(device_, descriptor_pool_, INPUT_OUTPUT_DESCRIPTOR_SET_BINDINGS, |
| 247 | INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE, INPUT_OUTPUT_BANK_INFO, | 247 | INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE, INPUT_OUTPUT_BANK_INFO, |
| 248 | COMPUTE_PUSH_CONSTANT_RANGE<sizeof(u32) * 3>, VULKAN_QUAD_INDEXED_COMP_SPV), | 248 | COMPUTE_PUSH_CONSTANT_RANGE<sizeof(u32) * 3>, VULKAN_QUAD_INDEXED_COMP_SPV), |
| 249 | scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_}, | 249 | scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_}, |
| 250 | update_descriptor_queue{update_descriptor_queue_} {} | 250 | compute_pass_descriptor_queue{compute_pass_descriptor_queue_} {} |
| 251 | 251 | ||
| 252 | QuadIndexedPass::~QuadIndexedPass() = default; | 252 | QuadIndexedPass::~QuadIndexedPass() = default; |
| 253 | 253 | ||
| @@ -272,10 +272,10 @@ std::pair<VkBuffer, VkDeviceSize> QuadIndexedPass::Assemble( | |||
| 272 | const std::size_t staging_size = num_tri_vertices * sizeof(u32); | 272 | const std::size_t staging_size = num_tri_vertices * sizeof(u32); |
| 273 | const auto staging = staging_buffer_pool.Request(staging_size, MemoryUsage::DeviceLocal); | 273 | const auto staging = staging_buffer_pool.Request(staging_size, MemoryUsage::DeviceLocal); |
| 274 | 274 | ||
| 275 | update_descriptor_queue.Acquire(); | 275 | compute_pass_descriptor_queue.Acquire(); |
| 276 | update_descriptor_queue.AddBuffer(src_buffer, src_offset, input_size); | 276 | compute_pass_descriptor_queue.AddBuffer(src_buffer, src_offset, input_size); |
| 277 | update_descriptor_queue.AddBuffer(staging.buffer, staging.offset, staging_size); | 277 | compute_pass_descriptor_queue.AddBuffer(staging.buffer, staging.offset, staging_size); |
| 278 | const void* const descriptor_data{update_descriptor_queue.UpdateData()}; | 278 | const void* const descriptor_data{compute_pass_descriptor_queue.UpdateData()}; |
| 279 | 279 | ||
| 280 | scheduler.RequestOutsideRenderPassOperationContext(); | 280 | scheduler.RequestOutsideRenderPassOperationContext(); |
| 281 | scheduler.Record([this, descriptor_data, num_tri_vertices, base_vertex, index_shift, | 281 | scheduler.Record([this, descriptor_data, num_tri_vertices, base_vertex, index_shift, |
| @@ -304,13 +304,14 @@ std::pair<VkBuffer, VkDeviceSize> QuadIndexedPass::Assemble( | |||
| 304 | ASTCDecoderPass::ASTCDecoderPass(const Device& device_, Scheduler& scheduler_, | 304 | ASTCDecoderPass::ASTCDecoderPass(const Device& device_, Scheduler& scheduler_, |
| 305 | DescriptorPool& descriptor_pool_, | 305 | DescriptorPool& descriptor_pool_, |
| 306 | StagingBufferPool& staging_buffer_pool_, | 306 | StagingBufferPool& staging_buffer_pool_, |
| 307 | UpdateDescriptorQueue& update_descriptor_queue_, | 307 | ComputePassDescriptorQueue& compute_pass_descriptor_queue_, |
| 308 | MemoryAllocator& memory_allocator_) | 308 | MemoryAllocator& memory_allocator_) |
| 309 | : ComputePass(device_, descriptor_pool_, ASTC_DESCRIPTOR_SET_BINDINGS, | 309 | : ComputePass(device_, descriptor_pool_, ASTC_DESCRIPTOR_SET_BINDINGS, |
| 310 | ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY, ASTC_BANK_INFO, | 310 | ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY, ASTC_BANK_INFO, |
| 311 | COMPUTE_PUSH_CONSTANT_RANGE<sizeof(AstcPushConstants)>, ASTC_DECODER_COMP_SPV), | 311 | COMPUTE_PUSH_CONSTANT_RANGE<sizeof(AstcPushConstants)>, ASTC_DECODER_COMP_SPV), |
| 312 | scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_}, | 312 | scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_}, |
| 313 | update_descriptor_queue{update_descriptor_queue_}, memory_allocator{memory_allocator_} {} | 313 | compute_pass_descriptor_queue{compute_pass_descriptor_queue_}, memory_allocator{ |
| 314 | memory_allocator_} {} | ||
| 314 | 315 | ||
| 315 | ASTCDecoderPass::~ASTCDecoderPass() = default; | 316 | ASTCDecoderPass::~ASTCDecoderPass() = default; |
| 316 | 317 | ||
| @@ -358,11 +359,11 @@ void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map, | |||
| 358 | const u32 num_dispatches_y = Common::DivCeil(swizzle.num_tiles.height, 8U); | 359 | const u32 num_dispatches_y = Common::DivCeil(swizzle.num_tiles.height, 8U); |
| 359 | const u32 num_dispatches_z = image.info.resources.layers; | 360 | const u32 num_dispatches_z = image.info.resources.layers; |
| 360 | 361 | ||
| 361 | update_descriptor_queue.Acquire(); | 362 | compute_pass_descriptor_queue.Acquire(); |
| 362 | update_descriptor_queue.AddBuffer(map.buffer, input_offset, | 363 | compute_pass_descriptor_queue.AddBuffer(map.buffer, input_offset, |
| 363 | image.guest_size_bytes - swizzle.buffer_offset); | 364 | image.guest_size_bytes - swizzle.buffer_offset); |
| 364 | update_descriptor_queue.AddImage(image.StorageImageView(swizzle.level)); | 365 | compute_pass_descriptor_queue.AddImage(image.StorageImageView(swizzle.level)); |
| 365 | const void* const descriptor_data{update_descriptor_queue.UpdateData()}; | 366 | const void* const descriptor_data{compute_pass_descriptor_queue.UpdateData()}; |
| 366 | 367 | ||
| 367 | // To unswizzle the ASTC data | 368 | // To unswizzle the ASTC data |
| 368 | const auto params = MakeBlockLinearSwizzle2DParams(swizzle, image.info); | 369 | const auto params = MakeBlockLinearSwizzle2DParams(swizzle, image.info); |
diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.h b/src/video_core/renderer_vulkan/vk_compute_pass.h index c4c8fa081..dd3927376 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pass.h +++ b/src/video_core/renderer_vulkan/vk_compute_pass.h | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "video_core/engines/maxwell_3d.h" | 10 | #include "video_core/engines/maxwell_3d.h" |
| 11 | #include "video_core/renderer_vulkan/vk_descriptor_pool.h" | 11 | #include "video_core/renderer_vulkan/vk_descriptor_pool.h" |
| 12 | #include "video_core/renderer_vulkan/vk_update_descriptor.h" | ||
| 12 | #include "video_core/vulkan_common/vulkan_memory_allocator.h" | 13 | #include "video_core/vulkan_common/vulkan_memory_allocator.h" |
| 13 | #include "video_core/vulkan_common/vulkan_wrapper.h" | 14 | #include "video_core/vulkan_common/vulkan_wrapper.h" |
| 14 | 15 | ||
| @@ -21,7 +22,6 @@ namespace Vulkan { | |||
| 21 | class Device; | 22 | class Device; |
| 22 | class StagingBufferPool; | 23 | class StagingBufferPool; |
| 23 | class Scheduler; | 24 | class Scheduler; |
| 24 | class UpdateDescriptorQueue; | ||
| 25 | class Image; | 25 | class Image; |
| 26 | struct StagingBufferRef; | 26 | struct StagingBufferRef; |
| 27 | 27 | ||
| @@ -50,7 +50,7 @@ class Uint8Pass final : public ComputePass { | |||
| 50 | public: | 50 | public: |
| 51 | explicit Uint8Pass(const Device& device_, Scheduler& scheduler_, | 51 | explicit Uint8Pass(const Device& device_, Scheduler& scheduler_, |
| 52 | DescriptorPool& descriptor_pool_, StagingBufferPool& staging_buffer_pool_, | 52 | DescriptorPool& descriptor_pool_, StagingBufferPool& staging_buffer_pool_, |
| 53 | UpdateDescriptorQueue& update_descriptor_queue_); | 53 | ComputePassDescriptorQueue& compute_pass_descriptor_queue_); |
| 54 | ~Uint8Pass(); | 54 | ~Uint8Pass(); |
| 55 | 55 | ||
| 56 | /// Assemble uint8 indices into an uint16 index buffer | 56 | /// Assemble uint8 indices into an uint16 index buffer |
| @@ -61,7 +61,7 @@ public: | |||
| 61 | private: | 61 | private: |
| 62 | Scheduler& scheduler; | 62 | Scheduler& scheduler; |
| 63 | StagingBufferPool& staging_buffer_pool; | 63 | StagingBufferPool& staging_buffer_pool; |
| 64 | UpdateDescriptorQueue& update_descriptor_queue; | 64 | ComputePassDescriptorQueue& compute_pass_descriptor_queue; |
| 65 | }; | 65 | }; |
| 66 | 66 | ||
| 67 | class QuadIndexedPass final : public ComputePass { | 67 | class QuadIndexedPass final : public ComputePass { |
| @@ -69,7 +69,7 @@ public: | |||
| 69 | explicit QuadIndexedPass(const Device& device_, Scheduler& scheduler_, | 69 | explicit QuadIndexedPass(const Device& device_, Scheduler& scheduler_, |
| 70 | DescriptorPool& descriptor_pool_, | 70 | DescriptorPool& descriptor_pool_, |
| 71 | StagingBufferPool& staging_buffer_pool_, | 71 | StagingBufferPool& staging_buffer_pool_, |
| 72 | UpdateDescriptorQueue& update_descriptor_queue_); | 72 | ComputePassDescriptorQueue& compute_pass_descriptor_queue_); |
| 73 | ~QuadIndexedPass(); | 73 | ~QuadIndexedPass(); |
| 74 | 74 | ||
| 75 | std::pair<VkBuffer, VkDeviceSize> Assemble( | 75 | std::pair<VkBuffer, VkDeviceSize> Assemble( |
| @@ -79,7 +79,7 @@ public: | |||
| 79 | private: | 79 | private: |
| 80 | Scheduler& scheduler; | 80 | Scheduler& scheduler; |
| 81 | StagingBufferPool& staging_buffer_pool; | 81 | StagingBufferPool& staging_buffer_pool; |
| 82 | UpdateDescriptorQueue& update_descriptor_queue; | 82 | ComputePassDescriptorQueue& compute_pass_descriptor_queue; |
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| 85 | class ASTCDecoderPass final : public ComputePass { | 85 | class ASTCDecoderPass final : public ComputePass { |
| @@ -87,7 +87,7 @@ public: | |||
| 87 | explicit ASTCDecoderPass(const Device& device_, Scheduler& scheduler_, | 87 | explicit ASTCDecoderPass(const Device& device_, Scheduler& scheduler_, |
| 88 | DescriptorPool& descriptor_pool_, | 88 | DescriptorPool& descriptor_pool_, |
| 89 | StagingBufferPool& staging_buffer_pool_, | 89 | StagingBufferPool& staging_buffer_pool_, |
| 90 | UpdateDescriptorQueue& update_descriptor_queue_, | 90 | ComputePassDescriptorQueue& compute_pass_descriptor_queue_, |
| 91 | MemoryAllocator& memory_allocator_); | 91 | MemoryAllocator& memory_allocator_); |
| 92 | ~ASTCDecoderPass(); | 92 | ~ASTCDecoderPass(); |
| 93 | 93 | ||
| @@ -97,7 +97,7 @@ public: | |||
| 97 | private: | 97 | private: |
| 98 | Scheduler& scheduler; | 98 | Scheduler& scheduler; |
| 99 | StagingBufferPool& staging_buffer_pool; | 99 | StagingBufferPool& staging_buffer_pool; |
| 100 | UpdateDescriptorQueue& update_descriptor_queue; | 100 | ComputePassDescriptorQueue& compute_pass_descriptor_queue; |
| 101 | MemoryAllocator& memory_allocator; | 101 | MemoryAllocator& memory_allocator; |
| 102 | }; | 102 | }; |
| 103 | 103 | ||
diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp index 2a0f0dbf0..733e70d9d 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp | |||
| @@ -26,13 +26,13 @@ using Tegra::Texture::TexturePair; | |||
| 26 | 26 | ||
| 27 | ComputePipeline::ComputePipeline(const Device& device_, vk::PipelineCache& pipeline_cache_, | 27 | ComputePipeline::ComputePipeline(const Device& device_, vk::PipelineCache& pipeline_cache_, |
| 28 | DescriptorPool& descriptor_pool, | 28 | DescriptorPool& descriptor_pool, |
| 29 | UpdateDescriptorQueue& update_descriptor_queue_, | 29 | GuestDescriptorQueue& guest_descriptor_queue_, |
| 30 | Common::ThreadWorker* thread_worker, | 30 | Common::ThreadWorker* thread_worker, |
| 31 | PipelineStatistics* pipeline_statistics, | 31 | PipelineStatistics* pipeline_statistics, |
| 32 | VideoCore::ShaderNotify* shader_notify, const Shader::Info& info_, | 32 | VideoCore::ShaderNotify* shader_notify, const Shader::Info& info_, |
| 33 | vk::ShaderModule spv_module_) | 33 | vk::ShaderModule spv_module_) |
| 34 | : device{device_}, pipeline_cache(pipeline_cache_), | 34 | : device{device_}, |
| 35 | update_descriptor_queue{update_descriptor_queue_}, info{info_}, | 35 | pipeline_cache(pipeline_cache_), guest_descriptor_queue{guest_descriptor_queue_}, info{info_}, |
| 36 | spv_module(std::move(spv_module_)) { | 36 | spv_module(std::move(spv_module_)) { |
| 37 | if (shader_notify) { | 37 | if (shader_notify) { |
| 38 | shader_notify->MarkShaderBuilding(); | 38 | shader_notify->MarkShaderBuilding(); |
| @@ -99,7 +99,7 @@ ComputePipeline::ComputePipeline(const Device& device_, vk::PipelineCache& pipel | |||
| 99 | void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, | 99 | void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, |
| 100 | Tegra::MemoryManager& gpu_memory, Scheduler& scheduler, | 100 | Tegra::MemoryManager& gpu_memory, Scheduler& scheduler, |
| 101 | BufferCache& buffer_cache, TextureCache& texture_cache) { | 101 | BufferCache& buffer_cache, TextureCache& texture_cache) { |
| 102 | update_descriptor_queue.Acquire(); | 102 | guest_descriptor_queue.Acquire(); |
| 103 | 103 | ||
| 104 | buffer_cache.SetComputeUniformBufferState(info.constant_buffer_mask, &uniform_buffer_sizes); | 104 | buffer_cache.SetComputeUniformBufferState(info.constant_buffer_mask, &uniform_buffer_sizes); |
| 105 | buffer_cache.UnbindComputeStorageBuffers(); | 105 | buffer_cache.UnbindComputeStorageBuffers(); |
| @@ -194,7 +194,7 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, | |||
| 194 | RescalingPushConstant rescaling; | 194 | RescalingPushConstant rescaling; |
| 195 | const VkSampler* samplers_it{samplers.data()}; | 195 | const VkSampler* samplers_it{samplers.data()}; |
| 196 | const VideoCommon::ImageViewInOut* views_it{views.data()}; | 196 | const VideoCommon::ImageViewInOut* views_it{views.data()}; |
| 197 | PushImageDescriptors(texture_cache, update_descriptor_queue, info, rescaling, samplers_it, | 197 | PushImageDescriptors(texture_cache, guest_descriptor_queue, info, rescaling, samplers_it, |
| 198 | views_it); | 198 | views_it); |
| 199 | 199 | ||
| 200 | if (!is_built.load(std::memory_order::relaxed)) { | 200 | if (!is_built.load(std::memory_order::relaxed)) { |
| @@ -204,7 +204,7 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute, | |||
| 204 | build_condvar.wait(lock, [this] { return is_built.load(std::memory_order::relaxed); }); | 204 | build_condvar.wait(lock, [this] { return is_built.load(std::memory_order::relaxed); }); |
| 205 | }); | 205 | }); |
| 206 | } | 206 | } |
| 207 | const void* const descriptor_data{update_descriptor_queue.UpdateData()}; | 207 | const void* const descriptor_data{guest_descriptor_queue.UpdateData()}; |
| 208 | const bool is_rescaling = !info.texture_descriptors.empty() || !info.image_descriptors.empty(); | 208 | const bool is_rescaling = !info.texture_descriptors.empty() || !info.image_descriptors.empty(); |
| 209 | scheduler.Record([this, descriptor_data, is_rescaling, | 209 | scheduler.Record([this, descriptor_data, is_rescaling, |
| 210 | rescaling_data = rescaling.Data()](vk::CommandBuffer cmdbuf) { | 210 | rescaling_data = rescaling.Data()](vk::CommandBuffer cmdbuf) { |
diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.h b/src/video_core/renderer_vulkan/vk_compute_pipeline.h index 78d77027f..d1a1e2c46 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.h | |||
| @@ -30,7 +30,7 @@ class ComputePipeline { | |||
| 30 | public: | 30 | public: |
| 31 | explicit ComputePipeline(const Device& device, vk::PipelineCache& pipeline_cache, | 31 | explicit ComputePipeline(const Device& device, vk::PipelineCache& pipeline_cache, |
| 32 | DescriptorPool& descriptor_pool, | 32 | DescriptorPool& descriptor_pool, |
| 33 | UpdateDescriptorQueue& update_descriptor_queue, | 33 | GuestDescriptorQueue& guest_descriptor_queue, |
| 34 | Common::ThreadWorker* thread_worker, | 34 | Common::ThreadWorker* thread_worker, |
| 35 | PipelineStatistics* pipeline_statistics, | 35 | PipelineStatistics* pipeline_statistics, |
| 36 | VideoCore::ShaderNotify* shader_notify, const Shader::Info& info, | 36 | VideoCore::ShaderNotify* shader_notify, const Shader::Info& info, |
| @@ -48,7 +48,7 @@ public: | |||
| 48 | private: | 48 | private: |
| 49 | const Device& device; | 49 | const Device& device; |
| 50 | vk::PipelineCache& pipeline_cache; | 50 | vk::PipelineCache& pipeline_cache; |
| 51 | UpdateDescriptorQueue& update_descriptor_queue; | 51 | GuestDescriptorQueue& guest_descriptor_queue; |
| 52 | Shader::Info info; | 52 | Shader::Info info; |
| 53 | 53 | ||
| 54 | VideoCommon::ComputeUniformBufferSizes uniform_buffer_sizes{}; | 54 | VideoCommon::ComputeUniformBufferSizes uniform_buffer_sizes{}; |
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index baedc4424..f1bcd5cd6 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp | |||
| @@ -236,13 +236,13 @@ GraphicsPipeline::GraphicsPipeline( | |||
| 236 | Scheduler& scheduler_, BufferCache& buffer_cache_, TextureCache& texture_cache_, | 236 | Scheduler& scheduler_, BufferCache& buffer_cache_, TextureCache& texture_cache_, |
| 237 | vk::PipelineCache& pipeline_cache_, VideoCore::ShaderNotify* shader_notify, | 237 | vk::PipelineCache& pipeline_cache_, VideoCore::ShaderNotify* shader_notify, |
| 238 | const Device& device_, DescriptorPool& descriptor_pool, | 238 | const Device& device_, DescriptorPool& descriptor_pool, |
| 239 | UpdateDescriptorQueue& update_descriptor_queue_, Common::ThreadWorker* worker_thread, | 239 | GuestDescriptorQueue& guest_descriptor_queue_, Common::ThreadWorker* worker_thread, |
| 240 | PipelineStatistics* pipeline_statistics, RenderPassCache& render_pass_cache, | 240 | PipelineStatistics* pipeline_statistics, RenderPassCache& render_pass_cache, |
| 241 | const GraphicsPipelineCacheKey& key_, std::array<vk::ShaderModule, NUM_STAGES> stages, | 241 | const GraphicsPipelineCacheKey& key_, std::array<vk::ShaderModule, NUM_STAGES> stages, |
| 242 | const std::array<const Shader::Info*, NUM_STAGES>& infos) | 242 | const std::array<const Shader::Info*, NUM_STAGES>& infos) |
| 243 | : key{key_}, device{device_}, texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, | 243 | : key{key_}, device{device_}, texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, |
| 244 | pipeline_cache(pipeline_cache_), scheduler{scheduler_}, | 244 | pipeline_cache(pipeline_cache_), scheduler{scheduler_}, |
| 245 | update_descriptor_queue{update_descriptor_queue_}, spv_modules{std::move(stages)} { | 245 | guest_descriptor_queue{guest_descriptor_queue_}, spv_modules{std::move(stages)} { |
| 246 | if (shader_notify) { | 246 | if (shader_notify) { |
| 247 | shader_notify->MarkShaderBuilding(); | 247 | shader_notify->MarkShaderBuilding(); |
| 248 | } | 248 | } |
| @@ -449,7 +449,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 449 | buffer_cache.UpdateGraphicsBuffers(is_indexed); | 449 | buffer_cache.UpdateGraphicsBuffers(is_indexed); |
| 450 | buffer_cache.BindHostGeometryBuffers(is_indexed); | 450 | buffer_cache.BindHostGeometryBuffers(is_indexed); |
| 451 | 451 | ||
| 452 | update_descriptor_queue.Acquire(); | 452 | guest_descriptor_queue.Acquire(); |
| 453 | 453 | ||
| 454 | RescalingPushConstant rescaling; | 454 | RescalingPushConstant rescaling; |
| 455 | RenderAreaPushConstant render_area; | 455 | RenderAreaPushConstant render_area; |
| @@ -457,7 +457,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 457 | const VideoCommon::ImageViewInOut* views_it{views.data()}; | 457 | const VideoCommon::ImageViewInOut* views_it{views.data()}; |
| 458 | const auto prepare_stage{[&](size_t stage) LAMBDA_FORCEINLINE { | 458 | const auto prepare_stage{[&](size_t stage) LAMBDA_FORCEINLINE { |
| 459 | buffer_cache.BindHostStageBuffers(stage); | 459 | buffer_cache.BindHostStageBuffers(stage); |
| 460 | PushImageDescriptors(texture_cache, update_descriptor_queue, stage_infos[stage], rescaling, | 460 | PushImageDescriptors(texture_cache, guest_descriptor_queue, stage_infos[stage], rescaling, |
| 461 | samplers_it, views_it); | 461 | samplers_it, views_it); |
| 462 | const auto& info{stage_infos[0]}; | 462 | const auto& info{stage_infos[0]}; |
| 463 | if (info.uses_render_area) { | 463 | if (info.uses_render_area) { |
| @@ -499,7 +499,7 @@ void GraphicsPipeline::ConfigureDraw(const RescalingPushConstant& rescaling, | |||
| 499 | const bool is_rescaling{texture_cache.IsRescaling()}; | 499 | const bool is_rescaling{texture_cache.IsRescaling()}; |
| 500 | const bool update_rescaling{scheduler.UpdateRescaling(is_rescaling)}; | 500 | const bool update_rescaling{scheduler.UpdateRescaling(is_rescaling)}; |
| 501 | const bool bind_pipeline{scheduler.UpdateGraphicsPipeline(this)}; | 501 | const bool bind_pipeline{scheduler.UpdateGraphicsPipeline(this)}; |
| 502 | const void* const descriptor_data{update_descriptor_queue.UpdateData()}; | 502 | const void* const descriptor_data{guest_descriptor_queue.UpdateData()}; |
| 503 | scheduler.Record([this, descriptor_data, bind_pipeline, rescaling_data = rescaling.Data(), | 503 | scheduler.Record([this, descriptor_data, bind_pipeline, rescaling_data = rescaling.Data(), |
| 504 | is_rescaling, update_rescaling, | 504 | is_rescaling, update_rescaling, |
| 505 | uses_render_area = render_area.uses_render_area, | 505 | uses_render_area = render_area.uses_render_area, |
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h index 67c657d0e..99e56e9ad 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h | |||
| @@ -64,7 +64,6 @@ class RenderPassCache; | |||
| 64 | class RescalingPushConstant; | 64 | class RescalingPushConstant; |
| 65 | class RenderAreaPushConstant; | 65 | class RenderAreaPushConstant; |
| 66 | class Scheduler; | 66 | class Scheduler; |
| 67 | class UpdateDescriptorQueue; | ||
| 68 | 67 | ||
| 69 | class GraphicsPipeline { | 68 | class GraphicsPipeline { |
| 70 | static constexpr size_t NUM_STAGES = Tegra::Engines::Maxwell3D::Regs::MaxShaderStage; | 69 | static constexpr size_t NUM_STAGES = Tegra::Engines::Maxwell3D::Regs::MaxShaderStage; |
| @@ -74,7 +73,7 @@ public: | |||
| 74 | Scheduler& scheduler, BufferCache& buffer_cache, TextureCache& texture_cache, | 73 | Scheduler& scheduler, BufferCache& buffer_cache, TextureCache& texture_cache, |
| 75 | vk::PipelineCache& pipeline_cache, VideoCore::ShaderNotify* shader_notify, | 74 | vk::PipelineCache& pipeline_cache, VideoCore::ShaderNotify* shader_notify, |
| 76 | const Device& device, DescriptorPool& descriptor_pool, | 75 | const Device& device, DescriptorPool& descriptor_pool, |
| 77 | UpdateDescriptorQueue& update_descriptor_queue, Common::ThreadWorker* worker_thread, | 76 | GuestDescriptorQueue& guest_descriptor_queue, Common::ThreadWorker* worker_thread, |
| 78 | PipelineStatistics* pipeline_statistics, RenderPassCache& render_pass_cache, | 77 | PipelineStatistics* pipeline_statistics, RenderPassCache& render_pass_cache, |
| 79 | const GraphicsPipelineCacheKey& key, std::array<vk::ShaderModule, NUM_STAGES> stages, | 78 | const GraphicsPipelineCacheKey& key, std::array<vk::ShaderModule, NUM_STAGES> stages, |
| 80 | const std::array<const Shader::Info*, NUM_STAGES>& infos); | 79 | const std::array<const Shader::Info*, NUM_STAGES>& infos); |
| @@ -133,7 +132,7 @@ private: | |||
| 133 | BufferCache& buffer_cache; | 132 | BufferCache& buffer_cache; |
| 134 | vk::PipelineCache& pipeline_cache; | 133 | vk::PipelineCache& pipeline_cache; |
| 135 | Scheduler& scheduler; | 134 | Scheduler& scheduler; |
| 136 | UpdateDescriptorQueue& update_descriptor_queue; | 135 | GuestDescriptorQueue& guest_descriptor_queue; |
| 137 | 136 | ||
| 138 | void (*configure_func)(GraphicsPipeline*, bool){}; | 137 | void (*configure_func)(GraphicsPipeline*, bool){}; |
| 139 | 138 | ||
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index a318d643e..66dfe5733 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -277,11 +277,11 @@ bool GraphicsPipelineCacheKey::operator==(const GraphicsPipelineCacheKey& rhs) c | |||
| 277 | 277 | ||
| 278 | PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device_, | 278 | PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device_, |
| 279 | Scheduler& scheduler_, DescriptorPool& descriptor_pool_, | 279 | Scheduler& scheduler_, DescriptorPool& descriptor_pool_, |
| 280 | UpdateDescriptorQueue& update_descriptor_queue_, | 280 | GuestDescriptorQueue& guest_descriptor_queue_, |
| 281 | RenderPassCache& render_pass_cache_, BufferCache& buffer_cache_, | 281 | RenderPassCache& render_pass_cache_, BufferCache& buffer_cache_, |
| 282 | TextureCache& texture_cache_, VideoCore::ShaderNotify& shader_notify_) | 282 | TextureCache& texture_cache_, VideoCore::ShaderNotify& shader_notify_) |
| 283 | : VideoCommon::ShaderCache{rasterizer_}, device{device_}, scheduler{scheduler_}, | 283 | : VideoCommon::ShaderCache{rasterizer_}, device{device_}, scheduler{scheduler_}, |
| 284 | descriptor_pool{descriptor_pool_}, update_descriptor_queue{update_descriptor_queue_}, | 284 | descriptor_pool{descriptor_pool_}, guest_descriptor_queue{guest_descriptor_queue_}, |
| 285 | render_pass_cache{render_pass_cache_}, buffer_cache{buffer_cache_}, | 285 | render_pass_cache{render_pass_cache_}, buffer_cache{buffer_cache_}, |
| 286 | texture_cache{texture_cache_}, shader_notify{shader_notify_}, | 286 | texture_cache{texture_cache_}, shader_notify{shader_notify_}, |
| 287 | use_asynchronous_shaders{Settings::values.use_asynchronous_shaders.GetValue()}, | 287 | use_asynchronous_shaders{Settings::values.use_asynchronous_shaders.GetValue()}, |
| @@ -643,7 +643,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline( | |||
| 643 | Common::ThreadWorker* const thread_worker{build_in_parallel ? &workers : nullptr}; | 643 | Common::ThreadWorker* const thread_worker{build_in_parallel ? &workers : nullptr}; |
| 644 | return std::make_unique<GraphicsPipeline>( | 644 | return std::make_unique<GraphicsPipeline>( |
| 645 | scheduler, buffer_cache, texture_cache, vulkan_pipeline_cache, &shader_notify, device, | 645 | scheduler, buffer_cache, texture_cache, vulkan_pipeline_cache, &shader_notify, device, |
| 646 | descriptor_pool, update_descriptor_queue, thread_worker, statistics, render_pass_cache, key, | 646 | descriptor_pool, guest_descriptor_queue, thread_worker, statistics, render_pass_cache, key, |
| 647 | std::move(modules), infos); | 647 | std::move(modules), infos); |
| 648 | 648 | ||
| 649 | } catch (const Shader::Exception& exception) { | 649 | } catch (const Shader::Exception& exception) { |
| @@ -698,7 +698,8 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline( | |||
| 698 | PipelineStatistics* statistics, bool build_in_parallel) try { | 698 | PipelineStatistics* statistics, bool build_in_parallel) try { |
| 699 | // TODO: Remove this when Intel fixes their shader compiler. | 699 | // TODO: Remove this when Intel fixes their shader compiler. |
| 700 | // https://github.com/IGCIT/Intel-GPU-Community-Issue-Tracker-IGCIT/issues/159 | 700 | // https://github.com/IGCIT/Intel-GPU-Community-Issue-Tracker-IGCIT/issues/159 |
| 701 | if (device.GetDriverID() == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) { | 701 | if (device.GetDriverID() == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS && |
| 702 | !Settings::values.enable_compute_pipelines.GetValue()) { | ||
| 702 | LOG_ERROR(Render_Vulkan, "Skipping 0x{:016x}", key.Hash()); | 703 | LOG_ERROR(Render_Vulkan, "Skipping 0x{:016x}", key.Hash()); |
| 703 | return nullptr; | 704 | return nullptr; |
| 704 | } | 705 | } |
| @@ -722,7 +723,7 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline( | |||
| 722 | } | 723 | } |
| 723 | Common::ThreadWorker* const thread_worker{build_in_parallel ? &workers : nullptr}; | 724 | Common::ThreadWorker* const thread_worker{build_in_parallel ? &workers : nullptr}; |
| 724 | return std::make_unique<ComputePipeline>(device, vulkan_pipeline_cache, descriptor_pool, | 725 | return std::make_unique<ComputePipeline>(device, vulkan_pipeline_cache, descriptor_pool, |
| 725 | update_descriptor_queue, thread_worker, statistics, | 726 | guest_descriptor_queue, thread_worker, statistics, |
| 726 | &shader_notify, program.info, std::move(spv_module)); | 727 | &shader_notify, program.info, std::move(spv_module)); |
| 727 | 728 | ||
| 728 | } catch (const Shader::Exception& exception) { | 729 | } catch (const Shader::Exception& exception) { |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index 5171912d7..15aa7e224 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h | |||
| @@ -82,7 +82,6 @@ class PipelineStatistics; | |||
| 82 | class RasterizerVulkan; | 82 | class RasterizerVulkan; |
| 83 | class RenderPassCache; | 83 | class RenderPassCache; |
| 84 | class Scheduler; | 84 | class Scheduler; |
| 85 | class UpdateDescriptorQueue; | ||
| 86 | 85 | ||
| 87 | using VideoCommon::ShaderInfo; | 86 | using VideoCommon::ShaderInfo; |
| 88 | 87 | ||
| @@ -102,7 +101,7 @@ class PipelineCache : public VideoCommon::ShaderCache { | |||
| 102 | public: | 101 | public: |
| 103 | explicit PipelineCache(RasterizerVulkan& rasterizer, const Device& device, Scheduler& scheduler, | 102 | explicit PipelineCache(RasterizerVulkan& rasterizer, const Device& device, Scheduler& scheduler, |
| 104 | DescriptorPool& descriptor_pool, | 103 | DescriptorPool& descriptor_pool, |
| 105 | UpdateDescriptorQueue& update_descriptor_queue, | 104 | GuestDescriptorQueue& guest_descriptor_queue, |
| 106 | RenderPassCache& render_pass_cache, BufferCache& buffer_cache, | 105 | RenderPassCache& render_pass_cache, BufferCache& buffer_cache, |
| 107 | TextureCache& texture_cache, VideoCore::ShaderNotify& shader_notify_); | 106 | TextureCache& texture_cache, VideoCore::ShaderNotify& shader_notify_); |
| 108 | ~PipelineCache(); | 107 | ~PipelineCache(); |
| @@ -144,7 +143,7 @@ private: | |||
| 144 | const Device& device; | 143 | const Device& device; |
| 145 | Scheduler& scheduler; | 144 | Scheduler& scheduler; |
| 146 | DescriptorPool& descriptor_pool; | 145 | DescriptorPool& descriptor_pool; |
| 147 | UpdateDescriptorQueue& update_descriptor_queue; | 146 | GuestDescriptorQueue& guest_descriptor_queue; |
| 148 | RenderPassCache& render_pass_cache; | 147 | RenderPassCache& render_pass_cache; |
| 149 | BufferCache& buffer_cache; | 148 | BufferCache& buffer_cache; |
| 150 | TextureCache& texture_cache; | 149 | TextureCache& texture_cache; |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index cbf23552c..8d3a9736b 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -160,17 +160,16 @@ RasterizerVulkan::RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra | |||
| 160 | : RasterizerAccelerated{cpu_memory_}, gpu{gpu_}, screen_info{screen_info_}, device{device_}, | 160 | : RasterizerAccelerated{cpu_memory_}, gpu{gpu_}, screen_info{screen_info_}, device{device_}, |
| 161 | memory_allocator{memory_allocator_}, state_tracker{state_tracker_}, scheduler{scheduler_}, | 161 | memory_allocator{memory_allocator_}, state_tracker{state_tracker_}, scheduler{scheduler_}, |
| 162 | staging_pool(device, memory_allocator, scheduler), descriptor_pool(device, scheduler), | 162 | staging_pool(device, memory_allocator, scheduler), descriptor_pool(device, scheduler), |
| 163 | update_descriptor_queue(device, scheduler), | 163 | guest_descriptor_queue(device, scheduler), compute_pass_descriptor_queue(device, scheduler), |
| 164 | blit_image(device, scheduler, state_tracker, descriptor_pool), | 164 | blit_image(device, scheduler, state_tracker, descriptor_pool), render_pass_cache(device), |
| 165 | render_pass_cache(device), texture_cache_runtime{device, scheduler, | 165 | texture_cache_runtime{ |
| 166 | memory_allocator, staging_pool, | 166 | device, scheduler, memory_allocator, staging_pool, |
| 167 | blit_image, render_pass_cache, | 167 | blit_image, render_pass_cache, descriptor_pool, compute_pass_descriptor_queue}, |
| 168 | descriptor_pool, update_descriptor_queue}, | ||
| 169 | texture_cache(texture_cache_runtime, *this), | 168 | texture_cache(texture_cache_runtime, *this), |
| 170 | buffer_cache_runtime(device, memory_allocator, scheduler, staging_pool, | 169 | buffer_cache_runtime(device, memory_allocator, scheduler, staging_pool, |
| 171 | update_descriptor_queue, descriptor_pool), | 170 | guest_descriptor_queue, compute_pass_descriptor_queue, descriptor_pool), |
| 172 | buffer_cache(*this, cpu_memory_, buffer_cache_runtime), | 171 | buffer_cache(*this, cpu_memory_, buffer_cache_runtime), |
| 173 | pipeline_cache(*this, device, scheduler, descriptor_pool, update_descriptor_queue, | 172 | pipeline_cache(*this, device, scheduler, descriptor_pool, guest_descriptor_queue, |
| 174 | render_pass_cache, buffer_cache, texture_cache, gpu.ShaderNotify()), | 173 | render_pass_cache, buffer_cache, texture_cache, gpu.ShaderNotify()), |
| 175 | query_cache{*this, cpu_memory_, device, scheduler}, | 174 | query_cache{*this, cpu_memory_, device, scheduler}, |
| 176 | accelerate_dma(buffer_cache, texture_cache, scheduler), | 175 | accelerate_dma(buffer_cache, texture_cache, scheduler), |
| @@ -656,7 +655,8 @@ void RasterizerVulkan::FlushCommands() { | |||
| 656 | 655 | ||
| 657 | void RasterizerVulkan::TickFrame() { | 656 | void RasterizerVulkan::TickFrame() { |
| 658 | draw_counter = 0; | 657 | draw_counter = 0; |
| 659 | update_descriptor_queue.TickFrame(); | 658 | guest_descriptor_queue.TickFrame(); |
| 659 | compute_pass_descriptor_queue.TickFrame(); | ||
| 660 | fence_manager.TickFrame(); | 660 | fence_manager.TickFrame(); |
| 661 | staging_pool.TickFrame(); | 661 | staging_pool.TickFrame(); |
| 662 | { | 662 | { |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 9bd422850..b39710b3c 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h | |||
| @@ -184,7 +184,8 @@ private: | |||
| 184 | 184 | ||
| 185 | StagingBufferPool staging_pool; | 185 | StagingBufferPool staging_pool; |
| 186 | DescriptorPool descriptor_pool; | 186 | DescriptorPool descriptor_pool; |
| 187 | UpdateDescriptorQueue update_descriptor_queue; | 187 | GuestDescriptorQueue guest_descriptor_queue; |
| 188 | ComputePassDescriptorQueue compute_pass_descriptor_queue; | ||
| 188 | BlitImageHelper blit_image; | 189 | BlitImageHelper blit_image; |
| 189 | RenderPassCache render_pass_cache; | 190 | RenderPassCache render_pass_cache; |
| 190 | 191 | ||
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 9ca7751c5..4d0481f2a 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -798,13 +798,13 @@ TextureCacheRuntime::TextureCacheRuntime(const Device& device_, Scheduler& sched | |||
| 798 | BlitImageHelper& blit_image_helper_, | 798 | BlitImageHelper& blit_image_helper_, |
| 799 | RenderPassCache& render_pass_cache_, | 799 | RenderPassCache& render_pass_cache_, |
| 800 | DescriptorPool& descriptor_pool, | 800 | DescriptorPool& descriptor_pool, |
| 801 | UpdateDescriptorQueue& update_descriptor_queue) | 801 | ComputePassDescriptorQueue& compute_pass_descriptor_queue) |
| 802 | : device{device_}, scheduler{scheduler_}, memory_allocator{memory_allocator_}, | 802 | : device{device_}, scheduler{scheduler_}, memory_allocator{memory_allocator_}, |
| 803 | staging_buffer_pool{staging_buffer_pool_}, blit_image_helper{blit_image_helper_}, | 803 | staging_buffer_pool{staging_buffer_pool_}, blit_image_helper{blit_image_helper_}, |
| 804 | render_pass_cache{render_pass_cache_}, resolution{Settings::values.resolution_info} { | 804 | render_pass_cache{render_pass_cache_}, resolution{Settings::values.resolution_info} { |
| 805 | if (Settings::values.accelerate_astc) { | 805 | if (Settings::values.accelerate_astc) { |
| 806 | astc_decoder_pass.emplace(device, scheduler, descriptor_pool, staging_buffer_pool, | 806 | astc_decoder_pass.emplace(device, scheduler, descriptor_pool, staging_buffer_pool, |
| 807 | update_descriptor_queue, memory_allocator); | 807 | compute_pass_descriptor_queue, memory_allocator); |
| 808 | } | 808 | } |
| 809 | } | 809 | } |
| 810 | 810 | ||
| @@ -1864,6 +1864,7 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime, | |||
| 1864 | num_layers = std::max(num_layers, color_buffer->range.extent.layers); | 1864 | num_layers = std::max(num_layers, color_buffer->range.extent.layers); |
| 1865 | images[num_images] = color_buffer->ImageHandle(); | 1865 | images[num_images] = color_buffer->ImageHandle(); |
| 1866 | image_ranges[num_images] = MakeSubresourceRange(color_buffer); | 1866 | image_ranges[num_images] = MakeSubresourceRange(color_buffer); |
| 1867 | rt_map[index] = num_images; | ||
| 1867 | samples = color_buffer->Samples(); | 1868 | samples = color_buffer->Samples(); |
| 1868 | ++num_images; | 1869 | ++num_images; |
| 1869 | } | 1870 | } |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index 6f360177a..4166b3d20 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h | |||
| @@ -34,7 +34,6 @@ class ImageView; | |||
| 34 | class Framebuffer; | 34 | class Framebuffer; |
| 35 | class RenderPassCache; | 35 | class RenderPassCache; |
| 36 | class StagingBufferPool; | 36 | class StagingBufferPool; |
| 37 | class UpdateDescriptorQueue; | ||
| 38 | class Scheduler; | 37 | class Scheduler; |
| 39 | 38 | ||
| 40 | class TextureCacheRuntime { | 39 | class TextureCacheRuntime { |
| @@ -45,7 +44,7 @@ public: | |||
| 45 | BlitImageHelper& blit_image_helper_, | 44 | BlitImageHelper& blit_image_helper_, |
| 46 | RenderPassCache& render_pass_cache_, | 45 | RenderPassCache& render_pass_cache_, |
| 47 | DescriptorPool& descriptor_pool, | 46 | DescriptorPool& descriptor_pool, |
| 48 | UpdateDescriptorQueue& update_descriptor_queue); | 47 | ComputePassDescriptorQueue& compute_pass_descriptor_queue); |
| 49 | 48 | ||
| 50 | void Finish(); | 49 | void Finish(); |
| 51 | 50 | ||
| @@ -335,7 +334,7 @@ public: | |||
| 335 | } | 334 | } |
| 336 | 335 | ||
| 337 | [[nodiscard]] bool HasAspectColorBit(size_t index) const noexcept { | 336 | [[nodiscard]] bool HasAspectColorBit(size_t index) const noexcept { |
| 338 | return (image_ranges.at(index).aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != 0; | 337 | return (image_ranges.at(rt_map[index]).aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != 0; |
| 339 | } | 338 | } |
| 340 | 339 | ||
| 341 | [[nodiscard]] bool HasAspectDepthBit() const noexcept { | 340 | [[nodiscard]] bool HasAspectDepthBit() const noexcept { |
| @@ -355,6 +354,7 @@ private: | |||
| 355 | u32 num_images = 0; | 354 | u32 num_images = 0; |
| 356 | std::array<VkImage, 9> images{}; | 355 | std::array<VkImage, 9> images{}; |
| 357 | std::array<VkImageSubresourceRange, 9> image_ranges{}; | 356 | std::array<VkImageSubresourceRange, 9> image_ranges{}; |
| 357 | std::array<size_t, NUM_RT> rt_map{}; | ||
| 358 | bool has_depth{}; | 358 | bool has_depth{}; |
| 359 | bool has_stencil{}; | 359 | bool has_stencil{}; |
| 360 | }; | 360 | }; |
diff --git a/src/video_core/renderer_vulkan/vk_update_descriptor.h b/src/video_core/renderer_vulkan/vk_update_descriptor.h index 1c1a7020b..310fb551a 100644 --- a/src/video_core/renderer_vulkan/vk_update_descriptor.h +++ b/src/video_core/renderer_vulkan/vk_update_descriptor.h | |||
| @@ -32,7 +32,7 @@ class UpdateDescriptorQueue final { | |||
| 32 | // This should be plenty for the vast majority of cases. Most desktop platforms only | 32 | // This should be plenty for the vast majority of cases. Most desktop platforms only |
| 33 | // provide up to 3 swapchain images. | 33 | // provide up to 3 swapchain images. |
| 34 | static constexpr size_t FRAMES_IN_FLIGHT = 5; | 34 | static constexpr size_t FRAMES_IN_FLIGHT = 5; |
| 35 | static constexpr size_t FRAME_PAYLOAD_SIZE = 0x10000; | 35 | static constexpr size_t FRAME_PAYLOAD_SIZE = 0x20000; |
| 36 | static constexpr size_t PAYLOAD_SIZE = FRAME_PAYLOAD_SIZE * FRAMES_IN_FLIGHT; | 36 | static constexpr size_t PAYLOAD_SIZE = FRAME_PAYLOAD_SIZE * FRAMES_IN_FLIGHT; |
| 37 | 37 | ||
| 38 | public: | 38 | public: |
| @@ -86,4 +86,8 @@ private: | |||
| 86 | std::array<DescriptorUpdateEntry, PAYLOAD_SIZE> payload; | 86 | std::array<DescriptorUpdateEntry, PAYLOAD_SIZE> payload; |
| 87 | }; | 87 | }; |
| 88 | 88 | ||
| 89 | // TODO: should these be separate classes instead? | ||
| 90 | using GuestDescriptorQueue = UpdateDescriptorQueue; | ||
| 91 | using ComputePassDescriptorQueue = UpdateDescriptorQueue; | ||
| 92 | |||
| 89 | } // namespace Vulkan | 93 | } // namespace Vulkan |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index e1198dcf8..b24086fce 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -1469,7 +1469,7 @@ std::optional<typename TextureCache<P>::BlitImages> TextureCache<P>::GetBlitImag | |||
| 1469 | if (!copy.must_accelerate) { | 1469 | if (!copy.must_accelerate) { |
| 1470 | do { | 1470 | do { |
| 1471 | if (!src_id && !dst_id) { | 1471 | if (!src_id && !dst_id) { |
| 1472 | return std::nullopt; | 1472 | break; |
| 1473 | } | 1473 | } |
| 1474 | if (src_id && True(slot_images[src_id].flags & ImageFlagBits::GpuModified)) { | 1474 | if (src_id && True(slot_images[src_id].flags & ImageFlagBits::GpuModified)) { |
| 1475 | break; | 1475 | break; |
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 6ffca2af2..161f050b8 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp | |||
| @@ -1009,6 +1009,8 @@ void Device::CollectPhysicalMemoryInfo() { | |||
| 1009 | device_access_memory += mem_properties.memoryHeaps[element].size; | 1009 | device_access_memory += mem_properties.memoryHeaps[element].size; |
| 1010 | } | 1010 | } |
| 1011 | if (!is_integrated) { | 1011 | if (!is_integrated) { |
| 1012 | const u64 reserve_memory = std::min<u64>(device_access_memory / 8, 1_GiB); | ||
| 1013 | device_access_memory -= reserve_memory; | ||
| 1012 | return; | 1014 | return; |
| 1013 | } | 1015 | } |
| 1014 | const s64 available_memory = static_cast<s64>(device_access_memory - device_initial_usage); | 1016 | const s64 available_memory = static_cast<s64>(device_access_memory - device_initial_usage); |
diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index 1732866e0..e28a556f8 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp | |||
| @@ -147,7 +147,7 @@ public: | |||
| 147 | 147 | ||
| 148 | /// Returns whether this allocation is compatible with the arguments. | 148 | /// Returns whether this allocation is compatible with the arguments. |
| 149 | [[nodiscard]] bool IsCompatible(VkMemoryPropertyFlags flags, u32 type_mask) const { | 149 | [[nodiscard]] bool IsCompatible(VkMemoryPropertyFlags flags, u32 type_mask) const { |
| 150 | return (flags & property_flags) == property_flags && (type_mask & shifted_memory_type) != 0; | 150 | return (flags & property_flags) == flags && (type_mask & shifted_memory_type) != 0; |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | private: | 153 | private: |
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index a49d12266..70737c54e 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp | |||
| @@ -443,6 +443,7 @@ void Config::ReadControlValues() { | |||
| 443 | ReadBasicSetting(Settings::values.mouse_panning_sensitivity); | 443 | ReadBasicSetting(Settings::values.mouse_panning_sensitivity); |
| 444 | ReadBasicSetting(Settings::values.enable_joycon_driver); | 444 | ReadBasicSetting(Settings::values.enable_joycon_driver); |
| 445 | ReadBasicSetting(Settings::values.enable_procon_driver); | 445 | ReadBasicSetting(Settings::values.enable_procon_driver); |
| 446 | ReadBasicSetting(Settings::values.random_amiibo_id); | ||
| 446 | 447 | ||
| 447 | ReadBasicSetting(Settings::values.tas_enable); | 448 | ReadBasicSetting(Settings::values.tas_enable); |
| 448 | ReadBasicSetting(Settings::values.tas_loop); | 449 | ReadBasicSetting(Settings::values.tas_loop); |
| @@ -715,6 +716,7 @@ void Config::ReadRendererValues() { | |||
| 715 | ReadGlobalSetting(Settings::values.use_asynchronous_shaders); | 716 | ReadGlobalSetting(Settings::values.use_asynchronous_shaders); |
| 716 | ReadGlobalSetting(Settings::values.use_fast_gpu_time); | 717 | ReadGlobalSetting(Settings::values.use_fast_gpu_time); |
| 717 | ReadGlobalSetting(Settings::values.use_vulkan_driver_pipeline_cache); | 718 | ReadGlobalSetting(Settings::values.use_vulkan_driver_pipeline_cache); |
| 719 | ReadGlobalSetting(Settings::values.enable_compute_pipelines); | ||
| 718 | ReadGlobalSetting(Settings::values.bg_red); | 720 | ReadGlobalSetting(Settings::values.bg_red); |
| 719 | ReadGlobalSetting(Settings::values.bg_green); | 721 | ReadGlobalSetting(Settings::values.bg_green); |
| 720 | ReadGlobalSetting(Settings::values.bg_blue); | 722 | ReadGlobalSetting(Settings::values.bg_blue); |
| @@ -1150,6 +1152,7 @@ void Config::SaveControlValues() { | |||
| 1150 | WriteBasicSetting(Settings::values.enable_raw_input); | 1152 | WriteBasicSetting(Settings::values.enable_raw_input); |
| 1151 | WriteBasicSetting(Settings::values.enable_joycon_driver); | 1153 | WriteBasicSetting(Settings::values.enable_joycon_driver); |
| 1152 | WriteBasicSetting(Settings::values.enable_procon_driver); | 1154 | WriteBasicSetting(Settings::values.enable_procon_driver); |
| 1155 | WriteBasicSetting(Settings::values.random_amiibo_id); | ||
| 1153 | WriteBasicSetting(Settings::values.keyboard_enabled); | 1156 | WriteBasicSetting(Settings::values.keyboard_enabled); |
| 1154 | WriteBasicSetting(Settings::values.emulate_analog_keyboard); | 1157 | WriteBasicSetting(Settings::values.emulate_analog_keyboard); |
| 1155 | WriteBasicSetting(Settings::values.mouse_panning_sensitivity); | 1158 | WriteBasicSetting(Settings::values.mouse_panning_sensitivity); |
| @@ -1364,6 +1367,7 @@ void Config::SaveRendererValues() { | |||
| 1364 | WriteGlobalSetting(Settings::values.use_asynchronous_shaders); | 1367 | WriteGlobalSetting(Settings::values.use_asynchronous_shaders); |
| 1365 | WriteGlobalSetting(Settings::values.use_fast_gpu_time); | 1368 | WriteGlobalSetting(Settings::values.use_fast_gpu_time); |
| 1366 | WriteGlobalSetting(Settings::values.use_vulkan_driver_pipeline_cache); | 1369 | WriteGlobalSetting(Settings::values.use_vulkan_driver_pipeline_cache); |
| 1370 | WriteGlobalSetting(Settings::values.enable_compute_pipelines); | ||
| 1367 | WriteGlobalSetting(Settings::values.bg_red); | 1371 | WriteGlobalSetting(Settings::values.bg_red); |
| 1368 | WriteGlobalSetting(Settings::values.bg_green); | 1372 | WriteGlobalSetting(Settings::values.bg_green); |
| 1369 | WriteGlobalSetting(Settings::values.bg_blue); | 1373 | WriteGlobalSetting(Settings::values.bg_blue); |
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index 2aaefcc05..8e76a819a 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp | |||
| @@ -36,8 +36,9 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, | |||
| 36 | debug_tab_tab{std::make_unique<ConfigureDebugTab>(system_, this)}, | 36 | debug_tab_tab{std::make_unique<ConfigureDebugTab>(system_, this)}, |
| 37 | filesystem_tab{std::make_unique<ConfigureFilesystem>(this)}, | 37 | filesystem_tab{std::make_unique<ConfigureFilesystem>(this)}, |
| 38 | general_tab{std::make_unique<ConfigureGeneral>(system_, this)}, | 38 | general_tab{std::make_unique<ConfigureGeneral>(system_, this)}, |
| 39 | graphics_tab{std::make_unique<ConfigureGraphics>(system_, this)}, | ||
| 40 | graphics_advanced_tab{std::make_unique<ConfigureGraphicsAdvanced>(system_, this)}, | 39 | graphics_advanced_tab{std::make_unique<ConfigureGraphicsAdvanced>(system_, this)}, |
| 40 | graphics_tab{std::make_unique<ConfigureGraphics>( | ||
| 41 | system_, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, this)}, | ||
| 41 | hotkeys_tab{std::make_unique<ConfigureHotkeys>(system_.HIDCore(), this)}, | 42 | hotkeys_tab{std::make_unique<ConfigureHotkeys>(system_.HIDCore(), this)}, |
| 42 | input_tab{std::make_unique<ConfigureInput>(system_, this)}, | 43 | input_tab{std::make_unique<ConfigureInput>(system_, this)}, |
| 43 | network_tab{std::make_unique<ConfigureNetwork>(system_, this)}, | 44 | network_tab{std::make_unique<ConfigureNetwork>(system_, this)}, |
diff --git a/src/yuzu/configuration/configure_dialog.h b/src/yuzu/configuration/configure_dialog.h index 1f724834a..a086a07c4 100644 --- a/src/yuzu/configuration/configure_dialog.h +++ b/src/yuzu/configuration/configure_dialog.h | |||
| @@ -72,8 +72,8 @@ private: | |||
| 72 | std::unique_ptr<ConfigureDebugTab> debug_tab_tab; | 72 | std::unique_ptr<ConfigureDebugTab> debug_tab_tab; |
| 73 | std::unique_ptr<ConfigureFilesystem> filesystem_tab; | 73 | std::unique_ptr<ConfigureFilesystem> filesystem_tab; |
| 74 | std::unique_ptr<ConfigureGeneral> general_tab; | 74 | std::unique_ptr<ConfigureGeneral> general_tab; |
| 75 | std::unique_ptr<ConfigureGraphics> graphics_tab; | ||
| 76 | std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab; | 75 | std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab; |
| 76 | std::unique_ptr<ConfigureGraphics> graphics_tab; | ||
| 77 | std::unique_ptr<ConfigureHotkeys> hotkeys_tab; | 77 | std::unique_ptr<ConfigureHotkeys> hotkeys_tab; |
| 78 | std::unique_ptr<ConfigureInput> input_tab; | 78 | std::unique_ptr<ConfigureInput> input_tab; |
| 79 | std::unique_ptr<ConfigureNetwork> network_tab; | 79 | std::unique_ptr<ConfigureNetwork> network_tab; |
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index 76e5b7499..f316b598c 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp | |||
| @@ -2,9 +2,11 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | // Include this early to include Vulkan headers how we want to | 4 | // Include this early to include Vulkan headers how we want to |
| 5 | #include "video_core/vulkan_common/vulkan_device.h" | ||
| 5 | #include "video_core/vulkan_common/vulkan_wrapper.h" | 6 | #include "video_core/vulkan_common/vulkan_wrapper.h" |
| 6 | 7 | ||
| 7 | #include <algorithm> | 8 | #include <algorithm> |
| 9 | #include <functional> | ||
| 8 | #include <iosfwd> | 10 | #include <iosfwd> |
| 9 | #include <iterator> | 11 | #include <iterator> |
| 10 | #include <string> | 12 | #include <string> |
| @@ -74,8 +76,11 @@ static constexpr Settings::VSyncMode PresentModeToSetting(VkPresentModeKHR mode) | |||
| 74 | } | 76 | } |
| 75 | } | 77 | } |
| 76 | 78 | ||
| 77 | ConfigureGraphics::ConfigureGraphics(const Core::System& system_, QWidget* parent) | 79 | ConfigureGraphics::ConfigureGraphics(const Core::System& system_, |
| 78 | : QWidget(parent), ui{std::make_unique<Ui::ConfigureGraphics>()}, system{system_} { | 80 | const std::function<void()>& expose_compute_option_, |
| 81 | QWidget* parent) | ||
| 82 | : QWidget(parent), ui{std::make_unique<Ui::ConfigureGraphics>()}, | ||
| 83 | expose_compute_option{expose_compute_option_}, system{system_} { | ||
| 79 | vulkan_device = Settings::values.vulkan_device.GetValue(); | 84 | vulkan_device = Settings::values.vulkan_device.GetValue(); |
| 80 | RetrieveVulkanDevices(); | 85 | RetrieveVulkanDevices(); |
| 81 | 86 | ||
| @@ -513,8 +518,7 @@ void ConfigureGraphics::RetrieveVulkanDevices() try { | |||
| 513 | const Common::DynamicLibrary library = OpenLibrary(); | 518 | const Common::DynamicLibrary library = OpenLibrary(); |
| 514 | const vk::Instance instance = CreateInstance(library, dld, VK_API_VERSION_1_1, wsi.type); | 519 | const vk::Instance instance = CreateInstance(library, dld, VK_API_VERSION_1_1, wsi.type); |
| 515 | const std::vector<VkPhysicalDevice> physical_devices = instance.EnumeratePhysicalDevices(); | 520 | const std::vector<VkPhysicalDevice> physical_devices = instance.EnumeratePhysicalDevices(); |
| 516 | vk::SurfaceKHR surface = //< needed to view present modes for a device | 521 | vk::SurfaceKHR surface = CreateSurface(instance, wsi); |
| 517 | CreateSurface(instance, wsi); | ||
| 518 | 522 | ||
| 519 | vulkan_devices.clear(); | 523 | vulkan_devices.clear(); |
| 520 | vulkan_devices.reserve(physical_devices.size()); | 524 | vulkan_devices.reserve(physical_devices.size()); |
| @@ -527,6 +531,17 @@ void ConfigureGraphics::RetrieveVulkanDevices() try { | |||
| 527 | physical_device.GetSurfacePresentModesKHR(*surface); | 531 | physical_device.GetSurfacePresentModesKHR(*surface); |
| 528 | vulkan_devices.push_back(QString::fromStdString(name)); | 532 | vulkan_devices.push_back(QString::fromStdString(name)); |
| 529 | device_present_modes.push_back(present_modes); | 533 | device_present_modes.push_back(present_modes); |
| 534 | |||
| 535 | VkPhysicalDeviceDriverProperties driver_properties{}; | ||
| 536 | driver_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES; | ||
| 537 | driver_properties.pNext = nullptr; | ||
| 538 | VkPhysicalDeviceProperties2 properties{}; | ||
| 539 | properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; | ||
| 540 | properties.pNext = &driver_properties; | ||
| 541 | dld.vkGetPhysicalDeviceProperties2(physical_device, &properties); | ||
| 542 | if (driver_properties.driverID == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) { | ||
| 543 | expose_compute_option(); | ||
| 544 | } | ||
| 530 | } | 545 | } |
| 531 | } catch (const Vulkan::vk::Exception& exception) { | 546 | } catch (const Vulkan::vk::Exception& exception) { |
| 532 | LOG_ERROR(Frontend, "Failed to enumerate devices with error: {}", exception.what()); | 547 | LOG_ERROR(Frontend, "Failed to enumerate devices with error: {}", exception.what()); |
diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h index 901f604a5..364b1cac2 100644 --- a/src/yuzu/configuration/configure_graphics.h +++ b/src/yuzu/configuration/configure_graphics.h | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <functional> | ||
| 6 | #include <memory> | 7 | #include <memory> |
| 7 | #include <vector> | 8 | #include <vector> |
| 8 | #include <QColor> | 9 | #include <QColor> |
| @@ -37,7 +38,9 @@ class ConfigureGraphics : public QWidget { | |||
| 37 | Q_OBJECT | 38 | Q_OBJECT |
| 38 | 39 | ||
| 39 | public: | 40 | public: |
| 40 | explicit ConfigureGraphics(const Core::System& system_, QWidget* parent = nullptr); | 41 | explicit ConfigureGraphics(const Core::System& system_, |
| 42 | const std::function<void()>& expose_compute_option_, | ||
| 43 | QWidget* parent = nullptr); | ||
| 41 | ~ConfigureGraphics() override; | 44 | ~ConfigureGraphics() override; |
| 42 | 45 | ||
| 43 | void ApplyConfiguration(); | 46 | void ApplyConfiguration(); |
| @@ -81,6 +84,7 @@ private: | |||
| 81 | // selection in the combobox | 84 | // selection in the combobox |
| 82 | u32 vulkan_device{}; | 85 | u32 vulkan_device{}; |
| 83 | Settings::ShaderBackend shader_backend{}; | 86 | Settings::ShaderBackend shader_backend{}; |
| 87 | const std::function<void()>& expose_compute_option; | ||
| 84 | 88 | ||
| 85 | const Core::System& system; | 89 | const Core::System& system; |
| 86 | }; | 90 | }; |
diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp index 627ed8b17..1f3e489d0 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.cpp +++ b/src/yuzu/configuration/configure_graphics_advanced.cpp | |||
| @@ -15,6 +15,8 @@ ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced(const Core::System& system_ | |||
| 15 | SetupPerGameUI(); | 15 | SetupPerGameUI(); |
| 16 | 16 | ||
| 17 | SetConfiguration(); | 17 | SetConfiguration(); |
| 18 | |||
| 19 | ui->enable_compute_pipelines_checkbox->setVisible(false); | ||
| 18 | } | 20 | } |
| 19 | 21 | ||
| 20 | ConfigureGraphicsAdvanced::~ConfigureGraphicsAdvanced() = default; | 22 | ConfigureGraphicsAdvanced::~ConfigureGraphicsAdvanced() = default; |
| @@ -27,6 +29,7 @@ void ConfigureGraphicsAdvanced::SetConfiguration() { | |||
| 27 | ui->async_astc->setEnabled(runtime_lock); | 29 | ui->async_astc->setEnabled(runtime_lock); |
| 28 | ui->use_asynchronous_shaders->setEnabled(runtime_lock); | 30 | ui->use_asynchronous_shaders->setEnabled(runtime_lock); |
| 29 | ui->anisotropic_filtering_combobox->setEnabled(runtime_lock); | 31 | ui->anisotropic_filtering_combobox->setEnabled(runtime_lock); |
| 32 | ui->enable_compute_pipelines_checkbox->setEnabled(runtime_lock); | ||
| 30 | 33 | ||
| 31 | ui->async_present->setChecked(Settings::values.async_presentation.GetValue()); | 34 | ui->async_present->setChecked(Settings::values.async_presentation.GetValue()); |
| 32 | ui->renderer_force_max_clock->setChecked(Settings::values.renderer_force_max_clock.GetValue()); | 35 | ui->renderer_force_max_clock->setChecked(Settings::values.renderer_force_max_clock.GetValue()); |
| @@ -36,6 +39,8 @@ void ConfigureGraphicsAdvanced::SetConfiguration() { | |||
| 36 | ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue()); | 39 | ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue()); |
| 37 | ui->use_vulkan_driver_pipeline_cache->setChecked( | 40 | ui->use_vulkan_driver_pipeline_cache->setChecked( |
| 38 | Settings::values.use_vulkan_driver_pipeline_cache.GetValue()); | 41 | Settings::values.use_vulkan_driver_pipeline_cache.GetValue()); |
| 42 | ui->enable_compute_pipelines_checkbox->setChecked( | ||
| 43 | Settings::values.enable_compute_pipelines.GetValue()); | ||
| 39 | 44 | ||
| 40 | if (Settings::IsConfiguringGlobal()) { | 45 | if (Settings::IsConfiguringGlobal()) { |
| 41 | ui->gpu_accuracy->setCurrentIndex( | 46 | ui->gpu_accuracy->setCurrentIndex( |
| @@ -74,6 +79,9 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() { | |||
| 74 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vulkan_driver_pipeline_cache, | 79 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vulkan_driver_pipeline_cache, |
| 75 | ui->use_vulkan_driver_pipeline_cache, | 80 | ui->use_vulkan_driver_pipeline_cache, |
| 76 | use_vulkan_driver_pipeline_cache); | 81 | use_vulkan_driver_pipeline_cache); |
| 82 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_compute_pipelines, | ||
| 83 | ui->enable_compute_pipelines_checkbox, | ||
| 84 | enable_compute_pipelines); | ||
| 77 | } | 85 | } |
| 78 | 86 | ||
| 79 | void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) { | 87 | void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) { |
| @@ -104,6 +112,8 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() { | |||
| 104 | Settings::values.use_vulkan_driver_pipeline_cache.UsingGlobal()); | 112 | Settings::values.use_vulkan_driver_pipeline_cache.UsingGlobal()); |
| 105 | ui->anisotropic_filtering_combobox->setEnabled( | 113 | ui->anisotropic_filtering_combobox->setEnabled( |
| 106 | Settings::values.max_anisotropy.UsingGlobal()); | 114 | Settings::values.max_anisotropy.UsingGlobal()); |
| 115 | ui->enable_compute_pipelines_checkbox->setEnabled( | ||
| 116 | Settings::values.enable_compute_pipelines.UsingGlobal()); | ||
| 107 | 117 | ||
| 108 | return; | 118 | return; |
| 109 | } | 119 | } |
| @@ -125,6 +135,9 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() { | |||
| 125 | ConfigurationShared::SetColoredTristate(ui->use_vulkan_driver_pipeline_cache, | 135 | ConfigurationShared::SetColoredTristate(ui->use_vulkan_driver_pipeline_cache, |
| 126 | Settings::values.use_vulkan_driver_pipeline_cache, | 136 | Settings::values.use_vulkan_driver_pipeline_cache, |
| 127 | use_vulkan_driver_pipeline_cache); | 137 | use_vulkan_driver_pipeline_cache); |
| 138 | ConfigurationShared::SetColoredTristate(ui->enable_compute_pipelines_checkbox, | ||
| 139 | Settings::values.enable_compute_pipelines, | ||
| 140 | enable_compute_pipelines); | ||
| 128 | ConfigurationShared::SetColoredComboBox( | 141 | ConfigurationShared::SetColoredComboBox( |
| 129 | ui->gpu_accuracy, ui->label_gpu_accuracy, | 142 | ui->gpu_accuracy, ui->label_gpu_accuracy, |
| 130 | static_cast<int>(Settings::values.gpu_accuracy.GetValue(true))); | 143 | static_cast<int>(Settings::values.gpu_accuracy.GetValue(true))); |
| @@ -132,3 +145,7 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() { | |||
| 132 | ui->anisotropic_filtering_combobox, ui->af_label, | 145 | ui->anisotropic_filtering_combobox, ui->af_label, |
| 133 | static_cast<int>(Settings::values.max_anisotropy.GetValue(true))); | 146 | static_cast<int>(Settings::values.max_anisotropy.GetValue(true))); |
| 134 | } | 147 | } |
| 148 | |||
| 149 | void ConfigureGraphicsAdvanced::ExposeComputeOption() { | ||
| 150 | ui->enable_compute_pipelines_checkbox->setVisible(true); | ||
| 151 | } | ||
diff --git a/src/yuzu/configuration/configure_graphics_advanced.h b/src/yuzu/configuration/configure_graphics_advanced.h index ae3c10946..1c7b636b9 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.h +++ b/src/yuzu/configuration/configure_graphics_advanced.h | |||
| @@ -28,6 +28,8 @@ public: | |||
| 28 | void ApplyConfiguration(); | 28 | void ApplyConfiguration(); |
| 29 | void SetConfiguration(); | 29 | void SetConfiguration(); |
| 30 | 30 | ||
| 31 | void ExposeComputeOption(); | ||
| 32 | |||
| 31 | private: | 33 | private: |
| 32 | void changeEvent(QEvent* event) override; | 34 | void changeEvent(QEvent* event) override; |
| 33 | void RetranslateUI(); | 35 | void RetranslateUI(); |
| @@ -44,6 +46,7 @@ private: | |||
| 44 | ConfigurationShared::CheckState use_asynchronous_shaders; | 46 | ConfigurationShared::CheckState use_asynchronous_shaders; |
| 45 | ConfigurationShared::CheckState use_fast_gpu_time; | 47 | ConfigurationShared::CheckState use_fast_gpu_time; |
| 46 | ConfigurationShared::CheckState use_vulkan_driver_pipeline_cache; | 48 | ConfigurationShared::CheckState use_vulkan_driver_pipeline_cache; |
| 49 | ConfigurationShared::CheckState enable_compute_pipelines; | ||
| 47 | 50 | ||
| 48 | const Core::System& system; | 51 | const Core::System& system; |
| 49 | }; | 52 | }; |
diff --git a/src/yuzu/configuration/configure_graphics_advanced.ui b/src/yuzu/configuration/configure_graphics_advanced.ui index 9d8cbea09..9ef7c8e8f 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.ui +++ b/src/yuzu/configuration/configure_graphics_advanced.ui | |||
| @@ -137,6 +137,17 @@ | |||
| 137 | </widget> | 137 | </widget> |
| 138 | </item> | 138 | </item> |
| 139 | <item> | 139 | <item> |
| 140 | <widget class="QCheckBox" name="enable_compute_pipelines_checkbox"> | ||
| 141 | <property name="toolTip"> | ||
| 142 | <string>Enable compute pipelines, required by some games. This setting only exists for Intel proprietary drivers, and may crash if enabled. | ||
| 143 | Compute pipelines are always enabled on all other drivers.</string> | ||
| 144 | </property> | ||
| 145 | <property name="text"> | ||
| 146 | <string>Enable Compute Pipelines (Intel Vulkan only)</string> | ||
| 147 | </property> | ||
| 148 | </widget> | ||
| 149 | </item> | ||
| 150 | <item> | ||
| 140 | <widget class="QWidget" name="af_layout" native="true"> | 151 | <widget class="QWidget" name="af_layout" native="true"> |
| 141 | <layout class="QHBoxLayout" name="horizontalLayout_1"> | 152 | <layout class="QHBoxLayout" name="horizontalLayout_1"> |
| 142 | <property name="leftMargin"> | 153 | <property name="leftMargin"> |
diff --git a/src/yuzu/configuration/configure_hotkeys.cpp b/src/yuzu/configuration/configure_hotkeys.cpp index daa77a8f8..0b2a965f8 100644 --- a/src/yuzu/configuration/configure_hotkeys.cpp +++ b/src/yuzu/configuration/configure_hotkeys.cpp | |||
| @@ -48,7 +48,9 @@ ConfigureHotkeys::ConfigureHotkeys(Core::HID::HIDCore& hid_core, QWidget* parent | |||
| 48 | 48 | ||
| 49 | connect(poll_timer.get(), &QTimer::timeout, [this] { | 49 | connect(poll_timer.get(), &QTimer::timeout, [this] { |
| 50 | const auto buttons = controller->GetNpadButtons(); | 50 | const auto buttons = controller->GetNpadButtons(); |
| 51 | if (buttons.raw != Core::HID::NpadButton::None) { | 51 | const auto home_pressed = controller->GetHomeButtons().home != 0; |
| 52 | const auto capture_pressed = controller->GetCaptureButtons().capture != 0; | ||
| 53 | if (home_pressed || capture_pressed) { | ||
| 52 | SetPollingResult(buttons.raw, false); | 54 | SetPollingResult(buttons.raw, false); |
| 53 | return; | 55 | return; |
| 54 | } | 56 | } |
| @@ -154,8 +156,10 @@ void ConfigureHotkeys::ConfigureController(QModelIndex index) { | |||
| 154 | model->setData(index, previous_key); | 156 | model->setData(index, previous_key); |
| 155 | return; | 157 | return; |
| 156 | } | 158 | } |
| 157 | 159 | const auto home_pressed = this->controller->GetHomeButtons().home != 0; | |
| 158 | const QString button_string = tr("Home+%1").arg(GetButtonName(button)); | 160 | const auto capture_pressed = this->controller->GetCaptureButtons().capture != 0; |
| 161 | const QString button_string = | ||
| 162 | GetButtonCombinationName(button, home_pressed, capture_pressed); | ||
| 159 | 163 | ||
| 160 | const auto [key_sequence_used, used_action] = IsUsedControllerKey(button_string); | 164 | const auto [key_sequence_used, used_action] = IsUsedControllerKey(button_string); |
| 161 | 165 | ||
| @@ -174,72 +178,83 @@ void ConfigureHotkeys::ConfigureController(QModelIndex index) { | |||
| 174 | poll_timer->start(200); // Check for new inputs every 200ms | 178 | poll_timer->start(200); // Check for new inputs every 200ms |
| 175 | // We need to disable configuration to be able to read npad buttons | 179 | // We need to disable configuration to be able to read npad buttons |
| 176 | controller->DisableConfiguration(); | 180 | controller->DisableConfiguration(); |
| 177 | controller->DisableSystemButtons(); | ||
| 178 | } | 181 | } |
| 179 | 182 | ||
| 180 | void ConfigureHotkeys::SetPollingResult(Core::HID::NpadButton button, const bool cancel) { | 183 | void ConfigureHotkeys::SetPollingResult(Core::HID::NpadButton button, const bool cancel) { |
| 181 | timeout_timer->stop(); | 184 | timeout_timer->stop(); |
| 182 | poll_timer->stop(); | 185 | poll_timer->stop(); |
| 186 | (*input_setter)(button, cancel); | ||
| 183 | // Re-Enable configuration | 187 | // Re-Enable configuration |
| 184 | controller->EnableConfiguration(); | 188 | controller->EnableConfiguration(); |
| 185 | controller->EnableSystemButtons(); | ||
| 186 | |||
| 187 | (*input_setter)(button, cancel); | ||
| 188 | 189 | ||
| 189 | input_setter = std::nullopt; | 190 | input_setter = std::nullopt; |
| 190 | } | 191 | } |
| 191 | 192 | ||
| 192 | QString ConfigureHotkeys::GetButtonName(Core::HID::NpadButton button) const { | 193 | QString ConfigureHotkeys::GetButtonCombinationName(Core::HID::NpadButton button, |
| 194 | const bool home = false, | ||
| 195 | const bool capture = false) const { | ||
| 193 | Core::HID::NpadButtonState state{button}; | 196 | Core::HID::NpadButtonState state{button}; |
| 197 | QString button_combination; | ||
| 198 | if (home) { | ||
| 199 | button_combination.append(QStringLiteral("Home+")); | ||
| 200 | } | ||
| 201 | if (capture) { | ||
| 202 | button_combination.append(QStringLiteral("Screenshot+")); | ||
| 203 | } | ||
| 194 | if (state.a) { | 204 | if (state.a) { |
| 195 | return QStringLiteral("A"); | 205 | button_combination.append(QStringLiteral("A+")); |
| 196 | } | 206 | } |
| 197 | if (state.b) { | 207 | if (state.b) { |
| 198 | return QStringLiteral("B"); | 208 | button_combination.append(QStringLiteral("B+")); |
| 199 | } | 209 | } |
| 200 | if (state.x) { | 210 | if (state.x) { |
| 201 | return QStringLiteral("X"); | 211 | button_combination.append(QStringLiteral("X+")); |
| 202 | } | 212 | } |
| 203 | if (state.y) { | 213 | if (state.y) { |
| 204 | return QStringLiteral("Y"); | 214 | button_combination.append(QStringLiteral("Y+")); |
| 205 | } | 215 | } |
| 206 | if (state.l || state.right_sl || state.left_sl) { | 216 | if (state.l || state.right_sl || state.left_sl) { |
| 207 | return QStringLiteral("L"); | 217 | button_combination.append(QStringLiteral("L+")); |
| 208 | } | 218 | } |
| 209 | if (state.r || state.right_sr || state.left_sr) { | 219 | if (state.r || state.right_sr || state.left_sr) { |
| 210 | return QStringLiteral("R"); | 220 | button_combination.append(QStringLiteral("R+")); |
| 211 | } | 221 | } |
| 212 | if (state.zl) { | 222 | if (state.zl) { |
| 213 | return QStringLiteral("ZL"); | 223 | button_combination.append(QStringLiteral("ZL+")); |
| 214 | } | 224 | } |
| 215 | if (state.zr) { | 225 | if (state.zr) { |
| 216 | return QStringLiteral("ZR"); | 226 | button_combination.append(QStringLiteral("ZR+")); |
| 217 | } | 227 | } |
| 218 | if (state.left) { | 228 | if (state.left) { |
| 219 | return QStringLiteral("Dpad_Left"); | 229 | button_combination.append(QStringLiteral("Dpad_Left+")); |
| 220 | } | 230 | } |
| 221 | if (state.right) { | 231 | if (state.right) { |
| 222 | return QStringLiteral("Dpad_Right"); | 232 | button_combination.append(QStringLiteral("Dpad_Right+")); |
| 223 | } | 233 | } |
| 224 | if (state.up) { | 234 | if (state.up) { |
| 225 | return QStringLiteral("Dpad_Up"); | 235 | button_combination.append(QStringLiteral("Dpad_Up+")); |
| 226 | } | 236 | } |
| 227 | if (state.down) { | 237 | if (state.down) { |
| 228 | return QStringLiteral("Dpad_Down"); | 238 | button_combination.append(QStringLiteral("Dpad_Down+")); |
| 229 | } | 239 | } |
| 230 | if (state.stick_l) { | 240 | if (state.stick_l) { |
| 231 | return QStringLiteral("Left_Stick"); | 241 | button_combination.append(QStringLiteral("Left_Stick+")); |
| 232 | } | 242 | } |
| 233 | if (state.stick_r) { | 243 | if (state.stick_r) { |
| 234 | return QStringLiteral("Right_Stick"); | 244 | button_combination.append(QStringLiteral("Right_Stick+")); |
| 235 | } | 245 | } |
| 236 | if (state.minus) { | 246 | if (state.minus) { |
| 237 | return QStringLiteral("Minus"); | 247 | button_combination.append(QStringLiteral("Minus+")); |
| 238 | } | 248 | } |
| 239 | if (state.plus) { | 249 | if (state.plus) { |
| 240 | return QStringLiteral("Plus"); | 250 | button_combination.append(QStringLiteral("Plus+")); |
| 251 | } | ||
| 252 | if (button_combination.isEmpty()) { | ||
| 253 | return tr("Invalid"); | ||
| 254 | } else { | ||
| 255 | button_combination.chop(1); | ||
| 256 | return button_combination; | ||
| 241 | } | 257 | } |
| 242 | return tr("Invalid"); | ||
| 243 | } | 258 | } |
| 244 | 259 | ||
| 245 | std::pair<bool, QString> ConfigureHotkeys::IsUsedKey(QKeySequence key_sequence) const { | 260 | std::pair<bool, QString> ConfigureHotkeys::IsUsedKey(QKeySequence key_sequence) const { |
diff --git a/src/yuzu/configuration/configure_hotkeys.h b/src/yuzu/configuration/configure_hotkeys.h index e8e414320..5fd1bcbfe 100644 --- a/src/yuzu/configuration/configure_hotkeys.h +++ b/src/yuzu/configuration/configure_hotkeys.h | |||
| @@ -59,7 +59,7 @@ private: | |||
| 59 | QStandardItemModel* model; | 59 | QStandardItemModel* model; |
| 60 | 60 | ||
| 61 | void SetPollingResult(Core::HID::NpadButton button, bool cancel); | 61 | void SetPollingResult(Core::HID::NpadButton button, bool cancel); |
| 62 | QString GetButtonName(Core::HID::NpadButton button) const; | 62 | QString GetButtonCombinationName(Core::HID::NpadButton button, bool home, bool capture) const; |
| 63 | Core::HID::EmulatedController* controller; | 63 | Core::HID::EmulatedController* controller; |
| 64 | std::unique_ptr<QTimer> timeout_timer; | 64 | std::unique_ptr<QTimer> timeout_timer; |
| 65 | std::unique_ptr<QTimer> poll_timer; | 65 | std::unique_ptr<QTimer> poll_timer; |
diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp index 8d81322f3..f13156434 100644 --- a/src/yuzu/configuration/configure_input_advanced.cpp +++ b/src/yuzu/configuration/configure_input_advanced.cpp | |||
| @@ -140,6 +140,7 @@ void ConfigureInputAdvanced::ApplyConfiguration() { | |||
| 140 | Settings::values.enable_ir_sensor = ui->enable_ir_sensor->isChecked(); | 140 | Settings::values.enable_ir_sensor = ui->enable_ir_sensor->isChecked(); |
| 141 | Settings::values.enable_joycon_driver = ui->enable_joycon_driver->isChecked(); | 141 | Settings::values.enable_joycon_driver = ui->enable_joycon_driver->isChecked(); |
| 142 | Settings::values.enable_procon_driver = ui->enable_procon_driver->isChecked(); | 142 | Settings::values.enable_procon_driver = ui->enable_procon_driver->isChecked(); |
| 143 | Settings::values.random_amiibo_id = ui->random_amiibo_id->isChecked(); | ||
| 143 | } | 144 | } |
| 144 | 145 | ||
| 145 | void ConfigureInputAdvanced::LoadConfiguration() { | 146 | void ConfigureInputAdvanced::LoadConfiguration() { |
| @@ -176,6 +177,7 @@ void ConfigureInputAdvanced::LoadConfiguration() { | |||
| 176 | ui->enable_ir_sensor->setChecked(Settings::values.enable_ir_sensor.GetValue()); | 177 | ui->enable_ir_sensor->setChecked(Settings::values.enable_ir_sensor.GetValue()); |
| 177 | ui->enable_joycon_driver->setChecked(Settings::values.enable_joycon_driver.GetValue()); | 178 | ui->enable_joycon_driver->setChecked(Settings::values.enable_joycon_driver.GetValue()); |
| 178 | ui->enable_procon_driver->setChecked(Settings::values.enable_procon_driver.GetValue()); | 179 | ui->enable_procon_driver->setChecked(Settings::values.enable_procon_driver.GetValue()); |
| 180 | ui->random_amiibo_id->setChecked(Settings::values.random_amiibo_id.GetValue()); | ||
| 179 | 181 | ||
| 180 | UpdateUIEnabled(); | 182 | UpdateUIEnabled(); |
| 181 | } | 183 | } |
diff --git a/src/yuzu/configuration/configure_input_advanced.ui b/src/yuzu/configuration/configure_input_advanced.ui index 0eb2b34bc..2e8b13660 100644 --- a/src/yuzu/configuration/configure_input_advanced.ui +++ b/src/yuzu/configuration/configure_input_advanced.ui | |||
| @@ -2728,6 +2728,22 @@ | |||
| 2728 | </widget> | 2728 | </widget> |
| 2729 | </item> | 2729 | </item> |
| 2730 | <item row="7" column="0"> | 2730 | <item row="7" column="0"> |
| 2731 | <widget class="QCheckBox" name="random_amiibo_id"> | ||
| 2732 | <property name="toolTip"> | ||
| 2733 | <string>Allows unlimited uses of the same Amiibo in games that would otherwise limit you to one use.</string> | ||
| 2734 | </property> | ||
| 2735 | <property name="minimumSize"> | ||
| 2736 | <size> | ||
| 2737 | <width>0</width> | ||
| 2738 | <height>23</height> | ||
| 2739 | </size> | ||
| 2740 | </property> | ||
| 2741 | <property name="text"> | ||
| 2742 | <string>Use random Amiibo ID</string> | ||
| 2743 | </property> | ||
| 2744 | </widget> | ||
| 2745 | </item> | ||
| 2746 | <item row="8" column="0"> | ||
| 2731 | <widget class="QCheckBox" name="mouse_panning"> | 2747 | <widget class="QCheckBox" name="mouse_panning"> |
| 2732 | <property name="minimumSize"> | 2748 | <property name="minimumSize"> |
| 2733 | <size> | 2749 | <size> |
| @@ -2740,7 +2756,7 @@ | |||
| 2740 | </property> | 2756 | </property> |
| 2741 | </widget> | 2757 | </widget> |
| 2742 | </item> | 2758 | </item> |
| 2743 | <item row="7" column="2"> | 2759 | <item row="8" column="2"> |
| 2744 | <widget class="QSpinBox" name="mouse_panning_sensitivity"> | 2760 | <widget class="QSpinBox" name="mouse_panning_sensitivity"> |
| 2745 | <property name="toolTip"> | 2761 | <property name="toolTip"> |
| 2746 | <string>Mouse sensitivity</string> | 2762 | <string>Mouse sensitivity</string> |
| @@ -2762,14 +2778,14 @@ | |||
| 2762 | </property> | 2778 | </property> |
| 2763 | </widget> | 2779 | </widget> |
| 2764 | </item> | 2780 | </item> |
| 2765 | <item row="8" column="0"> | 2781 | <item row="9" column="0"> |
| 2766 | <widget class="QLabel" name="motion_touch"> | 2782 | <widget class="QLabel" name="motion_touch"> |
| 2767 | <property name="text"> | 2783 | <property name="text"> |
| 2768 | <string>Motion / Touch</string> | 2784 | <string>Motion / Touch</string> |
| 2769 | </property> | 2785 | </property> |
| 2770 | </widget> | 2786 | </widget> |
| 2771 | </item> | 2787 | </item> |
| 2772 | <item row="8" column="2"> | 2788 | <item row="9" column="2"> |
| 2773 | <widget class="QPushButton" name="buttonMotionTouch"> | 2789 | <widget class="QPushButton" name="buttonMotionTouch"> |
| 2774 | <property name="text"> | 2790 | <property name="text"> |
| 2775 | <string>Configure</string> | 2791 | <string>Configure</string> |
diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index 7e757eafd..7ac162586 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp | |||
| @@ -48,8 +48,9 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st | |||
| 48 | audio_tab = std::make_unique<ConfigureAudio>(system_, this); | 48 | audio_tab = std::make_unique<ConfigureAudio>(system_, this); |
| 49 | cpu_tab = std::make_unique<ConfigureCpu>(system_, this); | 49 | cpu_tab = std::make_unique<ConfigureCpu>(system_, this); |
| 50 | general_tab = std::make_unique<ConfigureGeneral>(system_, this); | 50 | general_tab = std::make_unique<ConfigureGeneral>(system_, this); |
| 51 | graphics_tab = std::make_unique<ConfigureGraphics>(system_, this); | ||
| 52 | graphics_advanced_tab = std::make_unique<ConfigureGraphicsAdvanced>(system_, this); | 51 | graphics_advanced_tab = std::make_unique<ConfigureGraphicsAdvanced>(system_, this); |
| 52 | graphics_tab = std::make_unique<ConfigureGraphics>( | ||
| 53 | system_, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, this); | ||
| 53 | input_tab = std::make_unique<ConfigureInputPerGame>(system_, game_config.get(), this); | 54 | input_tab = std::make_unique<ConfigureInputPerGame>(system_, game_config.get(), this); |
| 54 | system_tab = std::make_unique<ConfigureSystem>(system_, this); | 55 | system_tab = std::make_unique<ConfigureSystem>(system_, this); |
| 55 | 56 | ||
diff --git a/src/yuzu/configuration/configure_per_game.h b/src/yuzu/configuration/configure_per_game.h index 4ecc43541..85752f1fa 100644 --- a/src/yuzu/configuration/configure_per_game.h +++ b/src/yuzu/configuration/configure_per_game.h | |||
| @@ -75,8 +75,8 @@ private: | |||
| 75 | std::unique_ptr<ConfigureAudio> audio_tab; | 75 | std::unique_ptr<ConfigureAudio> audio_tab; |
| 76 | std::unique_ptr<ConfigureCpu> cpu_tab; | 76 | std::unique_ptr<ConfigureCpu> cpu_tab; |
| 77 | std::unique_ptr<ConfigureGeneral> general_tab; | 77 | std::unique_ptr<ConfigureGeneral> general_tab; |
| 78 | std::unique_ptr<ConfigureGraphics> graphics_tab; | ||
| 79 | std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab; | 78 | std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab; |
| 79 | std::unique_ptr<ConfigureGraphics> graphics_tab; | ||
| 80 | std::unique_ptr<ConfigureInputPerGame> input_tab; | 80 | std::unique_ptr<ConfigureInputPerGame> input_tab; |
| 81 | std::unique_ptr<ConfigureSystem> system_tab; | 81 | std::unique_ptr<ConfigureSystem> system_tab; |
| 82 | }; | 82 | }; |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index d932e33a7..4489f43af 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -1164,7 +1164,8 @@ void GMainWindow::InitializeRecentFileMenuActions() { | |||
| 1164 | UpdateRecentFiles(); | 1164 | UpdateRecentFiles(); |
| 1165 | } | 1165 | } |
| 1166 | 1166 | ||
| 1167 | void GMainWindow::LinkActionShortcut(QAction* action, const QString& action_name) { | 1167 | void GMainWindow::LinkActionShortcut(QAction* action, const QString& action_name, |
| 1168 | const bool tas_allowed) { | ||
| 1168 | static const QString main_window = QStringLiteral("Main Window"); | 1169 | static const QString main_window = QStringLiteral("Main Window"); |
| 1169 | action->setShortcut(hotkey_registry.GetKeySequence(main_window, action_name)); | 1170 | action->setShortcut(hotkey_registry.GetKeySequence(main_window, action_name)); |
| 1170 | action->setShortcutContext(hotkey_registry.GetShortcutContext(main_window, action_name)); | 1171 | action->setShortcutContext(hotkey_registry.GetShortcutContext(main_window, action_name)); |
| @@ -1176,7 +1177,14 @@ void GMainWindow::LinkActionShortcut(QAction* action, const QString& action_name | |||
| 1176 | const auto* controller_hotkey = | 1177 | const auto* controller_hotkey = |
| 1177 | hotkey_registry.GetControllerHotkey(main_window, action_name, controller); | 1178 | hotkey_registry.GetControllerHotkey(main_window, action_name, controller); |
| 1178 | connect( | 1179 | connect( |
| 1179 | controller_hotkey, &ControllerShortcut::Activated, this, [action] { action->trigger(); }, | 1180 | controller_hotkey, &ControllerShortcut::Activated, this, |
| 1181 | [action, tas_allowed, this] { | ||
| 1182 | auto [tas_status, current_tas_frame, total_tas_frames] = | ||
| 1183 | input_subsystem->GetTas()->GetStatus(); | ||
| 1184 | if (tas_allowed || tas_status == InputCommon::TasInput::TasState::Stopped) { | ||
| 1185 | action->trigger(); | ||
| 1186 | } | ||
| 1187 | }, | ||
| 1180 | Qt::QueuedConnection); | 1188 | Qt::QueuedConnection); |
| 1181 | } | 1189 | } |
| 1182 | 1190 | ||
| @@ -1193,9 +1201,9 @@ void GMainWindow::InitializeHotkeys() { | |||
| 1193 | LinkActionShortcut(ui->action_Show_Status_Bar, QStringLiteral("Toggle Status Bar")); | 1201 | LinkActionShortcut(ui->action_Show_Status_Bar, QStringLiteral("Toggle Status Bar")); |
| 1194 | LinkActionShortcut(ui->action_Fullscreen, QStringLiteral("Fullscreen")); | 1202 | LinkActionShortcut(ui->action_Fullscreen, QStringLiteral("Fullscreen")); |
| 1195 | LinkActionShortcut(ui->action_Capture_Screenshot, QStringLiteral("Capture Screenshot")); | 1203 | LinkActionShortcut(ui->action_Capture_Screenshot, QStringLiteral("Capture Screenshot")); |
| 1196 | LinkActionShortcut(ui->action_TAS_Start, QStringLiteral("TAS Start/Stop")); | 1204 | LinkActionShortcut(ui->action_TAS_Start, QStringLiteral("TAS Start/Stop"), true); |
| 1197 | LinkActionShortcut(ui->action_TAS_Record, QStringLiteral("TAS Record")); | 1205 | LinkActionShortcut(ui->action_TAS_Record, QStringLiteral("TAS Record"), true); |
| 1198 | LinkActionShortcut(ui->action_TAS_Reset, QStringLiteral("TAS Reset")); | 1206 | LinkActionShortcut(ui->action_TAS_Reset, QStringLiteral("TAS Reset"), true); |
| 1199 | 1207 | ||
| 1200 | static const QString main_window = QStringLiteral("Main Window"); | 1208 | static const QString main_window = QStringLiteral("Main Window"); |
| 1201 | const auto connect_shortcut = [&]<typename Fn>(const QString& action_name, const Fn& function) { | 1209 | const auto connect_shortcut = [&]<typename Fn>(const QString& action_name, const Fn& function) { |
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 7b23f2a59..17631a2d9 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -214,7 +214,8 @@ public slots: | |||
| 214 | 214 | ||
| 215 | private: | 215 | private: |
| 216 | /// Updates an action's shortcut and text to reflect an updated hotkey from the hotkey registry. | 216 | /// Updates an action's shortcut and text to reflect an updated hotkey from the hotkey registry. |
| 217 | void LinkActionShortcut(QAction* action, const QString& action_name); | 217 | void LinkActionShortcut(QAction* action, const QString& action_name, |
| 218 | const bool tas_allowed = false); | ||
| 218 | 219 | ||
| 219 | void RegisterMetaTypes(); | 220 | void RegisterMetaTypes(); |
| 220 | 221 | ||
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index abe7092fc..dc9a3d68f 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp | |||
| @@ -169,6 +169,7 @@ void Config::ReadValues() { | |||
| 169 | ReadSetting("ControlsGeneral", Settings::values.enable_raw_input); | 169 | ReadSetting("ControlsGeneral", Settings::values.enable_raw_input); |
| 170 | ReadSetting("ControlsGeneral", Settings::values.enable_joycon_driver); | 170 | ReadSetting("ControlsGeneral", Settings::values.enable_joycon_driver); |
| 171 | ReadSetting("ControlsGeneral", Settings::values.enable_procon_driver); | 171 | ReadSetting("ControlsGeneral", Settings::values.enable_procon_driver); |
| 172 | ReadSetting("ControlsGeneral", Settings::values.random_amiibo_id); | ||
| 172 | ReadSetting("ControlsGeneral", Settings::values.emulate_analog_keyboard); | 173 | ReadSetting("ControlsGeneral", Settings::values.emulate_analog_keyboard); |
| 173 | ReadSetting("ControlsGeneral", Settings::values.vibration_enabled); | 174 | ReadSetting("ControlsGeneral", Settings::values.vibration_enabled); |
| 174 | ReadSetting("ControlsGeneral", Settings::values.enable_accurate_vibrations); | 175 | ReadSetting("ControlsGeneral", Settings::values.enable_accurate_vibrations); |