Fix MakeCurrent and shader issues with AMD 22.7 driver

This commit is contained in:
pawelniegowski 2022-07-29 12:26:18 +02:00
parent 6764264488
commit ff81fb04b4
6 changed files with 35 additions and 2 deletions

View file

@ -30,7 +30,6 @@ SharedContext_SDL2::SharedContext_SDL2() {
} }
SharedContext_SDL2::~SharedContext_SDL2() { SharedContext_SDL2::~SharedContext_SDL2() {
DoneCurrent();
SDL_GL_DeleteContext(context); SDL_GL_DeleteContext(context);
SDL_DestroyWindow(window); SDL_DestroyWindow(window);
} }
@ -185,6 +184,7 @@ EmuWindow_SDL2::EmuWindow_SDL2(bool fullscreen) {
window_context = SDL_GL_CreateContext(render_window); window_context = SDL_GL_CreateContext(render_window);
core_context = CreateSharedContext(); core_context = CreateSharedContext();
last_saved_context = nullptr;
if (window_context == nullptr) { if (window_context == nullptr) {
LOG_CRITICAL(Frontend, "Failed to create SDL2 GL context: {}", SDL_GetError()); LOG_CRITICAL(Frontend, "Failed to create SDL2 GL context: {}", SDL_GetError());
@ -222,6 +222,14 @@ std::unique_ptr<Frontend::GraphicsContext> EmuWindow_SDL2::CreateSharedContext()
return std::make_unique<SharedContext_SDL2>(); return std::make_unique<SharedContext_SDL2>();
} }
void EmuWindow_SDL2::SaveContext() {
last_saved_context = SDL_GL_GetCurrentContext();
}
void EmuWindow_SDL2::RestoreContext() {
SDL_GL_MakeCurrent(render_window, last_saved_context);
}
void EmuWindow_SDL2::Present() { void EmuWindow_SDL2::Present() {
SDL_GL_MakeCurrent(render_window, window_context); SDL_GL_MakeCurrent(render_window, window_context);
SDL_GL_SetSwapInterval(1); SDL_GL_SetSwapInterval(1);

View file

@ -49,6 +49,11 @@ public:
/// Creates a new context that is shared with the current context /// Creates a new context that is shared with the current context
std::unique_ptr<GraphicsContext> CreateSharedContext() const override; std::unique_ptr<GraphicsContext> CreateSharedContext() const override;
/// Saves the current context, for the purpose of e.g. creating new shared contexts
void SaveContext() override;
/// Restores the context previously saved
void RestoreContext() override;
private: private:
/// Called by PollEvents when a key is pressed or released. /// Called by PollEvents when a key is pressed or released.
void OnKeyEvent(int key, u8 state); void OnKeyEvent(int key, u8 state);
@ -94,6 +99,9 @@ private:
/// The OpenGL context associated with the window /// The OpenGL context associated with the window
SDL_GLContext window_context; SDL_GLContext window_context;
/// Used by SaveContext and RestoreContext
SDL_GLContext last_saved_context;
/// The OpenGL context associated with the core /// The OpenGL context associated with the core
std::unique_ptr<Frontend::GraphicsContext> core_context; std::unique_ptr<Frontend::GraphicsContext> core_context;

View file

@ -53,6 +53,8 @@ void EmuThread::run() {
emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0); emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0);
core_context.MakeCurrent();
if (Core::System::GetInstance().frame_limiter.IsFrameAdvancing()) { if (Core::System::GetInstance().frame_limiter.IsFrameAdvancing()) {
// Usually the loading screen is hidden after the first frame is drawn. In this case // Usually the loading screen is hidden after the first frame is drawn. In this case
// we hide it immediately as we need to wait for user input to start the emulation. // we hide it immediately as we need to wait for user input to start the emulation.

View file

@ -111,6 +111,16 @@ public:
return nullptr; return nullptr;
} }
/**
* Save current GraphicsContext.
*/
virtual void SaveContext() {};
/**
* Restore saved GraphicsContext.
*/
virtual void RestoreContext() {};
/** /**
* Signal that a touch pressed event has occurred (e.g. mouse click pressed) * Signal that a touch pressed event has occurred (e.g. mouse click pressed)
* @param framebuffer_x Framebuffer x-coordinate that was pressed * @param framebuffer_x Framebuffer x-coordinate that was pressed

View file

@ -706,6 +706,8 @@ void ShaderProgramManager::LoadDiskCache(const std::atomic_bool& stop_loading,
const std::size_t bucket_size{load_raws_size / num_workers}; const std::size_t bucket_size{load_raws_size / num_workers};
std::vector<std::unique_ptr<Frontend::GraphicsContext>> contexts(num_workers); std::vector<std::unique_ptr<Frontend::GraphicsContext>> contexts(num_workers);
std::vector<std::thread> threads(num_workers); std::vector<std::thread> threads(num_workers);
emu_window.SaveContext();
for (std::size_t i = 0; i < num_workers; ++i) { for (std::size_t i = 0; i < num_workers; ++i) {
const bool is_last_worker = i + 1 == num_workers; const bool is_last_worker = i + 1 == num_workers;
const std::size_t start{bucket_size * i}; const std::size_t start{bucket_size * i};
@ -713,11 +715,14 @@ void ShaderProgramManager::LoadDiskCache(const std::atomic_bool& stop_loading,
// On some platforms the shared context has to be created from the GUI thread // On some platforms the shared context has to be created from the GUI thread
contexts[i] = emu_window.CreateSharedContext(); contexts[i] = emu_window.CreateSharedContext();
// Release the context, so it can be immediately used by the spawned thread
contexts[i]->DoneCurrent();
threads[i] = std::thread(LoadRawSepareble, contexts[i].get(), start, end); threads[i] = std::thread(LoadRawSepareble, contexts[i].get(), start, end);
} }
for (auto& thread : threads) { for (auto& thread : threads) {
thread.join(); thread.join();
} }
emu_window.RestoreContext();
if (compilation_failed) { if (compilation_failed) {
disk_cache.InvalidateAll(); disk_cache.InvalidateAll();

View file

@ -26,7 +26,7 @@ GLuint LoadShader(const char* source, GLenum type) {
#extension GL_EXT_clip_cull_distance : enable #extension GL_EXT_clip_cull_distance : enable
#endif // defined(GL_EXT_clip_cull_distance) #endif // defined(GL_EXT_clip_cull_distance)
)" )"
: "#version 330\n"; : "#version 430\n";
const char* debug_type; const char* debug_type;
switch (type) { switch (type) {