gl: Improve async compiler synchronization with initialization

- On multithreaded mesa, the program initialization routine was not
  being flushed correctly. Set up synchronization fence after initialization
is complete.
This commit is contained in:
kd-11 2020-06-07 11:13:20 +03:00 committed by kd-11
parent 87cc937d4e
commit ebbf329b6a
2 changed files with 34 additions and 28 deletions

View File

@ -2712,7 +2712,7 @@ public:
glUseProgram(m_id);
}
void link()
void link(std::function<void(program*)> init_func = {})
{
glLinkProgram(m_id);
@ -2736,6 +2736,11 @@ public:
}
else
{
if (init_func)
{
init_func(this);
}
m_fence.create();
if (!is_primary_context_thread())

View File

@ -42,38 +42,39 @@ struct GLTraits
.bind_fragment_data_location("ocol1", 1)
.bind_fragment_data_location("ocol2", 2)
.bind_fragment_data_location("ocol3", 3)
.link();
// Program locations are guaranteed to not change after linking
// Texture locations are simply bound to the TIUs so this can be done once
for (int i = 0; i < rsx::limits::fragment_textures_count; ++i)
{
int location;
if (result->uniforms.has_location(rsx::constants::fragment_texture_names[i], &location))
.link([](gl::glsl::program* program)
{
// Assign location to TIU
result->uniforms[location] = GL_FRAGMENT_TEXTURES_START + i;
// Check for stencil mirror
const std::string mirror_name = std::string(rsx::constants::fragment_texture_names[i]) + "_stencil";
if (result->uniforms.has_location(mirror_name, &location))
// Program locations are guaranteed to not change after linking
// Texture locations are simply bound to the TIUs so this can be done once
for (int i = 0; i < rsx::limits::fragment_textures_count; ++i)
{
// Assign mirror to TIU
result->uniforms[location] = GL_STENCIL_MIRRORS_START + i;
int location;
if (program->uniforms.has_location(rsx::constants::fragment_texture_names[i], &location))
{
// Assign location to TIU
program->uniforms[location] = GL_FRAGMENT_TEXTURES_START + i;
// Check for stencil mirror
const std::string mirror_name = std::string(rsx::constants::fragment_texture_names[i]) + "_stencil";
if (program->uniforms.has_location(mirror_name, &location))
{
// Assign mirror to TIU
program->uniforms[location] = GL_STENCIL_MIRRORS_START + i;
}
}
}
}
}
for (int i = 0; i < rsx::limits::vertex_textures_count; ++i)
{
int location;
if (result->uniforms.has_location(rsx::constants::vertex_texture_names[i], &location))
result->uniforms[location] = GL_VERTEX_TEXTURES_START + i;
}
for (int i = 0; i < rsx::limits::vertex_textures_count; ++i)
{
int location;
if (program->uniforms.has_location(rsx::constants::vertex_texture_names[i], &location))
program->uniforms[location] = GL_VERTEX_TEXTURES_START + i;
}
// Bind locations 0 and 1 to the stream buffers
result->uniforms[0] = GL_STREAM_BUFFER_START + 0;
result->uniforms[1] = GL_STREAM_BUFFER_START + 1;
// Bind locations 0 and 1 to the stream buffers
program->uniforms[0] = GL_STREAM_BUFFER_START + 0;
program->uniforms[1] = GL_STREAM_BUFFER_START + 1;
});
if (g_cfg.video.log_programs)
{