Compare commits

..

3 Commits

Author SHA1 Message Date
yuzubot
1f4de06459 Android 220 2024-01-31 01:00:18 +00:00
yuzubot
20f50df7f8 Merge yuzu-emu#12760 2024-01-31 01:00:17 +00:00
yuzubot
776a6ea3f1 Merge yuzu-emu#12749 2024-01-31 01:00:17 +00:00
23 changed files with 217 additions and 285 deletions

View File

@@ -1,12 +1,7 @@
| Pull Request | Commit | Title | Author | Merged? |
|----|----|----|----|----|
| [12749](https://github.com/yuzu-emu/yuzu-android//pull/12749) | [`aad4b0d6f`](https://github.com/yuzu-emu/yuzu-android//pull/12749/files) | general: workarounds for SMMU syncing issues | [liamwhite](https://github.com/liamwhite/) | Yes |
| [12760](https://github.com/yuzu-emu/yuzu-android//pull/12760) | [`817d91623`](https://github.com/yuzu-emu/yuzu-android//pull/12760/files) | am: rewrite for multiprocess support | [liamwhite](https://github.com/liamwhite/) | Yes |
| [12858](https://github.com/yuzu-emu/yuzu-android//pull/12858) | [`5510b3197`](https://github.com/yuzu-emu/yuzu-android//pull/12858/files) | internal_network: only poll for accept on blocking sockets | [liamwhite](https://github.com/liamwhite/) | Yes |
| [12864](https://github.com/yuzu-emu/yuzu-android//pull/12864) | [`9ed82a280`](https://github.com/yuzu-emu/yuzu-android//pull/12864/files) | Small time fixes | [Kelebek1](https://github.com/Kelebek1/) | Yes |
| [12867](https://github.com/yuzu-emu/yuzu-android//pull/12867) | [`a97ecc237`](https://github.com/yuzu-emu/yuzu-android//pull/12867/files) | aoc: fix DLC listing | [liamwhite](https://github.com/liamwhite/) | Yes |
| [12868](https://github.com/yuzu-emu/yuzu-android//pull/12868) | [`e8be665f1`](https://github.com/yuzu-emu/yuzu-android//pull/12868/files) | settings: Allow audio sink, input, and output to be set per game | [t895](https://github.com/t895/) | Yes |
| [12869](https://github.com/yuzu-emu/yuzu-android//pull/12869) | [`acd46c9bd`](https://github.com/yuzu-emu/yuzu-android//pull/12869/files) | SMMU: A set of different fixes. | [FernandoS27](https://github.com/FernandoS27/) | Yes |
| [12749](https://github.com/yuzu-emu/yuzu-android//pull/12749) | [`e644610e1`](https://github.com/yuzu-emu/yuzu-android//pull/12749/files) | general: workarounds for SMMU syncing issues | [liamwhite](https://github.com/liamwhite/) | Yes |
| [12760](https://github.com/yuzu-emu/yuzu-android//pull/12760) | [`8e0a40434`](https://github.com/yuzu-emu/yuzu-android//pull/12760/files) | am: rewrite for multiprocess support | [liamwhite](https://github.com/liamwhite/) | Yes |
End of merge log. You can find the original README.md below the break.

View File

@@ -134,12 +134,12 @@ struct Values {
Linkage linkage{};
// Audio
SwitchableSetting<AudioEngine> sink_id{linkage, AudioEngine::Auto, "output_engine",
Category::Audio, Specialization::RuntimeList};
SwitchableSetting<std::string> audio_output_device_id{
linkage, "auto", "output_device", Category::Audio, Specialization::RuntimeList};
SwitchableSetting<std::string> audio_input_device_id{
linkage, "auto", "input_device", Category::Audio, Specialization::RuntimeList};
Setting<AudioEngine> sink_id{linkage, AudioEngine::Auto, "output_engine", Category::Audio,
Specialization::RuntimeList};
Setting<std::string> audio_output_device_id{linkage, "auto", "output_device", Category::Audio,
Specialization::RuntimeList};
Setting<std::string> audio_input_device_id{linkage, "auto", "input_device", Category::Audio,
Specialization::RuntimeList};
SwitchableSetting<AudioMode, true> sound_index{
linkage, AudioMode::Stereo, AudioMode::Mono, AudioMode::Surround,
"sound_index", Category::SystemAudio, Specialization::Default, true,

View File

@@ -5,7 +5,6 @@
#include <array>
#include <atomic>
#include <bit>
#include <deque>
#include <memory>
#include <mutex>
@@ -182,28 +181,24 @@ private:
}
Common::VirtualBuffer<VAddr> cpu_backing_address;
using CounterType = u8;
using CounterAtomicType = std::atomic_uint8_t;
static constexpr size_t subentries = 8 / sizeof(CounterType);
static constexpr size_t subentries = 8 / sizeof(u8);
static constexpr size_t subentries_mask = subentries - 1;
static constexpr size_t subentries_shift =
std::countr_zero(sizeof(u64)) - std::countr_zero(sizeof(CounterType));
class CounterEntry final {
public:
CounterEntry() = default;
CounterAtomicType& Count(std::size_t page) {
std::atomic_uint8_t& Count(std::size_t page) {
return values[page & subentries_mask];
}
const CounterAtomicType& Count(std::size_t page) const {
const std::atomic_uint8_t& Count(std::size_t page) const {
return values[page & subentries_mask];
}
private:
std::array<CounterAtomicType, subentries> values{};
std::array<std::atomic_uint8_t, subentries> values{};
};
static_assert(sizeof(CounterEntry) == subentries * sizeof(CounterType),
static_assert(sizeof(CounterEntry) == subentries * sizeof(u8),
"CounterEntry should be 8 bytes!");
static constexpr size_t num_counter_entries =

View File

@@ -213,8 +213,8 @@ void DeviceMemoryManager<Traits>::Free(DAddr start, size_t size) {
}
template <typename Traits>
void DeviceMemoryManager<Traits>::Map(DAddr address, VAddr virtual_address, size_t size, Asid asid,
bool track) {
void DeviceMemoryManager<Traits>::Map(DAddr address, VAddr virtual_address, size_t size,
Asid asid, bool track) {
Core::Memory::Memory* process_memory = registered_processes[asid.id];
size_t start_page_d = address >> Memory::YUZU_PAGEBITS;
size_t num_pages = Common::AlignUp(size, Memory::YUZU_PAGESIZE) >> Memory::YUZU_PAGEBITS;
@@ -519,36 +519,22 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size
const size_t page_end = Common::DivCeil(addr + size, Memory::YUZU_PAGESIZE);
size_t page = addr >> Memory::YUZU_PAGEBITS;
auto [asid, base_vaddress] = ExtractCPUBacking(page);
size_t vpage = base_vaddress >> Memory::YUZU_PAGEBITS;
auto* memory_device_inter = registered_processes[asid.id];
const auto release_pending = [&] {
if (uncache_bytes > 0) {
MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS,
uncache_bytes, false);
uncache_bytes = 0;
}
if (cache_bytes > 0) {
MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS,
cache_bytes, true);
cache_bytes = 0;
}
};
for (; page != page_end; ++page) {
CounterAtomicType& count = cached_pages->at(page >> subentries_shift).Count(page);
auto [asid_2, vpage] = ExtractCPUBacking(page);
vpage >>= Memory::YUZU_PAGEBITS;
std::atomic_uint8_t& count = cached_pages->at(page >> 3).Count(page);
if (vpage == 0) [[unlikely]] {
release_pending();
continue;
}
if (asid.id != asid_2.id) [[unlikely]] {
release_pending();
memory_device_inter = registered_processes[asid_2.id];
if (delta > 0) {
ASSERT_MSG(count.load(std::memory_order::relaxed) < std::numeric_limits<u8>::max(),
"Count may overflow!");
} else if (delta < 0) {
ASSERT_MSG(count.load(std::memory_order::relaxed) > 0, "Count may underflow!");
} else {
ASSERT_MSG(false, "Delta must be non-zero!");
}
// Adds or subtracts 1, as count is a unsigned 8-bit value
count.fetch_add(static_cast<CounterType>(delta), std::memory_order_release);
count.fetch_add(static_cast<u8>(delta), std::memory_order_release);
// Assume delta is either -1 or 1
if (count.load(std::memory_order::relaxed) == 0) {
@@ -567,12 +553,20 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size
}
cache_bytes += Memory::YUZU_PAGESIZE;
} else if (cache_bytes > 0) {
MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS,
cache_bytes, true);
MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes,
true);
cache_bytes = 0;
}
vpage++;
}
if (uncache_bytes > 0) {
MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS, uncache_bytes,
false);
}
if (cache_bytes > 0) {
MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes,
true);
}
release_pending();
}
} // namespace Core

View File

@@ -207,7 +207,7 @@ void Error::Execute() {
void Error::DisplayCompleted() {
complete = true;
PushOutData(std::make_shared<IStorage>(system, std::vector<u8>(0x1000)));
PushOutData(std::make_shared<IStorage>(system, std::vector<u8>()));
Exit();
}

View File

@@ -202,7 +202,7 @@ void AOC_U::ListAddOnContent(HLERequestContext& ctx) {
LOG_DEBUG(Service_AOC, "called with offset={}, count={}, process_id={}", offset, count,
process_id);
const auto current = FileSys::GetBaseTitleID(system.GetApplicationProcessProgramID());
const auto current = system.GetApplicationProcessProgramID();
std::vector<u32> out;
const auto& disabled = Settings::values.disabled_addons[current];

View File

@@ -197,27 +197,32 @@ Result TimeZoneService::ToCalendarTimeWithMyRule(
Result TimeZoneService::ToPosixTime(Out<u32> out_count,
OutArray<s64, BufferAttr_HipcPointer> out_times,
const Service::PSC::Time::CalendarTime& calendar_time,
InRule rule) {
Out<u32> out_times_count,
Service::PSC::Time::CalendarTime& calendar_time, InRule rule) {
SCOPE_EXIT({
LOG_DEBUG(Service_Time,
"called. calendar_time={} out_count={} out_times[0]={} out_times[1]={}",
calendar_time, *out_count, out_times[0], out_times[1]);
"called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} "
"out_times_count={}",
calendar_time, *out_count, out_times[0], out_times[1], *out_times_count);
});
R_RETURN(m_wrapped_service->ToPosixTime(out_count, out_times, calendar_time, rule));
R_RETURN(
m_wrapped_service->ToPosixTime(out_count, out_times, out_times_count, calendar_time, rule));
}
Result TimeZoneService::ToPosixTimeWithMyRule(
Out<u32> out_count, OutArray<s64, BufferAttr_HipcPointer> out_times,
const Service::PSC::Time::CalendarTime& calendar_time) {
Result TimeZoneService::ToPosixTimeWithMyRule(Out<u32> out_count,
OutArray<s64, BufferAttr_HipcPointer> out_times,
Out<u32> out_times_count,
Service::PSC::Time::CalendarTime& calendar_time) {
SCOPE_EXIT({
LOG_DEBUG(Service_Time,
"called. calendar_time={} out_count={} out_times[0]={} out_times[1]={}",
calendar_time, *out_count, out_times[0], out_times[1]);
"called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} "
"out_times_count={}",
calendar_time, *out_count, out_times[0], out_times[1], *out_times_count);
});
R_RETURN(m_wrapped_service->ToPosixTimeWithMyRule(out_count, out_times, calendar_time));
R_RETURN(m_wrapped_service->ToPosixTimeWithMyRule(out_count, out_times, out_times_count,
calendar_time));
}
} // namespace Service::Glue::Time

View File

@@ -68,10 +68,12 @@ public:
Out<Service::PSC::Time::CalendarTime> out_calendar_time,
Out<Service::PSC::Time::CalendarAdditionalInfo> out_additional_info, s64 time);
Result ToPosixTime(Out<u32> out_count, OutArray<s64, BufferAttr_HipcPointer> out_times,
const Service::PSC::Time::CalendarTime& calendar_time, InRule rule);
Out<u32> out_times_count, Service::PSC::Time::CalendarTime& calendar_time,
InRule rule);
Result ToPosixTimeWithMyRule(Out<u32> out_count,
OutArray<s64, BufferAttr_HipcPointer> out_times,
const Service::PSC::Time::CalendarTime& calendar_time);
Out<u32> out_times_count,
Service::PSC::Time::CalendarTime& calendar_time);
private:
Core::System& m_system;

View File

@@ -189,7 +189,7 @@ struct fmt::formatter<Service::PSC::Time::SteadyClockTimePoint> : fmt::formatter
template <typename FormatContext>
auto format(const Service::PSC::Time::SteadyClockTimePoint& time_point,
FormatContext& ctx) const {
return fmt::format_to(ctx.out(), "[time_point={}]", time_point.time_point);
return fmt::format_to(ctx.out(), "time_point={}", time_point.time_point);
}
};
@@ -197,7 +197,7 @@ template <>
struct fmt::formatter<Service::PSC::Time::SystemClockContext> : fmt::formatter<fmt::string_view> {
template <typename FormatContext>
auto format(const Service::PSC::Time::SystemClockContext& context, FormatContext& ctx) const {
return fmt::format_to(ctx.out(), "[offset={} steady_time_point={}]", context.offset,
return fmt::format_to(ctx.out(), "offset={} steady_time_point={}", context.offset,
context.steady_time_point.time_point);
}
};
@@ -206,9 +206,8 @@ template <>
struct fmt::formatter<Service::PSC::Time::CalendarTime> : fmt::formatter<fmt::string_view> {
template <typename FormatContext>
auto format(const Service::PSC::Time::CalendarTime& calendar, FormatContext& ctx) const {
return fmt::format_to(ctx.out(), "[{:02}/{:02}/{:04} {:02}:{:02}:{:02}]", calendar.day,
calendar.month, calendar.year, calendar.hour, calendar.minute,
calendar.second);
return fmt::format_to(ctx.out(), "{}/{}/{} {}:{}:{}", calendar.day, calendar.month,
calendar.year, calendar.hour, calendar.minute, calendar.second);
}
};
@@ -218,7 +217,7 @@ struct fmt::formatter<Service::PSC::Time::CalendarAdditionalInfo>
template <typename FormatContext>
auto format(const Service::PSC::Time::CalendarAdditionalInfo& additional,
FormatContext& ctx) const {
return fmt::format_to(ctx.out(), "[weekday={} yearday={} name={} is_dst={} ut_offset={}]",
return fmt::format_to(ctx.out(), "weekday={} yearday={} name={} is_dst={} ut_offset={}",
additional.day_of_week, additional.day_of_year,
additional.name.data(), additional.is_dst, additional.ut_offset);
}
@@ -228,7 +227,8 @@ template <>
struct fmt::formatter<Service::PSC::Time::LocationName> : fmt::formatter<fmt::string_view> {
template <typename FormatContext>
auto format(const Service::PSC::Time::LocationName& name, FormatContext& ctx) const {
return formatter<string_view>::format(name.data(), ctx);
std::string_view n{name.data(), name.size()};
return formatter<string_view>::format(n, ctx);
}
};
@@ -236,7 +236,8 @@ template <>
struct fmt::formatter<Service::PSC::Time::RuleVersion> : fmt::formatter<fmt::string_view> {
template <typename FormatContext>
auto format(const Service::PSC::Time::RuleVersion& version, FormatContext& ctx) const {
return formatter<string_view>::format(version.data(), ctx);
std::string_view v{version.data(), version.size()};
return formatter<string_view>::format(v, ctx);
}
};
@@ -246,11 +247,10 @@ struct fmt::formatter<Service::PSC::Time::ClockSnapshot> : fmt::formatter<fmt::s
auto format(const Service::PSC::Time::ClockSnapshot& snapshot, FormatContext& ctx) const {
return fmt::format_to(
ctx.out(),
"[user_context={} network_context={} user_time={} network_time={} "
"user_calendar_time={} "
"user_context={} network_context={} user_time={} network_time={} user_calendar_time={} "
"network_calendar_time={} user_calendar_additional_time={} "
"network_calendar_additional_time={} steady_clock_time_point={} location={} "
"is_automatic_correction_enabled={} type={}]",
"is_automatic_correction_enabled={} type={}",
snapshot.user_context, snapshot.network_context, snapshot.user_time,
snapshot.network_time, snapshot.user_calendar_time, snapshot.network_calendar_time,
snapshot.user_calendar_additional_time, snapshot.network_calendar_additional_time,
@@ -266,7 +266,7 @@ struct fmt::formatter<Service::PSC::Time::ContinuousAdjustmentTimePoint>
auto format(const Service::PSC::Time::ContinuousAdjustmentTimePoint& time_point,
FormatContext& ctx) const {
return fmt::format_to(ctx.out(),
"[rtc_offset={} diff_scale={} shift_amount={} lower={} upper={}]",
"rtc_offset={} diff_scale={} shift_amount={} lower={} upper={}",
time_point.rtc_offset, time_point.diff_scale, time_point.shift_amount,
time_point.lower, time_point.upper);
}

View File

@@ -120,8 +120,11 @@ Result ServiceManager::SetupStandardNetworkSystemClockCore(SystemClockContext& c
context, context.steady_time_point.clock_source_id.RawString(), accuracy);
// TODO this is a hack! The network clock should be updated independently, from the ntc service
// and maybe elsewhere. We do not do that, so fix the clock to the local clock.
m_local_system_clock.GetContext(context);
// and maybe elsewhere. We do not do that, so fix the clock to the local clock on first boot
// to avoid it being stuck at 0.
if (context == Service::PSC::Time::SystemClockContext{}) {
m_local_system_clock.GetContext(context);
}
m_network_system_clock.SetContextWriter(m_network_system_context_writer);
m_network_system_clock.Initialize(context, accuracy);
@@ -135,6 +138,13 @@ Result ServiceManager::SetupStandardUserSystemClockCore(bool automatic_correctio
LOG_DEBUG(Service_Time, "called. automatic_correction={} time_point={} clock_source_id={}",
automatic_correction, time_point, time_point.clock_source_id.RawString());
// TODO this is a hack! The user clock should be updated independently, from the ntc service
// and maybe elsewhere. We do not do that, so fix the clock to the local clock on first boot
// to avoid it being stuck at 0.
if (time_point == Service::PSC::Time::SteadyClockTimePoint{}) {
m_local_system_clock.GetCurrentTimePoint(time_point);
}
m_user_system_clock.SetAutomaticCorrection(automatic_correction);
m_user_system_clock.SetTimePointAndSignal(time_point);
m_user_system_clock.SetInitialized();

View File

@@ -140,11 +140,11 @@ Result TimeZone::ParseBinaryInto(Tz::Rule& out_rule, std::span<const u8> binary)
R_RETURN(ParseBinaryImpl(out_rule, binary));
}
Result TimeZone::ToPosixTime(u32& out_count, std::span<s64> out_times, size_t out_times_max_count,
const CalendarTime& calendar, const Tz::Rule& rule) {
Result TimeZone::ToPosixTime(u32& out_count, std::span<s64> out_times, u32 out_times_count,
CalendarTime& calendar, const Tz::Rule& rule) {
std::scoped_lock l{m_mutex};
auto res = ToPosixTimeImpl(out_count, out_times, out_times_max_count, calendar, rule, -1);
auto res = ToPosixTimeImpl(out_count, out_times, out_times_count, calendar, rule, -1);
if (res != ResultSuccess) {
if (res == ResultTimeZoneNotFound) {
@@ -158,10 +158,10 @@ Result TimeZone::ToPosixTime(u32& out_count, std::span<s64> out_times, size_t ou
}
Result TimeZone::ToPosixTimeWithMyRule(u32& out_count, std::span<s64> out_times,
size_t out_times_max_count, const CalendarTime& calendar) {
u32 out_times_count, CalendarTime& calendar) {
std::scoped_lock l{m_mutex};
auto res = ToPosixTimeImpl(out_count, out_times, out_times_max_count, calendar, m_my_rule, -1);
auto res = ToPosixTimeImpl(out_count, out_times, out_times_count, calendar, m_my_rule, -1);
if (res != ResultSuccess) {
if (res == ResultTimeZoneNotFound) {
@@ -212,23 +212,20 @@ Result TimeZone::ToCalendarTimeImpl(CalendarTime& out_calendar_time,
R_SUCCEED();
}
Result TimeZone::ToPosixTimeImpl(u32& out_count, std::span<s64> out_times,
size_t out_times_max_count, const CalendarTime& calendar,
const Tz::Rule& rule, s32 is_dst) {
Result TimeZone::ToPosixTimeImpl(u32& out_count, std::span<s64> out_times, u32 out_times_count,
CalendarTime& calendar, const Tz::Rule& rule, s32 is_dst) {
R_TRY(ValidateRule(rule));
CalendarTime local_calendar{calendar};
local_calendar.month -= 1;
local_calendar.year -= 1900;
calendar.month -= 1;
calendar.year -= 1900;
Tz::CalendarTimeInternal internal{
.tm_sec = local_calendar.second,
.tm_min = local_calendar.minute,
.tm_hour = local_calendar.hour,
.tm_mday = local_calendar.day,
.tm_mon = local_calendar.month,
.tm_year = local_calendar.year,
.tm_sec = calendar.second,
.tm_min = calendar.minute,
.tm_hour = calendar.hour,
.tm_mday = calendar.day,
.tm_mon = calendar.month,
.tm_year = calendar.year,
.tm_wday = 0,
.tm_yday = 0,
.tm_isdst = is_dst,
@@ -246,9 +243,9 @@ Result TimeZone::ToPosixTimeImpl(u32& out_count, std::span<s64> out_times,
R_RETURN(ResultTimeZoneNotFound);
}
if (internal.tm_sec != local_calendar.second || internal.tm_min != local_calendar.minute ||
internal.tm_hour != local_calendar.hour || internal.tm_mday != local_calendar.day ||
internal.tm_mon != local_calendar.month || internal.tm_year != local_calendar.year) {
if (internal.tm_sec != calendar.second || internal.tm_min != calendar.minute ||
internal.tm_hour != calendar.hour || internal.tm_mday != calendar.day ||
internal.tm_mon != calendar.month || internal.tm_year != calendar.year) {
R_RETURN(ResultTimeZoneNotFound);
}
@@ -257,7 +254,7 @@ Result TimeZone::ToPosixTimeImpl(u32& out_count, std::span<s64> out_times,
}
out_times[0] = time;
if (out_times_max_count < 2) {
if (out_times_count < 2) {
out_count = 1;
R_SUCCEED();
}

View File

@@ -38,18 +38,18 @@ public:
CalendarAdditionalInfo& calendar_additional, s64 time);
Result ParseBinary(LocationName& name, std::span<const u8> binary);
Result ParseBinaryInto(Tz::Rule& out_rule, std::span<const u8> binary);
Result ToPosixTime(u32& out_count, std::span<s64> out_times, size_t out_times_max_count,
const CalendarTime& calendar, const Tz::Rule& rule);
Result ToPosixTimeWithMyRule(u32& out_count, std::span<s64> out_times,
size_t out_times_max_count, const CalendarTime& calendar);
Result ToPosixTime(u32& out_count, std::span<s64> out_times, u32 out_times_count,
CalendarTime& calendar, const Tz::Rule& rule);
Result ToPosixTimeWithMyRule(u32& out_count, std::span<s64> out_times, u32 out_times_count,
CalendarTime& calendar);
private:
Result ParseBinaryImpl(Tz::Rule& out_rule, std::span<const u8> binary);
Result ToCalendarTimeImpl(CalendarTime& out_calendar_time,
CalendarAdditionalInfo& out_additional_info, s64 time,
const Tz::Rule& rule);
Result ToPosixTimeImpl(u32& out_count, std::span<s64> out_times, size_t out_times_max_count,
const CalendarTime& calendar, const Tz::Rule& rule, s32 is_dst);
Result ToPosixTimeImpl(u32& out_count, std::span<s64> out_times, u32 out_times_count,
CalendarTime& calendar, const Tz::Rule& rule, s32 is_dst);
bool m_initialized{};
std::recursive_mutex m_mutex;

View File

@@ -138,28 +138,32 @@ Result TimeZoneService::ToCalendarTimeWithMyRule(Out<CalendarTime> out_calendar_
Result TimeZoneService::ToPosixTime(Out<u32> out_count,
OutArray<s64, BufferAttr_HipcPointer> out_times,
const CalendarTime& calendar_time, InRule rule) {
Out<u32> out_times_count, CalendarTime& calendar_time,
InRule rule) {
SCOPE_EXIT({
LOG_DEBUG(Service_Time,
"called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} ",
calendar_time, *out_count, out_times[0], out_times[1]);
"called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} "
"out_times_count={}",
calendar_time, *out_count, out_times[0], out_times[1], *out_times_count);
});
R_RETURN(
m_time_zone.ToPosixTime(*out_count, out_times, out_times.size(), calendar_time, *rule));
m_time_zone.ToPosixTime(*out_count, out_times, *out_times_count, calendar_time, *rule));
}
Result TimeZoneService::ToPosixTimeWithMyRule(Out<u32> out_count,
OutArray<s64, BufferAttr_HipcPointer> out_times,
const CalendarTime& calendar_time) {
Out<u32> out_times_count,
CalendarTime& calendar_time) {
SCOPE_EXIT({
LOG_DEBUG(Service_Time,
"called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} ",
calendar_time, *out_count, out_times[0], out_times[1]);
"called. calendar_time={} out_count={} out_times[0]={} out_times[1]={} "
"out_times_count={}",
calendar_time, *out_count, out_times[0], out_times[1], *out_times_count);
});
R_RETURN(
m_time_zone.ToPosixTimeWithMyRule(*out_count, out_times, out_times.size(), calendar_time));
m_time_zone.ToPosixTimeWithMyRule(*out_count, out_times, *out_times_count, calendar_time));
}
} // namespace Service::PSC::Time

View File

@@ -50,10 +50,10 @@ public:
Result ToCalendarTimeWithMyRule(Out<CalendarTime> out_calendar_time,
Out<CalendarAdditionalInfo> out_additional_info, s64 time);
Result ToPosixTime(Out<u32> out_count, OutArray<s64, BufferAttr_HipcPointer> out_times,
const CalendarTime& calendar_time, InRule rule);
Out<u32> out_times_count, CalendarTime& calendar_time, InRule rule);
Result ToPosixTimeWithMyRule(Out<u32> out_count,
OutArray<s64, BufferAttr_HipcPointer> out_times,
const CalendarTime& calendar_time);
Out<u32> out_times_count, CalendarTime& calendar_time);
private:
Core::System& m_system;

View File

@@ -25,7 +25,7 @@
namespace Service::Set {
namespace {
constexpr u32 SETTINGS_VERSION{3u};
constexpr u32 SETTINGS_VERSION{2u};
constexpr auto SETTINGS_MAGIC = Common::MakeMagic('y', 'u', 'z', 'u', '_', 's', 'e', 't');
struct SettingsHeader {
u64 magic;

View File

@@ -693,23 +693,20 @@ std::pair<SocketBase::AcceptResult, Errno> Socket::Accept() {
sockaddr_in addr;
socklen_t addrlen = sizeof(addr);
const bool wait_for_accept = !is_non_blocking;
if (wait_for_accept) {
std::vector<WSAPOLLFD> host_pollfds{
WSAPOLLFD{fd, POLLIN, 0},
WSAPOLLFD{GetInterruptSocket(), POLLIN, 0},
};
std::vector<WSAPOLLFD> host_pollfds{
WSAPOLLFD{fd, POLLIN, 0},
WSAPOLLFD{GetInterruptSocket(), POLLIN, 0},
};
while (true) {
const int pollres =
WSAPoll(host_pollfds.data(), static_cast<ULONG>(host_pollfds.size()), -1);
if (host_pollfds[1].revents != 0) {
// Interrupt signaled before a client could be accepted, break
return {AcceptResult{}, Errno::AGAIN};
}
if (pollres > 0) {
break;
}
while (true) {
const int pollres =
WSAPoll(host_pollfds.data(), static_cast<ULONG>(host_pollfds.size()), -1);
if (host_pollfds[1].revents != 0) {
// Interrupt signaled before a client could be accepted, break
return {AcceptResult{}, Errno::AGAIN};
}
if (pollres > 0) {
break;
}
}
@@ -916,7 +913,6 @@ Errno Socket::SetRcvTimeo(u32 value) {
Errno Socket::SetNonBlock(bool enable) {
if (EnableNonBlock(fd, enable)) {
is_non_blocking = enable;
return Errno::SUCCESS;
}
return GetAndLogLastError();

View File

@@ -166,9 +166,6 @@ public:
bool IsOpened() const override;
void HandleProxyPacket(const ProxyPacket& packet) override;
private:
bool is_non_blocking = false;
};
std::pair<s32, Errno> Poll(std::vector<PollFD>& poll_fds, s32 timeout);

View File

@@ -1091,6 +1091,20 @@ bool Memory::InvalidateNCE(Common::ProcessAddress vaddr, size_t size) {
[&] { rasterizer = true; });
if (rasterizer) {
impl->InvalidateGPUMemory(ptr, size);
const auto type = impl->current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Type();
if (type == Common::PageType::RasterizerCachedMemory) {
// Check if device mapped. If not, this bugged and we can unmark.
DAddr addr{};
Common::ScratchBuffer<u32> buffer;
impl->gpu_device_memory->ApplyOpOnPointer(ptr, buffer,
[&](DAddr address) { addr = address; });
if (addr == 0) {
LOG_ERROR(HW_Memory, "Fixing unmapped cached region {:#x}", GetInteger(vaddr));
impl->RasterizerMarkRegionCached(GetInteger(vaddr), size, false);
}
}
}
#ifdef __linux__

View File

@@ -243,10 +243,12 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf
const u64 size_in_bytes{Tegra::Texture::CalculateSize(
true, bytes_per_pixel, framebuffer.stride, framebuffer.height, 1, block_height_log2, 0)};
const u8* const host_ptr{device_memory.GetPointer<u8>(framebuffer_addr)};
const std::span<const u8> input_data(host_ptr, size_in_bytes);
Tegra::Texture::UnswizzleTexture(gl_framebuffer_data, input_data, bytes_per_pixel,
framebuffer.width, framebuffer.height, 1, block_height_log2,
0);
if (host_ptr != nullptr) {
const std::span<const u8> input_data(host_ptr, size_in_bytes);
Tegra::Texture::UnswizzleTexture(gl_framebuffer_data, input_data, bytes_per_pixel,
framebuffer.width, framebuffer.height, 1,
block_height_log2, 0);
}
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(framebuffer.stride));

View File

@@ -230,9 +230,11 @@ void BlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer,
const u64 tiled_size{Tegra::Texture::CalculateSize(true, bytes_per_pixel,
framebuffer.stride, framebuffer.height,
1, block_height_log2, 0)};
Tegra::Texture::UnswizzleTexture(
mapped_span.subspan(image_offset, linear_size), std::span(host_ptr, tiled_size),
bytes_per_pixel, framebuffer.width, framebuffer.height, 1, block_height_log2, 0);
if (host_ptr != nullptr) {
Tegra::Texture::UnswizzleTexture(
mapped_span.subspan(image_offset, linear_size), std::span(host_ptr, tiled_size),
bytes_per_pixel, framebuffer.width, framebuffer.height, 1, block_height_log2, 0);
}
const VkBufferImageCopy copy{
.bufferOffset = image_offset,

View File

@@ -1431,7 +1431,8 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, DA
}
}
};
ForEachSparseImageInRegion(channel_state->gpu_memory.GetID(), gpu_addr, size_bytes, region_check_gpu);
ForEachSparseImageInRegion(channel_state->gpu_memory.GetID(), gpu_addr, size_bytes,
region_check_gpu);
bool can_rescale = info.rescaleable;
bool any_rescaled = false;
@@ -1892,37 +1893,38 @@ void TextureCache<P>::ForEachSparseImageInRegion(size_t as_id, GPUVAddr gpu_addr
return;
}
auto& sparse_page_table = gpu_page_table_storage[*storage_id * 2 + 1];
ForEachGPUPage(gpu_addr, size, [this, &sparse_page_table, &images, gpu_addr, size, func](u64 page) {
const auto it = sparse_page_table.find(page);
if (it == sparse_page_table.end()) {
if constexpr (BOOL_BREAK) {
return false;
} else {
return;
}
}
for (const ImageId image_id : it->second) {
Image& image = slot_images[image_id];
if (True(image.flags & ImageFlagBits::Picked)) {
continue;
}
if (!image.OverlapsGPU(gpu_addr, size)) {
continue;
}
image.flags |= ImageFlagBits::Picked;
images.push_back(image_id);
if constexpr (BOOL_BREAK) {
if (func(image_id, image)) {
return true;
}
} else {
func(image_id, image);
}
}
if constexpr (BOOL_BREAK) {
return false;
}
});
ForEachGPUPage(gpu_addr, size,
[this, &sparse_page_table, &images, gpu_addr, size, func](u64 page) {
const auto it = sparse_page_table.find(page);
if (it == sparse_page_table.end()) {
if constexpr (BOOL_BREAK) {
return false;
} else {
return;
}
}
for (const ImageId image_id : it->second) {
Image& image = slot_images[image_id];
if (True(image.flags & ImageFlagBits::Picked)) {
continue;
}
if (!image.OverlapsGPU(gpu_addr, size)) {
continue;
}
image.flags |= ImageFlagBits::Picked;
images.push_back(image_id);
if constexpr (BOOL_BREAK) {
if (func(image_id, image)) {
return true;
}
} else {
func(image_id, image);
}
}
if constexpr (BOOL_BREAK) {
return false;
}
});
for (const ImageId image_id : images) {
slot_images[image_id].flags &= ~ImageFlagBits::Picked;
}
@@ -1994,8 +1996,9 @@ void TextureCache<P>::RegisterImage(ImageId image_id) {
sparse_maps.push_back(map_id);
});
sparse_views.emplace(image_id, std::move(sparse_maps));
ForEachGPUPage(image.gpu_addr, image.guest_size_bytes,
[this, image_id](u64 page) { (*channel_state->sparse_page_table)[page].push_back(image_id); });
ForEachGPUPage(image.gpu_addr, image.guest_size_bytes, [this, image_id](u64 page) {
(*channel_state->sparse_page_table)[page].push_back(image_id);
});
}
template <class P>

View File

@@ -5,7 +5,6 @@
#include <memory>
#include <vector>
#include <QComboBox>
#include <QPushButton>
#include "audio_core/sink/sink.h"
#include "audio_core/sink/sink_details.h"
@@ -68,99 +67,19 @@ void ConfigureAudio::Setup(const ConfigurationShared::Builder& builder) {
hold.emplace(std::pair{setting->Id(), widget});
auto global_sink_match = [this] {
return static_cast<Settings::AudioEngine>(sink_combo_box->currentIndex()) ==
Settings::values.sink_id.GetValue(true);
};
if (setting->Id() == Settings::values.sink_id.Id()) {
// TODO (lat9nq): Let the system manage sink_id
sink_combo_box = widget->combobox;
InitializeAudioSinkComboBox();
if (Settings::IsConfiguringGlobal()) {
connect(sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
&ConfigureAudio::UpdateAudioDevices);
} else {
restore_sink_button = ConfigurationShared::Widget::CreateRestoreGlobalButton(
Settings::values.sink_id.UsingGlobal(), widget);
widget->layout()->addWidget(restore_sink_button);
connect(restore_sink_button, &QAbstractButton::clicked, [this](bool) {
Settings::values.sink_id.SetGlobal(true);
const int sink_index = static_cast<int>(Settings::values.sink_id.GetValue());
sink_combo_box->setCurrentIndex(sink_index);
ConfigureAudio::UpdateAudioDevices(sink_index);
Settings::values.audio_output_device_id.SetGlobal(true);
Settings::values.audio_input_device_id.SetGlobal(true);
restore_sink_button->setVisible(false);
});
connect(sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged),
[this, global_sink_match](const int slot) {
Settings::values.sink_id.SetGlobal(false);
Settings::values.audio_output_device_id.SetGlobal(false);
Settings::values.audio_input_device_id.SetGlobal(false);
restore_sink_button->setVisible(true);
restore_sink_button->setEnabled(true);
output_device_combo_box->setCurrentIndex(0);
restore_output_device_button->setVisible(true);
restore_output_device_button->setEnabled(global_sink_match());
input_device_combo_box->setCurrentIndex(0);
restore_input_device_button->setVisible(true);
restore_input_device_button->setEnabled(global_sink_match());
ConfigureAudio::UpdateAudioDevices(slot);
});
}
connect(sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
&ConfigureAudio::UpdateAudioDevices);
} else if (setting->Id() == Settings::values.audio_output_device_id.Id()) {
// Keep track of output (and input) device comboboxes to populate them with system
// devices, which are determined at run time
output_device_combo_box = widget->combobox;
if (!Settings::IsConfiguringGlobal()) {
restore_output_device_button =
ConfigurationShared::Widget::CreateRestoreGlobalButton(
Settings::values.audio_output_device_id.UsingGlobal(), widget);
restore_output_device_button->setEnabled(global_sink_match());
restore_output_device_button->setVisible(
!Settings::values.audio_output_device_id.UsingGlobal());
widget->layout()->addWidget(restore_output_device_button);
connect(restore_output_device_button, &QAbstractButton::clicked, [this](bool) {
Settings::values.audio_output_device_id.SetGlobal(true);
SetOutputDevicesFromDeviceID();
restore_output_device_button->setVisible(false);
});
connect(output_device_combo_box, qOverload<int>(&QComboBox::currentIndexChanged),
[this, global_sink_match](int) {
if (updating_devices) {
return;
}
Settings::values.audio_output_device_id.SetGlobal(false);
restore_output_device_button->setVisible(true);
restore_output_device_button->setEnabled(global_sink_match());
});
}
} else if (setting->Id() == Settings::values.audio_input_device_id.Id()) {
input_device_combo_box = widget->combobox;
if (!Settings::IsConfiguringGlobal()) {
restore_input_device_button =
ConfigurationShared::Widget::CreateRestoreGlobalButton(
Settings::values.audio_input_device_id.UsingGlobal(), widget);
widget->layout()->addWidget(restore_input_device_button);
connect(restore_input_device_button, &QAbstractButton::clicked, [this](bool) {
Settings::values.audio_input_device_id.SetGlobal(true);
SetInputDevicesFromDeviceID();
restore_input_device_button->setVisible(false);
});
connect(input_device_combo_box, qOverload<int>(&QComboBox::currentIndexChanged),
[this, global_sink_match](int) {
if (updating_devices) {
return;
}
Settings::values.audio_input_device_id.SetGlobal(false);
restore_input_device_button->setVisible(true);
restore_input_device_button->setEnabled(global_sink_match());
});
}
}
}
@@ -170,13 +89,16 @@ void ConfigureAudio::Setup(const ConfigurationShared::Builder& builder) {
}
void ConfigureAudio::SetConfiguration() {
if (!Settings::IsConfiguringGlobal()) {
return;
}
SetOutputSinkFromSinkID();
// The device list cannot be pre-populated (nor listed) until the output sink is known.
UpdateAudioDevices(sink_combo_box->currentIndex());
SetOutputDevicesFromDeviceID();
SetInputDevicesFromDeviceID();
SetAudioDevicesFromDeviceID();
}
void ConfigureAudio::SetOutputSinkFromSinkID() {
@@ -194,8 +116,8 @@ void ConfigureAudio::SetOutputSinkFromSinkID() {
sink_combo_box->setCurrentIndex(new_sink_index);
}
void ConfigureAudio::SetOutputDevicesFromDeviceID() {
int new_device_index = 0;
void ConfigureAudio::SetAudioDevicesFromDeviceID() {
int new_device_index = -1;
const QString output_device_id =
QString::fromStdString(Settings::values.audio_output_device_id.GetValue());
@@ -207,10 +129,8 @@ void ConfigureAudio::SetOutputDevicesFromDeviceID() {
}
output_device_combo_box->setCurrentIndex(new_device_index);
}
void ConfigureAudio::SetInputDevicesFromDeviceID() {
int new_device_index = 0;
new_device_index = -1;
const QString input_device_id =
QString::fromStdString(Settings::values.audio_input_device_id.GetValue());
for (int index = 0; index < input_device_combo_box->count(); index++) {
@@ -229,12 +149,15 @@ void ConfigureAudio::ApplyConfiguration() {
apply_func(is_powered_on);
}
Settings::values.sink_id.LoadString(
sink_combo_box->itemText(sink_combo_box->currentIndex()).toStdString());
Settings::values.audio_output_device_id.SetValue(
output_device_combo_box->itemText(output_device_combo_box->currentIndex()).toStdString());
Settings::values.audio_input_device_id.SetValue(
input_device_combo_box->itemText(input_device_combo_box->currentIndex()).toStdString());
if (Settings::IsConfiguringGlobal()) {
Settings::values.sink_id.LoadString(
sink_combo_box->itemText(sink_combo_box->currentIndex()).toStdString());
Settings::values.audio_output_device_id.SetValue(
output_device_combo_box->itemText(output_device_combo_box->currentIndex())
.toStdString());
Settings::values.audio_input_device_id.SetValue(
input_device_combo_box->itemText(input_device_combo_box->currentIndex()).toStdString());
}
}
void ConfigureAudio::changeEvent(QEvent* event) {
@@ -246,7 +169,6 @@ void ConfigureAudio::changeEvent(QEvent* event) {
}
void ConfigureAudio::UpdateAudioDevices(int sink_index) {
updating_devices = true;
output_device_combo_box->clear();
output_device_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name));
@@ -261,7 +183,6 @@ void ConfigureAudio::UpdateAudioDevices(int sink_index) {
for (const auto& device : AudioCore::Sink::GetDeviceListForSink(sink_id, true)) {
input_device_combo_box->addItem(QString::fromStdString(device));
}
updating_devices = false;
}
void ConfigureAudio::InitializeAudioSinkComboBox() {

View File

@@ -45,8 +45,7 @@ private:
void UpdateAudioDevices(int sink_index);
void SetOutputSinkFromSinkID();
void SetOutputDevicesFromDeviceID();
void SetInputDevicesFromDeviceID();
void SetAudioDevicesFromDeviceID();
void Setup(const ConfigurationShared::Builder& builder);
@@ -56,11 +55,7 @@ private:
std::vector<std::function<void(bool)>> apply_funcs{};
bool updating_devices = false;
QComboBox* sink_combo_box;
QPushButton* restore_sink_button;
QComboBox* output_device_combo_box;
QPushButton* restore_output_device_button;
QComboBox* input_device_combo_box;
QPushButton* restore_input_device_button;
};