diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_graphics_pipeline.cpp | 30 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_graphics_pipeline.h | 7 |
2 files changed, 33 insertions, 4 deletions
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp index c8b2d833d..fac0034fb 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp +++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp | |||
| @@ -237,10 +237,12 @@ GraphicsPipeline::GraphicsPipeline( | |||
| 237 | if (key.xfb_enabled && device.UseAssemblyShaders()) { | 237 | if (key.xfb_enabled && device.UseAssemblyShaders()) { |
| 238 | GenerateTransformFeedbackState(); | 238 | GenerateTransformFeedbackState(); |
| 239 | } | 239 | } |
| 240 | auto func{[this, device, sources, sources_spirv, | 240 | const bool in_parallel = thread_worker != nullptr; |
| 241 | shader_notify](ShaderContext::Context*) mutable { | 241 | const auto backend = device.GetShaderBackend(); |
| 242 | auto func{[this, sources = std::move(sources), sources_spirv = std::move(sources_spirv), | ||
| 243 | shader_notify, backend, in_parallel](ShaderContext::Context*) mutable { | ||
| 242 | for (size_t stage = 0; stage < 5; ++stage) { | 244 | for (size_t stage = 0; stage < 5; ++stage) { |
| 243 | switch (device.GetShaderBackend()) { | 245 | switch (backend) { |
| 244 | case Settings::ShaderBackend::GLSL: | 246 | case Settings::ShaderBackend::GLSL: |
| 245 | if (!sources[stage].empty()) { | 247 | if (!sources[stage].empty()) { |
| 246 | source_programs[stage] = CreateProgram(sources[stage], Stage(stage)); | 248 | source_programs[stage] = CreateProgram(sources[stage], Stage(stage)); |
| @@ -249,6 +251,10 @@ GraphicsPipeline::GraphicsPipeline( | |||
| 249 | case Settings::ShaderBackend::GLASM: | 251 | case Settings::ShaderBackend::GLASM: |
| 250 | if (!sources[stage].empty()) { | 252 | if (!sources[stage].empty()) { |
| 251 | assembly_programs[stage] = CompileProgram(sources[stage], AssemblyStage(stage)); | 253 | assembly_programs[stage] = CompileProgram(sources[stage], AssemblyStage(stage)); |
| 254 | if (in_parallel) { | ||
| 255 | // Make sure program is built before continuing when building in parallel | ||
| 256 | glGetString(GL_PROGRAM_ERROR_STRING_NV); | ||
| 257 | } | ||
| 252 | } | 258 | } |
| 253 | break; | 259 | break; |
| 254 | case Settings::ShaderBackend::SPIRV: | 260 | case Settings::ShaderBackend::SPIRV: |
| @@ -258,10 +264,20 @@ GraphicsPipeline::GraphicsPipeline( | |||
| 258 | break; | 264 | break; |
| 259 | } | 265 | } |
| 260 | } | 266 | } |
| 267 | if (in_parallel && backend != Settings::ShaderBackend::GLASM) { | ||
| 268 | // Make sure programs have built if we are building shaders in parallel | ||
| 269 | for (OGLProgram& program : source_programs) { | ||
| 270 | if (program.handle != 0) { | ||
| 271 | GLint status{}; | ||
| 272 | glGetProgramiv(program.handle, GL_LINK_STATUS, &status); | ||
| 273 | } | ||
| 274 | } | ||
| 275 | } | ||
| 261 | if (shader_notify) { | 276 | if (shader_notify) { |
| 262 | shader_notify->MarkShaderComplete(); | 277 | shader_notify->MarkShaderComplete(); |
| 263 | } | 278 | } |
| 264 | is_built = true; | 279 | is_built = true; |
| 280 | built_condvar.notify_one(); | ||
| 265 | }}; | 281 | }}; |
| 266 | if (thread_worker) { | 282 | if (thread_worker) { |
| 267 | thread_worker->QueueWork(std::move(func)); | 283 | thread_worker->QueueWork(std::move(func)); |
| @@ -434,6 +450,9 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) { | |||
| 434 | buffer_cache.UpdateGraphicsBuffers(is_indexed); | 450 | buffer_cache.UpdateGraphicsBuffers(is_indexed); |
| 435 | buffer_cache.BindHostGeometryBuffers(is_indexed); | 451 | buffer_cache.BindHostGeometryBuffers(is_indexed); |
| 436 | 452 | ||
| 453 | if (!is_built.load(std::memory_order::relaxed)) { | ||
| 454 | WaitForBuild(); | ||
| 455 | } | ||
| 437 | if (assembly_programs[0].handle != 0) { | 456 | if (assembly_programs[0].handle != 0) { |
| 438 | program_manager.BindAssemblyPrograms(assembly_programs, enabled_stages_mask); | 457 | program_manager.BindAssemblyPrograms(assembly_programs, enabled_stages_mask); |
| 439 | } else { | 458 | } else { |
| @@ -545,4 +564,9 @@ void GraphicsPipeline::GenerateTransformFeedbackState() { | |||
| 545 | num_xfb_strides = static_cast<GLsizei>(current_stream - xfb_streams.data()); | 564 | num_xfb_strides = static_cast<GLsizei>(current_stream - xfb_streams.data()); |
| 546 | } | 565 | } |
| 547 | 566 | ||
| 567 | void GraphicsPipeline::WaitForBuild() { | ||
| 568 | std::unique_lock lock{built_mutex}; | ||
| 569 | built_condvar.wait(lock, [this] { return is_built.load(std::memory_order::relaxed); }); | ||
| 570 | } | ||
| 571 | |||
| 548 | } // namespace OpenGL | 572 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.h b/src/video_core/renderer_opengl/gl_graphics_pipeline.h index 5e34b9537..4e28d9a42 100644 --- a/src/video_core/renderer_opengl/gl_graphics_pipeline.h +++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.h | |||
| @@ -119,6 +119,8 @@ private: | |||
| 119 | 119 | ||
| 120 | void GenerateTransformFeedbackState(); | 120 | void GenerateTransformFeedbackState(); |
| 121 | 121 | ||
| 122 | void WaitForBuild(); | ||
| 123 | |||
| 122 | TextureCache& texture_cache; | 124 | TextureCache& texture_cache; |
| 123 | BufferCache& buffer_cache; | 125 | BufferCache& buffer_cache; |
| 124 | Tegra::MemoryManager& gpu_memory; | 126 | Tegra::MemoryManager& gpu_memory; |
| @@ -143,13 +145,16 @@ private: | |||
| 143 | 145 | ||
| 144 | bool use_storage_buffers{}; | 146 | bool use_storage_buffers{}; |
| 145 | bool writes_global_memory{}; | 147 | bool writes_global_memory{}; |
| 146 | std::atomic_bool is_built{false}; | ||
| 147 | 148 | ||
| 148 | static constexpr std::size_t XFB_ENTRY_STRIDE = 3; | 149 | static constexpr std::size_t XFB_ENTRY_STRIDE = 3; |
| 149 | GLsizei num_xfb_attribs{}; | 150 | GLsizei num_xfb_attribs{}; |
| 150 | GLsizei num_xfb_strides{}; | 151 | GLsizei num_xfb_strides{}; |
| 151 | std::array<GLint, 128 * XFB_ENTRY_STRIDE * Maxwell::NumTransformFeedbackBuffers> xfb_attribs{}; | 152 | std::array<GLint, 128 * XFB_ENTRY_STRIDE * Maxwell::NumTransformFeedbackBuffers> xfb_attribs{}; |
| 152 | std::array<GLint, Maxwell::NumTransformFeedbackBuffers> xfb_streams{}; | 153 | std::array<GLint, Maxwell::NumTransformFeedbackBuffers> xfb_streams{}; |
| 154 | |||
| 155 | std::mutex built_mutex; | ||
| 156 | std::condition_variable built_condvar; | ||
| 157 | std::atomic_bool is_built{false}; | ||
| 153 | }; | 158 | }; |
| 154 | 159 | ||
| 155 | } // namespace OpenGL | 160 | } // namespace OpenGL |