diff options
24 files changed, 173 insertions, 97 deletions
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 // Only detect account/device saves from the future location. switch (type) { case SaveDataType::SaveData: - return fmt::format("{}/account/{}/{:016X}/1", space_id_path, uuid.RawString(), title_id); + return fmt::format("{}/account/{}/{:016X}/0", space_id_path, uuid.RawString(), title_id); case SaveDataType::DeviceSaveData: - return fmt::format("{}/device/{:016X}/1", space_id_path, title_id); + return fmt::format("{}/device/{:016X}/0", space_id_path, title_id); default: return ""; } 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 @@ #include "core/file_sys/savedata_factory.h" #include "core/hle/kernel/k_event.h" #include "core/hle/kernel/k_transfer_memory.h" +#include "core/hle/result.h" #include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applet_ae.h" @@ -1335,7 +1336,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_) {24, nullptr, "GetLaunchStorageInfoForDebug"}, {25, &IApplicationFunctions::ExtendSaveData, "ExtendSaveData"}, {26, &IApplicationFunctions::GetSaveDataSize, "GetSaveDataSize"}, - {27, nullptr, "CreateCacheStorage"}, + {27, &IApplicationFunctions::CreateCacheStorage, "CreateCacheStorage"}, {28, nullptr, "GetSaveDataSizeMax"}, {29, nullptr, "GetCacheStorageMax"}, {30, &IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed, "BeginBlockingHomeButtonShortAndLongPressed"}, @@ -1738,6 +1739,36 @@ void IApplicationFunctions::GetSaveDataSize(HLERequestContext& ctx) { rb.Push(size.journal); } +void IApplicationFunctions::CreateCacheStorage(HLERequestContext& ctx) { + struct InputParameters { + u16 index; + s64 size; + s64 journal_size; + }; + static_assert(sizeof(InputParameters) == 24); + + struct OutputParameters { + u32 storage_target; + u64 required_size; + }; + static_assert(sizeof(OutputParameters) == 16); + + IPC::RequestParser rp{ctx}; + const auto params = rp.PopRaw<InputParameters>(); + + LOG_WARNING(Service_AM, "(STUBBED) called with index={}, size={:#x}, journal_size={:#x}", + params.index, params.size, params.journal_size); + + const OutputParameters resp{ + .storage_target = 1, + .required_size = 0, + }; + + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(ResultSuccess); + rb.PushRaw(resp); +} + void IApplicationFunctions::QueryApplicationPlayStatistics(HLERequestContext& ctx) { LOG_WARNING(Service_AM, "(STUBBED) called"); 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: void GetPseudoDeviceId(HLERequestContext& ctx); void ExtendSaveData(HLERequestContext& ctx); void GetSaveDataSize(HLERequestContext& ctx); + void CreateCacheStorage(HLERequestContext& ctx); void BeginBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx); void EndBlockingHomeButtonShortAndLongPressed(HLERequestContext& ctx); 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 @@ #include "core/file_sys/savedata_factory.h" #include "core/file_sys/system_archive/system_archive.h" #include "core/file_sys/vfs.h" +#include "core/hle/result.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/filesystem/fsp_srv.h" +#include "core/hle/service/hle_ipc.h" #include "core/hle/service/ipc_helpers.h" #include "core/reporter.h" @@ -552,9 +554,9 @@ public: // Write the data to memory ctx.WriteBuffer(begin, range_size); - IPC::ResponseBuilder rb{ctx, 3}; + IPC::ResponseBuilder rb{ctx, 4}; rb.Push(ResultSuccess); - rb.Push<u32>(static_cast<u32>(actual_entries)); + rb.Push<u64>(actual_entries); } private: @@ -712,7 +714,7 @@ FSP_SRV::FSP_SRV(Core::System& system_) {59, nullptr, "WriteSaveDataFileSystemExtraData"}, {60, nullptr, "OpenSaveDataInfoReader"}, {61, &FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId, "OpenSaveDataInfoReaderBySaveDataSpaceId"}, - {62, nullptr, "OpenCacheStorageList"}, + {62, &FSP_SRV::OpenSaveDataInfoReaderOnlyCacheStorage, "OpenSaveDataInfoReaderOnlyCacheStorage"}, {64, nullptr, "OpenSaveDataInternalStorageFileSystem"}, {65, nullptr, "UpdateSaveDataMacForDebug"}, {66, nullptr, "WriteSaveDataFileSystemExtraData2"}, @@ -921,6 +923,15 @@ void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(HLERequestContext& ctx) { std::make_shared<ISaveDataInfoReader>(system, space, fsc)); } +void FSP_SRV::OpenSaveDataInfoReaderOnlyCacheStorage(HLERequestContext& ctx) { + LOG_WARNING(Service_FS, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface<ISaveDataInfoReader>(system, FileSys::SaveDataSpaceId::TemporaryStorage, + fsc); +} + void FSP_SRV::WriteSaveDataFileSystemExtraDataBySaveDataAttribute(HLERequestContext& ctx) { LOG_WARNING(Service_FS, "(STUBBED) called."); 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: void OpenSaveDataFileSystem(HLERequestContext& ctx); void OpenReadOnlySaveDataFileSystem(HLERequestContext& ctx); void OpenSaveDataInfoReaderBySaveDataSpaceId(HLERequestContext& ctx); + void OpenSaveDataInfoReaderOnlyCacheStorage(HLERequestContext& ctx); void WriteSaveDataFileSystemExtraDataBySaveDataAttribute(HLERequestContext& ctx); void ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute(HLERequestContext& ctx); 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( } void Controller_NPad::VibrateControllers( - const std::vector<Core::HID::VibrationDeviceHandle>& vibration_device_handles, - const std::vector<Core::HID::VibrationValue>& vibration_values) { + std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles, + std::span<const Core::HID::VibrationValue> vibration_values) { if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) { return; } 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: const Core::HID::VibrationValue& vibration_value); void VibrateControllers( - const std::vector<Core::HID::VibrationDeviceHandle>& vibration_device_handles, - const std::vector<Core::HID::VibrationValue>& vibration_values); + std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles, + std::span<const Core::HID::VibrationValue> vibration_values); Core::HID::VibrationValue GetLastVibration( 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) { IPC::RequestParser rp{ctx}; const auto applet_resource_user_id{rp.Pop<u64>()}; - const auto handles = ctx.ReadBuffer(0); - const auto vibrations = ctx.ReadBuffer(1); - - std::vector<Core::HID::VibrationDeviceHandle> vibration_device_handles( - handles.size() / sizeof(Core::HID::VibrationDeviceHandle)); - std::vector<Core::HID::VibrationValue> vibration_values(vibrations.size() / - sizeof(Core::HID::VibrationValue)); - - std::memcpy(vibration_device_handles.data(), handles.data(), handles.size()); - std::memcpy(vibration_values.data(), vibrations.data(), vibrations.size()); + const auto handle_data = ctx.ReadBuffer(0); + const auto handle_count = ctx.GetReadBufferNumElements<Core::HID::VibrationDeviceHandle>(0); + const auto vibration_data = ctx.ReadBuffer(1); + const auto vibration_count = ctx.GetReadBufferNumElements<Core::HID::VibrationValue>(1); + + auto vibration_device_handles = + std::span(reinterpret_cast<const Core::HID::VibrationDeviceHandle*>(handle_data.data()), + handle_count); + auto vibration_values = std::span( + reinterpret_cast<const Core::HID::VibrationValue*>(vibration_data.data()), vibration_count); applet_resource->GetController<Controller_NPad>(HidController::NPad) .VibrateControllers(vibration_device_handles, vibration_values); 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, std::scoped_lock lock{core->mutex}; slots[slot] = {}; + slots[slot].fence = Fence::NoFence(); slots[slot].graphic_buffer = buffer; slots[slot].frame_number = 0; @@ -854,7 +855,7 @@ void BufferQueueProducer::Transact(HLERequestContext& ctx, TransactionId code, u status = DequeueBuffer(&slot, &fence, is_async, width, height, pixel_format, usage); parcel_out.Write(slot); - parcel_out.WriteObject(&fence); + parcel_out.WriteFlattenedObject(&fence); break; } case TransactionId::RequestBuffer: { @@ -864,7 +865,7 @@ void BufferQueueProducer::Transact(HLERequestContext& ctx, TransactionId code, u status = RequestBuffer(slot, &buf); - parcel_out.WriteObject(buf); + parcel_out.WriteFlattenedObject(buf); break; } 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: class OutputParcel final { public: - static constexpr std::size_t DefaultBufferSize = 0x40; - - OutputParcel() : buffer(DefaultBufferSize) {} - - template <typename T> - explicit OutputParcel(const T& out_data) : buffer(DefaultBufferSize) { - Write(out_data); - } + OutputParcel() = default; template <typename T> void Write(const T& val) { - static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable."); - - if (buffer.size() < write_index + sizeof(T)) { - buffer.resize(buffer.size() + sizeof(T) + DefaultBufferSize); - } - - std::memcpy(buffer.data() + write_index, &val, sizeof(T)); - write_index += sizeof(T); - write_index = Common::AlignUp(write_index, 4); + this->WriteImpl(val, m_data_buffer); } template <typename T> - void WriteObject(const T* ptr) { - static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable."); - + void WriteFlattenedObject(const T* ptr) { if (!ptr) { - Write<u32>(0); + this->Write<u32>(0); return; } - Write<u32>(1); - Write<s64>(sizeof(T)); - Write(*ptr); + this->Write<u32>(1); + this->Write<s64>(sizeof(T)); + this->Write(*ptr); } template <typename T> - void WriteObject(const std::shared_ptr<T> ptr) { - WriteObject(ptr.get()); + void WriteFlattenedObject(const std::shared_ptr<T> ptr) { + this->WriteFlattenedObject(ptr.get()); + } + + template <typename T> + void WriteInterface(const T& val) { + this->WriteImpl(val, m_data_buffer); + this->WriteImpl(0U, m_object_buffer); } std::vector<u8> Serialize() const { + std::vector<u8> output_buffer(sizeof(ParcelHeader) + m_data_buffer.size() + + m_object_buffer.size()); + ParcelHeader header{}; - header.data_size = static_cast<u32>(write_index - sizeof(ParcelHeader)); + header.data_size = static_cast<u32>(m_data_buffer.size()); header.data_offset = sizeof(ParcelHeader); - header.objects_size = 4; - header.objects_offset = static_cast<u32>(sizeof(ParcelHeader) + header.data_size); - std::memcpy(buffer.data(), &header, sizeof(ParcelHeader)); + header.objects_size = static_cast<u32>(m_object_buffer.size()); + header.objects_offset = header.data_offset + header.data_size; + + std::memcpy(output_buffer.data(), &header, sizeof(header)); + std::ranges::copy(m_data_buffer, output_buffer.data() + header.data_offset); + std::ranges::copy(m_object_buffer, output_buffer.data() + header.objects_offset); + + return output_buffer; + } + +private: + template <typename T> + requires(std::is_trivially_copyable_v<T>) + void WriteImpl(const T& val, std::vector<u8>& buffer) { + const size_t aligned_size = Common::AlignUp(sizeof(T), 4); + const size_t old_size = buffer.size(); + buffer.resize(old_size + aligned_size); - return buffer; + std::memcpy(buffer.data() + old_size, &val, sizeof(T)); } private: - mutable std::vector<u8> buffer; - std::size_t write_index = sizeof(ParcelHeader); + std::vector<u8> m_data_buffer; + std::vector<u8> m_object_buffer; }; } // 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 static_assert(std::is_trivially_copyable_v<SystemClockContext>, "SystemClockContext must be trivially copyable"); +struct ContinuousAdjustmentTimePoint { + s64 measurement_offset; + s64 diff_scale; + u32 shift_amount; + s64 lower; + s64 upper; + Common::UUID clock_source_id; +}; +static_assert(sizeof(ContinuousAdjustmentTimePoint) == 0x38); +static_assert(std::is_trivially_copyable_v<ContinuousAdjustmentTimePoint>, + "ContinuousAdjustmentTimePoint must be trivially copyable"); + /// https://switchbrew.org/wiki/Glue_services#TimeSpanType struct TimeSpanType { 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, } void SharedMemory::UpdateLocalSystemClockContext(const Clock::SystemClockContext& context) { + // lower and upper are related to the measurement point for the steady time point, + // and compare equal on boot + const s64 time_point_ns = context.steady_time_point.time_point * 1'000'000'000LL; + + // This adjusts for some sort of time skew + // Both 0 on boot + const s64 diff_scale = 0; + const u32 shift_amount = 0; + + const Clock::ContinuousAdjustmentTimePoint adjustment{ + .measurement_offset = system.CoreTiming().GetGlobalTimeNs().count(), + .diff_scale = diff_scale, + .shift_amount = shift_amount, + .lower = time_point_ns, + .upper = time_point_ns, + .clock_source_id = context.steady_time_point.clock_source_id, + }; + + StoreToLockFreeAtomicType(&GetFormat()->continuous_adjustment_timepoint, adjustment); StoreToLockFreeAtomicType(&GetFormat()->standard_local_system_clock_context, context); } 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: LockFreeAtomicType<Clock::SystemClockContext> standard_local_system_clock_context; LockFreeAtomicType<Clock::SystemClockContext> standard_network_system_clock_context; LockFreeAtomicType<bool> is_standard_user_system_clock_automatic_correction_enabled; - u32 format_version; + LockFreeAtomicType<Clock::ContinuousAdjustmentTimePoint> continuous_adjustment_timepoint; }; static_assert(offsetof(Format, standard_steady_clock_timepoint) == 0x0); static_assert(offsetof(Format, standard_local_system_clock_context) == 0x38); static_assert(offsetof(Format, standard_network_system_clock_context) == 0x80); static_assert(offsetof(Format, is_standard_user_system_clock_automatic_correction_enabled) == 0xc8); - static_assert(sizeof(Format) == 0xd8, "Format is an invalid size"); + static_assert(offsetof(Format, continuous_adjustment_timepoint) == 0xd0); + static_assert(sizeof(Format) == 0x148, "Format is an invalid size"); void SetupStandardSteadyClock(const Common::UUID& clock_source_id, 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: private: const u32 magic = 2; const u32 process_id = 1; - const u32 id; - INSERT_PADDING_WORDS(3); + const u64 id; + INSERT_PADDING_WORDS(2); std::array<u8, 8> dispdrv = {'d', 'i', 's', 'p', 'd', 'r', 'v', '\0'}; INSERT_PADDING_WORDS(2); }; @@ -608,7 +608,9 @@ private: return; } - const auto parcel = android::OutputParcel{NativeWindow{*buffer_queue_id}}; + android::OutputParcel parcel; + parcel.WriteInterface(NativeWindow{*buffer_queue_id}); + const auto buffer_size = ctx.WriteBuffer(parcel.Serialize()); IPC::ResponseBuilder rb{ctx, 4}; @@ -654,7 +656,9 @@ private: return; } - const auto parcel = android::OutputParcel{NativeWindow{*buffer_queue_id}}; + android::OutputParcel parcel; + parcel.WriteInterface(NativeWindow{*buffer_queue_id}); + const auto buffer_size = ctx.WriteBuffer(parcel.Serialize()); IPC::ResponseBuilder rb{ctx, 6}; 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 { InvalidHandle, NotSupported, Disabled, + Delayed, Unknown, }; 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() { } DriverResult NfcProtocol::ScanAmiibo(std::vector<u8>& data) { + if (update_counter++ < AMIIBO_UPDATE_DELAY) { + return DriverResult::Delayed; + } + update_counter = 0; + LOG_DEBUG(Input, "Start NFC pooling Mode"); ScopedSetBlocking sb(this); DriverResult result{DriverResult::Success}; @@ -87,7 +92,7 @@ DriverResult NfcProtocol::ScanAmiibo(std::vector<u8>& data) { result = WaitUntilNfcIsReady(); } if (result == DriverResult::Success) { - result = StartPolling(tag_data); + result = StartPolling(tag_data, 7); } if (result == DriverResult::Success) { result = GetAmiiboData(data); @@ -129,9 +134,8 @@ DriverResult NfcProtocol::WaitUntilNfcIsReady() { return DriverResult::Success; } -DriverResult NfcProtocol::StartPolling(TagFoundData& data) { +DriverResult NfcProtocol::StartPolling(TagFoundData& data, std::size_t timeout_limit) { LOG_DEBUG(Input, "Start Polling for tag"); - constexpr std::size_t timeout_limit = 7; MCUCommandResponse output{}; std::size_t tries = 0; 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: bool IsEnabled() const; private: + // Number of times the function will be delayed until it outputs valid data + static constexpr std::size_t AMIIBO_UPDATE_DELAY = 15; + struct TagFoundData { u8 type; std::vector<u8> uuid; @@ -39,7 +42,7 @@ private: DriverResult WaitUntilNfcIsReady(); - DriverResult StartPolling(TagFoundData& data); + DriverResult StartPolling(TagFoundData& data, std::size_t timeout_limit = 1); DriverResult ReadTag(const TagFoundData& data); @@ -56,6 +59,7 @@ private: NFCReadBlockCommand GetReadBlockCommand(NFCPages pages) const; bool is_enabled{}; + std::size_t update_counter{}; }; } // namespace InputCommon::Joycon diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index fff57ffa9..98756e4da 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -131,33 +131,15 @@ std::optional<VideoCore::RasterizerDownloadArea> BufferCache<P>::GetFlushArea(VA template <class P> void BufferCache<P>::DownloadMemory(VAddr cpu_addr, u64 size) { - WaitOnAsyncFlushes(cpu_addr, size); ForEachBufferInRange(cpu_addr, size, [&](BufferId, Buffer& buffer) { DownloadBufferMemory(buffer, cpu_addr, size); }); } template <class P> -void BufferCache<P>::WaitOnAsyncFlushes(VAddr cpu_addr, u64 size) { - bool must_wait = false; - ForEachInOverlapCounter(async_downloads, cpu_addr, size, - [&](VAddr, VAddr, int) { must_wait = true; }); - bool must_release = false; - ForEachInRangeSet(pending_ranges, cpu_addr, size, [&](VAddr, VAddr) { must_release = true; }); - if (must_release) { - std::function<void()> tmp([]() {}); - rasterizer.SignalFence(std::move(tmp)); - } - if (must_wait || must_release) { - rasterizer.ReleaseFences(); - } -} - -template <class P> void BufferCache<P>::ClearDownload(IntervalType subtract_interval) { RemoveEachInOverlapCounter(async_downloads, subtract_interval, -1024); uncommitted_ranges.subtract(subtract_interval); - pending_ranges.subtract(subtract_interval); for (auto& interval_set : committed_ranges) { interval_set.subtract(subtract_interval); } @@ -177,7 +159,6 @@ bool BufferCache<P>::DMACopy(GPUVAddr src_address, GPUVAddr dest_address, u64 am } const IntervalType subtract_interval{*cpu_dest_address, *cpu_dest_address + amount}; - WaitOnAsyncFlushes(*cpu_src_address, static_cast<u32>(amount)); ClearDownload(subtract_interval); BufferId buffer_a; @@ -205,7 +186,6 @@ bool BufferCache<P>::DMACopy(GPUVAddr src_address, GPUVAddr dest_address, u64 am const IntervalType add_interval{new_base_address, new_base_address + size}; tmp_intervals.push_back(add_interval); uncommitted_ranges.add(add_interval); - pending_ranges.add(add_interval); }; ForEachInRangeSet(common_ranges, *cpu_src_address, amount, mirror); // This subtraction in this order is important for overlapping copies. @@ -492,7 +472,6 @@ void BufferCache<P>::CommitAsyncFlushesHigh() { } MICROPROFILE_SCOPE(GPU_DownloadMemory); - pending_ranges.clear(); auto it = committed_ranges.begin(); while (it != committed_ranges.end()) { auto& current_intervals = *it; @@ -1232,7 +1211,6 @@ void BufferCache<P>::MarkWrittenBuffer(BufferId buffer_id, VAddr cpu_addr, u32 s const IntervalType base_interval{cpu_addr, cpu_addr + size}; common_ranges.add(base_interval); uncommitted_ranges.add(base_interval); - pending_ranges.add(base_interval); } template <class P> @@ -1677,14 +1655,15 @@ typename BufferCache<P>::Binding BufferCache<P>::StorageBufferBinding(GPUVAddr s const bool is_nvn_cbuf = cbuf_index == 0; // The NVN driver buffer (index 0) is known to pack the SSBO address followed by its size. if (is_nvn_cbuf) { - return gpu_memory->Read<u32>(ssbo_addr + 8); + const u32 ssbo_size = gpu_memory->Read<u32>(ssbo_addr + 8); + if (ssbo_size != 0) { + return ssbo_size; + } } // Other titles (notably Doom Eternal) may use STG/LDG on buffer addresses in custom defined // cbufs, which do not store the sizes adjacent to the addresses, so use the fully // mapped buffer size for now. const u32 memory_layout_size = static_cast<u32>(gpu_memory->GetMemoryLayoutSize(gpu_addr)); - LOG_INFO(HW_GPU, "Binding storage buffer for cbuf index {}, MemoryLayoutSize 0x{:X}", - cbuf_index, memory_layout_size); return memory_layout_size; }(); 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: void RunGarbageCollector(); - void WaitOnAsyncFlushes(VAddr cpu_addr, u64 size); - void BindHostIndexBuffer(); void BindHostVertexBuffers(); @@ -547,7 +545,6 @@ private: IntervalSet uncommitted_ranges; IntervalSet common_ranges; IntervalSet cached_ranges; - IntervalSet pending_ranges; std::deque<IntervalSet> committed_ranges; // Async Buffers 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 writer.WriteUe(0); writer.WriteBit(context.h264_parameter_set.entropy_coding_mode_flag != 0); - writer.WriteBit(false); + writer.WriteBit(context.h264_parameter_set.pic_order_present_flag != 0); writer.WriteUe(0); writer.WriteUe(context.h264_parameter_set.num_refidx_l0_default_active); 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 writer.WriteBit(context.h264_parameter_set.redundant_pic_cnt_present_flag != 0); writer.WriteBit(context.h264_parameter_set.transform_8x8_mode_flag != 0); - writer.WriteBit(true); + writer.WriteBit(true); // pic_scaling_matrix_present_flag for (s32 index = 0; index < 6; index++) { writer.WriteBit(true); diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 012d6fa73..4d0481f2a 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1864,6 +1864,7 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime, num_layers = std::max(num_layers, color_buffer->range.extent.layers); images[num_images] = color_buffer->ImageHandle(); image_ranges[num_images] = MakeSubresourceRange(color_buffer); + rt_map[index] = num_images; samples = color_buffer->Samples(); ++num_images; } diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index 23473bf9c..4166b3d20 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -334,7 +334,7 @@ public: } [[nodiscard]] bool HasAspectColorBit(size_t index) const noexcept { - return (image_ranges.at(index).aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != 0; + return (image_ranges.at(rt_map[index]).aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != 0; } [[nodiscard]] bool HasAspectDepthBit() const noexcept { @@ -354,6 +354,7 @@ private: u32 num_images = 0; std::array<VkImage, 9> images{}; std::array<VkImageSubresourceRange, 9> image_ranges{}; + std::array<size_t, NUM_RT> rt_map{}; bool has_depth{}; bool has_stencil{}; }; 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() { device_access_memory += mem_properties.memoryHeaps[element].size; } if (!is_integrated) { + const u64 reserve_memory = std::min<u64>(device_access_memory / 8, 1_GiB); + device_access_memory -= reserve_memory; return; } 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: /// Returns whether this allocation is compatible with the arguments. [[nodiscard]] bool IsCompatible(VkMemoryPropertyFlags flags, u32 type_mask) const { - return (flags & property_flags) == property_flags && (type_mask & shifted_memory_type) != 0; + return (flags & property_flags) == flags && (type_mask & shifted_memory_type) != 0; } private: |