summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--appveyor.yml4
m---------externals/dynarmic0
-rw-r--r--src/core/core.cpp5
-rw-r--r--src/core/file_sys/registered_cache.cpp2
-rw-r--r--src/core/file_sys/vfs_real.cpp6
-rw-r--r--src/core/file_sys/vfs_real.h20
-rw-r--r--src/core/file_sys/xts_archive.cpp1
-rw-r--r--src/core/hle/kernel/kernel.cpp24
-rw-r--r--src/core/hle/kernel/kernel.h18
-rw-r--r--src/core/hle/kernel/svc.cpp12
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp7
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp30
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.h2
-rw-r--r--src/core/hle/service/service.cpp9
-rw-r--r--src/core/hle/service/service.h7
-rw-r--r--src/core/loader/loader.cpp5
-rw-r--r--src/core/loader/loader.h6
-rw-r--r--src/video_core/engines/maxwell_3d.cpp5
-rw-r--r--src/video_core/engines/shader_bytecode.h15
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp29
-rw-r--r--src/yuzu/game_list.cpp3
-rw-r--r--src/yuzu/game_list.h2
-rw-r--r--src/yuzu/game_list_p.h5
-rw-r--r--src/yuzu/main.cpp17
-rw-r--r--src/yuzu/main.h5
-rw-r--r--src/yuzu_cmd/yuzu.cpp1
26 files changed, 182 insertions, 58 deletions
diff --git a/appveyor.yml b/appveyor.yml
index d68ae87b1..d475816ab 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -162,10 +162,6 @@ artifacts:
- path: $(BUILD_ZIP)
name: build
type: zip
- - path: $(BUILD_SYMBOLS)
- name: debugsymbols
- - path: $(BUILD_UPDATE)
- name: update
deploy:
provider: GitHub
diff --git a/externals/dynarmic b/externals/dynarmic
-Subproject a42f301c28832bb2b4ffaf4fe7b84b9765542f4
+Subproject 0435ac2d80d19a8025f5bf45629314e9ee9253e
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 2cfae18df..29983b9b4 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -14,6 +14,9 @@
#include "core/core.h"
#include "core/core_cpu.h"
#include "core/core_timing.h"
+#include "core/file_sys/mode.h"
+#include "core/file_sys/vfs_concat.h"
+#include "core/file_sys/vfs_real.h"
#include "core/gdbstub/gdbstub.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/kernel.h"
@@ -27,8 +30,6 @@
#include "core/perf_stats.h"
#include "core/settings.h"
#include "core/telemetry_session.h"
-#include "file_sys/vfs_concat.h"
-#include "file_sys/vfs_real.h"
#include "video_core/debug_utils/debug_utils.h"
#include "video_core/gpu.h"
#include "video_core/renderer_base.h"
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp
index dacf8568b..fe5d36930 100644
--- a/src/core/file_sys/registered_cache.cpp
+++ b/src/core/file_sys/registered_cache.cpp
@@ -5,9 +5,9 @@
#include <regex>
#include <mbedtls/sha256.h>
#include "common/assert.h"
+#include "common/file_util.h"
#include "common/hex_util.h"
#include "common/logging/log.h"
-#include "core/crypto/encryption_layer.h"
#include "core/file_sys/card_image.h"
#include "core/file_sys/nca_metadata.h"
#include "core/file_sys/registered_cache.h"
diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp
index 2b8ac7103..89b101145 100644
--- a/src/core/file_sys/vfs_real.cpp
+++ b/src/core/file_sys/vfs_real.cpp
@@ -8,6 +8,7 @@
#include <utility>
#include "common/assert.h"
#include "common/common_paths.h"
+#include "common/file_util.h"
#include "common/logging/log.h"
#include "core/file_sys/vfs_real.h"
@@ -39,6 +40,7 @@ static std::string ModeFlagsToString(Mode mode) {
}
RealVfsFilesystem::RealVfsFilesystem() : VfsFilesystem(nullptr) {}
+RealVfsFilesystem::~RealVfsFilesystem() = default;
std::string RealVfsFilesystem::GetName() const {
return "Real";
@@ -219,6 +221,8 @@ RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::shared_ptr<FileUtil::IOF
parent_components(FileUtil::SliceVector(path_components, 0, path_components.size() - 1)),
perms(perms_) {}
+RealVfsFile::~RealVfsFile() = default;
+
std::string RealVfsFile::GetName() const {
return path_components.back();
}
@@ -312,6 +316,8 @@ RealVfsDirectory::RealVfsDirectory(RealVfsFilesystem& base_, const std::string&
FileUtil::CreateDir(path);
}
+RealVfsDirectory::~RealVfsDirectory() = default;
+
std::shared_ptr<VfsFile> RealVfsDirectory::GetFileRelative(std::string_view path) const {
const auto full_path = FileUtil::SanitizePath(this->path + DIR_SEP + std::string(path));
if (!FileUtil::Exists(full_path) || FileUtil::IsDirectory(full_path))
diff --git a/src/core/file_sys/vfs_real.h b/src/core/file_sys/vfs_real.h
index 989803d43..7db86691f 100644
--- a/src/core/file_sys/vfs_real.h
+++ b/src/core/file_sys/vfs_real.h
@@ -6,15 +6,19 @@
#include <string_view>
#include <boost/container/flat_map.hpp>
-#include "common/file_util.h"
#include "core/file_sys/mode.h"
#include "core/file_sys/vfs.h"
+namespace FileUtil {
+class IOFile;
+}
+
namespace FileSys {
class RealVfsFilesystem : public VfsFilesystem {
public:
RealVfsFilesystem();
+ ~RealVfsFilesystem() override;
std::string GetName() const override;
bool IsReadable() const override;
@@ -40,10 +44,9 @@ class RealVfsFile : public VfsFile {
friend class RealVfsDirectory;
friend class RealVfsFilesystem;
- RealVfsFile(RealVfsFilesystem& base, std::shared_ptr<FileUtil::IOFile> backing,
- const std::string& path, Mode perms = Mode::Read);
-
public:
+ ~RealVfsFile() override;
+
std::string GetName() const override;
size_t GetSize() const override;
bool Resize(size_t new_size) override;
@@ -55,6 +58,9 @@ public:
bool Rename(std::string_view name) override;
private:
+ RealVfsFile(RealVfsFilesystem& base, std::shared_ptr<FileUtil::IOFile> backing,
+ const std::string& path, Mode perms = Mode::Read);
+
bool Close();
RealVfsFilesystem& base;
@@ -70,9 +76,9 @@ private:
class RealVfsDirectory : public VfsDirectory {
friend class RealVfsFilesystem;
- RealVfsDirectory(RealVfsFilesystem& base, const std::string& path, Mode perms = Mode::Read);
-
public:
+ ~RealVfsDirectory() override;
+
std::shared_ptr<VfsFile> GetFileRelative(std::string_view path) const override;
std::shared_ptr<VfsDirectory> GetDirectoryRelative(std::string_view path) const override;
std::shared_ptr<VfsFile> GetFile(std::string_view name) const override;
@@ -97,6 +103,8 @@ protected:
bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override;
private:
+ RealVfsDirectory(RealVfsFilesystem& base, const std::string& path, Mode perms = Mode::Read);
+
template <typename T, typename R>
std::vector<std::shared_ptr<R>> IterateEntries() const;
diff --git a/src/core/file_sys/xts_archive.cpp b/src/core/file_sys/xts_archive.cpp
index 552835738..4dbc25c55 100644
--- a/src/core/file_sys/xts_archive.cpp
+++ b/src/core/file_sys/xts_archive.cpp
@@ -10,6 +10,7 @@
#include <mbedtls/md.h>
#include <mbedtls/sha256.h>
#include "common/assert.h"
+#include "common/file_util.h"
#include "common/hex_util.h"
#include "common/logging/log.h"
#include "core/crypto/aes_util.h"
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 615d7901a..7902c2882 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -13,6 +13,7 @@
#include "core/core.h"
#include "core/core_timing.h"
+#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/process.h"
@@ -124,6 +125,8 @@ struct KernelCore::Impl {
timer_callback_handle_table.Clear();
timer_callback_event_type = nullptr;
+
+ named_ports.clear();
}
void InitializeResourceLimits(KernelCore& kernel) {
@@ -217,6 +220,10 @@ struct KernelCore::Impl {
// TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future,
// allowing us to simply use a pool index or similar.
Kernel::HandleTable thread_wakeup_callback_handle_table;
+
+ /// Map of named ports managed by the kernel, which can be retrieved using
+ /// the ConnectToPort SVC.
+ NamedPortTable named_ports;
};
KernelCore::KernelCore() : impl{std::make_unique<Impl>()} {}
@@ -257,6 +264,23 @@ void KernelCore::AppendNewProcess(SharedPtr<Process> process) {
impl->process_list.push_back(std::move(process));
}
+void KernelCore::AddNamedPort(std::string name, SharedPtr<ClientPort> port) {
+ impl->named_ports.emplace(std::move(name), std::move(port));
+}
+
+KernelCore::NamedPortTable::iterator KernelCore::FindNamedPort(const std::string& name) {
+ return impl->named_ports.find(name);
+}
+
+KernelCore::NamedPortTable::const_iterator KernelCore::FindNamedPort(
+ const std::string& name) const {
+ return impl->named_ports.find(name);
+}
+
+bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const {
+ return port != impl->named_ports.cend();
+}
+
u32 KernelCore::CreateNewObjectID() {
return impl->next_object_id++;
}
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 089e959ac..ab2e9bffa 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -4,6 +4,8 @@
#pragma once
+#include <string>
+#include <unordered_map>
#include "core/hle/kernel/object.h"
template <typename T>
@@ -15,6 +17,7 @@ struct EventType;
namespace Kernel {
+class ClientPort;
class HandleTable;
class Process;
class ResourceLimit;
@@ -25,6 +28,9 @@ enum class ResourceLimitCategory : u8;
/// Represents a single instance of the kernel.
class KernelCore {
+private:
+ using NamedPortTable = std::unordered_map<std::string, SharedPtr<ClientPort>>;
+
public:
KernelCore();
~KernelCore();
@@ -59,6 +65,18 @@ public:
/// Adds the given shared pointer to an internal list of active processes.
void AppendNewProcess(SharedPtr<Process> process);
+ /// Adds a port to the named port table
+ void AddNamedPort(std::string name, SharedPtr<ClientPort> port);
+
+ /// Finds a port within the named port table with the given name.
+ NamedPortTable::iterator FindNamedPort(const std::string& name);
+
+ /// Finds a port within the named port table with the given name.
+ NamedPortTable::const_iterator FindNamedPort(const std::string& name) const;
+
+ /// Determines whether or not the given port is a valid named port.
+ bool IsValidNamedPort(NamedPortTable::const_iterator port) const;
+
private:
friend class Object;
friend class Process;
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 5da71cff0..1c9373ed8 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -68,19 +68,22 @@ static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
/// Connect to an OS service given the port name, returns the handle to the port to out
static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address) {
- if (!Memory::IsValidVirtualAddress(port_name_address))
+ if (!Memory::IsValidVirtualAddress(port_name_address)) {
return ERR_NOT_FOUND;
+ }
static constexpr std::size_t PortNameMaxLength = 11;
// Read 1 char beyond the max allowed port name to detect names that are too long.
std::string port_name = Memory::ReadCString(port_name_address, PortNameMaxLength + 1);
- if (port_name.size() > PortNameMaxLength)
+ if (port_name.size() > PortNameMaxLength) {
return ERR_PORT_NAME_TOO_LONG;
+ }
LOG_TRACE(Kernel_SVC, "called port_name={}", port_name);
- auto it = Service::g_kernel_named_ports.find(port_name);
- if (it == Service::g_kernel_named_ports.end()) {
+ auto& kernel = Core::System::GetInstance().Kernel();
+ auto it = kernel.FindNamedPort(port_name);
+ if (!kernel.IsValidNamedPort(it)) {
LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: {}", port_name);
return ERR_NOT_FOUND;
}
@@ -91,7 +94,6 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address
CASCADE_RESULT(client_session, client_port->Connect());
// Return the client session
- auto& kernel = Core::System::GetInstance().Kernel();
CASCADE_RESULT(*out_handle, kernel.HandleTable().Create(client_session));
return RESULT_SUCCESS;
}
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp
index 881c39e31..a4426af96 100644
--- a/src/core/hle/service/filesystem/filesystem.cpp
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -60,17 +60,20 @@ ResultCode VfsDirectoryServiceWrapper::CreateFile(const std::string& path_, u64
ResultCode VfsDirectoryServiceWrapper::DeleteFile(const std::string& path_) const {
std::string path(FileUtil::SanitizePath(path_));
- auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path));
if (path.empty()) {
// TODO(DarkLordZach): Why do games call this and what should it do? Works as is but...
return RESULT_SUCCESS;
}
- if (dir->GetFile(FileUtil::GetFilename(path)) == nullptr)
+
+ auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(path));
+ if (dir->GetFile(FileUtil::GetFilename(path)) == nullptr) {
return FileSys::ERROR_PATH_NOT_FOUND;
+ }
if (!dir->DeleteFile(FileUtil::GetFilename(path))) {
// TODO(DarkLordZach): Find a better error code for this
return ResultCode(-1);
}
+
return RESULT_SUCCESS;
}
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index 5759299fe..3f8ff67e8 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -26,6 +26,17 @@
namespace Service::FileSystem {
+enum class FileSystemType : u8 {
+ Invalid0 = 0,
+ Invalid1 = 1,
+ Logo = 2,
+ ContentControl = 3,
+ ContentManual = 4,
+ ContentMeta = 5,
+ ContentData = 6,
+ ApplicationPackage = 7,
+};
+
class IStorage final : public ServiceFramework<IStorage> {
public:
explicit IStorage(FileSys::VirtualFile backend_)
@@ -420,7 +431,7 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
{0, nullptr, "MountContent"},
{1, &FSP_SRV::Initialize, "Initialize"},
{2, nullptr, "OpenDataFileSystemByCurrentProcess"},
- {7, nullptr, "OpenFileSystemWithPatch"},
+ {7, &FSP_SRV::OpenFileSystemWithPatch, "OpenFileSystemWithPatch"},
{8, nullptr, "OpenFileSystemWithId"},
{9, nullptr, "OpenDataFileSystemByApplicationId"},
{11, nullptr, "OpenBisFileSystem"},
@@ -444,7 +455,7 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
{34, nullptr, "GetCacheStorageSize"},
{51, &FSP_SRV::MountSaveData, "MountSaveData"},
{52, nullptr, "OpenSaveDataFileSystemBySystemSaveDataId"},
- {53, nullptr, "OpenReadOnlySaveDataFileSystem"},
+ {53, &FSP_SRV::OpenReadOnlySaveDataFileSystem, "OpenReadOnlySaveDataFileSystem"},
{57, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"},
{58, nullptr, "ReadSaveDataFileSystemExtraData"},
{59, nullptr, "WriteSaveDataFileSystemExtraData"},
@@ -516,6 +527,16 @@ void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
}
+void FSP_SRV::OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+
+ const auto type = rp.PopRaw<FileSystemType>();
+ const auto title_id = rp.PopRaw<u64>();
+
+ IPC::ResponseBuilder rb{ctx, 2, 0, 0};
+ rb.Push(ResultCode(-1));
+}
+
void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_FS, "called");
@@ -563,6 +584,11 @@ void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) {
rb.PushIpcInterface<IFileSystem>(std::move(filesystem));
}
+void FSP_SRV::OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_FS, "(STUBBED) called, delegating to 51 OpenSaveDataFilesystem");
+ MountSaveData(ctx);
+}
+
void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_FS, "(STUBBED) called");
diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h
index f073ac523..2b5c21abb 100644
--- a/src/core/hle/service/filesystem/fsp_srv.h
+++ b/src/core/hle/service/filesystem/fsp_srv.h
@@ -20,9 +20,11 @@ public:
private:
void Initialize(Kernel::HLERequestContext& ctx);
+ void OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx);
void MountSdCard(Kernel::HLERequestContext& ctx);
void CreateSaveData(Kernel::HLERequestContext& ctx);
void MountSaveData(Kernel::HLERequestContext& ctx);
+ void OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx);
void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
void OpenDataStorageByDataId(Kernel::HLERequestContext& ctx);
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 8fb907072..9d804652e 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -12,6 +12,7 @@
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/handle_table.h"
+#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/server_port.h"
#include "core/hle/kernel/thread.h"
@@ -114,7 +115,7 @@ void ServiceFrameworkBase::InstallAsNamedPort() {
std::tie(server_port, client_port) =
ServerPort::CreatePortPair(kernel, max_sessions, service_name);
server_port->SetHleHandler(shared_from_this());
- AddNamedPort(service_name, std::move(client_port));
+ kernel.AddNamedPort(service_name, std::move(client_port));
}
Kernel::SharedPtr<Kernel::ClientPort> ServiceFrameworkBase::CreatePort() {
@@ -197,11 +198,6 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& co
////////////////////////////////////////////////////////////////////////////////////////////////////
// Module interface
-// TODO(yuriks): Move to kernel
-void AddNamedPort(std::string name, SharedPtr<ClientPort> port) {
- g_kernel_named_ports.emplace(std::move(name), std::move(port));
-}
-
/// Initialize ServiceManager
void Init(std::shared_ptr<SM::ServiceManager>& sm, const FileSys::VirtualFilesystem& rfs) {
// NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it
@@ -264,7 +260,6 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, const FileSys::VirtualFilesys
/// Shutdown ServiceManager
void Shutdown() {
- g_kernel_named_ports.clear();
LOG_DEBUG(Service, "shutdown OK");
}
} // namespace Service
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index cd9c74f3d..7a051523e 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -6,7 +6,6 @@
#include <cstddef>
#include <string>
-#include <unordered_map>
#include <boost/container/flat_map.hpp>
#include "common/common_types.h"
#include "core/hle/kernel/hle_ipc.h"
@@ -187,10 +186,4 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm,
/// Shutdown ServiceManager
void Shutdown();
-/// Map of named ports managed by the kernel, which can be retrieved using the ConnectToPort SVC.
-extern std::unordered_map<std::string, Kernel::SharedPtr<Kernel::ClientPort>> g_kernel_named_ports;
-
-/// Adds a port to the named port table
-void AddNamedPort(std::string name, Kernel::SharedPtr<Kernel::ClientPort> port);
-
} // namespace Service
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index c13fb49b8..5980cdb25 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -5,9 +5,9 @@
#include <memory>
#include <ostream>
#include <string>
+#include "common/file_util.h"
#include "common/logging/log.h"
#include "common/string_util.h"
-#include "core/file_sys/vfs_real.h"
#include "core/hle/kernel/process.h"
#include "core/loader/deconstructed_rom_directory.h"
#include "core/loader/elf.h"
@@ -144,6 +144,9 @@ std::ostream& operator<<(std::ostream& os, ResultStatus status) {
return os;
}
+AppLoader::AppLoader(FileSys::VirtualFile file) : file(std::move(file)) {}
+AppLoader::~AppLoader() = default;
+
/**
* Get a loader for a file with a specific type
* @param file The file to load
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h
index 885fee84c..5a8540b0e 100644
--- a/src/core/loader/loader.h
+++ b/src/core/loader/loader.h
@@ -4,7 +4,6 @@
#pragma once
-#include <algorithm>
#include <iosfwd>
#include <memory>
#include <string>
@@ -12,7 +11,6 @@
#include <vector>
#include <boost/optional.hpp>
#include "common/common_types.h"
-#include "common/file_util.h"
#include "core/file_sys/vfs.h"
#include "core/hle/kernel/object.h"
@@ -114,8 +112,8 @@ std::ostream& operator<<(std::ostream& os, ResultStatus status);
/// Interface for loading an application
class AppLoader : NonCopyable {
public:
- explicit AppLoader(FileSys::VirtualFile file) : file(std::move(file)) {}
- virtual ~AppLoader() {}
+ explicit AppLoader(FileSys::VirtualFile file);
+ virtual ~AppLoader();
/**
* Returns the type of this file
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 68ff1e86b..e63ad4d46 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -5,6 +5,7 @@
#include <cinttypes>
#include "common/assert.h"
#include "core/core.h"
+#include "core/core_timing.h"
#include "core/memory.h"
#include "video_core/debug_utils/debug_utils.h"
#include "video_core/engines/maxwell_3d.h"
@@ -194,8 +195,8 @@ void Maxwell3D::ProcessQueryGet() {
// wait queues.
LongQueryResult query_result{};
query_result.value = result;
- // TODO(Subv): Generate a real GPU timestamp and write it here instead of 0
- query_result.timestamp = 0;
+ // TODO(Subv): Generate a real GPU timestamp and write it here instead of CoreTiming
+ query_result.timestamp = CoreTiming::GetTicks();
Memory::WriteBlock(*address, &query_result, sizeof(query_result));
}
break;
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 3e4efbe0c..a7daea766 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -243,7 +243,8 @@ enum class TextureType : u64 {
TextureCube = 3,
};
-enum class IpaMode : u64 { Pass = 0, None = 1, Constant = 2, Sc = 3 };
+enum class IpaInterpMode : u64 { Linear = 0, Perspective = 1, Flat = 2, Sc = 3 };
+enum class IpaSampleMode : u64 { Default = 0, Centroid = 1, Offset = 2 };
union Instruction {
Instruction& operator=(const Instruction& instr) {
@@ -328,10 +329,16 @@ union Instruction {
} alu;
union {
- BitField<54, 3, IpaMode> mode;
+ BitField<51, 1, u64> saturate;
+ BitField<52, 2, IpaSampleMode> sample_mode;
+ BitField<54, 2, IpaInterpMode> interp_mode;
} ipa;
union {
+ BitField<39, 2, u64> tab5cb8_2;
+ BitField<41, 3, u64> tab5c68_1;
+ BitField<44, 2, u64> tab5c68_0;
+ BitField<47, 1, u64> cc;
BitField<48, 1, u64> negate_b;
} fmul;
@@ -399,8 +406,11 @@ union Instruction {
} flow;
union {
+ BitField<47, 1, u64> cc;
BitField<48, 1, u64> negate_b;
BitField<49, 1, u64> negate_c;
+ BitField<51, 2, u64> tab5980_1;
+ BitField<53, 2, u64> tab5980_0;
} ffma;
union {
@@ -509,6 +519,7 @@ union Instruction {
union {
BitField<0, 8, Register> gpr0;
BitField<28, 8, Register> gpr28;
+ BitField<49, 1, u64> nodep;
BitField<50, 3, u64> component_mask_selector;
BitField<53, 4, u64> texture_info;
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 391c92d47..c4e7e1e3b 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -887,6 +887,8 @@ private:
// TEXS has two destination registers and a swizzle. The first two elements in the swizzle
// go into gpr0+0 and gpr0+1, and the rest goes into gpr28+0 and gpr28+1
+ ASSERT_MSG(instr.texs.nodep == 0, "TEXS nodep not implemented");
+
size_t written_components = 0;
for (u32 component = 0; component < 4; ++component) {
if (!instr.texs.IsComponentEnabled(component)) {
@@ -1038,6 +1040,15 @@ private:
case OpCode::Id::FMUL_R:
case OpCode::Id::FMUL_IMM: {
// FMUL does not have 'abs' bits and only the second operand has a 'neg' bit.
+ ASSERT_MSG(instr.fmul.tab5cb8_2 == 0, "FMUL tab5cb8_2({}) is not implemented",
+ instr.fmul.tab5cb8_2.Value());
+ ASSERT_MSG(instr.fmul.tab5c68_1 == 0, "FMUL tab5cb8_1({}) is not implemented",
+ instr.fmul.tab5c68_1.Value());
+ ASSERT_MSG(instr.fmul.tab5c68_0 == 1, "FMUL tab5cb8_0({}) is not implemented",
+ instr.fmul.tab5c68_0
+ .Value()); // SMO typical sends 1 here which seems to be the default
+ ASSERT_MSG(instr.fmul.cc == 0, "FMUL cc is not implemented");
+
op_b = GetOperandAbsNeg(op_b, false, instr.fmul.negate_b);
regs.SetRegisterToFloat(instr.gpr0, 0, op_a + " * " + op_b, 1, 1,
instr.alu.saturate_d);
@@ -1436,6 +1447,12 @@ private:
std::string op_b = instr.ffma.negate_b ? "-" : "";
std::string op_c = instr.ffma.negate_c ? "-" : "";
+ ASSERT_MSG(instr.ffma.cc == 0, "FFMA cc not implemented");
+ ASSERT_MSG(instr.ffma.tab5980_0 == 1, "FFMA tab5980_0({}) not implemented",
+ instr.ffma.tab5980_0.Value()); // Seems to be 1 by default based on SMO
+ ASSERT_MSG(instr.ffma.tab5980_1 == 0, "FFMA tab5980_1({}) not implemented",
+ instr.ffma.tab5980_1.Value());
+
switch (opcode->GetId()) {
case OpCode::Id::FFMA_CR: {
op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
@@ -2110,8 +2127,12 @@ private:
case OpCode::Id::IPA: {
const auto& attribute = instr.attribute.fmt28;
const auto& reg = instr.gpr0;
- switch (instr.ipa.mode) {
- case Tegra::Shader::IpaMode::Pass:
+ ASSERT_MSG(instr.ipa.sample_mode == Tegra::Shader::IpaSampleMode::Default,
+ "Unhandled IPA sample mode: {}",
+ static_cast<u32>(instr.ipa.sample_mode.Value()));
+ ASSERT_MSG(instr.ipa.saturate == 0, "IPA saturate not implemented");
+ switch (instr.ipa.interp_mode) {
+ case Tegra::Shader::IpaInterpMode::Linear:
if (stage == Maxwell3D::Regs::ShaderStage::Fragment &&
attribute.index == Attribute::Index::Position) {
switch (attribute.element) {
@@ -2132,12 +2153,12 @@ private:
regs.SetRegisterToInputAttibute(reg, attribute.element, attribute.index);
}
break;
- case Tegra::Shader::IpaMode::None:
+ case Tegra::Shader::IpaInterpMode::Perspective:
regs.SetRegisterToInputAttibute(reg, attribute.element, attribute.index);
break;
default:
LOG_CRITICAL(HW_GPU, "Unhandled IPA mode: {}",
- static_cast<u32>(instr.ipa.mode.Value()));
+ static_cast<u32>(instr.ipa.interp_mode.Value()));
UNREACHABLE();
regs.SetRegisterToInputAttibute(reg, attribute.element, attribute.index);
}
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index d15242d59..a3f4d9421 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -16,8 +16,9 @@
#include <boost/container/flat_map.hpp>
#include <fmt/format.h>
#include "common/common_paths.h"
+#include "common/common_types.h"
+#include "common/file_util.h"
#include "common/logging/log.h"
-#include "common/string_util.h"
#include "core/file_sys/content_archive.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/registered_cache.h"
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h
index 6a5c2f5f8..84731464a 100644
--- a/src/yuzu/game_list.h
+++ b/src/yuzu/game_list.h
@@ -20,6 +20,8 @@
#include <QVBoxLayout>
#include <QWidget>
+#include "common/common_types.h"
+
class GameListWorker;
class GMainWindow;
diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h
index 3624cb21a..4ddd8cd88 100644
--- a/src/yuzu/game_list_p.h
+++ b/src/yuzu/game_list_p.h
@@ -4,18 +4,23 @@
#pragma once
+#include <algorithm>
#include <array>
#include <atomic>
#include <map>
#include <memory>
+#include <string>
#include <unordered_map>
#include <utility>
+
#include <QCoreApplication>
#include <QImage>
#include <QObject>
#include <QRunnable>
#include <QStandardItem>
#include <QString>
+
+#include "common/common_types.h"
#include "common/logging/log.h"
#include "common/string_util.h"
#include "yuzu/ui_settings.h"
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index e11ba7854..fd73b8541 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -18,6 +18,7 @@
#include <QtWidgets>
#include <fmt/format.h>
#include "common/common_paths.h"
+#include "common/file_util.h"
#include "common/logging/backend.h"
#include "common/logging/filter.h"
#include "common/logging/log.h"
@@ -419,7 +420,7 @@ void GMainWindow::OnDisplayTitleBars(bool show) {
}
}
-bool GMainWindow::SupportsRequiredGLExtensions() {
+QStringList GMainWindow::GetUnsupportedGLExtensions() {
QStringList unsupported_ext;
if (!GLAD_GL_ARB_program_interface_query)
@@ -446,7 +447,7 @@ bool GMainWindow::SupportsRequiredGLExtensions() {
for (const QString& ext : unsupported_ext)
LOG_CRITICAL(Frontend, "Unsupported GL extension: {}", ext.toStdString());
- return unsupported_ext.empty();
+ return unsupported_ext;
}
bool GMainWindow::LoadROM(const QString& filename) {
@@ -464,11 +465,13 @@ bool GMainWindow::LoadROM(const QString& filename) {
return false;
}
- if (!SupportsRequiredGLExtensions()) {
- QMessageBox::critical(
- this, tr("Error while initializing OpenGL Core!"),
- tr("Your GPU may not support one or more required OpenGL extensions. Please "
- "ensure you have the latest graphics driver. See the log for more details."));
+ QStringList unsupported_gl_extensions = GetUnsupportedGLExtensions();
+ if (!unsupported_gl_extensions.empty()) {
+ QMessageBox::critical(this, tr("Error while initializing OpenGL Core!"),
+ tr("Your GPU may not support one or more required OpenGL"
+ "extensions. Please ensure you have the latest graphics "
+ "driver.<br><br>Unsupported extensions:<br>") +
+ unsupported_gl_extensions.join("<br>"));
return false;
}
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 0b97e8220..29bc6e004 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -6,8 +6,11 @@
#include <memory>
#include <unordered_map>
+
#include <QMainWindow>
#include <QTimer>
+
+#include "common/common_types.h"
#include "core/core.h"
#include "ui_main.h"
#include "yuzu/hotkeys.h"
@@ -85,7 +88,7 @@ private:
void ConnectWidgetEvents();
void ConnectMenuEvents();
- bool SupportsRequiredGLExtensions();
+ QStringList GetUnsupportedGLExtensions();
bool LoadROM(const QString& filename);
void BootGame(const QString& filename);
void ShutdownGame();
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index 41e7da897..173ac0e0f 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -10,6 +10,7 @@
#include <fmt/ostream.h>
#include "common/common_paths.h"
+#include "common/file_util.h"
#include "common/logging/backend.h"
#include "common/logging/filter.h"
#include "common/logging/log.h"