diff options
| author | 2022-12-13 12:30:15 -0500 | |
|---|---|---|
| committer | 2022-12-13 13:23:23 -0500 | |
| commit | d5f53da79d944869eb88416494ecf10a47eee90d (patch) | |
| tree | 8b2bc2084d711ba2196d2e8121216eac25e982cb /src | |
| parent | Merge pull request #9425 from german77/german_unlimited (diff) | |
| download | yuzu-d5f53da79d944869eb88416494ecf10a47eee90d.tar.gz yuzu-d5f53da79d944869eb88416494ecf10a47eee90d.tar.xz yuzu-d5f53da79d944869eb88416494ecf10a47eee90d.zip | |
renderer_opengl: refactor context acquire
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/gpu.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_device.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_device.h | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 76 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.h | 1 | ||||
| -rw-r--r-- | src/yuzu/bootmanager.cpp | 3 |
6 files changed, 62 insertions, 38 deletions
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 28b38273e..c6d54be63 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -223,8 +223,6 @@ struct GPU::Impl { | |||
| 223 | /// core timing events. | 223 | /// core timing events. |
| 224 | void Start() { | 224 | void Start() { |
| 225 | gpu_thread.StartThread(*renderer, renderer->Context(), *scheduler); | 225 | gpu_thread.StartThread(*renderer, renderer->Context(), *scheduler); |
| 226 | cpu_context = renderer->GetRenderWindow().CreateSharedContext(); | ||
| 227 | cpu_context->MakeCurrent(); | ||
| 228 | } | 226 | } |
| 229 | 227 | ||
| 230 | void NotifyShutdown() { | 228 | void NotifyShutdown() { |
| @@ -235,6 +233,9 @@ struct GPU::Impl { | |||
| 235 | 233 | ||
| 236 | /// Obtain the CPU Context | 234 | /// Obtain the CPU Context |
| 237 | void ObtainContext() { | 235 | void ObtainContext() { |
| 236 | if (!cpu_context) { | ||
| 237 | cpu_context = renderer->GetRenderWindow().CreateSharedContext(); | ||
| 238 | } | ||
| 238 | cpu_context->MakeCurrent(); | 239 | cpu_context->MakeCurrent(); |
| 239 | } | 240 | } |
| 240 | 241 | ||
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp index e2e3dac34..4c5020def 100644 --- a/src/video_core/renderer_opengl/gl_device.cpp +++ b/src/video_core/renderer_opengl/gl_device.cpp | |||
| @@ -126,9 +126,11 @@ Device::Device() { | |||
| 126 | const bool is_intel = vendor_name == "Intel"; | 126 | const bool is_intel = vendor_name == "Intel"; |
| 127 | 127 | ||
| 128 | #ifdef __unix__ | 128 | #ifdef __unix__ |
| 129 | const bool is_linux = true; | 129 | constexpr bool is_linux = true; |
| 130 | const bool is_wayland = strcasecmp(getenv("XDG_SESSION_TYPE"), "wayland") == 0; | ||
| 130 | #else | 131 | #else |
| 131 | const bool is_linux = false; | 132 | constexpr bool is_linux = false; |
| 133 | constexpr bool is_wayland = false; | ||
| 132 | #endif | 134 | #endif |
| 133 | 135 | ||
| 134 | bool disable_fast_buffer_sub_data = false; | 136 | bool disable_fast_buffer_sub_data = false; |
| @@ -194,9 +196,11 @@ Device::Device() { | |||
| 194 | } | 196 | } |
| 195 | 197 | ||
| 196 | // Blocks AMD and Intel OpenGL drivers on Windows from using asynchronous shader compilation. | 198 | // Blocks AMD and Intel OpenGL drivers on Windows from using asynchronous shader compilation. |
| 199 | // Blocks EGL on Wayland from using asynchronous shader compilation. | ||
| 197 | use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue() && | 200 | use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue() && |
| 198 | !(is_amd || (is_intel && !is_linux)); | 201 | !(is_amd || (is_intel && !is_linux)) && !is_wayland; |
| 199 | use_driver_cache = is_nvidia; | 202 | use_driver_cache = is_nvidia; |
| 203 | strict_context_required = is_wayland; | ||
| 200 | 204 | ||
| 201 | LOG_INFO(Render_OpenGL, "Renderer_VariableAOFFI: {}", has_variable_aoffi); | 205 | LOG_INFO(Render_OpenGL, "Renderer_VariableAOFFI: {}", has_variable_aoffi); |
| 202 | LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug); | 206 | LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug); |
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h index 5ef51ebcf..adb79c56e 100644 --- a/src/video_core/renderer_opengl/gl_device.h +++ b/src/video_core/renderer_opengl/gl_device.h | |||
| @@ -173,6 +173,10 @@ public: | |||
| 173 | return can_report_memory; | 173 | return can_report_memory; |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | bool StrictContextRequired() const { | ||
| 177 | return strict_context_required; | ||
| 178 | } | ||
| 179 | |||
| 176 | private: | 180 | private: |
| 177 | static bool TestVariableAoffi(); | 181 | static bool TestVariableAoffi(); |
| 178 | static bool TestPreciseBug(); | 182 | static bool TestPreciseBug(); |
| @@ -216,6 +220,7 @@ private: | |||
| 216 | bool has_cbuf_ftou_bug{}; | 220 | bool has_cbuf_ftou_bug{}; |
| 217 | bool has_bool_ref_bug{}; | 221 | bool has_bool_ref_bug{}; |
| 218 | bool can_report_memory{}; | 222 | bool can_report_memory{}; |
| 223 | bool strict_context_required{}; | ||
| 219 | 224 | ||
| 220 | std::string vendor_name; | 225 | std::string vendor_name; |
| 221 | }; | 226 | }; |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index a59d0d24e..fff55d585 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -174,6 +174,7 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo | |||
| 174 | texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, program_manager{program_manager_}, | 174 | texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, program_manager{program_manager_}, |
| 175 | state_tracker{state_tracker_}, shader_notify{shader_notify_}, | 175 | state_tracker{state_tracker_}, shader_notify{shader_notify_}, |
| 176 | use_asynchronous_shaders{device.UseAsynchronousShaders()}, | 176 | use_asynchronous_shaders{device.UseAsynchronousShaders()}, |
| 177 | strict_context_required{device.StrictContextRequired()}, | ||
| 177 | profile{ | 178 | profile{ |
| 178 | .supported_spirv = 0x00010000, | 179 | .supported_spirv = 0x00010000, |
| 179 | 180 | ||
| @@ -255,9 +256,14 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading, | |||
| 255 | } | 256 | } |
| 256 | shader_cache_filename = base_dir / "opengl.bin"; | 257 | shader_cache_filename = base_dir / "opengl.bin"; |
| 257 | 258 | ||
| 258 | if (!workers) { | 259 | if (!workers && !strict_context_required) { |
| 259 | workers = CreateWorkers(); | 260 | workers = CreateWorkers(); |
| 260 | } | 261 | } |
| 262 | std::optional<Context> strict_context; | ||
| 263 | if (strict_context_required) { | ||
| 264 | strict_context.emplace(emu_window); | ||
| 265 | } | ||
| 266 | |||
| 261 | struct { | 267 | struct { |
| 262 | std::mutex mutex; | 268 | std::mutex mutex; |
| 263 | size_t total{}; | 269 | size_t total{}; |
| @@ -265,44 +271,49 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading, | |||
| 265 | bool has_loaded{}; | 271 | bool has_loaded{}; |
| 266 | } state; | 272 | } state; |
| 267 | 273 | ||
| 274 | const auto queue_work{[&](Common::UniqueFunction<void, Context*>&& work) { | ||
| 275 | if (strict_context_required) { | ||
| 276 | work(&strict_context.value()); | ||
| 277 | } else { | ||
| 278 | workers->QueueWork(std::move(work)); | ||
| 279 | } | ||
| 280 | }}; | ||
| 268 | const auto load_compute{[&](std::ifstream& file, FileEnvironment env) { | 281 | const auto load_compute{[&](std::ifstream& file, FileEnvironment env) { |
| 269 | ComputePipelineKey key; | 282 | ComputePipelineKey key; |
| 270 | file.read(reinterpret_cast<char*>(&key), sizeof(key)); | 283 | file.read(reinterpret_cast<char*>(&key), sizeof(key)); |
| 271 | workers->QueueWork( | 284 | queue_work([this, key, env = std::move(env), &state, &callback](Context* ctx) mutable { |
| 272 | [this, key, env = std::move(env), &state, &callback](Context* ctx) mutable { | 285 | ctx->pools.ReleaseContents(); |
| 273 | ctx->pools.ReleaseContents(); | 286 | auto pipeline{CreateComputePipeline(ctx->pools, key, env)}; |
| 274 | auto pipeline{CreateComputePipeline(ctx->pools, key, env)}; | 287 | std::scoped_lock lock{state.mutex}; |
| 275 | std::scoped_lock lock{state.mutex}; | 288 | if (pipeline) { |
| 276 | if (pipeline) { | 289 | compute_cache.emplace(key, std::move(pipeline)); |
| 277 | compute_cache.emplace(key, std::move(pipeline)); | 290 | } |
| 278 | } | 291 | ++state.built; |
| 279 | ++state.built; | 292 | if (state.has_loaded) { |
| 280 | if (state.has_loaded) { | 293 | callback(VideoCore::LoadCallbackStage::Build, state.built, state.total); |
| 281 | callback(VideoCore::LoadCallbackStage::Build, state.built, state.total); | 294 | } |
| 282 | } | 295 | }); |
| 283 | }); | ||
| 284 | ++state.total; | 296 | ++state.total; |
| 285 | }}; | 297 | }}; |
| 286 | const auto load_graphics{[&](std::ifstream& file, std::vector<FileEnvironment> envs) { | 298 | const auto load_graphics{[&](std::ifstream& file, std::vector<FileEnvironment> envs) { |
| 287 | GraphicsPipelineKey key; | 299 | GraphicsPipelineKey key; |
| 288 | file.read(reinterpret_cast<char*>(&key), sizeof(key)); | 300 | file.read(reinterpret_cast<char*>(&key), sizeof(key)); |
| 289 | workers->QueueWork( | 301 | queue_work([this, key, envs = std::move(envs), &state, &callback](Context* ctx) mutable { |
| 290 | [this, key, envs = std::move(envs), &state, &callback](Context* ctx) mutable { | 302 | boost::container::static_vector<Shader::Environment*, 5> env_ptrs; |
| 291 | boost::container::static_vector<Shader::Environment*, 5> env_ptrs; | 303 | for (auto& env : envs) { |
| 292 | for (auto& env : envs) { | 304 | env_ptrs.push_back(&env); |
| 293 | env_ptrs.push_back(&env); | 305 | } |
| 294 | } | 306 | ctx->pools.ReleaseContents(); |
| 295 | ctx->pools.ReleaseContents(); | 307 | auto pipeline{CreateGraphicsPipeline(ctx->pools, key, MakeSpan(env_ptrs), false)}; |
| 296 | auto pipeline{CreateGraphicsPipeline(ctx->pools, key, MakeSpan(env_ptrs), false)}; | 308 | std::scoped_lock lock{state.mutex}; |
| 297 | std::scoped_lock lock{state.mutex}; | 309 | if (pipeline) { |
| 298 | if (pipeline) { | 310 | graphics_cache.emplace(key, std::move(pipeline)); |
| 299 | graphics_cache.emplace(key, std::move(pipeline)); | 311 | } |
| 300 | } | 312 | ++state.built; |
| 301 | ++state.built; | 313 | if (state.has_loaded) { |
| 302 | if (state.has_loaded) { | 314 | callback(VideoCore::LoadCallbackStage::Build, state.built, state.total); |
| 303 | callback(VideoCore::LoadCallbackStage::Build, state.built, state.total); | 315 | } |
| 304 | } | 316 | }); |
| 305 | }); | ||
| 306 | ++state.total; | 317 | ++state.total; |
| 307 | }}; | 318 | }}; |
| 308 | LoadPipelines(stop_loading, shader_cache_filename, CACHE_VERSION, load_compute, load_graphics); | 319 | LoadPipelines(stop_loading, shader_cache_filename, CACHE_VERSION, load_compute, load_graphics); |
| @@ -314,6 +325,9 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading, | |||
| 314 | state.has_loaded = true; | 325 | state.has_loaded = true; |
| 315 | lock.unlock(); | 326 | lock.unlock(); |
| 316 | 327 | ||
| 328 | if (strict_context_required) { | ||
| 329 | return; | ||
| 330 | } | ||
| 317 | workers->WaitForRequests(stop_loading); | 331 | workers->WaitForRequests(stop_loading); |
| 318 | if (!use_asynchronous_shaders) { | 332 | if (!use_asynchronous_shaders) { |
| 319 | workers.reset(); | 333 | workers.reset(); |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h index 53ffea904..f82420592 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_cache.h | |||
| @@ -69,6 +69,7 @@ private: | |||
| 69 | StateTracker& state_tracker; | 69 | StateTracker& state_tracker; |
| 70 | VideoCore::ShaderNotify& shader_notify; | 70 | VideoCore::ShaderNotify& shader_notify; |
| 71 | const bool use_asynchronous_shaders; | 71 | const bool use_asynchronous_shaders; |
| 72 | const bool strict_context_required; | ||
| 72 | 73 | ||
| 73 | GraphicsPipelineKey graphics_key{}; | 74 | GraphicsPipelineKey graphics_key{}; |
| 74 | GraphicsPipeline* current_pipeline{}; | 75 | GraphicsPipeline* current_pipeline{}; |
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 5b5b6fed8..1437dec88 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp | |||
| @@ -61,8 +61,6 @@ void EmuThread::run() { | |||
| 61 | 61 | ||
| 62 | // Main process has been loaded. Make the context current to this thread and begin GPU and CPU | 62 | // Main process has been loaded. Make the context current to this thread and begin GPU and CPU |
| 63 | // execution. | 63 | // execution. |
| 64 | gpu.Start(); | ||
| 65 | |||
| 66 | gpu.ObtainContext(); | 64 | gpu.ObtainContext(); |
| 67 | 65 | ||
| 68 | emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); | 66 | emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); |
| @@ -77,6 +75,7 @@ void EmuThread::run() { | |||
| 77 | emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0); | 75 | emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0); |
| 78 | 76 | ||
| 79 | gpu.ReleaseContext(); | 77 | gpu.ReleaseContext(); |
| 78 | gpu.Start(); | ||
| 80 | 79 | ||
| 81 | system.GetCpuManager().OnGpuReady(); | 80 | system.GetCpuManager().OnGpuReady(); |
| 82 | 81 | ||