summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Liam2022-12-13 12:30:15 -0500
committerGravatar Alexander Orzechowski2022-12-13 13:23:23 -0500
commitd5f53da79d944869eb88416494ecf10a47eee90d (patch)
tree8b2bc2084d711ba2196d2e8121216eac25e982cb /src
parentMerge pull request #9425 from german77/german_unlimited (diff)
downloadyuzu-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.cpp5
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp10
-rw-r--r--src/video_core/renderer_opengl/gl_device.h5
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp76
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.h1
-rw-r--r--src/yuzu/bootmanager.cpp3
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
176private: 180private:
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