summaryrefslogtreecommitdiff
path: root/src/mesa/state_tracker/st_texture.h
diff options
context:
space:
mode:
authorNicolai Hähnle <nicolai.haehnle@amd.com>2017-10-22 17:38:36 +0200
committerNicolai Hähnle <nicolai.haehnle@amd.com>2017-11-09 11:50:55 +0100
commit637240d824051b8b99f35c165cabe31106612f2a (patch)
treea0fa593530357172edf6414f5b6548dc9cc88e7e /src/mesa/state_tracker/st_texture.h
parent8d20c660a9831c367d98ed2fea25e5276e6466f2 (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 <marek.olsak@amd.com>
Diffstat (limited to 'src/mesa/state_tracker/st_texture.h')
-rw-r--r--src/mesa/state_tracker/st_texture.h40
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