diff options
| -rw-r--r-- | src/core/core.cpp | 4 | ||||
| -rw-r--r-- | src/core/frontend/emu_window.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/video_core.cpp | 4 | ||||
| -rw-r--r-- | src/yuzu/bootmanager.cpp | 97 | ||||
| -rw-r--r-- | src/yuzu/bootmanager.h | 9 | ||||
| -rw-r--r-- | src/yuzu_cmd/yuzu.cpp | 4 | ||||
| -rw-r--r-- | src/yuzu_tester/emu_window/emu_window_sdl2_hide.cpp | 42 | ||||
| -rw-r--r-- | src/yuzu_tester/emu_window/emu_window_sdl2_hide.h | 9 | ||||
| -rw-r--r-- | src/yuzu_tester/yuzu.cpp | 6 | 
11 files changed, 83 insertions, 102 deletions
| diff --git a/src/core/core.cpp b/src/core/core.cpp index 6cc4a0812..26a580cb7 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -169,6 +169,9 @@ struct System::Impl {          interrupt_manager = std::make_unique<Core::Hardware::InterruptManager>(system);          gpu_core = VideoCore::CreateGPU(emu_window, system); +        if (!gpu_core) { +            return ResultStatus::ErrorVideoCore; +        }          gpu_core->Renderer().Rasterizer().SetupDirtyFlags();          is_powered_on = true; @@ -181,7 +184,6 @@ struct System::Impl {      ResultStatus Load(System& system, Frontend::EmuWindow& emu_window,                        const std::string& filepath) { -          app_loader = Loader::GetLoader(GetGameFileFromPath(virtual_filesystem, filepath));          if (!app_loader) {              LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath); diff --git a/src/core/frontend/emu_window.h b/src/core/frontend/emu_window.h index bb283d844..72294d4d8 100644 --- a/src/core/frontend/emu_window.h +++ b/src/core/frontend/emu_window.h @@ -30,7 +30,7 @@ public:      class Scoped {      public: -        Scoped(GraphicsContext& context_) : context(context_) { +        explicit Scoped(GraphicsContext& context_) : context(context_) {              context.MakeCurrent();          }          ~Scoped() { diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 8f59e0442..046ee55a5 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -305,6 +305,7 @@ void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading,      }      const std::vector gl_cache = disk_cache.LoadPrecompiled(); +    const auto supported_formats = GetSupportedFormats();      // Track if precompiled cache was altered during loading to know if we have to      // serialize the virtual precompiled cache file back to the hard drive @@ -327,7 +328,6 @@ void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading,      const auto worker = [&](Core::Frontend::GraphicsContext* context, std::size_t begin,                              std::size_t end) {          const auto scope = context->Acquire(); -        const auto supported_formats = GetSupportedFormats();          for (std::size_t i = begin; i < end; ++i) {              if (stop_loading) { diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 6f08803c1..f1a28cc21 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -7,7 +7,9 @@  #include <cstdlib>  #include <cstring>  #include <memory> +  #include <glad/glad.h> +  #include "common/assert.h"  #include "common/logging/log.h"  #include "common/microprofile.h" @@ -313,8 +315,8 @@ public:  RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system,                                 Core::Frontend::GraphicsContext& context) -    : VideoCore::RendererBase{emu_window}, emu_window{emu_window}, system{system}, frame_mailbox{}, -      has_debug_tool{HasDebugTool()}, context{context} {} +    : VideoCore::RendererBase{emu_window}, emu_window{emu_window}, system{system}, +      frame_mailbox{}, context{context}, has_debug_tool{HasDebugTool()} {}  RendererOpenGL::~RendererOpenGL() = default; diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index fd9fec018..f60bdc60a 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp @@ -30,7 +30,7 @@ std::unique_ptr<VideoCore::RendererBase> CreateRenderer(Core::Frontend::EmuWindo          return nullptr;      }  } -} // namespace +} // Anonymous namespace  namespace VideoCore { @@ -39,7 +39,7 @@ std::unique_ptr<Tegra::GPU> CreateGPU(Core::Frontend::EmuWindow& emu_window, Cor      const auto scope = context->Acquire();      auto renderer = CreateRenderer(emu_window, system, *context);      if (!renderer->Init()) { -        return {}; +        return nullptr;      }      if (Settings::values.use_asynchronous_gpu_emulation) { diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index d120ee818..4e9ced8ba 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -42,6 +42,10 @@ EmuThread::~EmuThread() = default;  void EmuThread::run() {      MicroProfileOnThreadCreate("EmuThread"); +    // Main process has been loaded. Make the context current to this thread and begin GPU and CPU +    // execution. +    Core::System::GetInstance().GPU().Start(); +      emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);      Core::System::GetInstance().Renderer().Rasterizer().LoadDiskResources( @@ -51,10 +55,6 @@ void EmuThread::run() {      emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0); -    // Main process has been loaded. Make the context current to this thread and begin GPU and CPU -    // execution. -    Core::System::GetInstance().GPU().Start(); -      // Holds whether the cpu was running during the last iteration,      // so that the DebugModeLeft signal can be emitted before the      // next execution step @@ -152,7 +152,7 @@ public:          if (is_current) {              return;          } -        context->makeCurrent(surface); +        is_current = context->makeCurrent(surface);      }      void DoneCurrent() override { @@ -160,7 +160,11 @@ public:          is_current = false;      } -    QOpenGLContext* GetShareContext() const { +    QOpenGLContext* GetShareContext() { +        return context.get(); +    } + +    const QOpenGLContext* GetShareContext() const {          return context.get();      } @@ -177,13 +181,15 @@ class DummyContext : public Core::Frontend::GraphicsContext {};  class RenderWidget : public QWidget {  public: -    RenderWidget(GRenderWindow* parent) : QWidget(parent), render_window(parent) { +    explicit RenderWidget(GRenderWindow* parent) : QWidget(parent), render_window(parent) {          setAttribute(Qt::WA_NativeWindow);          setAttribute(Qt::WA_PaintOnScreen);      }      virtual ~RenderWidget() = default; +    /// Called on the UI thread when this Widget is ready to draw +    /// Dervied classes can override this to draw the latest frame.      virtual void Present() {}      void paintEvent(QPaintEvent* event) override { @@ -191,56 +197,6 @@ public:          update();      } -    void resizeEvent(QResizeEvent* ev) override { -        render_window->resize(ev->size()); -        render_window->OnFramebufferSizeChanged(); -    } - -    void keyPressEvent(QKeyEvent* event) override { -        InputCommon::GetKeyboard()->PressKey(event->key()); -    } - -    void keyReleaseEvent(QKeyEvent* event) override { -        InputCommon::GetKeyboard()->ReleaseKey(event->key()); -    } - -    void mousePressEvent(QMouseEvent* event) override { -        if (event->source() == Qt::MouseEventSynthesizedBySystem) -            return; // touch input is handled in TouchBeginEvent - -        const auto pos{event->pos()}; -        if (event->button() == Qt::LeftButton) { -            const auto [x, y] = render_window->ScaleTouch(pos); -            render_window->TouchPressed(x, y); -        } else if (event->button() == Qt::RightButton) { -            InputCommon::GetMotionEmu()->BeginTilt(pos.x(), pos.y()); -        } -    } - -    void mouseMoveEvent(QMouseEvent* event) override { -        if (event->source() == Qt::MouseEventSynthesizedBySystem) -            return; // touch input is handled in TouchUpdateEvent - -        const auto pos{event->pos()}; -        const auto [x, y] = render_window->ScaleTouch(pos); -        render_window->TouchMoved(x, y); -        InputCommon::GetMotionEmu()->Tilt(pos.x(), pos.y()); -    } - -    void mouseReleaseEvent(QMouseEvent* event) override { -        if (event->source() == Qt::MouseEventSynthesizedBySystem) -            return; // touch input is handled in TouchEndEvent - -        if (event->button() == Qt::LeftButton) -            render_window->TouchReleased(); -        else if (event->button() == Qt::RightButton) -            InputCommon::GetMotionEmu()->EndTilt(); -    } - -    std::pair<unsigned, unsigned> GetSize() const { -        return std::make_pair(width(), height()); -    } -      QPaintEngine* paintEngine() const override {          return nullptr;      } @@ -276,6 +232,7 @@ private:      std::unique_ptr<Core::Frontend::GraphicsContext> context{};  }; +#ifdef HAS_VULKAN  class VulkanRenderWidget : public RenderWidget {  public:      explicit VulkanRenderWidget(GRenderWindow* parent, QVulkanInstance* instance) @@ -284,6 +241,7 @@ public:          windowHandle()->setVulkanInstance(instance);      }  }; +#endif  GRenderWindow::GRenderWindow(GMainWindow* parent_, EmuThread* emu_thread)      : QWidget(parent_), emu_thread(emu_thread) { @@ -358,7 +316,7 @@ qreal GRenderWindow::windowPixelRatio() const {      return devicePixelRatio();  } -std::pair<u32, u32> GRenderWindow::ScaleTouch(const QPointF pos) const { +std::pair<u32, u32> GRenderWindow::ScaleTouch(const QPointF& pos) const {      const qreal pixel_ratio = windowPixelRatio();      return {static_cast<u32>(std::max(std::round(pos.x() * pixel_ratio), qreal{0.0})),              static_cast<u32>(std::max(std::round(pos.y() * pixel_ratio), qreal{0.0}))}; @@ -378,8 +336,10 @@ void GRenderWindow::keyReleaseEvent(QKeyEvent* event) {  }  void GRenderWindow::mousePressEvent(QMouseEvent* event) { -    if (event->source() == Qt::MouseEventSynthesizedBySystem) -        return; // touch input is handled in TouchBeginEvent +    // touch input is handled in TouchBeginEvent +    if (event->source() == Qt::MouseEventSynthesizedBySystem) { +        return; +    }      auto pos = event->pos();      if (event->button() == Qt::LeftButton) { @@ -391,8 +351,10 @@ void GRenderWindow::mousePressEvent(QMouseEvent* event) {  }  void GRenderWindow::mouseMoveEvent(QMouseEvent* event) { -    if (event->source() == Qt::MouseEventSynthesizedBySystem) -        return; // touch input is handled in TouchUpdateEvent +    // touch input is handled in TouchUpdateEvent +    if (event->source() == Qt::MouseEventSynthesizedBySystem) { +        return; +    }      auto pos = event->pos();      const auto [x, y] = ScaleTouch(pos); @@ -401,13 +363,16 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {  }  void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) { -    if (event->source() == Qt::MouseEventSynthesizedBySystem) -        return; // touch input is handled in TouchEndEvent +    // touch input is handled in TouchEndEvent +    if (event->source() == Qt::MouseEventSynthesizedBySystem) { +        return; +    } -    if (event->button() == Qt::LeftButton) +    if (event->button() == Qt::LeftButton) {          this->TouchReleased(); -    else if (event->button() == Qt::RightButton) +    } else if (event->button() == Qt::RightButton) {          InputCommon::GetMotionEmu()->EndTilt(); +    }  }  void GRenderWindow::TouchBeginEvent(const QTouchEvent* event) { diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index 3739ec7ed..d69078df1 100644 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h @@ -7,11 +7,12 @@  #include <atomic>  #include <condition_variable>  #include <mutex> -#include <thread> +  #include <QImage>  #include <QThread>  #include <QWidget>  #include <QWindow> +  #include "common/thread.h"  #include "core/core.h"  #include "core/frontend/emu_window.h" @@ -84,8 +85,8 @@ private:      bool exec_step = false;      bool running = false;      std::atomic_bool stop_run{false}; -    std::mutex running_mutex = {}; -    std::condition_variable running_cv = {}; +    std::mutex running_mutex; +    std::condition_variable running_cv;  signals:      /** @@ -154,7 +155,7 @@ public:      void CaptureScreenshot(u32 res_scale, const QString& screenshot_path); -    std::pair<u32, u32> ScaleTouch(const QPointF pos) const; +    std::pair<u32, u32> ScaleTouch(const QPointF& pos) const;  public slots:      void OnEmulationStarting(EmuThread* emu_thread); diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index e5db7d819..4d2ea7e9e 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -230,11 +230,11 @@ int main(int argc, char** argv) {      system.TelemetrySession().AddField(Telemetry::FieldType::App, "Frontend", "SDL"); -    system.Renderer().Rasterizer().LoadDiskResources(); -      // Core is loaded, start the GPU (makes the GPU contexts current to this thread)      system.GPU().Start(); +    system.Renderer().Rasterizer().LoadDiskResources(); +      std::thread render_thread([&emu_window] { emu_window->Present(); });      while (emu_window->IsOpen()) {          system.RunLoop(); diff --git a/src/yuzu_tester/emu_window/emu_window_sdl2_hide.cpp b/src/yuzu_tester/emu_window/emu_window_sdl2_hide.cpp index a1bdb1a12..a837430cc 100644 --- a/src/yuzu_tester/emu_window/emu_window_sdl2_hide.cpp +++ b/src/yuzu_tester/emu_window/emu_window_sdl2_hide.cpp @@ -102,8 +102,6 @@ EmuWindow_SDL2_Hide::EmuWindow_SDL2_Hide() {      LOG_INFO(Frontend, "yuzu-tester Version: {} | {}-{}", Common::g_build_fullname,               Common::g_scm_branch, Common::g_scm_desc);      Settings::LogSettings(); - -    DoneCurrent();  }  EmuWindow_SDL2_Hide::~EmuWindow_SDL2_Hide() { @@ -114,14 +112,6 @@ EmuWindow_SDL2_Hide::~EmuWindow_SDL2_Hide() {  void EmuWindow_SDL2_Hide::PollEvents() {} -void EmuWindow_SDL2_Hide::MakeCurrent() { -    SDL_GL_MakeCurrent(render_window, gl_context); -} - -void EmuWindow_SDL2_Hide::DoneCurrent() { -    SDL_GL_MakeCurrent(render_window, nullptr); -} -  bool EmuWindow_SDL2_Hide::IsShown() const {      return false;  } @@ -129,3 +119,35 @@ bool EmuWindow_SDL2_Hide::IsShown() const {  void EmuWindow_SDL2_Hide::RetrieveVulkanHandlers(void*, void*, void*) const {      UNREACHABLE();  } + +class SDLGLContext : public Core::Frontend::GraphicsContext { +public: +    explicit SDLGLContext() { +        // create a hidden window to make the shared context against +        window = SDL_CreateWindow(NULL, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 0, 0, +                                  SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL); +        context = SDL_GL_CreateContext(window); +    } + +    ~SDLGLContext() { +        DoneCurrent(); +        SDL_GL_DeleteContext(context); +        SDL_DestroyWindow(window); +    } + +    void MakeCurrent() override { +        SDL_GL_MakeCurrent(window, context); +    } + +    void DoneCurrent() override { +        SDL_GL_MakeCurrent(window, nullptr); +    } + +private: +    SDL_Window* window; +    SDL_GLContext context; +}; + +std::unique_ptr<Core::Frontend::GraphicsContext> EmuWindow_SDL2_Hide::CreateSharedContext() const { +    return std::make_unique<SDLGLContext>(); +} diff --git a/src/yuzu_tester/emu_window/emu_window_sdl2_hide.h b/src/yuzu_tester/emu_window/emu_window_sdl2_hide.h index b13e15309..9f5d04fca 100644 --- a/src/yuzu_tester/emu_window/emu_window_sdl2_hide.h +++ b/src/yuzu_tester/emu_window/emu_window_sdl2_hide.h @@ -16,12 +16,6 @@ public:      /// Polls window events      void PollEvents() override; -    /// Makes the graphics context current for the caller thread -    void MakeCurrent() override; - -    /// Releases the GL context from the caller thread -    void DoneCurrent() override; -      /// Whether the screen is being shown or not.      bool IsShown() const override; @@ -29,8 +23,7 @@ public:      void RetrieveVulkanHandlers(void* get_instance_proc_addr, void* instance,                                  void* surface) const override; -    /// Whether the window is still open, and a close request hasn't yet been sent -    bool IsOpen() const; +    std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override;  private:      /// Whether the GPU and driver supports the OpenGL extension required diff --git a/src/yuzu_tester/yuzu.cpp b/src/yuzu_tester/yuzu.cpp index 94ad50cb3..676e70ebd 100644 --- a/src/yuzu_tester/yuzu.cpp +++ b/src/yuzu_tester/yuzu.cpp @@ -164,11 +164,6 @@ int main(int argc, char** argv) {      std::unique_ptr<EmuWindow_SDL2_Hide> emu_window{std::make_unique<EmuWindow_SDL2_Hide>()}; -    if (!Settings::values.use_multi_core) { -        // Single core mode must acquire OpenGL context for entire emulation session -        emu_window->MakeCurrent(); -    } -      bool finished = false;      int return_value = 0;      const auto callback = [&finished, @@ -257,6 +252,7 @@ int main(int argc, char** argv) {      system.TelemetrySession().AddField(Telemetry::FieldType::App, "Frontend", "SDLHideTester"); +    system.GPU().Start();      system.Renderer().Rasterizer().LoadDiskResources();      while (!finished) { | 
