early-access version 3032

main
pineappleEA 2022-10-17 14:43:31 +02:00
parent 971803d545
commit 6fb2358eb1
12 changed files with 101 additions and 50 deletions

View File

@ -1,7 +1,7 @@
yuzu emulator early access yuzu emulator early access
============= =============
This is the source code for early-access 3031. This is the source code for early-access 3032.
## Legal Notice ## Legal Notice

View File

@ -230,7 +230,9 @@ std::vector<std::string> ListSDLSinkDevices(bool capture) {
const int device_count = SDL_GetNumAudioDevices(capture); const int device_count = SDL_GetNumAudioDevices(capture);
for (int i = 0; i < device_count; ++i) { for (int i = 0; i < device_count; ++i) {
device_list.emplace_back(SDL_GetAudioDeviceName(i, 0)); if (const char* name = SDL_GetAudioDeviceName(i, capture)) {
device_list.emplace_back(name);
}
} }
return device_list; return device_list;

View File

@ -5,6 +5,7 @@
#include "common/assert.h" #include "common/assert.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/uuid.h"
#include "core/core.h" #include "core/core.h"
#include "core/file_sys/savedata_factory.h" #include "core/file_sys/savedata_factory.h"
#include "core/file_sys/vfs.h" #include "core/file_sys/vfs.h"
@ -59,6 +60,36 @@ bool ShouldSaveDataBeAutomaticallyCreated(SaveDataSpaceId space, const SaveDataA
attr.title_id == 0 && attr.save_id == 0); attr.title_id == 0 && attr.save_id == 0);
} }
std::string GetFutureSaveDataPath(SaveDataSpaceId space_id, SaveDataType type, u64 title_id,
u128 user_id) {
// Only detect nand user saves.
const auto space_id_path = [space_id]() -> std::string_view {
switch (space_id) {
case SaveDataSpaceId::NandUser:
return "/user/save";
default:
return "";
}
}();
if (space_id_path.empty()) {
return "";
}
Common::UUID uuid;
std::memcpy(uuid.uuid.data(), user_id.data(), sizeof(Common::UUID));
// 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);
case SaveDataType::DeviceSaveData:
return fmt::format("{}/device/{:016X}/1", space_id_path, title_id);
default:
return "";
}
}
} // Anonymous namespace } // Anonymous namespace
std::string SaveDataAttribute::DebugInfo() const { std::string SaveDataAttribute::DebugInfo() const {
@ -82,7 +113,7 @@ ResultVal<VirtualDir> SaveDataFactory::Create(SaveDataSpaceId space,
PrintSaveDataAttributeWarnings(meta); PrintSaveDataAttributeWarnings(meta);
const auto save_directory = const auto save_directory =
GetFullPath(system, space, meta.type, meta.title_id, meta.user_id, meta.save_id); GetFullPath(system, dir, space, meta.type, meta.title_id, meta.user_id, meta.save_id);
auto out = dir->CreateDirectoryRelative(save_directory); auto out = dir->CreateDirectoryRelative(save_directory);
@ -99,7 +130,7 @@ ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space,
const SaveDataAttribute& meta) const { const SaveDataAttribute& meta) const {
const auto save_directory = const auto save_directory =
GetFullPath(system, space, meta.type, meta.title_id, meta.user_id, meta.save_id); GetFullPath(system, dir, space, meta.type, meta.title_id, meta.user_id, meta.save_id);
auto out = dir->GetDirectoryRelative(save_directory); auto out = dir->GetDirectoryRelative(save_directory);
@ -134,9 +165,9 @@ std::string SaveDataFactory::GetSaveDataSpaceIdPath(SaveDataSpaceId space) {
} }
} }
std::string SaveDataFactory::GetFullPath(Core::System& system, SaveDataSpaceId space, std::string SaveDataFactory::GetFullPath(Core::System& system, VirtualDir dir,
SaveDataType type, u64 title_id, u128 user_id, SaveDataSpaceId space, SaveDataType type, u64 title_id,
u64 save_id) { u128 user_id, u64 save_id) {
// According to switchbrew, if a save is of type SaveData and the title id field is 0, it should // According to switchbrew, if a save is of type SaveData and the title id field is 0, it should
// be interpreted as the title id of the current process. // be interpreted as the title id of the current process.
if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) { if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) {
@ -145,6 +176,17 @@ std::string SaveDataFactory::GetFullPath(Core::System& system, SaveDataSpaceId s
} }
} }
// For compat with a future impl.
if (std::string future_path =
GetFutureSaveDataPath(space, type, title_id & ~(0xFFULL), user_id);
!future_path.empty()) {
// Check if this location exists, and prefer it over the old.
if (const auto future_dir = dir->GetDirectoryRelative(future_path); future_dir != nullptr) {
LOG_INFO(Service_FS, "Using save at new location: {}", future_path);
return future_path;
}
}
std::string out = GetSaveDataSpaceIdPath(space); std::string out = GetSaveDataSpaceIdPath(space);
switch (type) { switch (type) {
@ -167,7 +209,8 @@ std::string SaveDataFactory::GetFullPath(Core::System& system, SaveDataSpaceId s
SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id, SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
u128 user_id) const { u128 user_id) const {
const auto path = GetFullPath(system, SaveDataSpaceId::NandUser, type, title_id, user_id, 0); const auto path =
GetFullPath(system, dir, SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
const auto relative_dir = GetOrCreateDirectoryRelative(dir, path); const auto relative_dir = GetOrCreateDirectoryRelative(dir, path);
const auto size_file = relative_dir->GetFile(SAVE_DATA_SIZE_FILENAME); const auto size_file = relative_dir->GetFile(SAVE_DATA_SIZE_FILENAME);
@ -185,7 +228,8 @@ SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,
SaveDataSize new_value) const { SaveDataSize new_value) const {
const auto path = GetFullPath(system, SaveDataSpaceId::NandUser, type, title_id, user_id, 0); const auto path =
GetFullPath(system, dir, SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
const auto relative_dir = GetOrCreateDirectoryRelative(dir, path); const auto relative_dir = GetOrCreateDirectoryRelative(dir, path);
const auto size_file = relative_dir->CreateFile(SAVE_DATA_SIZE_FILENAME); const auto size_file = relative_dir->CreateFile(SAVE_DATA_SIZE_FILENAME);

View File

@ -95,8 +95,8 @@ public:
VirtualDir GetSaveDataSpaceDirectory(SaveDataSpaceId space) const; VirtualDir GetSaveDataSpaceDirectory(SaveDataSpaceId space) const;
static std::string GetSaveDataSpaceIdPath(SaveDataSpaceId space); static std::string GetSaveDataSpaceIdPath(SaveDataSpaceId space);
static std::string GetFullPath(Core::System& system, SaveDataSpaceId space, SaveDataType type, static std::string GetFullPath(Core::System& system, VirtualDir dir, SaveDataSpaceId space,
u64 title_id, u128 user_id, u64 save_id); SaveDataType type, u64 title_id, u128 user_id, u64 save_id);
SaveDataSize ReadSaveDataSize(SaveDataType type, u64 title_id, u128 user_id) const; SaveDataSize ReadSaveDataSize(SaveDataType type, u64 title_id, u128 user_id) const;
void WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, void WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,

View File

@ -14,7 +14,7 @@ enum class CameraAmbientNoiseLevel : u32 {
Low, Low,
Medium, Medium,
High, High,
Unkown3, // This level can't be reached Unknown3, // This level can't be reached
}; };
// This is nn::irsensor::CameraLightTarget // This is nn::irsensor::CameraLightTarget
@ -75,9 +75,9 @@ enum class IrCameraStatus : u32 {
enum class IrCameraInternalStatus : u32 { enum class IrCameraInternalStatus : u32 {
Stopped, Stopped,
FirmwareUpdateNeeded, FirmwareUpdateNeeded,
Unkown2, Unknown2,
Unkown3, Unknown3,
Unkown4, Unknown4,
FirmwareVersionRequested, FirmwareVersionRequested,
FirmwareVersionIsInvalid, FirmwareVersionIsInvalid,
Ready, Ready,
@ -121,20 +121,20 @@ enum class IrSensorFunctionLevel : u8 {
// This is nn::irsensor::MomentProcessorPreprocess // This is nn::irsensor::MomentProcessorPreprocess
enum class MomentProcessorPreprocess : u32 { enum class MomentProcessorPreprocess : u32 {
Unkown0, Unknown0,
Unkown1, Unknown1,
}; };
// This is nn::irsensor::PackedMomentProcessorPreprocess // This is nn::irsensor::PackedMomentProcessorPreprocess
enum class PackedMomentProcessorPreprocess : u8 { enum class PackedMomentProcessorPreprocess : u8 {
Unkown0, Unknown0,
Unkown1, Unknown1,
}; };
// This is nn::irsensor::PointingStatus // This is nn::irsensor::PointingStatus
enum class PointingStatus : u32 { enum class PointingStatus : u32 {
Unkown0, Unknown0,
Unkown1, Unknown1,
}; };
struct IrsRect { struct IrsRect {

View File

@ -8,6 +8,7 @@
#include "common/assert.h" #include "common/assert.h"
#include "common/common_funcs.h" #include "common/common_funcs.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "common/spin_lock.h"
namespace Kernel { namespace Kernel {
@ -36,28 +37,30 @@ public:
} }
void* Allocate() { void* Allocate() {
Node* ret = m_head.load(); m_lock.lock();
do { Node* ret = m_head;
if (ret == nullptr) { if (ret != nullptr) [[likely]] {
break; m_head = ret->next;
} }
} while (!m_head.compare_exchange_weak(ret, ret->next));
m_lock.unlock();
return ret; return ret;
} }
void Free(void* obj) { void Free(void* obj) {
Node* node = static_cast<Node*>(obj); m_lock.lock();
Node* cur_head = m_head.load(); Node* node = static_cast<Node*>(obj);
do { node->next = m_head;
node->next = cur_head; m_head = node;
} while (!m_head.compare_exchange_weak(cur_head, node));
m_lock.unlock();
} }
private: private:
std::atomic<Node*> m_head{}; std::atomic<Node*> m_head{};
Common::SpinLock m_lock;
}; };
} // namespace impl } // namespace impl

View File

@ -2118,7 +2118,7 @@ void Hid::WritePalmaWaveEntry(Kernel::HLERequestContext& ctx) {
ASSERT_MSG(t_mem->GetSize() == 0x3000, "t_mem has incorrect size"); ASSERT_MSG(t_mem->GetSize() == 0x3000, "t_mem has incorrect size");
LOG_WARNING(Service_HID, LOG_WARNING(Service_HID,
"(STUBBED) called, connection_handle={}, wave_set={}, unkown={}, " "(STUBBED) called, connection_handle={}, wave_set={}, unknown={}, "
"t_mem_handle=0x{:08X}, t_mem_size={}, size={}", "t_mem_handle=0x{:08X}, t_mem_size={}, size={}",
connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size); connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size);

View File

@ -37,10 +37,10 @@ private:
u8 pointing_status; u8 pointing_status;
INSERT_PADDING_BYTES(3); INSERT_PADDING_BYTES(3);
u32 unknown; u32 unknown;
float unkown_float1; float unknown_float1;
float position_x; float position_x;
float position_y; float position_y;
float unkown_float2; float unknown_float2;
Core::IrSensor::IrsRect window_of_interest; Core::IrSensor::IrsRect window_of_interest;
}; };
static_assert(sizeof(PointingProcessorMarkerData) == 0x20, static_assert(sizeof(PointingProcessorMarkerData) == 0x20,

View File

@ -272,14 +272,14 @@ IR::Program MergeDualVertexPrograms(IR::Program& vertex_a, IR::Program& vertex_b
void ConvertLegacyToGeneric(IR::Program& program, const Shader::RuntimeInfo& runtime_info) { void ConvertLegacyToGeneric(IR::Program& program, const Shader::RuntimeInfo& runtime_info) {
auto& stores = program.info.stores; auto& stores = program.info.stores;
if (stores.Legacy()) { if (stores.Legacy()) {
std::queue<IR::Attribute> ununsed_output_generics{}; std::queue<IR::Attribute> unused_output_generics{};
for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { for (size_t index = 0; index < IR::NUM_GENERICS; ++index) {
if (!stores.Generic(index)) { if (!stores.Generic(index)) {
ununsed_output_generics.push(IR::Attribute::Generic0X + index * 4); unused_output_generics.push(IR::Attribute::Generic0X + index * 4);
} }
} }
program.info.legacy_stores_mapping = program.info.legacy_stores_mapping =
GenerateLegacyToGenericMappings(stores, ununsed_output_generics, {}); GenerateLegacyToGenericMappings(stores, unused_output_generics, {});
for (IR::Block* const block : program.post_order_blocks) { for (IR::Block* const block : program.post_order_blocks) {
for (IR::Inst& inst : block->Instructions()) { for (IR::Inst& inst : block->Instructions()) {
switch (inst.GetOpcode()) { switch (inst.GetOpcode()) {
@ -300,16 +300,16 @@ void ConvertLegacyToGeneric(IR::Program& program, const Shader::RuntimeInfo& run
auto& loads = program.info.loads; auto& loads = program.info.loads;
if (loads.Legacy()) { if (loads.Legacy()) {
std::queue<IR::Attribute> ununsed_input_generics{}; std::queue<IR::Attribute> unused_input_generics{};
for (size_t index = 0; index < IR::NUM_GENERICS; ++index) { for (size_t index = 0; index < IR::NUM_GENERICS; ++index) {
const AttributeType input_type{runtime_info.generic_input_types[index]}; const AttributeType input_type{runtime_info.generic_input_types[index]};
if (!runtime_info.previous_stage_stores.Generic(index) || !loads.Generic(index) || if (!runtime_info.previous_stage_stores.Generic(index) || !loads.Generic(index) ||
input_type == AttributeType::Disabled) { input_type == AttributeType::Disabled) {
ununsed_input_generics.push(IR::Attribute::Generic0X + index * 4); unused_input_generics.push(IR::Attribute::Generic0X + index * 4);
} }
} }
auto mappings = GenerateLegacyToGenericMappings( auto mappings = GenerateLegacyToGenericMappings(
loads, ununsed_input_generics, runtime_info.previous_stage_legacy_stores_mapping); loads, unused_input_generics, runtime_info.previous_stage_legacy_stores_mapping);
for (IR::Block* const block : program.post_order_blocks) { for (IR::Block* const block : program.post_order_blocks) {
for (IR::Inst& inst : block->Instructions()) { for (IR::Inst& inst : block->Instructions()) {
switch (inst.GetOpcode()) { switch (inst.GetOpcode()) {

View File

@ -18,7 +18,7 @@ class DescriptorTable {
public: public:
explicit DescriptorTable(Tegra::MemoryManager& gpu_memory_) : gpu_memory{gpu_memory_} {} explicit DescriptorTable(Tegra::MemoryManager& gpu_memory_) : gpu_memory{gpu_memory_} {}
[[nodiscard]] bool Synchornize(GPUVAddr gpu_addr, u32 limit) { [[nodiscard]] bool Synchronize(GPUVAddr gpu_addr, u32 limit) {
[[likely]] if (current_gpu_addr == gpu_addr && current_limit == limit) { [[likely]] if (current_gpu_addr == gpu_addr && current_limit == limit) {
return false; return false;
} }

View File

@ -193,11 +193,11 @@ void TextureCache<P>::SynchronizeGraphicsDescriptors() {
const bool linked_tsc = maxwell3d->regs.sampler_binding == SamplerBinding::ViaHeaderBinding; const bool linked_tsc = maxwell3d->regs.sampler_binding == SamplerBinding::ViaHeaderBinding;
const u32 tic_limit = maxwell3d->regs.tex_header.limit; const u32 tic_limit = maxwell3d->regs.tex_header.limit;
const u32 tsc_limit = linked_tsc ? tic_limit : maxwell3d->regs.tex_sampler.limit; const u32 tsc_limit = linked_tsc ? tic_limit : maxwell3d->regs.tex_sampler.limit;
if (channel_state->graphics_sampler_table.Synchornize(maxwell3d->regs.tex_sampler.Address(), if (channel_state->graphics_sampler_table.Synchronize(maxwell3d->regs.tex_sampler.Address(),
tsc_limit)) { tsc_limit)) {
channel_state->graphics_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID); channel_state->graphics_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID);
} }
if (channel_state->graphics_image_table.Synchornize(maxwell3d->regs.tex_header.Address(), if (channel_state->graphics_image_table.Synchronize(maxwell3d->regs.tex_header.Address(),
tic_limit)) { tic_limit)) {
channel_state->graphics_image_view_ids.resize(tic_limit + 1, CORRUPT_ID); channel_state->graphics_image_view_ids.resize(tic_limit + 1, CORRUPT_ID);
} }
@ -209,10 +209,10 @@ void TextureCache<P>::SynchronizeComputeDescriptors() {
const u32 tic_limit = kepler_compute->regs.tic.limit; const u32 tic_limit = kepler_compute->regs.tic.limit;
const u32 tsc_limit = linked_tsc ? tic_limit : kepler_compute->regs.tsc.limit; const u32 tsc_limit = linked_tsc ? tic_limit : kepler_compute->regs.tsc.limit;
const GPUVAddr tsc_gpu_addr = kepler_compute->regs.tsc.Address(); const GPUVAddr tsc_gpu_addr = kepler_compute->regs.tsc.Address();
if (channel_state->compute_sampler_table.Synchornize(tsc_gpu_addr, tsc_limit)) { if (channel_state->compute_sampler_table.Synchronize(tsc_gpu_addr, tsc_limit)) {
channel_state->compute_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID); channel_state->compute_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID);
} }
if (channel_state->compute_image_table.Synchornize(kepler_compute->regs.tic.Address(), if (channel_state->compute_image_table.Synchronize(kepler_compute->regs.tic.Address(),
tic_limit)) { tic_limit)) {
channel_state->compute_image_view_ids.resize(tic_limit + 1, CORRUPT_ID); channel_state->compute_image_view_ids.resize(tic_limit + 1, CORRUPT_ID);
} }

View File

@ -1895,6 +1895,8 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
case GameListOpenTarget::SaveData: { case GameListOpenTarget::SaveData: {
open_target = tr("Save Data"); open_target = tr("Save Data");
const auto nand_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir); const auto nand_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir);
auto vfs_nand_dir =
vfs->OpenDirectory(Common::FS::PathToUTF8String(nand_dir), FileSys::Mode::Read);
if (has_user_save) { if (has_user_save) {
// User save data // User save data
@ -1921,15 +1923,15 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
ASSERT(user_id); ASSERT(user_id);
const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath( const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath(
*system, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData, *system, vfs_nand_dir, FileSys::SaveDataSpaceId::NandUser,
program_id, user_id->AsU128(), 0); FileSys::SaveDataType::SaveData, program_id, user_id->AsU128(), 0);
path = Common::FS::ConcatPathSafe(nand_dir, user_save_data_path); path = Common::FS::ConcatPathSafe(nand_dir, user_save_data_path);
} else { } else {
// Device save data // Device save data
const auto device_save_data_path = FileSys::SaveDataFactory::GetFullPath( const auto device_save_data_path = FileSys::SaveDataFactory::GetFullPath(
*system, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData, *system, vfs_nand_dir, FileSys::SaveDataSpaceId::NandUser,
program_id, {}, 0); FileSys::SaveDataType::SaveData, program_id, {}, 0);
path = Common::FS::ConcatPathSafe(nand_dir, device_save_data_path); path = Common::FS::ConcatPathSafe(nand_dir, device_save_data_path);
} }