Prepare frontend for multiple graphics APIs (#6347)

* externals: Update dynarmic

* settings: Introduce GraphicsAPI enum

* For now it's OpenGL only but will be expanded upon later

* citra_qt: Introduce backend agnostic context management

* Mostly a direct port from yuzu

* core: Simplify context acquire

* settings: Add option to create debug contexts

* renderer_opengl: Abstract initialization to Driver

* This commit also updates glad and adds some useful extensions which we will use in part 2

* Rasterizer construction is moved to the specific renderer instead of RendererBase.
  Software rendering has been disable to achieve this but will be brought back in the next commit.

* video_core: Remove Init/Shutdown methods from renderer

* The constructor and destructor can do the same job

* In addition move opengl function loading to Qt since SDL already does this. Also remove ErrorVideoCore which is never reached

* citra_qt: Decouple software renderer from opengl part 1

* citra: Decouple software renderer from opengl part 2

* android: Decouple software renderer from opengl part 3

* swrasterizer: Decouple software renderer from opengl part 4

* This commit simply enforces the renderer naming conventions in the software renderer

* video_core: Move RendererBase to VideoCore

* video_core: De-globalize screenshot state

* video_core: Pass system to the renderers

* video_core: Commonize shader uniform data

* video_core: Abstract backend agnostic rasterizer operations

* bootmanager: Remove references to OpenGL for macOS

OpenGL macOS headers definitions clash heavily with each other

* citra_qt: Proper title for api settings

* video_core: Reduce boost usage

* bootmanager: Fix hide mouse option

Remove event handlers from RenderWidget for events that are
already handled by the parent GRenderWindow.
Also enable mouse tracking on the RenderWidget.

* android: Remove software from graphics api list

* code: Address review comments

* citra: Port per-game settings read

* Having to update the default value for all backends is a pain so lets centralize it

* android: Rename to OpenGLES

---------

Co-authored-by: MerryMage <MerryMage@users.noreply.github.com>
Co-authored-by: Vitor Kiguchi <vitor-kiguchi@hotmail.com>
This commit is contained in:
GPUCode 2023-03-27 14:29:17 +03:00 committed by GitHub
parent 9ef42040af
commit b5d6f645bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
99 changed files with 3165 additions and 4501 deletions

View file

@ -113,8 +113,6 @@ add_library(core STATIC
frontend/input.h
frontend/mic.cpp
frontend/mic.h
frontend/scope_acquire_context.cpp
frontend/scope_acquire_context.h
gdbstub/gdbstub.cpp
gdbstub/gdbstub.h
hle/applets/applet.cpp

View file

@ -431,17 +431,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window,
video_dumper = std::make_unique<VideoDumper::NullBackend>();
#endif
VideoCore::ResultStatus result = VideoCore::Init(emu_window, secondary_window, *memory);
if (result != VideoCore::ResultStatus::Success) {
switch (result) {
case VideoCore::ResultStatus::ErrorGenericDrivers:
return ResultStatus::ErrorVideoCore_ErrorGenericDrivers;
case VideoCore::ResultStatus::ErrorBelowGL43:
return ResultStatus::ErrorVideoCore_ErrorBelowGL43;
default:
return ResultStatus::ErrorVideoCore;
}
}
VideoCore::Init(emu_window, secondary_window, *this);
LOG_DEBUG(Core, "Initialized OK");
@ -450,7 +440,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window,
return ResultStatus::Success;
}
RendererBase& System::Renderer() {
VideoCore::RendererBase& System::Renderer() {
return *VideoCore::g_renderer;
}

View file

@ -57,7 +57,9 @@ namespace VideoDumper {
class Backend;
}
namespace VideoCore {
class RendererBase;
}
namespace Core {
@ -87,14 +89,9 @@ public:
ErrorLoader_ErrorGbaTitle, ///< Error loading the specified application as it is GBA Virtual
///< Console
ErrorSystemFiles, ///< Error in finding system files
ErrorVideoCore, ///< Error in the video core
ErrorVideoCore_ErrorGenericDrivers, ///< Error in the video core due to the user having
/// generic drivers installed
ErrorVideoCore_ErrorBelowGL43, ///< Error in the video core due to the user not having
/// OpenGL 4.3 or higher
ErrorSavestate, ///< Error saving or loading
ShutdownRequested, ///< Emulated program requested a system shutdown
ErrorUnknown ///< Any other error
ErrorSavestate, ///< Error saving or loading
ShutdownRequested, ///< Emulated program requested a system shutdown
ErrorUnknown ///< Any other error
};
~System();
@ -210,7 +207,7 @@ public:
return *dsp_core;
}
[[nodiscard]] RendererBase& Renderer();
[[nodiscard]] VideoCore::RendererBase& Renderer();
/**
* Gets a reference to the service manager.

View file

@ -14,6 +14,17 @@
namespace Frontend {
/// Information for the Graphics Backends signifying what type of screen pointer is in
/// WindowInformation
enum class WindowSystemType : u8 {
Headless,
Android,
Windows,
MacOS,
X11,
Wayland,
};
struct Frame;
/**
* For smooth Vsync rendering, we want to always present the latest frame that the core generates,
@ -62,11 +73,33 @@ class GraphicsContext {
public:
virtual ~GraphicsContext();
/// Inform the driver to swap the front/back buffers and present the current image
virtual void SwapBuffers(){};
/// Makes the graphics context current for the caller thread
virtual void MakeCurrent() = 0;
virtual void MakeCurrent(){};
/// Releases (dunno if this is the "right" word) the context from the caller thread
virtual void DoneCurrent() = 0;
virtual void DoneCurrent(){};
class Scoped {
public:
explicit Scoped(GraphicsContext& context_) : context(context_) {
context.MakeCurrent();
}
~Scoped() {
context.DoneCurrent();
}
private:
GraphicsContext& context;
};
/// Calls MakeCurrent on the context and calls DoneCurrent when the scope for the returned value
/// ends
[[nodiscard]] Scoped Acquire() {
return Scoped{*this};
}
};
/**
@ -100,6 +133,23 @@ public:
Core::kScreenTopWidth, Core::kScreenTopHeight + Core::kScreenBottomHeight};
};
/// Data describing host window system information
struct WindowSystemInfo {
// Window system type. Determines which GL context or Vulkan WSI is used.
WindowSystemType type = WindowSystemType::Headless;
// Connection to a display server. This is used on X11 and Wayland platforms.
void* display_connection = nullptr;
// Render surface. This is a pointer to the native window handle, which depends
// on the platform. e.g. HWND for Windows, Window for X11. If the surface is
// set to nullptr, the video backend will run in headless mode.
void* render_surface = nullptr;
// Scale of the render surface. For hidpi systems, this will be >1.
float render_surface_scale = 1.0f;
};
/// Polls window events
virtual void PollEvents() = 0;
@ -163,6 +213,13 @@ public:
config = val;
}
/**
* Returns system information about the drawing area.
*/
const WindowSystemInfo& GetWindowInfo() const {
return window_info;
}
/**
* Gets the framebuffer layout (width, height, and screen regions)
* @note This method is thread-safe
@ -211,6 +268,7 @@ protected:
}
bool is_secondary{};
WindowSystemInfo window_info;
private:
/**

View file

@ -1,17 +0,0 @@
// Copyright 2019 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/frontend/emu_window.h"
#include "core/frontend/scope_acquire_context.h"
namespace Frontend {
ScopeAcquireContext::ScopeAcquireContext(Frontend::GraphicsContext& context) : context{context} {
context.MakeCurrent();
}
ScopeAcquireContext::~ScopeAcquireContext() {
context.DoneCurrent();
}
} // namespace Frontend

View file

@ -1,23 +0,0 @@
// Copyright 2019 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "common/common_types.h"
namespace Frontend {
class GraphicsContext;
/// Helper class to acquire/release window context within a given scope
class ScopeAcquireContext : NonCopyable {
public:
explicit ScopeAcquireContext(Frontend::GraphicsContext& context);
~ScopeAcquireContext();
private:
Frontend::GraphicsContext& context;
};
} // namespace Frontend

View file

@ -133,8 +133,8 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader) {
Settings::values.resolution_factor.GetValue());
AddField(Telemetry::FieldType::UserConfig, "Renderer_FrameLimit",
Settings::values.frame_limit.GetValue());
AddField(Telemetry::FieldType::UserConfig, "Renderer_UseHwRenderer",
Settings::values.use_hw_renderer.GetValue());
AddField(Telemetry::FieldType::UserConfig, "Renderer_Backend",
static_cast<int>(Settings::values.graphics_api.GetValue()));
AddField(Telemetry::FieldType::UserConfig, "Renderer_UseHwShader",
Settings::values.use_hw_shader.GetValue());
AddField(Telemetry::FieldType::UserConfig, "Renderer_ShadersAccurateMul",