Compare commits

..

8 Commits

Author SHA1 Message Date
c49529c542 Android 270 2024-02-26 15:41:31 +00:00
979176beae Merge yuzu-emu#13159 2024-02-26 15:41:30 +00:00
4c0763fecd Merge yuzu-emu#13135 2024-02-26 15:41:30 +00:00
f2e0148ab7 Merge yuzu-emu#13122 2024-02-26 15:41:30 +00:00
e49cb41451 Merge yuzu-emu#13096 2024-02-26 15:41:30 +00:00
3308458406 Merge yuzu-emu#13018 2024-02-26 15:41:30 +00:00
a6f38d918a Merge yuzu-emu#12749 2024-02-26 15:41:30 +00:00
fc59da23e3 Merge yuzu-emu#12461 2024-02-26 15:41:30 +00:00
38 changed files with 272 additions and 271 deletions

View File

@ -1,9 +1,12 @@
| Pull Request | Commit | Title | Author | Merged? |
|----|----|----|----|----|
| [12461](https://github.com/yuzu-emu/yuzu//pull/12461) | [`a84e8e26f`](https://github.com/yuzu-emu/yuzu//pull/12461/files) | Rework Nvdec and VIC to fix out-of-order videos, and speed up decoding. | [Kelebek1](https://github.com/Kelebek1/) | Yes |
| [13018](https://github.com/yuzu-emu/yuzu//pull/13018) | [`01cbc638a`](https://github.com/yuzu-emu/yuzu//pull/13018/files) | am: rewrite part 2 | [liamwhite](https://github.com/liamwhite/) | Yes |
| [13174](https://github.com/yuzu-emu/yuzu//pull/13174) | [`7d1284826`](https://github.com/yuzu-emu/yuzu//pull/13174/files) | glue/time: Remove global variables | [FearlessTobi](https://github.com/FearlessTobi/) | Yes |
| [13177](https://github.com/yuzu-emu/yuzu//pull/13177) | [`f5cc94f05`](https://github.com/yuzu-emu/yuzu//pull/13177/files) | vfs: misc performance improvements | [liamwhite](https://github.com/liamwhite/) | Yes |
| [12749](https://github.com/yuzu-emu/yuzu//pull/12749) | [`aad4b0d6f`](https://github.com/yuzu-emu/yuzu//pull/12749/files) | general: workarounds for SMMU syncing issues | [liamwhite](https://github.com/liamwhite/) | Yes |
| [13018](https://github.com/yuzu-emu/yuzu//pull/13018) | [`fffec12d3`](https://github.com/yuzu-emu/yuzu//pull/13018/files) | am: rewrite part 2 | [liamwhite](https://github.com/liamwhite/) | Yes |
| [13096](https://github.com/yuzu-emu/yuzu//pull/13096) | [`0a8759057`](https://github.com/yuzu-emu/yuzu//pull/13096/files) | texture_cache: use two-pass collection for costly load resources | [liamwhite](https://github.com/liamwhite/) | Yes |
| [13122](https://github.com/yuzu-emu/yuzu//pull/13122) | [`5dc08c7fe`](https://github.com/yuzu-emu/yuzu//pull/13122/files) | vk_rasterizer: flip scissor y on lower left origin mode | [liamwhite](https://github.com/liamwhite/) | Yes |
| [13135](https://github.com/yuzu-emu/yuzu//pull/13135) | [`fc6a87bba`](https://github.com/yuzu-emu/yuzu//pull/13135/files) | service: hid: Migrate HidServer to new IPC | [german77](https://github.com/german77/) | Yes |
| [13159](https://github.com/yuzu-emu/yuzu//pull/13159) | [`dc50b95a4`](https://github.com/yuzu-emu/yuzu//pull/13159/files) | core: enable error applet, add stubs for web applet | [liamwhite](https://github.com/liamwhite/) | Yes |
End of merge log. You can find the original README.md below the break.

View File

@ -343,7 +343,7 @@ void SetColorConsoleBackendEnabled(bool enabled) {
}
void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
unsigned int line_num, const char* function, fmt::string_view format,
unsigned int line_num, const char* function, const char* format,
const fmt::format_args& args) {
if (!initialization_in_progress_suppress_logging) {
Impl::Instance().PushEntry(log_class, log_level, filename, line_num, function,

View File

@ -24,12 +24,12 @@ constexpr const char* TrimSourcePath(std::string_view source) {
/// Logs a message to the global logger, using fmt
void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
unsigned int line_num, const char* function, fmt::string_view format,
unsigned int line_num, const char* function, const char* format,
const fmt::format_args& args);
template <typename... Args>
void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_num,
const char* function, fmt::format_string<Args...> format, const Args&... args) {
const char* function, const char* format, const Args&... args) {
FmtLogMessageImpl(log_class, log_level, filename, line_num, function, format,
fmt::make_format_args(args...));
}

View File

@ -435,6 +435,8 @@ struct Values {
linkage, false, "disable_shader_loop_safety_checks", Category::RendererDebug};
Setting<bool> enable_renderdoc_hotkey{linkage, false, "renderdoc_hotkey",
Category::RendererDebug};
// TODO: remove this once AMDVLK supports VK_EXT_depth_bias_control
bool renderer_amdvlk_depth_bias_workaround{};
Setting<bool> disable_buffer_reorder{linkage, false, "disable_buffer_reorder",
Category::RendererDebug};

View File

@ -394,6 +394,11 @@ struct System::Impl {
room_member->SendGameInfo(game_info);
}
// Workarounds:
// Activate this in Super Smash Brothers Ultimate, it only affects AMD cards using AMDVLK
Settings::values.renderer_amdvlk_depth_bias_workaround =
params.program_id == 0x1006A800016E000ULL;
status = SystemResultStatus::Success;
return status;
}
@ -452,6 +457,9 @@ struct System::Impl {
room_member->SendGameInfo(game_info);
}
// Workarounds
Settings::values.renderer_amdvlk_depth_bias_workaround = false;
// Reset all glue registrations
arp_manager.ResetAll();

View File

@ -31,8 +31,8 @@ AesXtsStorage::AesXtsStorage(VirtualFile base, const void* key1, const void* key
ASSERT(iv_size == IvSize);
ASSERT(Common::IsAligned(m_block_size, AesBlockSize));
std::memcpy(m_key.data() + 0, key1, KeySize / 2);
std::memcpy(m_key.data() + 0x10, key2, KeySize / 2);
std::memcpy(m_key.data() + 0, key1, KeySize);
std::memcpy(m_key.data() + 0x10, key2, KeySize);
std::memcpy(m_iv.data(), iv, IvSize);
m_cipher.emplace(m_key, Core::Crypto::Mode::XTS);

View File

@ -105,4 +105,12 @@ VirtualDir PartitionFilesystem::GetParentDirectory() const {
return nullptr;
}
void PartitionFilesystem::PrintDebugInfo() const {
LOG_DEBUG(Service_FS, "Magic: {:.4}", pfs_header.magic);
LOG_DEBUG(Service_FS, "Files: {}", pfs_header.num_entries);
for (u32 i = 0; i < pfs_header.num_entries; i++) {
LOG_DEBUG(Service_FS, " > File {}: {} (0x{:X} bytes)", i,
pfs_files[i]->GetName(), pfs_files[i]->GetSize());
}
}
} // namespace FileSys

View File

@ -35,6 +35,7 @@ public:
std::vector<VirtualDir> GetSubdirectories() const override;
std::string GetName() const override;
VirtualDir GetParentDirectory() const override;
void PrintDebugInfo() const;
private:
struct Header {

View File

@ -9,8 +9,9 @@
namespace FileSys {
OffsetVfsFile::OffsetVfsFile(VirtualFile file_, std::size_t size_, std::size_t offset_,
std::string name_)
: file(file_), offset(offset_), size(size_), name(std::move(name_)) {}
std::string name_, VirtualDir parent_)
: file(file_), offset(offset_), size(size_), name(std::move(name_)),
parent(parent_ == nullptr ? file->GetContainingDirectory() : std::move(parent_)) {}
OffsetVfsFile::~OffsetVfsFile() = default;
@ -36,7 +37,7 @@ bool OffsetVfsFile::Resize(std::size_t new_size) {
}
VirtualDir OffsetVfsFile::GetContainingDirectory() const {
return nullptr;
return parent;
}
bool OffsetVfsFile::IsWritable() const {

View File

@ -16,7 +16,7 @@ namespace FileSys {
class OffsetVfsFile : public VfsFile {
public:
OffsetVfsFile(VirtualFile file, std::size_t size, std::size_t offset = 0,
std::string new_name = "");
std::string new_name = "", VirtualDir new_parent = nullptr);
~OffsetVfsFile() override;
std::string GetName() const override;
@ -44,6 +44,7 @@ private:
std::size_t offset;
std::size_t size;
std::string name;
VirtualDir parent;
};
} // namespace FileSys

View File

@ -76,7 +76,6 @@ VfsEntryType RealVfsFilesystem::GetEntryType(std::string_view path_) const {
}
VirtualFile RealVfsFilesystem::OpenFileFromEntry(std::string_view path_, std::optional<u64> size,
std::optional<std::string> parent_path,
OpenMode perms) {
const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
std::scoped_lock lk{list_lock};
@ -95,14 +94,14 @@ VirtualFile RealVfsFilesystem::OpenFileFromEntry(std::string_view path_, std::op
this->InsertReferenceIntoListLocked(*reference);
auto file = std::shared_ptr<RealVfsFile>(
new RealVfsFile(*this, std::move(reference), path, perms, size, std::move(parent_path)));
new RealVfsFile(*this, std::move(reference), path, perms, size));
cache[path] = file;
return file;
}
VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, OpenMode perms) {
return OpenFileFromEntry(path_, {}, {}, perms);
return OpenFileFromEntry(path_, {}, perms);
}
VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, OpenMode perms) {
@ -269,11 +268,10 @@ void RealVfsFilesystem::RemoveReferenceFromListLocked(FileReference& reference)
}
RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::unique_ptr<FileReference> reference_,
const std::string& path_, OpenMode perms_, std::optional<u64> size_,
std::optional<std::string> parent_path_)
const std::string& path_, OpenMode perms_, std::optional<u64> size_)
: base(base_), reference(std::move(reference_)), path(path_),
parent_path(parent_path_ ? std::move(*parent_path_) : FS::GetParentPath(path_)),
path_components(FS::SplitPathComponentsCopy(path_)), size(size_), perms(perms_) {}
parent_path(FS::GetParentPath(path_)), path_components(FS::SplitPathComponentsCopy(path_)),
size(size_), perms(perms_) {}
RealVfsFile::~RealVfsFile() {
base.DropReference(std::move(reference));
@ -350,7 +348,7 @@ std::vector<VirtualFile> RealVfsDirectory::IterateEntries<RealVfsFile, VfsFile>(
&out](const std::filesystem::directory_entry& entry) {
const auto full_path_string = FS::PathToUTF8String(entry.path());
out.emplace_back(base.OpenFileFromEntry(full_path_string, entry.file_size(), path, perms));
out.emplace_back(base.OpenFileFromEntry(full_path_string, entry.file_size(), perms));
return true;
};

View File

@ -62,7 +62,6 @@ private:
private:
friend class RealVfsDirectory;
VirtualFile OpenFileFromEntry(std::string_view path, std::optional<u64> size,
std::optional<std::string> parent_path,
OpenMode perms = OpenMode::Read);
private:
@ -92,7 +91,7 @@ public:
private:
RealVfsFile(RealVfsFilesystem& base, std::unique_ptr<FileReference> reference,
const std::string& path, OpenMode perms = OpenMode::Read,
std::optional<u64> size = {}, std::optional<std::string> parent_path = {});
std::optional<u64> size = {});
RealVfsFilesystem& base;
std::unique_ptr<FileReference> reference;

View File

@ -11,6 +11,7 @@
#include "core/file_sys/vfs/vfs.h"
#include "core/hle/kernel/svc.h"
#include "core/hle/service/glue/time/manager.h"
#include "core/hle/service/glue/time/time_zone_binary.h"
#include "core/hle/service/psc/time/service_manager.h"
#include "core/hle/service/psc/time/static.h"
#include "core/hle/service/psc/time/system_clock.h"
@ -19,8 +20,8 @@
#include "core/hle/service/sm/sm.h"
namespace Service::Glue::Time {
static s64 CalendarTimeToEpoch(Service::PSC::Time::CalendarTime calendar) {
namespace {
s64 CalendarTimeToEpoch(Service::PSC::Time::CalendarTime calendar) {
constexpr auto is_leap = [](s32 year) -> bool {
return (((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0));
};
@ -49,8 +50,7 @@ static s64 CalendarTimeToEpoch(Service::PSC::Time::CalendarTime calendar) {
return epoch_s - 62135683200ll;
}
static s64 GetEpochTimeFromInitialYear(
std::shared_ptr<Service::Set::ISystemSettingsServer>& set_sys) {
s64 GetEpochTimeFromInitialYear(std::shared_ptr<Service::Set::ISystemSettingsServer>& set_sys) {
s32 year{2000};
set_sys->GetSettingsItemValueImpl(year, "time", "standard_user_clock_initial_year");
@ -65,32 +65,31 @@ static s64 GetEpochTimeFromInitialYear(
return CalendarTimeToEpoch(calendar);
}
static Service::PSC::Time::LocationName GetTimeZoneString(
TimeZoneBinary& time_zone_binary, Service::PSC::Time::LocationName& in_name) {
Service::PSC::Time::LocationName GetTimeZoneString(Service::PSC::Time::LocationName& in_name) {
auto configured_zone = Settings::GetTimeZoneString(Settings::values.time_zone_index.GetValue());
Service::PSC::Time::LocationName configured_name{};
std::memcpy(configured_name.data(), configured_zone.data(),
std::min(configured_name.size(), configured_zone.size()));
if (!time_zone_binary.IsValid(configured_name)) {
if (!IsTimeZoneBinaryValid(configured_name)) {
configured_zone = Common::TimeZone::FindSystemTimeZone();
configured_name = {};
std::memcpy(configured_name.data(), configured_zone.data(),
std::min(configured_name.size(), configured_zone.size()));
}
ASSERT_MSG(time_zone_binary.IsValid(configured_name), "Invalid time zone {}!",
ASSERT_MSG(IsTimeZoneBinaryValid(configured_name), "Invalid time zone {}!",
configured_name.data());
return configured_name;
}
} // namespace
TimeManager::TimeManager(Core::System& system)
: m_steady_clock_resource{system}, m_time_zone_binary{system}, m_worker{
system,
m_steady_clock_resource,
m_file_timestamp_worker} {
: m_steady_clock_resource{system}, m_worker{system, m_steady_clock_resource,
m_file_timestamp_worker} {
m_time_m =
system.ServiceManager().GetService<Service::PSC::Time::ServiceManager>("time:m", true);
@ -100,7 +99,7 @@ TimeManager::TimeManager(Core::System& system)
m_set_sys =
system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
res = m_time_zone_binary.Mount();
res = MountTimeZoneBinary(system);
ASSERT(res == ResultSuccess);
m_worker.Initialize(m_time_sm, m_set_sys);
@ -188,6 +187,10 @@ TimeManager::TimeManager(Core::System& system)
}
}
TimeManager::~TimeManager() {
ResetTimeZoneBinary();
}
Result TimeManager::SetupStandardSteadyClockCore() {
Common::UUID external_clock_source_id{};
auto res = m_set_sys->GetExternalSteadyClockSourceId(&external_clock_source_id);
@ -233,7 +236,7 @@ Result TimeManager::SetupTimeZoneServiceCore() {
auto res = m_set_sys->GetDeviceTimeZoneLocationName(&name);
ASSERT(res == ResultSuccess);
auto configured_zone = GetTimeZoneString(m_time_zone_binary, name);
auto configured_zone = GetTimeZoneString(name);
if (configured_zone != name) {
m_set_sys->SetDeviceTimeZoneLocationName(configured_zone);
@ -251,13 +254,13 @@ Result TimeManager::SetupTimeZoneServiceCore() {
res = m_set_sys->GetDeviceTimeZoneLocationUpdatedTime(&time_point);
ASSERT(res == ResultSuccess);
auto location_count = m_time_zone_binary.GetTimeZoneCount();
auto location_count = GetTimeZoneCount();
Service::PSC::Time::RuleVersion rule_version{};
m_time_zone_binary.GetTimeZoneVersion(rule_version);
GetTimeZoneVersion(rule_version);
std::span<const u8> rule_buffer{};
size_t rule_size{};
res = m_time_zone_binary.GetTimeZoneRule(rule_buffer, rule_size, name);
res = GetTimeZoneRule(rule_buffer, rule_size, name);
ASSERT(res == ResultSuccess);
res = m_time_m->SetupTimeZoneServiceCore(name, rule_version, location_count, time_point,

View File

@ -10,7 +10,6 @@
#include "core/file_sys/vfs/vfs_types.h"
#include "core/hle/service/glue/time/file_timestamp_worker.h"
#include "core/hle/service/glue/time/standard_steady_clock_resource.h"
#include "core/hle/service/glue/time/time_zone_binary.h"
#include "core/hle/service/glue/time/worker.h"
#include "core/hle/service/service.h"
@ -27,7 +26,7 @@ namespace Service::Glue::Time {
class TimeManager {
public:
explicit TimeManager(Core::System& system);
~TimeManager() = default;
~TimeManager();
std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys;
@ -35,7 +34,6 @@ public:
std::shared_ptr<Service::PSC::Time::StaticService> m_time_sm{};
StandardSteadyClockResource m_steady_clock_resource;
FileTimestampWorker m_file_timestamp_worker;
TimeZoneBinary m_time_zone_binary;
TimeWorker m_worker;
private:

View File

@ -26,9 +26,8 @@ StaticService::StaticService(Core::System& system_,
std::shared_ptr<TimeManager> time, const char* name)
: ServiceFramework{system_, name}, m_system{system_}, m_time_m{time->m_time_m},
m_setup_info{setup_info}, m_time_sm{time->m_time_sm},
m_file_timestamp_worker{time->m_file_timestamp_worker},
m_standard_steady_clock_resource{time->m_steady_clock_resource},
m_time_zone_binary{time->m_time_zone_binary} {
m_file_timestamp_worker{time->m_file_timestamp_worker}, m_standard_steady_clock_resource{
time->m_steady_clock_resource} {
// clang-format off
static const FunctionInfo functions[] = {
{0, D<&StaticService::GetStandardUserSystemClock>, "GetStandardUserSystemClock"},
@ -107,7 +106,7 @@ Result StaticService::GetTimeZoneService(OutInterface<TimeZoneService> out_servi
*out_service = std::make_shared<TimeZoneService>(
m_system, m_file_timestamp_worker, m_setup_info.can_write_timezone_device_location,
m_time_zone_binary, m_time_zone);
m_time_zone);
R_SUCCEED();
}

View File

@ -80,6 +80,5 @@ private:
std::shared_ptr<Service::PSC::Time::TimeZoneService> m_time_zone;
FileTimestampWorker& m_file_timestamp_worker;
StandardSteadyClockResource& m_standard_steady_clock_resource;
TimeZoneBinary& m_time_zone_binary;
};
} // namespace Service::Glue::Time

View File

@ -15,16 +15,19 @@
#include "core/hle/service/sm/sm.h"
namespace Service::Glue::Time {
namespace {
static std::mutex g_list_mutex;
static Common::IntrusiveListBaseTraits<Service::PSC::Time::OperationEvent>::ListType g_list_nodes{};
} // namespace
TimeZoneService::TimeZoneService(
Core::System& system_, FileTimestampWorker& file_timestamp_worker,
bool can_write_timezone_device_location, TimeZoneBinary& time_zone_binary,
bool can_write_timezone_device_location,
std::shared_ptr<Service::PSC::Time::TimeZoneService> time_zone_service)
: ServiceFramework{system_, "ITimeZoneService"}, m_system{system},
m_can_write_timezone_device_location{can_write_timezone_device_location},
m_file_timestamp_worker{file_timestamp_worker}, m_wrapped_service{std::move(
time_zone_service)},
m_operation_event{m_system}, m_time_zone_binary{time_zone_binary} {
m_file_timestamp_worker{file_timestamp_worker},
m_wrapped_service{std::move(time_zone_service)}, m_operation_event{m_system} {
// clang-format off
static const FunctionInfo functions[] = {
{0, D<&TimeZoneService::GetDeviceLocationName>, "GetDeviceLocationName"},
@ -45,6 +48,7 @@ TimeZoneService::TimeZoneService(
// clang-format on
RegisterHandlers(functions);
g_list_nodes.clear();
m_set_sys =
m_system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
}
@ -65,13 +69,13 @@ Result TimeZoneService::SetDeviceLocationName(
LOG_DEBUG(Service_Time, "called. location_name={}", location_name);
R_UNLESS(m_can_write_timezone_device_location, Service::PSC::Time::ResultPermissionDenied);
R_UNLESS(m_time_zone_binary.IsValid(location_name), Service::PSC::Time::ResultTimeZoneNotFound);
R_UNLESS(IsTimeZoneBinaryValid(location_name), Service::PSC::Time::ResultTimeZoneNotFound);
std::scoped_lock l{m_mutex};
std::span<const u8> binary{};
size_t binary_size{};
R_TRY(m_time_zone_binary.GetTimeZoneRule(binary, binary_size, location_name))
R_TRY(GetTimeZoneRule(binary, binary_size, location_name))
R_TRY(m_wrapped_service->SetDeviceLocationNameWithTimeZoneRule(location_name, binary));
@ -84,8 +88,8 @@ Result TimeZoneService::SetDeviceLocationName(
m_set_sys->SetDeviceTimeZoneLocationName(name);
m_set_sys->SetDeviceTimeZoneLocationUpdatedTime(time_point);
std::scoped_lock m{m_list_mutex};
for (auto& operation_event : m_list_nodes) {
std::scoped_lock m{g_list_mutex};
for (auto& operation_event : g_list_nodes) {
operation_event.m_event->Signal();
}
R_SUCCEED();
@ -108,8 +112,7 @@ Result TimeZoneService::LoadLocationNameList(
};
std::scoped_lock l{m_mutex};
R_RETURN(
m_time_zone_binary.GetTimeZoneLocationList(*out_count, out_names, out_names.size(), index));
R_RETURN(GetTimeZoneLocationList(*out_count, out_names, out_names.size(), index));
}
Result TimeZoneService::LoadTimeZoneRule(OutRule out_rule,
@ -119,7 +122,7 @@ Result TimeZoneService::LoadTimeZoneRule(OutRule out_rule,
std::scoped_lock l{m_mutex};
std::span<const u8> binary{};
size_t binary_size{};
R_TRY(m_time_zone_binary.GetTimeZoneRule(binary, binary_size, name))
R_TRY(GetTimeZoneRule(binary, binary_size, name))
R_RETURN(m_wrapped_service->ParseTimeZoneBinary(out_rule, binary));
}
@ -171,7 +174,7 @@ Result TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle(
m_operation_event.m_ctx.CreateEvent("Psc:TimeZoneService:OperationEvent");
operation_event_initialized = true;
std::scoped_lock l{m_mutex};
m_list_nodes.push_back(m_operation_event);
g_list_nodes.push_back(m_operation_event);
}
*out_event = &m_operation_event.m_event->GetReadableEvent();

View File

@ -32,7 +32,6 @@ class TimeZoneService;
namespace Service::Glue::Time {
class FileTimestampWorker;
class TimeZoneBinary;
class TimeZoneService final : public ServiceFramework<TimeZoneService> {
using InRule = InLargeData<Tz::Rule, BufferAttr_HipcMapAlias>;
@ -41,7 +40,7 @@ class TimeZoneService final : public ServiceFramework<TimeZoneService> {
public:
explicit TimeZoneService(
Core::System& system, FileTimestampWorker& file_timestamp_worker,
bool can_write_timezone_device_location, TimeZoneBinary& time_zone_binary,
bool can_write_timezone_device_location,
std::shared_ptr<Service::PSC::Time::TimeZoneService> time_zone_service);
~TimeZoneService() override;
@ -86,10 +85,6 @@ private:
std::mutex m_mutex;
bool operation_event_initialized{};
Service::PSC::Time::OperationEvent m_operation_event;
TimeZoneBinary& m_time_zone_binary;
std::mutex m_list_mutex;
Common::IntrusiveListBaseTraits<Service::PSC::Time::OperationEvent>::ListType m_list_nodes{};
};
} // namespace Service::Glue::Time

View File

@ -12,58 +12,18 @@
#include "core/hle/service/glue/time/time_zone_binary.h"
namespace Service::Glue::Time {
namespace {
constexpr u64 TimeZoneBinaryId = 0x10000000000080E;
void TimeZoneBinary::Reset() {
time_zone_binary_romfs = {};
time_zone_binary_mount_result = ResultUnknown;
time_zone_scratch_space.clear();
time_zone_scratch_space.resize(0x2800, 0);
}
static FileSys::VirtualDir g_time_zone_binary_romfs{};
static Result g_time_zone_binary_mount_result{ResultUnknown};
static std::vector<u8> g_time_zone_scratch_space(0x2800, 0);
Result TimeZoneBinary::Mount() {
Reset();
Result TimeZoneReadBinary(size_t& out_read_size, std::span<u8> out_buffer, size_t out_buffer_size,
std::string_view path) {
R_UNLESS(g_time_zone_binary_mount_result == ResultSuccess, g_time_zone_binary_mount_result);
auto& fsc{system.GetFileSystemController()};
std::unique_ptr<FileSys::NCA> nca{};
auto* bis_system = fsc.GetSystemNANDContents();
R_UNLESS(bis_system, ResultUnknown);
nca = bis_system->GetEntry(TimeZoneBinaryId, FileSys::ContentRecordType::Data);
if (nca) {
time_zone_binary_romfs = FileSys::ExtractRomFS(nca->GetRomFS());
}
if (time_zone_binary_romfs) {
// Validate that the romfs is readable, using invalid firmware keys can cause this to get
// set but the files to be garbage. In that case, we want to hit the next path and
// synthesise them instead.
time_zone_binary_mount_result = ResultSuccess;
Service::PSC::Time::LocationName name{"Etc/GMT"};
if (!IsValid(name)) {
Reset();
}
}
if (!time_zone_binary_romfs) {
time_zone_binary_romfs = FileSys::ExtractRomFS(
FileSys::SystemArchive::SynthesizeSystemArchive(TimeZoneBinaryId));
}
R_UNLESS(time_zone_binary_romfs, ResultUnknown);
time_zone_binary_mount_result = ResultSuccess;
R_SUCCEED();
}
Result TimeZoneBinary::Read(size_t& out_read_size, std::span<u8> out_buffer, size_t out_buffer_size,
std::string_view path) {
R_UNLESS(time_zone_binary_mount_result == ResultSuccess, time_zone_binary_mount_result);
auto vfs_file{time_zone_binary_romfs->GetFileRelative(path)};
auto vfs_file{g_time_zone_binary_romfs->GetFileRelative(path)};
R_UNLESS(vfs_file, ResultUnknown);
auto file_size{vfs_file->GetSize()};
@ -76,37 +36,82 @@ Result TimeZoneBinary::Read(size_t& out_read_size, std::span<u8> out_buffer, siz
R_SUCCEED();
}
} // namespace
void TimeZoneBinary::GetListPath(std::string& out_path) {
if (time_zone_binary_mount_result != ResultSuccess) {
void ResetTimeZoneBinary() {
g_time_zone_binary_romfs = {};
g_time_zone_binary_mount_result = ResultUnknown;
g_time_zone_scratch_space.clear();
g_time_zone_scratch_space.resize(0x2800, 0);
}
Result MountTimeZoneBinary(Core::System& system) {
ResetTimeZoneBinary();
auto& fsc{system.GetFileSystemController()};
std::unique_ptr<FileSys::NCA> nca{};
auto* bis_system = fsc.GetSystemNANDContents();
R_UNLESS(bis_system, ResultUnknown);
nca = bis_system->GetEntry(TimeZoneBinaryId, FileSys::ContentRecordType::Data);
if (nca) {
g_time_zone_binary_romfs = FileSys::ExtractRomFS(nca->GetRomFS());
}
if (g_time_zone_binary_romfs) {
// Validate that the romfs is readable, using invalid firmware keys can cause this to get
// set but the files to be garbage. In that case, we want to hit the next path and
// synthesise them instead.
g_time_zone_binary_mount_result = ResultSuccess;
Service::PSC::Time::LocationName name{"Etc/GMT"};
if (!IsTimeZoneBinaryValid(name)) {
ResetTimeZoneBinary();
}
}
if (!g_time_zone_binary_romfs) {
g_time_zone_binary_romfs = FileSys::ExtractRomFS(
FileSys::SystemArchive::SynthesizeSystemArchive(TimeZoneBinaryId));
}
R_UNLESS(g_time_zone_binary_romfs, ResultUnknown);
g_time_zone_binary_mount_result = ResultSuccess;
R_SUCCEED();
}
void GetTimeZoneBinaryListPath(std::string& out_path) {
if (g_time_zone_binary_mount_result != ResultSuccess) {
return;
}
// out_path = fmt::format("{}:/binaryList.txt", "TimeZoneBinary");
out_path = "/binaryList.txt";
}
void TimeZoneBinary::GetVersionPath(std::string& out_path) {
if (time_zone_binary_mount_result != ResultSuccess) {
void GetTimeZoneBinaryVersionPath(std::string& out_path) {
if (g_time_zone_binary_mount_result != ResultSuccess) {
return;
}
// out_path = fmt::format("{}:/version.txt", "TimeZoneBinary");
out_path = "/version.txt";
}
void TimeZoneBinary::GetTimeZonePath(std::string& out_path,
const Service::PSC::Time::LocationName& name) {
if (time_zone_binary_mount_result != ResultSuccess) {
void GetTimeZoneZonePath(std::string& out_path, const Service::PSC::Time::LocationName& name) {
if (g_time_zone_binary_mount_result != ResultSuccess) {
return;
}
// out_path = fmt::format("{}:/zoneinfo/{}", "TimeZoneBinary", name);
out_path = fmt::format("/zoneinfo/{}", name.data());
}
bool TimeZoneBinary::IsValid(const Service::PSC::Time::LocationName& name) {
bool IsTimeZoneBinaryValid(const Service::PSC::Time::LocationName& name) {
std::string path{};
GetTimeZonePath(path, name);
GetTimeZoneZonePath(path, name);
auto vfs_file{time_zone_binary_romfs->GetFileRelative(path)};
auto vfs_file{g_time_zone_binary_romfs->GetFileRelative(path)};
if (!vfs_file) {
LOG_INFO(Service_Time, "Could not find timezone file {}", path);
return false;
@ -114,19 +119,19 @@ bool TimeZoneBinary::IsValid(const Service::PSC::Time::LocationName& name) {
return vfs_file->GetSize() != 0;
}
u32 TimeZoneBinary::GetTimeZoneCount() {
u32 GetTimeZoneCount() {
std::string path{};
GetListPath(path);
GetTimeZoneBinaryListPath(path);
size_t bytes_read{};
if (Read(bytes_read, time_zone_scratch_space, 0x2800, path) != ResultSuccess) {
if (TimeZoneReadBinary(bytes_read, g_time_zone_scratch_space, 0x2800, path) != ResultSuccess) {
return 0;
}
if (bytes_read == 0) {
return 0;
}
auto chars = std::span(reinterpret_cast<char*>(time_zone_scratch_space.data()), bytes_read);
auto chars = std::span(reinterpret_cast<char*>(g_time_zone_scratch_space.data()), bytes_read);
u32 count{};
for (auto chr : chars) {
if (chr == '\n') {
@ -136,47 +141,50 @@ u32 TimeZoneBinary::GetTimeZoneCount() {
return count;
}
Result TimeZoneBinary::GetTimeZoneVersion(Service::PSC::Time::RuleVersion& out_rule_version) {
Result GetTimeZoneVersion(Service::PSC::Time::RuleVersion& out_rule_version) {
std::string path{};
GetVersionPath(path);
GetTimeZoneBinaryVersionPath(path);
auto rule_version_buffer{std::span(reinterpret_cast<u8*>(&out_rule_version),
sizeof(Service::PSC::Time::RuleVersion))};
size_t bytes_read{};
R_TRY(Read(bytes_read, rule_version_buffer, rule_version_buffer.size_bytes(), path));
R_TRY(TimeZoneReadBinary(bytes_read, rule_version_buffer, rule_version_buffer.size_bytes(),
path));
rule_version_buffer[bytes_read] = 0;
R_SUCCEED();
}
Result TimeZoneBinary::GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size,
const Service::PSC::Time::LocationName& name) {
Result GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size,
const Service::PSC::Time::LocationName& name) {
std::string path{};
GetTimeZonePath(path, name);
GetTimeZoneZonePath(path, name);
size_t bytes_read{};
R_TRY(Read(bytes_read, time_zone_scratch_space, time_zone_scratch_space.size(), path));
R_TRY(TimeZoneReadBinary(bytes_read, g_time_zone_scratch_space,
g_time_zone_scratch_space.size(), path));
out_rule = std::span(time_zone_scratch_space.data(), bytes_read);
out_rule = std::span(g_time_zone_scratch_space.data(), bytes_read);
out_rule_size = bytes_read;
R_SUCCEED();
}
Result TimeZoneBinary::GetTimeZoneLocationList(
u32& out_count, std::span<Service::PSC::Time::LocationName> out_names, size_t max_names,
u32 index) {
Result GetTimeZoneLocationList(u32& out_count,
std::span<Service::PSC::Time::LocationName> out_names,
size_t max_names, u32 index) {
std::string path{};
GetListPath(path);
GetTimeZoneBinaryListPath(path);
size_t bytes_read{};
R_TRY(Read(bytes_read, time_zone_scratch_space, time_zone_scratch_space.size(), path));
R_TRY(TimeZoneReadBinary(bytes_read, g_time_zone_scratch_space,
g_time_zone_scratch_space.size(), path));
out_count = 0;
R_SUCCEED_IF(bytes_read == 0);
Service::PSC::Time::LocationName current_name{};
size_t current_name_len{};
std::span<const u8> chars{time_zone_scratch_space};
std::span<const u8> chars{g_time_zone_scratch_space};
u32 name_count{};
for (auto chr : chars) {

View File

@ -6,7 +6,6 @@
#include <span>
#include <string>
#include <string_view>
#include <vector>
#include "core/hle/service/psc/time/common.h"
@ -16,34 +15,18 @@ class System;
namespace Service::Glue::Time {
class TimeZoneBinary {
public:
explicit TimeZoneBinary(Core::System& system_)
: time_zone_scratch_space(0x2800, 0), system{system_} {}
Result Mount();
bool IsValid(const Service::PSC::Time::LocationName& name);
u32 GetTimeZoneCount();
Result GetTimeZoneVersion(Service::PSC::Time::RuleVersion& out_rule_version);
Result GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size,
const Service::PSC::Time::LocationName& name);
Result GetTimeZoneLocationList(u32& out_count,
std::span<Service::PSC::Time::LocationName> out_names,
size_t max_names, u32 index);
private:
void Reset();
Result Read(size_t& out_read_size, std::span<u8> out_buffer, size_t out_buffer_size,
std::string_view path);
void GetListPath(std::string& out_path);
void GetVersionPath(std::string& out_path);
void GetTimeZonePath(std::string& out_path, const Service::PSC::Time::LocationName& name);
FileSys::VirtualDir time_zone_binary_romfs{};
Result time_zone_binary_mount_result{ResultUnknown};
std::vector<u8> time_zone_scratch_space;
Core::System& system;
};
void ResetTimeZoneBinary();
Result MountTimeZoneBinary(Core::System& system);
void GetTimeZoneBinaryListPath(std::string& out_path);
void GetTimeZoneBinaryVersionPath(std::string& out_path);
void GetTimeZoneZonePath(std::string& out_path, const Service::PSC::Time::LocationName& name);
bool IsTimeZoneBinaryValid(const Service::PSC::Time::LocationName& name);
u32 GetTimeZoneCount();
Result GetTimeZoneVersion(Service::PSC::Time::RuleVersion& out_rule_version);
Result GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size,
const Service::PSC::Time::LocationName& name);
Result GetTimeZoneLocationList(u32& out_count,
std::span<Service::PSC::Time::LocationName> out_names,
size_t max_names, u32 index);
} // namespace Service::Glue::Time

View File

@ -16,6 +16,23 @@
#include "core/hle/service/sm/sm.h"
namespace Service::Glue::Time {
namespace {
bool g_ig_report_network_clock_context_set{};
Service::PSC::Time::SystemClockContext g_report_network_clock_context{};
bool g_ig_report_ephemeral_clock_context_set{};
Service::PSC::Time::SystemClockContext g_report_ephemeral_clock_context{};
template <typename T>
T GetSettingsItemValue(std::shared_ptr<Service::Set::ISystemSettingsServer>& set_sys,
const char* category, const char* name) {
T v{};
auto res = set_sys->GetSettingsItemValueImpl(v, category, name);
ASSERT(res == ResultSuccess);
return v;
}
} // namespace
TimeWorker::TimeWorker(Core::System& system, StandardSteadyClockResource& steady_clock_resource,
FileTimestampWorker& file_timestamp_worker)
@ -26,6 +43,11 @@ TimeWorker::TimeWorker(Core::System& system, StandardSteadyClockResource& steady
"Glue:TimeWorker:SteadyClockTimerEvent")},
m_timer_file_system{m_ctx.CreateEvent("Glue:TimeWorker:FileTimeTimerEvent")},
m_alarm_worker{m_system, m_steady_clock_resource}, m_pm_state_change_handler{m_alarm_worker} {
g_ig_report_network_clock_context_set = false;
g_report_network_clock_context = {};
g_ig_report_ephemeral_clock_context_set = false;
g_report_ephemeral_clock_context = {};
m_timer_steady_clock_timing_event = Core::Timing::CreateEvent(
"Time::SteadyClockEvent",
[this](s64 time,
@ -60,14 +82,6 @@ TimeWorker::~TimeWorker() {
m_ctx.CloseEvent(m_timer_file_system);
}
template <typename T>
T TimeWorker::GetSettingsItemValue(const std::string& category, const std::string& name) {
T v{};
auto res = m_set_sys->GetSettingsItemValueImpl(v, category, name);
ASSERT(res == ResultSuccess);
return v;
}
void TimeWorker::Initialize(std::shared_ptr<Service::PSC::Time::StaticService> time_sm,
std::shared_ptr<Service::Set::ISystemSettingsServer> set_sys) {
m_set_sys = std::move(set_sys);
@ -77,8 +91,8 @@ void TimeWorker::Initialize(std::shared_ptr<Service::PSC::Time::StaticService> t
m_alarm_worker.Initialize(m_time_m);
auto steady_clock_interval_m =
GetSettingsItemValue<s32>("time", "standard_steady_clock_rtc_update_interval_minutes");
auto steady_clock_interval_m = GetSettingsItemValue<s32>(
m_set_sys, "time", "standard_steady_clock_rtc_update_interval_minutes");
auto one_minute_ns{
std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::minutes(1)).count()};
@ -88,7 +102,8 @@ void TimeWorker::Initialize(std::shared_ptr<Service::PSC::Time::StaticService> t
std::chrono::nanoseconds(steady_clock_interval_ns),
m_timer_steady_clock_timing_event);
auto fs_notify_time_s = GetSettingsItemValue<s32>("time", "notify_time_to_fs_interval_seconds");
auto fs_notify_time_s =
GetSettingsItemValue<s32>(m_set_sys, "time", "notify_time_to_fs_interval_seconds");
auto one_second_ns{
std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::seconds(1)).count()};
s64 fs_notify_time_ns{fs_notify_time_s * one_second_ns};
@ -203,14 +218,14 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) {
}
[[maybe_unused]] auto offset_before{
m_ig_report_network_clock_context_set ? m_report_network_clock_context.offset : 0};
g_ig_report_network_clock_context_set ? g_report_network_clock_context.offset : 0};
// TODO system report "standard_netclock_operation"
// "clock_time" = time
// "context_offset_before" = offset_before
// "context_offset_after" = context.offset
m_report_network_clock_context = context;
if (!m_ig_report_network_clock_context_set) {
m_ig_report_network_clock_context_set = true;
g_report_network_clock_context = context;
if (!g_ig_report_network_clock_context_set) {
g_ig_report_network_clock_context_set = true;
}
m_file_timestamp_worker.SetFilesystemPosixTime();
@ -232,16 +247,16 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) {
break;
}
[[maybe_unused]] auto offset_before{m_ig_report_ephemeral_clock_context_set
? m_report_ephemeral_clock_context.offset
[[maybe_unused]] auto offset_before{g_ig_report_ephemeral_clock_context_set
? g_report_ephemeral_clock_context.offset
: 0};
// TODO system report "ephemeral_netclock_operation"
// "clock_time" = time
// "context_offset_before" = offset_before
// "context_offset_after" = context.offset
m_report_ephemeral_clock_context = context;
if (!m_ig_report_ephemeral_clock_context_set) {
m_ig_report_ephemeral_clock_context_set = true;
g_report_ephemeral_clock_context = context;
if (!g_ig_report_ephemeral_clock_context_set) {
g_ig_report_ephemeral_clock_context_set = true;
}
break;
}

View File

@ -34,9 +34,6 @@ public:
void StartThread();
private:
template <typename T>
T GetSettingsItemValue(const std::string& category, const std::string& name);
void ThreadFunc(std::stop_token stop_token);
Core::System& m_system;
@ -62,11 +59,6 @@ private:
std::shared_ptr<Core::Timing::EventType> m_timer_file_system_timing_event;
AlarmWorker m_alarm_worker;
PmStateChangeHandler m_pm_state_change_handler;
bool m_ig_report_network_clock_context_set{};
Service::PSC::Time::SystemClockContext m_report_network_clock_context{};
bool m_ig_report_ephemeral_clock_context_set{};
Service::PSC::Time::SystemClockContext m_report_ephemeral_clock_context{};
};
} // namespace Service::Glue::Time

View File

@ -5,7 +5,6 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/service/nvdrv/core/container.h"
#include "core/hle/service/nvdrv/core/nvmap.h"
#include "core/hle/service/nvdrv/core/syncpoint_manager.h"
@ -76,7 +75,7 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu
case 0xd:
return WrapFixed(this, &nvhost_gpu::SetChannelPriority, input, output);
case 0x1a:
return WrapFixed(this, &nvhost_gpu::AllocGPFIFOEx2, input, output, fd);
return WrapFixed(this, &nvhost_gpu::AllocGPFIFOEx2, input, output);
case 0x1b:
return WrapFixedVariable(this, &nvhost_gpu::SubmitGPFIFOBase1, input, output, true);
case 0x1d:
@ -121,13 +120,8 @@ NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> inpu
return NvResult::NotImplemented;
}
void nvhost_gpu::OnOpen(NvCore::SessionId session_id, DeviceFD fd) {
sessions[fd] = session_id;
}
void nvhost_gpu::OnClose(DeviceFD fd) {
sessions.erase(fd);
}
void nvhost_gpu::OnOpen(NvCore::SessionId session_id, DeviceFD fd) {}
void nvhost_gpu::OnClose(DeviceFD fd) {}
NvResult nvhost_gpu::SetNVMAPfd(IoctlSetNvmapFD& params) {
LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd);
@ -167,7 +161,7 @@ NvResult nvhost_gpu::SetChannelPriority(IoctlChannelSetPriority& params) {
return NvResult::Success;
}
NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params, DeviceFD fd) {
NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params) {
LOG_WARNING(Service_NVDRV,
"(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, "
"unk1={:X}, unk2={:X}, unk3={:X}",
@ -179,12 +173,7 @@ NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params, DeviceFD fd) {
return NvResult::AlreadyAllocated;
}
u64 program_id{};
if (auto* const session = core.GetSession(sessions[fd]); session != nullptr) {
program_id = session->process->GetProgramId();
}
system.GPU().InitChannel(*channel_state, program_id);
system.GPU().InitChannel(*channel_state);
params.fence_out = syncpoint_manager.GetSyncpointFence(channel_syncpoint);

View File

@ -192,7 +192,7 @@ private:
NvResult ZCullBind(IoctlZCullBind& params);
NvResult SetErrorNotifier(IoctlSetErrorNotifier& params);
NvResult SetChannelPriority(IoctlChannelSetPriority& params);
NvResult AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params, DeviceFD fd);
NvResult AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params);
NvResult AllocateObjectContext(IoctlAllocObjCtx& params);
NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandList&& entries);
@ -210,7 +210,6 @@ private:
NvCore::SyncpointManager& syncpoint_manager;
NvCore::NvMap& nvmap;
std::shared_ptr<Tegra::Control::ChannelState> channel_state;
std::unordered_map<DeviceFD, NvCore::SessionId> sessions;
u32 channel_syncpoint;
std::mutex channel_mutex;

View File

@ -93,19 +93,13 @@ ServerManager::~ServerManager() {
m_threads.clear();
// Clean up ports.
auto port_it = m_servers.begin();
while (port_it != m_servers.end()) {
auto* const port = std::addressof(*port_it);
port_it = m_servers.erase(port_it);
delete port;
for (auto it = m_servers.begin(); it != m_servers.end(); it = m_servers.erase(it)) {
delete std::addressof(*it);
}
// Clean up sessions.
auto session_it = m_sessions.begin();
while (session_it != m_sessions.end()) {
auto* const session = std::addressof(*session_it);
session_it = m_sessions.erase(session_it);
delete session;
for (auto it = m_sessions.begin(); it != m_sessions.end(); it = m_sessions.erase(it)) {
delete std::addressof(*it);
}
// Close wakeup event.

View File

@ -36,23 +36,22 @@ std::optional<FileType> IdentifyFileLoader(FileSys::VirtualFile file) {
} // namespace
FileType IdentifyFile(FileSys::VirtualFile file) {
if (const auto nsp_type = IdentifyFileLoader<AppLoader_NSP>(file)) {
return *nsp_type;
} else if (const auto xci_type = IdentifyFileLoader<AppLoader_XCI>(file)) {
return *xci_type;
if (const auto romdir_type = IdentifyFileLoader<AppLoader_DeconstructedRomDirectory>(file)) {
return *romdir_type;
} else if (const auto nso_type = IdentifyFileLoader<AppLoader_NSO>(file)) {
return *nso_type;
} else if (const auto nro_type = IdentifyFileLoader<AppLoader_NRO>(file)) {
return *nro_type;
} else if (const auto nca_type = IdentifyFileLoader<AppLoader_NCA>(file)) {
return *nca_type;
} else if (const auto xci_type = IdentifyFileLoader<AppLoader_XCI>(file)) {
return *xci_type;
} else if (const auto nax_type = IdentifyFileLoader<AppLoader_NAX>(file)) {
return *nax_type;
} else if (const auto nsp_type = IdentifyFileLoader<AppLoader_NSP>(file)) {
return *nsp_type;
} else if (const auto kip_type = IdentifyFileLoader<AppLoader_KIP>(file)) {
return *kip_type;
} else if (const auto nso_type = IdentifyFileLoader<AppLoader_NSO>(file)) {
return *nso_type;
} else if (const auto romdir_type =
IdentifyFileLoader<AppLoader_DeconstructedRomDirectory>(file)) {
return *romdir_type;
} else {
return FileType::Unknown;
}

View File

@ -26,9 +26,6 @@ public:
void Track(u64 offset, u64 size) noexcept {
const size_t page = offset >> PAGE_SHIFT;
const size_t page_end = (offset + size) >> PAGE_SHIFT;
if (page_end < page || page_end >= pages.size()) {
return;
}
TrackPage(page, offset, size);
if (page == page_end) {
return;
@ -44,9 +41,6 @@ public:
[[nodiscard]] bool IsUsed(u64 offset, u64 size) const noexcept {
const size_t page = offset >> PAGE_SHIFT;
const size_t page_end = (offset + size) >> PAGE_SHIFT;
if (page_end < page || page_end >= pages.size()) {
return false;
}
if (IsPageUsed(page, offset, size)) {
return true;
}

View File

@ -16,9 +16,8 @@ namespace Tegra::Control {
ChannelState::ChannelState(s32 bind_id_) : bind_id{bind_id_}, initialized{} {}
void ChannelState::Init(Core::System& system, GPU& gpu, u64 program_id_) {
void ChannelState::Init(Core::System& system, GPU& gpu) {
ASSERT(memory_manager);
program_id = program_id_;
dma_pusher = std::make_unique<Tegra::DmaPusher>(system, gpu, *memory_manager, *this);
maxwell_3d = std::make_unique<Engines::Maxwell3D>(system, *memory_manager);
fermi_2d = std::make_unique<Engines::Fermi2D>(*memory_manager);

View File

@ -40,12 +40,11 @@ struct ChannelState {
ChannelState(ChannelState&& other) noexcept = default;
ChannelState& operator=(ChannelState&& other) noexcept = default;
void Init(Core::System& system, GPU& gpu, u64 program_id);
void Init(Core::System& system, GPU& gpu);
void BindRasterizer(VideoCore::RasterizerInterface* rasterizer);
s32 bind_id = -1;
u64 program_id = 0;
/// 3D engine
std::unique_ptr<Engines::Maxwell3D> maxwell_3d;
/// 2D engine

View File

@ -7,7 +7,7 @@ namespace VideoCommon {
ChannelInfo::ChannelInfo(Tegra::Control::ChannelState& channel_state)
: maxwell3d{*channel_state.maxwell_3d}, kepler_compute{*channel_state.kepler_compute},
gpu_memory{*channel_state.memory_manager}, program_id{channel_state.program_id} {}
gpu_memory{*channel_state.memory_manager} {}
template class VideoCommon::ChannelSetupCaches<VideoCommon::ChannelInfo>;

View File

@ -39,7 +39,6 @@ public:
Tegra::Engines::Maxwell3D& maxwell3d;
Tegra::Engines::KeplerCompute& kepler_compute;
Tegra::MemoryManager& gpu_memory;
u64 program_id;
};
template <class P>
@ -78,10 +77,9 @@ protected:
P* channel_state;
size_t current_channel_id{UNSET_CHANNEL};
size_t current_address_space{};
Tegra::Engines::Maxwell3D* maxwell3d{};
Tegra::Engines::KeplerCompute* kepler_compute{};
Tegra::MemoryManager* gpu_memory{};
u64 program_id{};
Tegra::Engines::Maxwell3D* maxwell3d;
Tegra::Engines::KeplerCompute* kepler_compute;
Tegra::MemoryManager* gpu_memory;
std::deque<P> channel_storage;
std::deque<size_t> free_channel_ids;

View File

@ -58,7 +58,6 @@ void ChannelSetupCaches<P>::BindToChannel(s32 id) {
maxwell3d = &channel_state->maxwell3d;
kepler_compute = &channel_state->kepler_compute;
gpu_memory = &channel_state->gpu_memory;
program_id = channel_state->program_id;
current_address_space = gpu_memory->GetID();
}
@ -77,7 +76,6 @@ void ChannelSetupCaches<P>::EraseChannel(s32 id) {
maxwell3d = nullptr;
kepler_compute = nullptr;
gpu_memory = nullptr;
program_id = 0;
} else if (current_channel_id != UNSET_CHANNEL) {
channel_state = &channel_storage[current_channel_id];
}

View File

@ -67,8 +67,8 @@ struct GPU::Impl {
return CreateChannel(new_channel_id++);
}
void InitChannel(Control::ChannelState& to_init, u64 program_id) {
to_init.Init(system, gpu, program_id);
void InitChannel(Control::ChannelState& to_init) {
to_init.Init(system, gpu);
to_init.BindRasterizer(rasterizer);
rasterizer->InitializeChannel(to_init);
}
@ -387,8 +387,8 @@ std::shared_ptr<Control::ChannelState> GPU::AllocateChannel() {
return impl->AllocateChannel();
}
void GPU::InitChannel(Control::ChannelState& to_init, u64 program_id) {
impl->InitChannel(to_init, program_id);
void GPU::InitChannel(Control::ChannelState& to_init) {
impl->InitChannel(to_init);
}
void GPU::BindChannel(s32 channel_id) {

View File

@ -149,7 +149,7 @@ public:
std::shared_ptr<Control::ChannelState> AllocateChannel();
void InitChannel(Control::ChannelState& to_init, u64 program_id);
void InitChannel(Control::ChannelState& to_init);
void BindChannel(s32 channel_id);

View File

@ -215,7 +215,6 @@ ShaderCache::ShaderCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
.support_gl_variable_aoffi = device.HasVariableAoffi(),
.support_gl_sparse_textures = device.HasSparseTexture2(),
.support_gl_derivative_control = device.HasDerivativeControl(),
.support_geometry_streams = true,
.warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyLargerThanGuest(),

View File

@ -71,7 +71,7 @@ const char* GetType(GLenum type) {
void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
const GLchar* message, const void* user_param) {
constexpr std::string_view format = "{} {} {}: {}";
const char format[] = "{} {} {}: {}";
const char* const str_source = GetSource(source);
const char* const str_type = GetType(type);

View File

@ -1082,16 +1082,37 @@ void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs) {
regs.zeta.format == Tegra::DepthFormat::X8Z24_UNORM ||
regs.zeta.format == Tegra::DepthFormat::S8Z24_UNORM ||
regs.zeta.format == Tegra::DepthFormat::V8Z24_UNORM;
if (is_d24 && !device.SupportsD24DepthBuffer() && program_id == 0x1006A800016E000ULL) {
// Only activate this in Super Smash Brothers Ultimate
bool force_unorm = ([&] {
if (!is_d24 || device.SupportsD24DepthBuffer()) {
return false;
}
if (device.IsExtDepthBiasControlSupported()) {
return true;
}
if (!Settings::values.renderer_amdvlk_depth_bias_workaround) {
return false;
}
// the base formulas can be obtained from here:
// https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-output-merger-stage-depth-bias
const double rescale_factor =
static_cast<double>(1ULL << (32 - 24)) / (static_cast<double>(0x1.ep+127));
units = static_cast<float>(static_cast<double>(units) * rescale_factor);
}
return false;
})();
scheduler.Record([constant = units, clamp = regs.depth_bias_clamp,
factor = regs.slope_scale_depth_bias](vk::CommandBuffer cmdbuf) {
factor = regs.slope_scale_depth_bias, force_unorm,
precise = device.HasExactDepthBiasControl()](vk::CommandBuffer cmdbuf) {
if (force_unorm) {
VkDepthBiasRepresentationInfoEXT info{
.sType = VK_STRUCTURE_TYPE_DEPTH_BIAS_REPRESENTATION_INFO_EXT,
.pNext = nullptr,
.depthBiasRepresentation =
VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORCE_UNORM_EXT,
.depthBiasExact = precise ? VK_TRUE : VK_FALSE,
};
cmdbuf.SetDepthBias(constant, clamp, factor, &info);
return;
}
cmdbuf.SetDepthBias(constant, clamp, factor);
});
}

View File

@ -2114,9 +2114,7 @@ void TextureCache<P>::TrackImage(ImageBase& image, ImageId image_id) {
ASSERT(False(image.flags & ImageFlagBits::Tracked));
image.flags |= ImageFlagBits::Tracked;
if (False(image.flags & ImageFlagBits::Sparse)) {
if (image.cpu_addr < ~(1ULL << 40)) {
device_memory.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, 1);
}
device_memory.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, 1);
return;
}
if (True(image.flags & ImageFlagBits::Registered)) {
@ -2142,9 +2140,7 @@ void TextureCache<P>::UntrackImage(ImageBase& image, ImageId image_id) {
ASSERT(True(image.flags & ImageFlagBits::Tracked));
image.flags &= ~ImageFlagBits::Tracked;
if (False(image.flags & ImageFlagBits::Sparse)) {
if (image.cpu_addr < ~(1ULL << 40)) {
device_memory.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, -1);
}
device_memory.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, -1);
return;
}
ASSERT(True(image.flags & ImageFlagBits::Registered));