Address review and fix broken yuzu-tester build

This commit is contained in:
James Rowe 2020-03-24 22:57:36 -06:00
parent 282adfc70b
commit cf9c94d401
11 changed files with 83 additions and 102 deletions

View File

@ -169,6 +169,9 @@ struct System::Impl {
interrupt_manager = std::make_unique<Core::Hardware::InterruptManager>(system); interrupt_manager = std::make_unique<Core::Hardware::InterruptManager>(system);
gpu_core = VideoCore::CreateGPU(emu_window, system); gpu_core = VideoCore::CreateGPU(emu_window, system);
if (!gpu_core) {
return ResultStatus::ErrorVideoCore;
}
gpu_core->Renderer().Rasterizer().SetupDirtyFlags(); gpu_core->Renderer().Rasterizer().SetupDirtyFlags();
is_powered_on = true; is_powered_on = true;
@ -181,7 +184,6 @@ struct System::Impl {
ResultStatus Load(System& system, Frontend::EmuWindow& emu_window, ResultStatus Load(System& system, Frontend::EmuWindow& emu_window,
const std::string& filepath) { const std::string& filepath) {
app_loader = Loader::GetLoader(GetGameFileFromPath(virtual_filesystem, filepath)); app_loader = Loader::GetLoader(GetGameFileFromPath(virtual_filesystem, filepath));
if (!app_loader) { if (!app_loader) {
LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath); LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);

View File

@ -30,7 +30,7 @@ public:
class Scoped { class Scoped {
public: public:
Scoped(GraphicsContext& context_) : context(context_) { explicit Scoped(GraphicsContext& context_) : context(context_) {
context.MakeCurrent(); context.MakeCurrent();
} }
~Scoped() { ~Scoped() {

View File

@ -305,6 +305,7 @@ void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading,
} }
const std::vector gl_cache = disk_cache.LoadPrecompiled(); 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 // 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 // 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, const auto worker = [&](Core::Frontend::GraphicsContext* context, std::size_t begin,
std::size_t end) { std::size_t end) {
const auto scope = context->Acquire(); const auto scope = context->Acquire();
const auto supported_formats = GetSupportedFormats();
for (std::size_t i = begin; i < end; ++i) { for (std::size_t i = begin; i < end; ++i) {
if (stop_loading) { if (stop_loading) {

View File

@ -7,7 +7,9 @@
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <memory> #include <memory>
#include <glad/glad.h> #include <glad/glad.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/microprofile.h" #include "common/microprofile.h"
@ -313,8 +315,8 @@ public:
RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system, RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system,
Core::Frontend::GraphicsContext& context) Core::Frontend::GraphicsContext& context)
: VideoCore::RendererBase{emu_window}, emu_window{emu_window}, system{system}, frame_mailbox{}, : VideoCore::RendererBase{emu_window}, emu_window{emu_window}, system{system},
has_debug_tool{HasDebugTool()}, context{context} {} frame_mailbox{}, context{context}, has_debug_tool{HasDebugTool()} {}
RendererOpenGL::~RendererOpenGL() = default; RendererOpenGL::~RendererOpenGL() = default;

View File

@ -30,7 +30,7 @@ std::unique_ptr<VideoCore::RendererBase> CreateRenderer(Core::Frontend::EmuWindo
return nullptr; return nullptr;
} }
} }
} // namespace } // Anonymous namespace
namespace VideoCore { namespace VideoCore {
@ -39,7 +39,7 @@ std::unique_ptr<Tegra::GPU> CreateGPU(Core::Frontend::EmuWindow& emu_window, Cor
const auto scope = context->Acquire(); const auto scope = context->Acquire();
auto renderer = CreateRenderer(emu_window, system, *context); auto renderer = CreateRenderer(emu_window, system, *context);
if (!renderer->Init()) { if (!renderer->Init()) {
return {}; return nullptr;
} }
if (Settings::values.use_asynchronous_gpu_emulation) { if (Settings::values.use_asynchronous_gpu_emulation) {

View File

@ -42,6 +42,10 @@ EmuThread::~EmuThread() = default;
void EmuThread::run() { void EmuThread::run() {
MicroProfileOnThreadCreate("EmuThread"); 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); emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
Core::System::GetInstance().Renderer().Rasterizer().LoadDiskResources( Core::System::GetInstance().Renderer().Rasterizer().LoadDiskResources(
@ -51,10 +55,6 @@ void EmuThread::run() {
emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0); 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, // Holds whether the cpu was running during the last iteration,
// so that the DebugModeLeft signal can be emitted before the // so that the DebugModeLeft signal can be emitted before the
// next execution step // next execution step
@ -152,7 +152,7 @@ public:
if (is_current) { if (is_current) {
return; return;
} }
context->makeCurrent(surface); is_current = context->makeCurrent(surface);
} }
void DoneCurrent() override { void DoneCurrent() override {
@ -160,7 +160,11 @@ public:
is_current = false; is_current = false;
} }
QOpenGLContext* GetShareContext() const { QOpenGLContext* GetShareContext() {
return context.get();
}
const QOpenGLContext* GetShareContext() const {
return context.get(); return context.get();
} }
@ -177,13 +181,15 @@ class DummyContext : public Core::Frontend::GraphicsContext {};
class RenderWidget : public QWidget { class RenderWidget : public QWidget {
public: 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_NativeWindow);
setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_PaintOnScreen);
} }
virtual ~RenderWidget() = default; 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() {} virtual void Present() {}
void paintEvent(QPaintEvent* event) override { void paintEvent(QPaintEvent* event) override {
@ -191,56 +197,6 @@ public:
update(); 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 { QPaintEngine* paintEngine() const override {
return nullptr; return nullptr;
} }
@ -276,6 +232,7 @@ private:
std::unique_ptr<Core::Frontend::GraphicsContext> context{}; std::unique_ptr<Core::Frontend::GraphicsContext> context{};
}; };
#ifdef HAS_VULKAN
class VulkanRenderWidget : public RenderWidget { class VulkanRenderWidget : public RenderWidget {
public: public:
explicit VulkanRenderWidget(GRenderWindow* parent, QVulkanInstance* instance) explicit VulkanRenderWidget(GRenderWindow* parent, QVulkanInstance* instance)
@ -284,6 +241,7 @@ public:
windowHandle()->setVulkanInstance(instance); windowHandle()->setVulkanInstance(instance);
} }
}; };
#endif
GRenderWindow::GRenderWindow(GMainWindow* parent_, EmuThread* emu_thread) GRenderWindow::GRenderWindow(GMainWindow* parent_, EmuThread* emu_thread)
: QWidget(parent_), emu_thread(emu_thread) { : QWidget(parent_), emu_thread(emu_thread) {
@ -358,7 +316,7 @@ qreal GRenderWindow::windowPixelRatio() const {
return devicePixelRatio(); 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(); const qreal pixel_ratio = windowPixelRatio();
return {static_cast<u32>(std::max(std::round(pos.x() * pixel_ratio), qreal{0.0})), 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}))}; 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) { void GRenderWindow::mousePressEvent(QMouseEvent* event) {
if (event->source() == Qt::MouseEventSynthesizedBySystem) // touch input is handled in TouchBeginEvent
return; // touch input is handled in TouchBeginEvent if (event->source() == Qt::MouseEventSynthesizedBySystem) {
return;
}
auto pos = event->pos(); auto pos = event->pos();
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
@ -391,8 +351,10 @@ void GRenderWindow::mousePressEvent(QMouseEvent* event) {
} }
void GRenderWindow::mouseMoveEvent(QMouseEvent* event) { void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
if (event->source() == Qt::MouseEventSynthesizedBySystem) // touch input is handled in TouchUpdateEvent
return; // touch input is handled in TouchUpdateEvent if (event->source() == Qt::MouseEventSynthesizedBySystem) {
return;
}
auto pos = event->pos(); auto pos = event->pos();
const auto [x, y] = ScaleTouch(pos); const auto [x, y] = ScaleTouch(pos);
@ -401,14 +363,17 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
} }
void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) { void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) {
if (event->source() == Qt::MouseEventSynthesizedBySystem) // touch input is handled in TouchEndEvent
return; // touch input is handled in TouchEndEvent if (event->source() == Qt::MouseEventSynthesizedBySystem) {
return;
}
if (event->button() == Qt::LeftButton) if (event->button() == Qt::LeftButton) {
this->TouchReleased(); this->TouchReleased();
else if (event->button() == Qt::RightButton) } else if (event->button() == Qt::RightButton) {
InputCommon::GetMotionEmu()->EndTilt(); InputCommon::GetMotionEmu()->EndTilt();
} }
}
void GRenderWindow::TouchBeginEvent(const QTouchEvent* event) { void GRenderWindow::TouchBeginEvent(const QTouchEvent* event) {
// TouchBegin always has exactly one touch point, so take the .first() // TouchBegin always has exactly one touch point, so take the .first()

View File

@ -7,11 +7,12 @@
#include <atomic> #include <atomic>
#include <condition_variable> #include <condition_variable>
#include <mutex> #include <mutex>
#include <thread>
#include <QImage> #include <QImage>
#include <QThread> #include <QThread>
#include <QWidget> #include <QWidget>
#include <QWindow> #include <QWindow>
#include "common/thread.h" #include "common/thread.h"
#include "core/core.h" #include "core/core.h"
#include "core/frontend/emu_window.h" #include "core/frontend/emu_window.h"
@ -84,8 +85,8 @@ private:
bool exec_step = false; bool exec_step = false;
bool running = false; bool running = false;
std::atomic_bool stop_run{false}; std::atomic_bool stop_run{false};
std::mutex running_mutex = {}; std::mutex running_mutex;
std::condition_variable running_cv = {}; std::condition_variable running_cv;
signals: signals:
/** /**
@ -154,7 +155,7 @@ public:
void CaptureScreenshot(u32 res_scale, const QString& screenshot_path); 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: public slots:
void OnEmulationStarting(EmuThread* emu_thread); void OnEmulationStarting(EmuThread* emu_thread);

View File

@ -230,11 +230,11 @@ int main(int argc, char** argv) {
system.TelemetrySession().AddField(Telemetry::FieldType::App, "Frontend", "SDL"); 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) // Core is loaded, start the GPU (makes the GPU contexts current to this thread)
system.GPU().Start(); system.GPU().Start();
system.Renderer().Rasterizer().LoadDiskResources();
std::thread render_thread([&emu_window] { emu_window->Present(); }); std::thread render_thread([&emu_window] { emu_window->Present(); });
while (emu_window->IsOpen()) { while (emu_window->IsOpen()) {
system.RunLoop(); system.RunLoop();

View File

@ -102,8 +102,6 @@ EmuWindow_SDL2_Hide::EmuWindow_SDL2_Hide() {
LOG_INFO(Frontend, "yuzu-tester Version: {} | {}-{}", Common::g_build_fullname, LOG_INFO(Frontend, "yuzu-tester Version: {} | {}-{}", Common::g_build_fullname,
Common::g_scm_branch, Common::g_scm_desc); Common::g_scm_branch, Common::g_scm_desc);
Settings::LogSettings(); Settings::LogSettings();
DoneCurrent();
} }
EmuWindow_SDL2_Hide::~EmuWindow_SDL2_Hide() { 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::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 { bool EmuWindow_SDL2_Hide::IsShown() const {
return false; return false;
} }
@ -129,3 +119,35 @@ bool EmuWindow_SDL2_Hide::IsShown() const {
void EmuWindow_SDL2_Hide::RetrieveVulkanHandlers(void*, void*, void*) const { void EmuWindow_SDL2_Hide::RetrieveVulkanHandlers(void*, void*, void*) const {
UNREACHABLE(); 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>();
}

View File

@ -16,12 +16,6 @@ public:
/// Polls window events /// Polls window events
void PollEvents() override; 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. /// Whether the screen is being shown or not.
bool IsShown() const override; bool IsShown() const override;
@ -29,8 +23,7 @@ public:
void RetrieveVulkanHandlers(void* get_instance_proc_addr, void* instance, void RetrieveVulkanHandlers(void* get_instance_proc_addr, void* instance,
void* surface) const override; void* surface) const override;
/// Whether the window is still open, and a close request hasn't yet been sent std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override;
bool IsOpen() const;
private: private:
/// Whether the GPU and driver supports the OpenGL extension required /// Whether the GPU and driver supports the OpenGL extension required

View File

@ -164,11 +164,6 @@ int main(int argc, char** argv) {
std::unique_ptr<EmuWindow_SDL2_Hide> emu_window{std::make_unique<EmuWindow_SDL2_Hide>()}; 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; bool finished = false;
int return_value = 0; int return_value = 0;
const auto callback = [&finished, const auto callback = [&finished,
@ -257,6 +252,7 @@ int main(int argc, char** argv) {
system.TelemetrySession().AddField(Telemetry::FieldType::App, "Frontend", "SDLHideTester"); system.TelemetrySession().AddField(Telemetry::FieldType::App, "Frontend", "SDLHideTester");
system.GPU().Start();
system.Renderer().Rasterizer().LoadDiskResources(); system.Renderer().Rasterizer().LoadDiskResources();
while (!finished) { while (!finished) {