diff options
author | Nicolai Hähnle <[email protected]> | 2017-10-22 17:38:36 +0200 |
---|---|---|
committer | Nicolai Hähnle <[email protected]> | 2017-11-09 11:50:55 +0100 |
commit | 637240d824051b8b99f35c165cabe31106612f2a (patch) | |
tree | a0fa593530357172edf6414f5b6548dc9cc88e7e /src/mesa/state_tracker/st_texture.h | |
parent | 8d20c660a9831c367d98ed2fea25e5276e6466f2 (diff) |
st/mesa: guard sampler views changes with a mutex
Some locking is unfortunately required, because well-formed GL programs
can have multiple threads racing to access the same texture, e.g.: two
threads/contexts rendering from the same texture, or one thread destroying
a context while the other is rendering from or modifying a texture.
Since even the simple mutex caused noticable slowdowns in the piglit
drawoverhead micro-benchmark, this patch uses a slightly more involved
approach to keep locks out of the fast path:
- the initial lookup of sampler views happens without taking a lock
- a per-texture lock is only taken when we have to modify the sampler
view(s)
- since each thread mostly operates only on the entry corresponding to
its context, the main issue is re-allocation of the sampler view array
when it needs to be grown, but the old copy is not freed
Old copies of the sampler views array are kept around in a linked list
until the entire texture object is deleted. The total memory wasted
in this way is roughly equal to the size of the current sampler views
array.
Fixes non-deterministic memory corruption in some
dEQP-EGL.functional.sharing.gles2.multithread.* tests, e.g.
dEQP-EGL.functional.sharing.gles2.multithread.simple.images.texture_source.create_texture_render
Reviewed-by: Marek Olšák <[email protected]>
Diffstat (limited to 'src/mesa/state_tracker/st_texture.h')
-rw-r--r-- | src/mesa/state_tracker/st_texture.h | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h index 8b549b86085..c10a2753104 100644 --- a/src/mesa/state_tracker/st_texture.h +++ b/src/mesa/state_tracker/st_texture.h @@ -31,6 +31,7 @@ #include "pipe/p_context.h" #include "util/u_sampler.h" +#include "util/simple_mtx.h" #include "main/mtypes.h" @@ -62,6 +63,16 @@ struct st_sampler_view { /** + * Container for per-context sampler views of a texture. + */ +struct st_sampler_views { + struct st_sampler_views *next; + uint32_t max; + uint32_t count; + struct st_sampler_view views[0]; +}; + +/** * Subclass of gl_texure_image. */ struct st_texture_image @@ -105,13 +116,34 @@ struct st_texture_object */ struct pipe_resource *pt; - /* Number of views in sampler_views array */ - GLuint num_sampler_views; + /* Protect modifications of the sampler_views array */ + simple_mtx_t validate_mutex; - /* Array of sampler views (one per context) attached to this texture + /* Container of sampler views (one per context) attached to this texture * object. Created lazily on first binding in context. + * + * Purely read-only accesses to the current context's own sampler view + * require no locking. Another thread may simultaneously replace the + * container object in order to grow the array, but the old container will + * be kept alive. + * + * Writing to the container (even for modifying the current context's own + * sampler view) always requires taking the validate_mutex to protect against + * concurrent container switches. + * + * NULL'ing another context's sampler view is allowed only while + * implementing an API call that modifies the texture: an application which + * calls those while simultaneously reading the texture in another context + * invokes undefined behavior. (TODO: a dubious violation of this rule is + * st_finalize_texture, which is a lazy operation that corresponds to a + * texture modification.) + */ + struct st_sampler_views *sampler_views; + + /* Old sampler views container objects that have not been freed yet because + * other threads/contexts may still be reading from them. */ - struct st_sampler_view *sampler_views; + struct st_sampler_views *sampler_views_old; /* True if this texture comes from the window system. Such a texture * cannot be reallocated and the format can only be changed with a sampler |