summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.cpp30
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.h7
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
567void 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