diff options
| author | 2019-05-24 22:42:08 -0400 | |
|---|---|---|
| committer | 2019-05-24 22:42:08 -0400 | |
| commit | 68c9c9222d97cbebf7f26096a839a8767123c50f (patch) | |
| tree | 1600a463f4653f335789cf3e2207c656797073c6 /src | |
| parent | Merge pull request #2485 from ReinUsesLisp/generic-memory (diff) | |
| parent | gl_shader_cache: Fix clang strict standard build issues (diff) | |
| download | yuzu-68c9c9222d97cbebf7f26096a839a8767123c50f.tar.gz yuzu-68c9c9222d97cbebf7f26096a839a8767123c50f.tar.xz yuzu-68c9c9222d97cbebf7f26096a839a8767123c50f.zip | |
Merge pull request #2358 from ReinUsesLisp/parallel-shader
gl_shader_cache: Use shared contexts to build shaders in parallel at boot
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 117 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.h | 14 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_disk_cache.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_disk_cache.h | 7 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.h | 3 | ||||
| -rw-r--r-- | src/yuzu/bootmanager.cpp | 18 |
9 files changed, 122 insertions, 62 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index dbd8049f5..f9b6dfeea 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -98,9 +98,11 @@ struct FramebufferCacheKey { | |||
| 98 | } | 98 | } |
| 99 | }; | 99 | }; |
| 100 | 100 | ||
| 101 | RasterizerOpenGL::RasterizerOpenGL(Core::System& system, ScreenInfo& info) | 101 | RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, |
| 102 | : res_cache{*this}, shader_cache{*this, system, device}, global_cache{*this}, system{system}, | 102 | ScreenInfo& info) |
| 103 | screen_info{info}, buffer_cache(*this, STREAM_BUFFER_SIZE) { | 103 | : res_cache{*this}, shader_cache{*this, system, emu_window, device}, |
| 104 | global_cache{*this}, system{system}, screen_info{info}, | ||
| 105 | buffer_cache(*this, STREAM_BUFFER_SIZE) { | ||
| 104 | OpenGLState::ApplyDefaultState(); | 106 | OpenGLState::ApplyDefaultState(); |
| 105 | 107 | ||
| 106 | shader_program_manager = std::make_unique<GLShader::ProgramManager>(); | 108 | shader_program_manager = std::make_unique<GLShader::ProgramManager>(); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 71b9c5ead..d78094138 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -48,7 +48,8 @@ struct FramebufferCacheKey; | |||
| 48 | 48 | ||
| 49 | class RasterizerOpenGL : public VideoCore::RasterizerInterface { | 49 | class RasterizerOpenGL : public VideoCore::RasterizerInterface { |
| 50 | public: | 50 | public: |
| 51 | explicit RasterizerOpenGL(Core::System& system, ScreenInfo& info); | 51 | explicit RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, |
| 52 | ScreenInfo& info); | ||
| 52 | ~RasterizerOpenGL() override; | 53 | ~RasterizerOpenGL() override; |
| 53 | 54 | ||
| 54 | void DrawArrays() override; | 55 | void DrawArrays() override; |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index f700dc89a..7ee1c99c0 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -2,10 +2,14 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <mutex> | ||
| 6 | #include <thread> | ||
| 5 | #include <boost/functional/hash.hpp> | 7 | #include <boost/functional/hash.hpp> |
| 6 | #include "common/assert.h" | 8 | #include "common/assert.h" |
| 7 | #include "common/hash.h" | 9 | #include "common/hash.h" |
| 10 | #include "common/scope_exit.h" | ||
| 8 | #include "core/core.h" | 11 | #include "core/core.h" |
| 12 | #include "core/frontend/emu_window.h" | ||
| 9 | #include "video_core/engines/maxwell_3d.h" | 13 | #include "video_core/engines/maxwell_3d.h" |
| 10 | #include "video_core/memory_manager.h" | 14 | #include "video_core/memory_manager.h" |
| 11 | #include "video_core/renderer_opengl/gl_rasterizer.h" | 15 | #include "video_core/renderer_opengl/gl_rasterizer.h" |
| @@ -344,8 +348,8 @@ ShaderDiskCacheUsage CachedShader::GetUsage(GLenum primitive_mode, | |||
| 344 | } | 348 | } |
| 345 | 349 | ||
| 346 | ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system, | 350 | ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system, |
| 347 | const Device& device) | 351 | Core::Frontend::EmuWindow& emu_window, const Device& device) |
| 348 | : RasterizerCache{rasterizer}, device{device}, disk_cache{system} {} | 352 | : RasterizerCache{rasterizer}, emu_window{emu_window}, device{device}, disk_cache{system} {} |
| 349 | 353 | ||
| 350 | void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading, | 354 | void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading, |
| 351 | const VideoCore::DiskResourceLoadCallback& callback) { | 355 | const VideoCore::DiskResourceLoadCallback& callback) { |
| @@ -353,62 +357,107 @@ void ShaderCacheOpenGL::LoadDiskCache(const std::atomic_bool& stop_loading, | |||
| 353 | if (!transferable) { | 357 | if (!transferable) { |
| 354 | return; | 358 | return; |
| 355 | } | 359 | } |
| 356 | const auto [raws, usages] = *transferable; | 360 | const auto [raws, shader_usages] = *transferable; |
| 357 | 361 | ||
| 358 | auto [decompiled, dumps] = disk_cache.LoadPrecompiled(); | 362 | auto [decompiled, dumps] = disk_cache.LoadPrecompiled(); |
| 359 | 363 | ||
| 360 | const auto supported_formats{GetSupportedFormats()}; | 364 | const auto supported_formats{GetSupportedFormats()}; |
| 361 | const auto unspecialized{ | 365 | const auto unspecialized_shaders{ |
| 362 | GenerateUnspecializedShaders(stop_loading, callback, raws, decompiled)}; | 366 | GenerateUnspecializedShaders(stop_loading, callback, raws, decompiled)}; |
| 363 | if (stop_loading) | 367 | if (stop_loading) { |
| 364 | return; | 368 | return; |
| 369 | } | ||
| 365 | 370 | ||
| 366 | // Track if precompiled cache was altered during loading to know if we have to serialize the | 371 | // Track if precompiled cache was altered during loading to know if we have to serialize the |
| 367 | // virtual precompiled cache file back to the hard drive | 372 | // virtual precompiled cache file back to the hard drive |
| 368 | bool precompiled_cache_altered = false; | 373 | bool precompiled_cache_altered = false; |
| 369 | 374 | ||
| 370 | // Build shaders | 375 | // Inform the frontend about shader build initialization |
| 371 | if (callback) | 376 | if (callback) { |
| 372 | callback(VideoCore::LoadCallbackStage::Build, 0, usages.size()); | 377 | callback(VideoCore::LoadCallbackStage::Build, 0, shader_usages.size()); |
| 373 | for (std::size_t i = 0; i < usages.size(); ++i) { | 378 | } |
| 374 | if (stop_loading) | ||
| 375 | return; | ||
| 376 | 379 | ||
| 377 | const auto& usage{usages[i]}; | 380 | std::mutex mutex; |
| 378 | LOG_INFO(Render_OpenGL, "Building shader {:016x} ({} of {})", usage.unique_identifier, | 381 | std::size_t built_shaders = 0; // It doesn't have be atomic since it's used behind a mutex |
| 379 | i + 1, usages.size()); | 382 | std::atomic_bool compilation_failed = false; |
| 380 | 383 | ||
| 381 | const auto& unspec{unspecialized.at(usage.unique_identifier)}; | 384 | const auto Worker = [&](Core::Frontend::GraphicsContext* context, std::size_t begin, |
| 382 | const auto dump_it = dumps.find(usage); | 385 | std::size_t end, const std::vector<ShaderDiskCacheUsage>& shader_usages, |
| 386 | const ShaderDumpsMap& dumps) { | ||
| 387 | context->MakeCurrent(); | ||
| 388 | SCOPE_EXIT({ return context->DoneCurrent(); }); | ||
| 383 | 389 | ||
| 384 | CachedProgram shader; | 390 | for (std::size_t i = begin; i < end; ++i) { |
| 385 | if (dump_it != dumps.end()) { | 391 | if (stop_loading || compilation_failed) { |
| 386 | // If the shader is dumped, attempt to load it with | 392 | return; |
| 387 | shader = GeneratePrecompiledProgram(dump_it->second, supported_formats); | 393 | } |
| 394 | const auto& usage{shader_usages[i]}; | ||
| 395 | LOG_INFO(Render_OpenGL, "Building shader {:016x} (index {} of {})", | ||
| 396 | usage.unique_identifier, i, shader_usages.size()); | ||
| 397 | |||
| 398 | const auto& unspecialized{unspecialized_shaders.at(usage.unique_identifier)}; | ||
| 399 | const auto dump{dumps.find(usage)}; | ||
| 400 | |||
| 401 | CachedProgram shader; | ||
| 402 | if (dump != dumps.end()) { | ||
| 403 | // If the shader is dumped, attempt to load it with | ||
| 404 | shader = GeneratePrecompiledProgram(dump->second, supported_formats); | ||
| 405 | if (!shader) { | ||
| 406 | compilation_failed = true; | ||
| 407 | return; | ||
| 408 | } | ||
| 409 | } | ||
| 388 | if (!shader) { | 410 | if (!shader) { |
| 389 | // Invalidate the precompiled cache if a shader dumped shader was rejected | 411 | shader = SpecializeShader(unspecialized.code, unspecialized.entries, |
| 390 | disk_cache.InvalidatePrecompiled(); | 412 | unspecialized.program_type, usage.bindings, |
| 391 | precompiled_cache_altered = true; | 413 | usage.primitive, true); |
| 392 | dumps.clear(); | ||
| 393 | } | 414 | } |
| 415 | |||
| 416 | std::scoped_lock lock(mutex); | ||
| 417 | if (callback) { | ||
| 418 | callback(VideoCore::LoadCallbackStage::Build, ++built_shaders, | ||
| 419 | shader_usages.size()); | ||
| 420 | } | ||
| 421 | |||
| 422 | precompiled_programs.emplace(usage, std::move(shader)); | ||
| 394 | } | 423 | } |
| 395 | if (!shader) { | 424 | }; |
| 396 | shader = SpecializeShader(unspec.code, unspec.entries, unspec.program_type, | 425 | |
| 397 | usage.bindings, usage.primitive, true); | 426 | const auto num_workers{static_cast<std::size_t>(std::thread::hardware_concurrency() + 1)}; |
| 398 | } | 427 | const std::size_t bucket_size{shader_usages.size() / num_workers}; |
| 399 | precompiled_programs.insert({usage, std::move(shader)}); | 428 | std::vector<std::unique_ptr<Core::Frontend::GraphicsContext>> contexts(num_workers); |
| 429 | std::vector<std::thread> threads(num_workers); | ||
| 430 | for (std::size_t i = 0; i < num_workers; ++i) { | ||
| 431 | const bool is_last_worker = i + 1 == num_workers; | ||
| 432 | const std::size_t start{bucket_size * i}; | ||
| 433 | const std::size_t end{is_last_worker ? shader_usages.size() : start + bucket_size}; | ||
| 434 | |||
| 435 | // On some platforms the shared context has to be created from the GUI thread | ||
| 436 | contexts[i] = emu_window.CreateSharedContext(); | ||
| 437 | threads[i] = std::thread(Worker, contexts[i].get(), start, end, shader_usages, dumps); | ||
| 438 | } | ||
| 439 | for (auto& thread : threads) { | ||
| 440 | thread.join(); | ||
| 441 | } | ||
| 400 | 442 | ||
| 401 | if (callback) | 443 | if (compilation_failed) { |
| 402 | callback(VideoCore::LoadCallbackStage::Build, i + 1, usages.size()); | 444 | // Invalidate the precompiled cache if a shader dumped shader was rejected |
| 445 | disk_cache.InvalidatePrecompiled(); | ||
| 446 | dumps.clear(); | ||
| 447 | precompiled_cache_altered = true; | ||
| 448 | return; | ||
| 449 | } | ||
| 450 | if (stop_loading) { | ||
| 451 | return; | ||
| 403 | } | 452 | } |
| 404 | 453 | ||
| 405 | // TODO(Rodrigo): Do state tracking for transferable shaders and do a dummy draw before | 454 | // TODO(Rodrigo): Do state tracking for transferable shaders and do a dummy draw before |
| 406 | // precompiling them | 455 | // precompiling them |
| 407 | 456 | ||
| 408 | for (std::size_t i = 0; i < usages.size(); ++i) { | 457 | for (std::size_t i = 0; i < shader_usages.size(); ++i) { |
| 409 | const auto& usage{usages[i]}; | 458 | const auto& usage{shader_usages[i]}; |
| 410 | if (dumps.find(usage) == dumps.end()) { | 459 | if (dumps.find(usage) == dumps.end()) { |
| 411 | const auto& program = precompiled_programs.at(usage); | 460 | const auto& program{precompiled_programs.at(usage)}; |
| 412 | disk_cache.SaveDump(usage, program->handle); | 461 | disk_cache.SaveDump(usage, program->handle); |
| 413 | precompiled_cache_altered = true; | 462 | precompiled_cache_altered = true; |
| 414 | } | 463 | } |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h index 31b979987..64e5a5594 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_cache.h | |||
| @@ -22,7 +22,11 @@ | |||
| 22 | 22 | ||
| 23 | namespace Core { | 23 | namespace Core { |
| 24 | class System; | 24 | class System; |
| 25 | } // namespace Core | 25 | } |
| 26 | |||
| 27 | namespace Core::Frontend { | ||
| 28 | class EmuWindow; | ||
| 29 | } | ||
| 26 | 30 | ||
| 27 | namespace OpenGL { | 31 | namespace OpenGL { |
| 28 | 32 | ||
| @@ -111,7 +115,7 @@ private: | |||
| 111 | class ShaderCacheOpenGL final : public RasterizerCache<Shader> { | 115 | class ShaderCacheOpenGL final : public RasterizerCache<Shader> { |
| 112 | public: | 116 | public: |
| 113 | explicit ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system, | 117 | explicit ShaderCacheOpenGL(RasterizerOpenGL& rasterizer, Core::System& system, |
| 114 | const Device& device); | 118 | Core::Frontend::EmuWindow& emu_window, const Device& device); |
| 115 | 119 | ||
| 116 | /// Loads disk cache for the current game | 120 | /// Loads disk cache for the current game |
| 117 | void LoadDiskCache(const std::atomic_bool& stop_loading, | 121 | void LoadDiskCache(const std::atomic_bool& stop_loading, |
| @@ -133,13 +137,13 @@ private: | |||
| 133 | CachedProgram GeneratePrecompiledProgram(const ShaderDiskCacheDump& dump, | 137 | CachedProgram GeneratePrecompiledProgram(const ShaderDiskCacheDump& dump, |
| 134 | const std::set<GLenum>& supported_formats); | 138 | const std::set<GLenum>& supported_formats); |
| 135 | 139 | ||
| 140 | Core::Frontend::EmuWindow& emu_window; | ||
| 136 | const Device& device; | 141 | const Device& device; |
| 137 | |||
| 138 | std::array<Shader, Maxwell::MaxShaderProgram> last_shaders; | ||
| 139 | |||
| 140 | ShaderDiskCacheOpenGL disk_cache; | 142 | ShaderDiskCacheOpenGL disk_cache; |
| 143 | |||
| 141 | PrecompiledShaders precompiled_shaders; | 144 | PrecompiledShaders precompiled_shaders; |
| 142 | PrecompiledPrograms precompiled_programs; | 145 | PrecompiledPrograms precompiled_programs; |
| 146 | std::array<Shader, Maxwell::MaxShaderProgram> last_shaders; | ||
| 143 | }; | 147 | }; |
| 144 | 148 | ||
| 145 | } // namespace OpenGL | 149 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp index fba9c594a..ee4a45ca2 100644 --- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp | |||
| @@ -183,8 +183,7 @@ ShaderDiskCacheOpenGL::LoadTransferable() { | |||
| 183 | return {{raws, usages}}; | 183 | return {{raws, usages}}; |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | std::pair<std::unordered_map<u64, ShaderDiskCacheDecompiled>, | 186 | std::pair<std::unordered_map<u64, ShaderDiskCacheDecompiled>, ShaderDumpsMap> |
| 187 | std::unordered_map<ShaderDiskCacheUsage, ShaderDiskCacheDump>> | ||
| 188 | ShaderDiskCacheOpenGL::LoadPrecompiled() { | 187 | ShaderDiskCacheOpenGL::LoadPrecompiled() { |
| 189 | if (!IsUsable()) | 188 | if (!IsUsable()) |
| 190 | return {}; | 189 | return {}; |
| @@ -208,8 +207,7 @@ ShaderDiskCacheOpenGL::LoadPrecompiled() { | |||
| 208 | return *result; | 207 | return *result; |
| 209 | } | 208 | } |
| 210 | 209 | ||
| 211 | std::optional<std::pair<std::unordered_map<u64, ShaderDiskCacheDecompiled>, | 210 | std::optional<std::pair<std::unordered_map<u64, ShaderDiskCacheDecompiled>, ShaderDumpsMap>> |
| 212 | std::unordered_map<ShaderDiskCacheUsage, ShaderDiskCacheDump>>> | ||
| 213 | ShaderDiskCacheOpenGL::LoadPrecompiledFile(FileUtil::IOFile& file) { | 211 | ShaderDiskCacheOpenGL::LoadPrecompiledFile(FileUtil::IOFile& file) { |
| 214 | // Read compressed file from disk and decompress to virtual precompiled cache file | 212 | // Read compressed file from disk and decompress to virtual precompiled cache file |
| 215 | std::vector<u8> compressed(file.GetSize()); | 213 | std::vector<u8> compressed(file.GetSize()); |
| @@ -230,7 +228,7 @@ ShaderDiskCacheOpenGL::LoadPrecompiledFile(FileUtil::IOFile& file) { | |||
| 230 | } | 228 | } |
| 231 | 229 | ||
| 232 | std::unordered_map<u64, ShaderDiskCacheDecompiled> decompiled; | 230 | std::unordered_map<u64, ShaderDiskCacheDecompiled> decompiled; |
| 233 | std::unordered_map<ShaderDiskCacheUsage, ShaderDiskCacheDump> dumps; | 231 | ShaderDumpsMap dumps; |
| 234 | while (precompiled_cache_virtual_file_offset < precompiled_cache_virtual_file.GetSize()) { | 232 | while (precompiled_cache_virtual_file_offset < precompiled_cache_virtual_file.GetSize()) { |
| 235 | PrecompiledEntryKind kind{}; | 233 | PrecompiledEntryKind kind{}; |
| 236 | if (!LoadObjectFromPrecompiled(kind)) { | 234 | if (!LoadObjectFromPrecompiled(kind)) { |
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.h b/src/video_core/renderer_opengl/gl_shader_disk_cache.h index 2da0a4a23..ecd72ba58 100644 --- a/src/video_core/renderer_opengl/gl_shader_disk_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.h | |||
| @@ -33,6 +33,11 @@ namespace OpenGL { | |||
| 33 | using ProgramCode = std::vector<u64>; | 33 | using ProgramCode = std::vector<u64>; |
| 34 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; | 34 | using Maxwell = Tegra::Engines::Maxwell3D::Regs; |
| 35 | 35 | ||
| 36 | struct ShaderDiskCacheUsage; | ||
| 37 | struct ShaderDiskCacheDump; | ||
| 38 | |||
| 39 | using ShaderDumpsMap = std::unordered_map<ShaderDiskCacheUsage, ShaderDiskCacheDump>; | ||
| 40 | |||
| 36 | /// Allocated bindings used by an OpenGL shader program | 41 | /// Allocated bindings used by an OpenGL shader program |
| 37 | struct BaseBindings { | 42 | struct BaseBindings { |
| 38 | u32 cbuf{}; | 43 | u32 cbuf{}; |
| @@ -294,4 +299,4 @@ private: | |||
| 294 | bool tried_to_load{}; | 299 | bool tried_to_load{}; |
| 295 | }; | 300 | }; |
| 296 | 301 | ||
| 297 | } // namespace OpenGL \ No newline at end of file | 302 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index d69cba9c3..3451d321d 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -97,8 +97,8 @@ static std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(const float width, cons | |||
| 97 | return matrix; | 97 | return matrix; |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& window, Core::System& system) | 100 | RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system) |
| 101 | : VideoCore::RendererBase{window}, system{system} {} | 101 | : VideoCore::RendererBase{emu_window}, emu_window{emu_window}, system{system} {} |
| 102 | 102 | ||
| 103 | RendererOpenGL::~RendererOpenGL() = default; | 103 | RendererOpenGL::~RendererOpenGL() = default; |
| 104 | 104 | ||
| @@ -265,7 +265,7 @@ void RendererOpenGL::CreateRasterizer() { | |||
| 265 | } | 265 | } |
| 266 | // Initialize sRGB Usage | 266 | // Initialize sRGB Usage |
| 267 | OpenGLState::ClearsRGBUsed(); | 267 | OpenGLState::ClearsRGBUsed(); |
| 268 | rasterizer = std::make_unique<RasterizerOpenGL>(system, screen_info); | 268 | rasterizer = std::make_unique<RasterizerOpenGL>(system, emu_window, screen_info); |
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, | 271 | void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index 6cbf9d2cb..4aebf2321 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h | |||
| @@ -45,7 +45,7 @@ struct ScreenInfo { | |||
| 45 | 45 | ||
| 46 | class RendererOpenGL : public VideoCore::RendererBase { | 46 | class RendererOpenGL : public VideoCore::RendererBase { |
| 47 | public: | 47 | public: |
| 48 | explicit RendererOpenGL(Core::Frontend::EmuWindow& window, Core::System& system); | 48 | explicit RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system); |
| 49 | ~RendererOpenGL() override; | 49 | ~RendererOpenGL() override; |
| 50 | 50 | ||
| 51 | /// Swap buffers (render frame) | 51 | /// Swap buffers (render frame) |
| @@ -77,6 +77,7 @@ private: | |||
| 77 | void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a, | 77 | void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a, |
| 78 | const TextureInfo& texture); | 78 | const TextureInfo& texture); |
| 79 | 79 | ||
| 80 | Core::Frontend::EmuWindow& emu_window; | ||
| 80 | Core::System& system; | 81 | Core::System& system; |
| 81 | 82 | ||
| 82 | OpenGLState state; | 83 | OpenGLState state; |
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index c2783d684..eeee603d1 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp | |||
| @@ -91,25 +91,25 @@ void EmuThread::run() { | |||
| 91 | 91 | ||
| 92 | class GGLContext : public Core::Frontend::GraphicsContext { | 92 | class GGLContext : public Core::Frontend::GraphicsContext { |
| 93 | public: | 93 | public: |
| 94 | explicit GGLContext(QOpenGLContext* shared_context) | 94 | explicit GGLContext(QOpenGLContext* shared_context) : shared_context{shared_context} { |
| 95 | : context{std::make_unique<QOpenGLContext>(shared_context)} { | 95 | context.setFormat(shared_context->format()); |
| 96 | surface.setFormat(shared_context->format()); | 96 | context.setShareContext(shared_context); |
| 97 | surface.create(); | 97 | context.create(); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | void MakeCurrent() override { | 100 | void MakeCurrent() override { |
| 101 | context->makeCurrent(&surface); | 101 | context.makeCurrent(shared_context->surface()); |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | void DoneCurrent() override { | 104 | void DoneCurrent() override { |
| 105 | context->doneCurrent(); | 105 | context.doneCurrent(); |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | void SwapBuffers() override {} | 108 | void SwapBuffers() override {} |
| 109 | 109 | ||
| 110 | private: | 110 | private: |
| 111 | std::unique_ptr<QOpenGLContext> context; | 111 | QOpenGLContext* shared_context; |
| 112 | QOffscreenSurface surface; | 112 | QOpenGLContext context; |
| 113 | }; | 113 | }; |
| 114 | 114 | ||
| 115 | // This class overrides paintEvent and resizeEvent to prevent the GUI thread from stealing GL | 115 | // This class overrides paintEvent and resizeEvent to prevent the GUI thread from stealing GL |
| @@ -358,7 +358,7 @@ void GRenderWindow::OnClientAreaResized(unsigned width, unsigned height) { | |||
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | std::unique_ptr<Core::Frontend::GraphicsContext> GRenderWindow::CreateSharedContext() const { | 360 | std::unique_ptr<Core::Frontend::GraphicsContext> GRenderWindow::CreateSharedContext() const { |
| 361 | return std::make_unique<GGLContext>(shared_context.get()); | 361 | return std::make_unique<GGLContext>(context.get()); |
| 362 | } | 362 | } |
| 363 | 363 | ||
| 364 | void GRenderWindow::InitRenderTarget() { | 364 | void GRenderWindow::InitRenderTarget() { |