diff options
34 files changed, 204 insertions, 70 deletions
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp index ad9e2915c..dbae75d8c 100644 --- a/src/audio_core/stream.cpp +++ b/src/audio_core/stream.cpp @@ -10,6 +10,7 @@  #include "audio_core/stream.h"  #include "common/assert.h"  #include "common/logging/log.h" +#include "common/microprofile.h"  #include "core/core_timing.h"  #include "core/core_timing_util.h"  #include "core/settings.h" @@ -94,7 +95,10 @@ void Stream::PlayNextBuffer() {      CoreTiming::ScheduleEventThreadsafe(GetBufferReleaseCycles(*active_buffer), release_event, {});  } +MICROPROFILE_DEFINE(AudioOutput, "Audio", "ReleaseActiveBuffer", MP_RGB(100, 100, 255)); +  void Stream::ReleaseActiveBuffer() { +    MICROPROFILE_SCOPE(AudioOutput);      ASSERT(active_buffer);      released_buffers.push(std::move(active_buffer));      release_callback(); diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index de44ccebd..b47f04988 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -7,6 +7,7 @@  #include <dynarmic/A64/a64.h>  #include <dynarmic/A64/config.h>  #include "common/logging/log.h" +#include "common/microprofile.h"  #include "core/arm/dynarmic/arm_dynarmic.h"  #include "core/core.h"  #include "core/core_cpu.h" @@ -143,7 +144,10 @@ std::unique_ptr<Dynarmic::A64::Jit> ARM_Dynarmic::MakeJit() const {      return std::make_unique<Dynarmic::A64::Jit>(config);  } +MICROPROFILE_DEFINE(ARM_Jit_Dynarmic, "ARM JIT", "Dynarmic", MP_RGB(255, 64, 64)); +  void ARM_Dynarmic::Run() { +    MICROPROFILE_SCOPE(ARM_Jit_Dynarmic);      ASSERT(Memory::GetCurrentPageTable() == current_page_table);      jit->Run(); diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp index 307f12198..4c4de2623 100644 --- a/src/core/arm/unicorn/arm_unicorn.cpp +++ b/src/core/arm/unicorn/arm_unicorn.cpp @@ -193,10 +193,10 @@ void ARM_Unicorn::Step() {      ExecuteInstructions(1);  } -MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64)); +MICROPROFILE_DEFINE(ARM_Jit_Unicorn, "ARM JIT", "Unicorn", MP_RGB(255, 64, 64));  void ARM_Unicorn::ExecuteInstructions(int num_instructions) { -    MICROPROFILE_SCOPE(ARM_Jit); +    MICROPROFILE_SCOPE(ARM_Jit_Unicorn);      CHECKED(uc_emu_start(uc, GetPC(), 1ULL << 63, 0, num_instructions));      CoreTiming::AddTicks(num_instructions);      if (GDBStub::IsServerEnabled()) { diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index 0b6c07de8..f768533da 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp @@ -8,12 +8,15 @@  #include <locale>  #include <sstream>  #include <string_view> +#include <tuple> +#include <vector>  #include "common/common_paths.h"  #include "common/file_util.h"  #include "common/hex_util.h"  #include "common/logging/log.h"  #include "core/crypto/aes_util.h"  #include "core/crypto/key_manager.h" +#include "core/loader/loader.h"  #include "core/settings.h"  namespace Core::Crypto { diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h index 7ca3e6cbc..bf51bf31f 100644 --- a/src/core/crypto/key_manager.h +++ b/src/core/crypto/key_manager.h @@ -6,13 +6,14 @@  #include <array>  #include <string> -#include <string_view> -#include <type_traits> -#include <vector>  #include <boost/container/flat_map.hpp> +#include <boost/optional.hpp>  #include <fmt/format.h>  #include "common/common_types.h" -#include "core/loader/loader.h" + +namespace Loader { +enum class ResultStatus : u16; +}  namespace Core::Crypto { diff --git a/src/core/file_sys/bis_factory.cpp b/src/core/file_sys/bis_factory.cpp index 08a7cea5a..205492897 100644 --- a/src/core/file_sys/bis_factory.cpp +++ b/src/core/file_sys/bis_factory.cpp @@ -3,6 +3,7 @@  // Refer to the license.txt file included.  #include "core/file_sys/bis_factory.h" +#include "core/file_sys/registered_cache.h"  namespace FileSys { @@ -13,6 +14,8 @@ BISFactory::BISFactory(VirtualDir nand_root_)        usrnand_cache(std::make_shared<RegisteredCache>(            GetOrCreateDirectoryRelative(nand_root, "/user/Contents/registered"))) {} +BISFactory::~BISFactory() = default; +  std::shared_ptr<RegisteredCache> BISFactory::GetSystemNANDContents() const {      return sysnand_cache;  } diff --git a/src/core/file_sys/bis_factory.h b/src/core/file_sys/bis_factory.h index a970a5e2e..9523dd864 100644 --- a/src/core/file_sys/bis_factory.h +++ b/src/core/file_sys/bis_factory.h @@ -5,17 +5,20 @@  #pragma once  #include <memory> -#include "core/loader/loader.h" -#include "registered_cache.h" + +#include "core/file_sys/vfs.h"  namespace FileSys { +class RegisteredCache; +  /// File system interface to the Built-In Storage  /// This is currently missing accessors to BIS partitions, but seemed like a good place for the NAND  /// registered caches.  class BISFactory {  public:      explicit BISFactory(VirtualDir nand_root); +    ~BISFactory();      std::shared_ptr<RegisteredCache> GetSystemNANDContents() const;      std::shared_ptr<RegisteredCache> GetUserNANDContents() const; diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp index d61a2ebe1..ce4423fa6 100644 --- a/src/core/file_sys/card_image.cpp +++ b/src/core/file_sys/card_image.cpp @@ -9,6 +9,7 @@  #include "common/logging/log.h"  #include "core/file_sys/card_image.h" +#include "core/file_sys/content_archive.h"  #include "core/file_sys/partition_filesystem.h"  #include "core/file_sys/vfs_offset.h"  #include "core/loader/loader.h" @@ -74,6 +75,8 @@ XCI::XCI(VirtualFile file_) : file(std::move(file_)), partitions(0x4) {      status = Loader::ResultStatus::Success;  } +XCI::~XCI() = default; +  Loader::ResultStatus XCI::GetStatus() const {      return status;  } diff --git a/src/core/file_sys/card_image.h b/src/core/file_sys/card_image.h index 54ab828d1..4f104d18a 100644 --- a/src/core/file_sys/card_image.h +++ b/src/core/file_sys/card_image.h @@ -5,15 +5,21 @@  #pragma once  #include <array> +#include <memory>  #include <vector>  #include "common/common_types.h"  #include "common/swap.h" -#include "core/file_sys/content_archive.h"  #include "core/file_sys/vfs.h" -#include "core/loader/loader.h" + +namespace Loader { +enum class ResultStatus : u16; +}  namespace FileSys { +class NCA; +enum class NCAContentType : u8; +  enum class GamecardSize : u8 {      S_1GB = 0xFA,      S_2GB = 0xF8, @@ -57,6 +63,7 @@ enum class XCIPartition : u8 { Update, Normal, Secure, Logo };  class XCI : public ReadOnlyVfsDirectory {  public:      explicit XCI(VirtualFile file); +    ~XCI() override;      Loader::ResultStatus GetStatus() const;      Loader::ResultStatus GetProgramNCAStatus() const; diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index e8b5d6ece..7cfb6f36b 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp @@ -3,12 +3,16 @@  // Refer to the license.txt file included.  #include <algorithm> +#include <cstring>  #include <utility> +  #include <boost/optional.hpp> +  #include "common/logging/log.h"  #include "core/crypto/aes_util.h"  #include "core/crypto/ctr_encryption_layer.h"  #include "core/file_sys/content_archive.h" +#include "core/file_sys/partition_filesystem.h"  #include "core/file_sys/romfs.h"  #include "core/file_sys/vfs_offset.h"  #include "core/loader/loader.h" diff --git a/src/core/file_sys/content_archive.h b/src/core/file_sys/content_archive.h index b961cfde7..0ea666cac 100644 --- a/src/core/file_sys/content_archive.h +++ b/src/core/file_sys/content_archive.h @@ -12,10 +12,12 @@  #include "common/common_funcs.h"  #include "common/common_types.h"  #include "common/swap.h" -#include "control_metadata.h"  #include "core/crypto/key_manager.h" -#include "core/file_sys/partition_filesystem.h" -#include "core/loader/loader.h" +#include "core/file_sys/vfs.h" + +namespace Loader { +enum class ResultStatus : u16; +}  namespace FileSys { diff --git a/src/core/file_sys/control_metadata.h b/src/core/file_sys/control_metadata.h index 8c2cc1a2a..1568046f1 100644 --- a/src/core/file_sys/control_metadata.h +++ b/src/core/file_sys/control_metadata.h @@ -8,6 +8,7 @@  #include <memory>  #include <string>  #include "common/common_funcs.h" +#include "common/common_types.h"  #include "core/file_sys/vfs.h"  namespace FileSys { diff --git a/src/core/file_sys/nca_metadata.cpp b/src/core/file_sys/nca_metadata.cpp index 449244444..cdfbc5aaf 100644 --- a/src/core/file_sys/nca_metadata.cpp +++ b/src/core/file_sys/nca_metadata.cpp @@ -3,10 +3,9 @@  // Refer to the license.txt file included.  #include <cstring> -#include "common/common_funcs.h" +#include "common/common_types.h"  #include "common/logging/log.h"  #include "common/swap.h" -#include "content_archive.h"  #include "core/file_sys/nca_metadata.h"  namespace FileSys { diff --git a/src/core/file_sys/nca_metadata.h b/src/core/file_sys/nca_metadata.h index ce05b4c1d..da5a8dbe8 100644 --- a/src/core/file_sys/nca_metadata.h +++ b/src/core/file_sys/nca_metadata.h @@ -4,7 +4,6 @@  #pragma once -#include <cstring>  #include <memory>  #include <vector>  #include "common/common_funcs.h" diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp index 279f987d4..ccb685526 100644 --- a/src/core/file_sys/program_metadata.cpp +++ b/src/core/file_sys/program_metadata.cpp @@ -2,7 +2,10 @@  // Licensed under GPLv2 or any later version  // Refer to the license.txt file included. -#include "common/file_util.h" +#include <cstddef> +#include <cstring> +#include <vector> +  #include "common/logging/log.h"  #include "core/file_sys/program_metadata.h"  #include "core/loader/loader.h" diff --git a/src/core/file_sys/program_metadata.h b/src/core/file_sys/program_metadata.h index 74a91052b..3c0a49f16 100644 --- a/src/core/file_sys/program_metadata.h +++ b/src/core/file_sys/program_metadata.h @@ -5,12 +5,10 @@  #pragma once  #include <array> -#include <string> -#include <vector>  #include "common/bit_field.h"  #include "common/common_types.h"  #include "common/swap.h" -#include "partition_filesystem.h" +#include "core/file_sys/vfs.h"  namespace Loader {  enum class ResultStatus : u16; diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index fe5d36930..d9decc104 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp @@ -8,10 +8,13 @@  #include "common/file_util.h"  #include "common/hex_util.h"  #include "common/logging/log.h" +#include "core/crypto/key_manager.h"  #include "core/file_sys/card_image.h" +#include "core/file_sys/content_archive.h"  #include "core/file_sys/nca_metadata.h"  #include "core/file_sys/registered_cache.h"  #include "core/file_sys/vfs_concat.h" +#include "core/loader/loader.h"  namespace FileSys {  std::string RegisteredCacheEntry::DebugInfo() const { diff --git a/src/core/file_sys/registered_cache.h b/src/core/file_sys/registered_cache.h index 7b8955dfa..fe2cdc3d9 100644 --- a/src/core/file_sys/registered_cache.h +++ b/src/core/file_sys/registered_cache.h @@ -11,15 +11,18 @@  #include <string>  #include <vector>  #include <boost/container/flat_map.hpp> -#include "common/common_funcs.h"  #include "common/common_types.h" -#include "content_archive.h" -#include "core/file_sys/nca_metadata.h"  #include "core/file_sys/vfs.h"  namespace FileSys { -class XCI;  class CNMT; +class NCA; +class XCI; + +enum class ContentRecordType : u8; +enum class TitleType : u8; + +struct ContentRecord;  using NcaID = std::array<u8, 0x10>;  using RegisteredCacheParsingFunction = std::function<VirtualFile(const VirtualFile&, const NcaID&)>; diff --git a/src/core/file_sys/romfs.h b/src/core/file_sys/romfs.h index 03a876d22..e54a7d7a9 100644 --- a/src/core/file_sys/romfs.h +++ b/src/core/file_sys/romfs.h @@ -6,6 +6,7 @@  #include <array>  #include "common/common_funcs.h" +#include "common/common_types.h"  #include "common/swap.h"  #include "core/file_sys/vfs.h" diff --git a/src/core/file_sys/romfs_factory.cpp b/src/core/file_sys/romfs_factory.cpp index eb4e6c865..66f9786e0 100644 --- a/src/core/file_sys/romfs_factory.cpp +++ b/src/core/file_sys/romfs_factory.cpp @@ -2,14 +2,13 @@  // Licensed under GPLv2 or any later version  // Refer to the license.txt file included. -#include <algorithm>  #include <memory> +#include "common/assert.h"  #include "common/common_types.h"  #include "common/logging/log.h" -#include "core/file_sys/nca_metadata.h" +#include "core/file_sys/content_archive.h"  #include "core/file_sys/registered_cache.h"  #include "core/file_sys/romfs_factory.h" -#include "core/hle/kernel/process.h"  #include "core/hle/service/filesystem/filesystem.h"  #include "core/loader/loader.h" diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index 952bd74b3..e437d34e5 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp @@ -3,6 +3,7 @@  // Refer to the license.txt file included.  #include <memory> +#include "common/assert.h"  #include "common/common_types.h"  #include "common/logging/log.h"  #include "core/core.h" diff --git a/src/core/file_sys/savedata_factory.h b/src/core/file_sys/savedata_factory.h index c6f9549f0..ba978695b 100644 --- a/src/core/file_sys/savedata_factory.h +++ b/src/core/file_sys/savedata_factory.h @@ -6,6 +6,7 @@  #include <memory>  #include <string> +#include "common/common_funcs.h"  #include "common/common_types.h"  #include "common/swap.h"  #include "core/file_sys/vfs.h" diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index 51638793d..878bbe439 100644 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp @@ -5,7 +5,9 @@  #include "common/common_paths.h"  #include "common/file_util.h"  #include "core/core.h" -#include "core/file_sys/bis_factory.h" +#include "core/file_sys/content_archive.h" +#include "core/file_sys/nca_metadata.h" +#include "core/file_sys/registered_cache.h"  #include "core/file_sys/romfs.h"  #include "core/hle/ipc_helpers.h"  #include "core/hle/service/filesystem/filesystem.h" diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp index 40aea6090..63b86e099 100644 --- a/src/core/hle/service/ssl/ssl.cpp +++ b/src/core/hle/service/ssl/ssl.cpp @@ -3,6 +3,9 @@  // Refer to the license.txt file included.  #include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/hle_ipc.h" +#include "core/hle/service/service.h" +#include "core/hle/service/sm/sm.h"  #include "core/hle/service/ssl/ssl.h"  namespace Service::SSL { @@ -81,36 +84,43 @@ private:      }  }; -void SSL::CreateContext(Kernel::HLERequestContext& ctx) { -    LOG_WARNING(Service_SSL, "(STUBBED) called"); +class SSL final : public ServiceFramework<SSL> { +public: +    explicit SSL() : ServiceFramework{"ssl"} { +        // clang-format off +        static const FunctionInfo functions[] = { +            {0, &SSL::CreateContext, "CreateContext"}, +            {1, nullptr, "GetContextCount"}, +            {2, nullptr, "GetCertificates"}, +            {3, nullptr, "GetCertificateBufSize"}, +            {4, nullptr, "DebugIoctl"}, +            {5, &SSL::SetInterfaceVersion, "SetInterfaceVersion"}, +            {6, nullptr, "FlushSessionCache"}, +        }; +        // clang-format on -    IPC::ResponseBuilder rb{ctx, 2, 0, 1}; -    rb.Push(RESULT_SUCCESS); -    rb.PushIpcInterface<ISslContext>(); -} +        RegisterHandlers(functions); +    } -SSL::SSL() : ServiceFramework("ssl") { -    static const FunctionInfo functions[] = { -        {0, &SSL::CreateContext, "CreateContext"}, -        {1, nullptr, "GetContextCount"}, -        {2, nullptr, "GetCertificates"}, -        {3, nullptr, "GetCertificateBufSize"}, -        {4, nullptr, "DebugIoctl"}, -        {5, &SSL::SetInterfaceVersion, "SetInterfaceVersion"}, -        {6, nullptr, "FlushSessionCache"}, -    }; -    RegisterHandlers(functions); -} +private: +    void CreateContext(Kernel::HLERequestContext& ctx) { +        LOG_WARNING(Service_SSL, "(STUBBED) called"); -void SSL::SetInterfaceVersion(Kernel::HLERequestContext& ctx) { -    LOG_WARNING(Service_SSL, "(STUBBED) called"); -    IPC::RequestParser rp{ctx}; -    u32 unk1 = rp.Pop<u32>(); // Probably minor/major? -    u32 unk2 = rp.Pop<u32>(); // TODO(ogniK): Figure out what this does +        IPC::ResponseBuilder rb{ctx, 2, 0, 1}; +        rb.Push(RESULT_SUCCESS); +        rb.PushIpcInterface<ISslContext>(); +    } -    IPC::ResponseBuilder rb{ctx, 2}; -    rb.Push(RESULT_SUCCESS); -} +    void SetInterfaceVersion(Kernel::HLERequestContext& ctx) { +        LOG_WARNING(Service_SSL, "(STUBBED) called"); +        IPC::RequestParser rp{ctx}; +        u32 unk1 = rp.Pop<u32>(); // Probably minor/major? +        u32 unk2 = rp.Pop<u32>(); // TODO(ogniK): Figure out what this does + +        IPC::ResponseBuilder rb{ctx, 2}; +        rb.Push(RESULT_SUCCESS); +    } +};  void InstallInterfaces(SM::ServiceManager& service_manager) {      std::make_shared<SSL>()->InstallAsService(service_manager); diff --git a/src/core/hle/service/ssl/ssl.h b/src/core/hle/service/ssl/ssl.h index 8fef13022..5cb04c3b9 100644 --- a/src/core/hle/service/ssl/ssl.h +++ b/src/core/hle/service/ssl/ssl.h @@ -4,20 +4,12 @@  #pragma once -#include "core/hle/service/service.h" +namespace Service::SM { +class ServiceManager; +}  namespace Service::SSL { -class SSL final : public ServiceFramework<SSL> { -public: -    explicit SSL(); -    ~SSL() = default; - -private: -    void CreateContext(Kernel::HLERequestContext& ctx); -    void SetInterfaceVersion(Kernel::HLERequestContext& ctx); -}; -  /// Registers all SSL services with the specified service manager.  void InstallInterfaces(SM::ServiceManager& service_manager); diff --git a/src/core/settings.h b/src/core/settings.h index ed6f42471..5bf1863e6 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -127,6 +127,8 @@ struct Values {      // Data Storage      bool use_virtual_sd; +    std::string nand_dir; +    std::string sdmc_dir;      // Renderer      float resolution_factor; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 7ce969f73..e260c9140 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -33,10 +33,13 @@ using PixelFormat = SurfaceParams::PixelFormat;  using SurfaceType = SurfaceParams::SurfaceType;  MICROPROFILE_DEFINE(OpenGL_VAO, "OpenGL", "Vertex Array Setup", MP_RGB(128, 128, 192)); -MICROPROFILE_DEFINE(OpenGL_VS, "OpenGL", "Vertex Shader Setup", MP_RGB(128, 128, 192)); -MICROPROFILE_DEFINE(OpenGL_FS, "OpenGL", "Fragment Shader Setup", MP_RGB(128, 128, 192)); +MICROPROFILE_DEFINE(OpenGL_Shader, "OpenGL", "Shader Setup", MP_RGB(128, 128, 192)); +MICROPROFILE_DEFINE(OpenGL_UBO, "OpenGL", "Const Buffer Setup", MP_RGB(128, 128, 192)); +MICROPROFILE_DEFINE(OpenGL_Index, "OpenGL", "Index Buffer Setup", MP_RGB(128, 128, 192)); +MICROPROFILE_DEFINE(OpenGL_Texture, "OpenGL", "Texture Setup", MP_RGB(128, 128, 192)); +MICROPROFILE_DEFINE(OpenGL_Framebuffer, "OpenGL", "Framebuffer Setup", MP_RGB(128, 128, 192));  MICROPROFILE_DEFINE(OpenGL_Drawing, "OpenGL", "Drawing", MP_RGB(128, 128, 192)); -MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255)); +MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(128, 128, 192));  MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100));  RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window, ScreenInfo& info) @@ -179,6 +182,7 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr,  }  std::pair<u8*, GLintptr> RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { +    MICROPROFILE_SCOPE(OpenGL_Shader);      auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();      // Next available bindpoints to use when uploading the const buffers and textures to the GLSL @@ -312,6 +316,7 @@ void RasterizerOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {  std::pair<Surface, Surface> RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb,                                                                      bool using_depth_fb,                                                                      bool preserve_contents) { +    MICROPROFILE_SCOPE(OpenGL_Framebuffer);      const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;      if (regs.rt[0].format == Tegra::RenderTargetFormat::NONE) { @@ -512,6 +517,7 @@ void RasterizerOpenGL::DrawArrays() {      // If indexed mode, copy the index buffer      GLintptr index_buffer_offset = 0;      if (is_indexed) { +        MICROPROFILE_SCOPE(OpenGL_Index);          std::tie(buffer_ptr, buffer_offset, index_buffer_offset) = UploadMemory(              buffer_ptr, buffer_offset, regs.index_array.StartAddress(), index_buffer_size);      } @@ -657,6 +663,7 @@ std::tuple<u8*, GLintptr, u32> RasterizerOpenGL::SetupConstBuffers(u8* buffer_pt                                                                     Maxwell::ShaderStage stage,                                                                     Shader& shader,                                                                     u32 current_bindpoint) { +    MICROPROFILE_SCOPE(OpenGL_UBO);      const auto& gpu = Core::System::GetInstance().GPU();      const auto& maxwell3d = gpu.Maxwell3D();      const auto& shader_stage = maxwell3d.state.shader_stages[static_cast<size_t>(stage)]; @@ -712,6 +719,7 @@ std::tuple<u8*, GLintptr, u32> RasterizerOpenGL::SetupConstBuffers(u8* buffer_pt  }  u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader, u32 current_unit) { +    MICROPROFILE_SCOPE(OpenGL_Texture);      const auto& gpu = Core::System::GetInstance().GPU();      const auto& maxwell3d = gpu.Maxwell3D();      const auto& entries = shader->GetShaderEntries().texture_samplers; diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index c4e7e1e3b..d3e8f5078 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -441,7 +441,7 @@ public:          declarations.AddNewLine();          // Append the sampler2D array for the used textures. -        size_t num_samplers = GetSamplers().size(); +        const size_t num_samplers = used_samplers.size();          if (num_samplers > 0) {              declarations.AddLine("uniform sampler2D " + SamplerEntry::GetArrayName(stage) + '[' +                                   std::to_string(num_samplers) + "];"); diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 60b6d6d44..c43e79e78 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -102,6 +102,20 @@ void Config::ReadValues() {      qt_config->beginGroup("Data Storage");      Settings::values.use_virtual_sd = qt_config->value("use_virtual_sd", true).toBool(); +    FileUtil::GetUserPath( +        FileUtil::UserPath::NANDDir, +        qt_config +            ->value("nand_directory", +                    QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir))) +            .toString() +            .toStdString()); +    FileUtil::GetUserPath( +        FileUtil::UserPath::SDMCDir, +        qt_config +            ->value("sdmc_directory", +                    QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir))) +            .toString() +            .toStdString());      qt_config->endGroup();      qt_config->beginGroup("System"); @@ -222,6 +236,10 @@ void Config::SaveValues() {      qt_config->beginGroup("Data Storage");      qt_config->setValue("use_virtual_sd", Settings::values.use_virtual_sd); +    qt_config->setValue("nand_directory", +                        QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir))); +    qt_config->setValue("sdmc_directory", +                        QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir)));      qt_config->endGroup();      qt_config->beginGroup("System"); diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index a3f4d9421..71953cee3 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -13,7 +13,6 @@  #include <QKeyEvent>  #include <QMenu>  #include <QThreadPool> -#include <boost/container/flat_map.hpp>  #include <fmt/format.h>  #include "common/common_paths.h"  #include "common/common_types.h" @@ -21,6 +20,7 @@  #include "common/logging/log.h"  #include "core/file_sys/content_archive.h"  #include "core/file_sys/control_metadata.h" +#include "core/file_sys/nca_metadata.h"  #include "core/file_sys/registered_cache.h"  #include "core/file_sys/romfs.h"  #include "core/file_sys/vfs_real.h" diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index fd73b8541..262e33487 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -12,6 +12,7 @@  #define QT_NO_OPENGL  #include <QDesktopWidget> +#include <QDialogButtonBox>  #include <QFileDialog>  #include <QMessageBox>  #include <QtGui> @@ -30,6 +31,7 @@  #include "core/core.h"  #include "core/crypto/key_manager.h"  #include "core/file_sys/card_image.h" +#include "core/file_sys/content_archive.h"  #include "core/file_sys/registered_cache.h"  #include "core/file_sys/savedata_factory.h"  #include "core/file_sys/vfs_real.h" @@ -373,6 +375,10 @@ void GMainWindow::ConnectMenuEvents() {              &GMainWindow::OnMenuInstallToNAND);      connect(ui.action_Select_Game_List_Root, &QAction::triggered, this,              &GMainWindow::OnMenuSelectGameListRoot); +    connect(ui.action_Select_NAND_Directory, &QAction::triggered, this, +            [this] { OnMenuSelectEmulatedDirectory(EmulatedDirectoryTarget::NAND); }); +    connect(ui.action_Select_SDMC_Directory, &QAction::triggered, this, +            [this] { OnMenuSelectEmulatedDirectory(EmulatedDirectoryTarget::SDMC); });      connect(ui.action_Exit, &QAction::triggered, this, &QMainWindow::close);      // Emulation @@ -888,6 +894,28 @@ void GMainWindow::OnMenuSelectGameListRoot() {      }  } +void GMainWindow::OnMenuSelectEmulatedDirectory(EmulatedDirectoryTarget target) { +    const auto res = QMessageBox::information( +        this, tr("Changing Emulated Directory"), +        tr("You are about to change the emulated %1 directory of the system. Please note " +           "that this does not also move the contents of the previous directory to the " +           "new one and you will have to do that yourself.") +            .arg(target == EmulatedDirectoryTarget::SDMC ? tr("SD card") : tr("NAND")), +        QMessageBox::StandardButtons{QMessageBox::Ok, QMessageBox::Cancel}); + +    if (res == QMessageBox::Cancel) +        return; + +    QString dir_path = QFileDialog::getExistingDirectory(this, tr("Select Directory")); +    if (!dir_path.isEmpty()) { +        FileUtil::GetUserPath(target == EmulatedDirectoryTarget::SDMC ? FileUtil::UserPath::SDMCDir +                                                                      : FileUtil::UserPath::NANDDir, +                              dir_path.toStdString()); +        Service::FileSystem::CreateFactories(vfs); +        game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan); +    } +} +  void GMainWindow::OnMenuRecentFile() {      QAction* action = qobject_cast<QAction*>(sender());      assert(action); diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 29bc6e004..089ea2445 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -35,6 +35,11 @@ namespace Tegra {  class DebugContext;  } +enum class EmulatedDirectoryTarget { +    NAND, +    SDMC, +}; +  class GMainWindow : public QMainWindow {      Q_OBJECT @@ -140,6 +145,8 @@ private slots:      void OnMenuInstallToNAND();      /// Called whenever a user selects the "File->Select Game List Root" menu item      void OnMenuSelectGameListRoot(); +    /// Called whenever a user select the "File->Select -- Directory" where -- is NAND or SD Card +    void OnMenuSelectEmulatedDirectory(EmulatedDirectoryTarget target);      void OnMenuRecentFile();      void OnConfigure();      void OnAbout(); diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui index faa0c626a..3879d4813 100644 --- a/src/yuzu/main.ui +++ b/src/yuzu/main.ui @@ -65,6 +65,9 @@      <addaction name="action_Select_Game_List_Root"/>      <addaction name="menu_recent_files"/>      <addaction name="separator"/> +    <addaction name="action_Select_NAND_Directory"/> +    <addaction name="action_Select_SDMC_Directory"/> +    <addaction name="separator"/>      <addaction name="action_Exit"/>     </widget>     <widget class="QMenu" name="menu_Emulation"> @@ -204,6 +207,22 @@      <string>Selects a folder to display in the game list</string>     </property>    </action> +  <action name="action_Select_NAND_Directory"> +   <property name="text"> +    <string>Select NAND Directory...</string> +   </property> +   <property name="toolTip"> +    <string>Selects a folder to use as the root of the emulated NAND</string> +   </property> +  </action> +  <action name="action_Select_SDMC_Directory"> +   <property name="text"> +    <string>Select SD Card Directory...</string> +   </property> +   <property name="toolTip"> +    <string>Selects a folder to use as the root of the emulated SD card</string> +   </property> +  </action>    <action name="action_Fullscreen">     <property name="checkable">      <bool>true</bool> diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index a95580152..f00b5a66b 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp @@ -114,6 +114,12 @@ void Config::ReadValues() {      // Data Storage      Settings::values.use_virtual_sd =          sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true); +    FileUtil::GetUserPath(FileUtil::UserPath::NANDDir, +                          sdl2_config->Get("Data Storage", "nand_directory", +                                           FileUtil::GetUserPath(FileUtil::UserPath::NANDDir))); +    FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir, +                          sdl2_config->Get("Data Storage", "nand_directory", +                                           FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir)));      // System      Settings::values.use_docked_mode = sdl2_config->GetBoolean("System", "use_docked_mode", false);  | 
