Mesa (master): freedreno/ir3: build binning variant at same time as draw variant

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jun 26 16:34:30 UTC 2020


Module: Mesa
Branch: master
Commit: 6aadb00e60fcf37bbef0dfe03e76e72e7c08bf33
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=6aadb00e60fcf37bbef0dfe03e76e72e7c08bf33

Author: Rob Clark <robdclark at chromium.org>
Date:   Sat Jun 20 12:53:36 2020 -0700

freedreno/ir3: build binning variant at same time as draw variant

For shader-cache, we are going to want to serialize them together.
Which is awkward if the two related variants are not compiled together.

This also decouples allocation and compile, which will simplify adding
shader-cache (which still needs to allocate, but can skip compile).

Signed-off-by: Rob Clark <robdclark at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5372>

---

 src/freedreno/ir3/ir3_shader.c                  | 99 +++++++++++++++++--------
 src/gallium/drivers/freedreno/ir3/ir3_gallium.c | 12 ++-
 2 files changed, 76 insertions(+), 35 deletions(-)

diff --git a/src/freedreno/ir3/ir3_shader.c b/src/freedreno/ir3/ir3_shader.c
index 76d3946c701..bcea1e82534 100644
--- a/src/freedreno/ir3/ir3_shader.c
+++ b/src/freedreno/ir3/ir3_shader.c
@@ -171,17 +171,40 @@ assemble_variant(struct ir3_shader_variant *v)
 	v->ir = NULL;
 }
 
+static bool
+compile_variant(struct ir3_shader_variant *v)
+{
+	int ret = ir3_compile_shader_nir(v->shader->compiler, v);
+	if (ret) {
+		debug_error("compile failed!");
+		return false;
+	}
+
+	assemble_variant(v);
+	if (!v->bin) {
+		debug_error("assemble failed!");
+		return false;
+	}
+
+	return true;
+}
+
 /*
  * For creating normal shader variants, 'nonbinning' is NULL.  For
  * creating binning pass shader, it is link to corresponding normal
  * (non-binning) variant.
  */
 static struct ir3_shader_variant *
-create_variant(struct ir3_shader *shader, const struct ir3_shader_key *key,
+alloc_variant(struct ir3_shader *shader, const struct ir3_shader_key *key,
 		struct ir3_shader_variant *nonbinning)
 {
-	struct ir3_shader_variant *v = rzalloc_size(shader, sizeof(*v));
-	int ret;
+	void *mem_ctx = shader;
+	/* hang the binning variant off it's non-binning counterpart instead
+	 * of the shader, to simplify the error cleanup paths
+	 */
+	if (nonbinning)
+		mem_ctx = nonbinning;
+	struct ir3_shader_variant *v = rzalloc_size(mem_ctx, sizeof(*v));
 
 	if (!v)
 		return NULL;
@@ -197,17 +220,36 @@ create_variant(struct ir3_shader *shader, const struct ir3_shader_key *key,
 	if (!v->binning_pass)
 		v->const_state = rzalloc_size(v, sizeof(*v->const_state));
 
-	ret = ir3_compile_shader_nir(shader->compiler, v);
-	if (ret) {
-		debug_error("compile failed!");
+	return v;
+}
+
+static bool
+needs_binning_variant(struct ir3_shader_variant *v)
+{
+	if ((v->type == MESA_SHADER_VERTEX) && ir3_has_binning_vs(&v->key))
+		return true;
+	return false;
+}
+
+static struct ir3_shader_variant *
+create_variant(struct ir3_shader *shader, const struct ir3_shader_key *key)
+{
+	struct ir3_shader_variant *v = alloc_variant(shader, key, NULL);
+
+	if (!v)
 		goto fail;
+
+	if (needs_binning_variant(v)) {
+		v->binning = alloc_variant(shader, key, v);
+		if (!v->binning)
+			goto fail;
 	}
 
-	assemble_variant(v);
-	if (!v->bin) {
-		debug_error("assemble failed!");
+	if (!compile_variant(v))
+		goto fail;
+
+	if (needs_binning_variant(v) && !compile_variant(v->binning))
 		goto fail;
-	}
 
 	return v;
 
@@ -217,26 +259,15 @@ fail:
 }
 
 static inline struct ir3_shader_variant *
-shader_variant(struct ir3_shader *shader, const struct ir3_shader_key *key,
-		bool *created)
+shader_variant(struct ir3_shader *shader, const struct ir3_shader_key *key)
 {
 	struct ir3_shader_variant *v;
 
-	*created = false;
-
 	for (v = shader->variants; v; v = v->next)
 		if (ir3_shader_key_equal(key, &v->key))
 			return v;
 
-	/* compile new variant if it doesn't exist already: */
-	v = create_variant(shader, key, NULL);
-	if (v) {
-		v->next = shader->variants;
-		shader->variants = v;
-		*created = true;
-	}
-
-	return v;
+	return NULL;
 }
 
 struct ir3_shader_variant *
@@ -244,17 +275,23 @@ ir3_shader_get_variant(struct ir3_shader *shader, const struct ir3_shader_key *k
 		bool binning_pass, bool *created)
 {
 	mtx_lock(&shader->variants_lock);
-	struct ir3_shader_variant *v =
-			shader_variant(shader, key, created);
-
-	if (v && binning_pass) {
-		if (!v->binning) {
-			v->binning = create_variant(shader, key, v);
+	struct ir3_shader_variant *v = shader_variant(shader, key);
+
+	if (!v) {
+		/* compile new variant if it doesn't exist already: */
+		v = create_variant(shader, key);
+		if (v) {
+			v->next = shader->variants;
+			shader->variants = v;
 			*created = true;
 		}
-		mtx_unlock(&shader->variants_lock);
-		return v->binning;
 	}
+
+	if (v && binning_pass) {
+		v = v->binning;
+		assert(v);
+	}
+
 	mtx_unlock(&shader->variants_lock);
 
 	return v;
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_gallium.c b/src/gallium/drivers/freedreno/ir3/ir3_gallium.c
index a660a916d99..af307906896 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_gallium.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_gallium.c
@@ -44,8 +44,7 @@
 #include "ir3/ir3_nir.h"
 
 static void
-dump_shader_info(struct ir3_shader_variant *v, bool binning_pass,
-		struct pipe_debug_callback *debug)
+dump_shader_info(struct ir3_shader_variant *v, struct pipe_debug_callback *debug)
 {
 	if (!unlikely(fd_mesa_debug & FD_DBG_SHADERDB))
 		return;
@@ -118,9 +117,14 @@ ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key,
 					key.vastc_srgb, key.fastc_srgb);
 
 		}
-		dump_shader_info(v, binning_pass, debug);
 
+		dump_shader_info(v, debug);
 		upload_shader_variant(v);
+
+		if (v->binning) {
+			upload_shader_variant(v->binning);
+			dump_shader_info(v->binning, debug);
+		}
 	}
 
 	return v;
@@ -285,7 +289,7 @@ ir3_shader_state_delete(struct pipe_context *pctx, void *hwcso)
 		fd_bo_del(v->bo);
 		v->bo = NULL;
 
-		if (v->binning) {
+		if (v->binning && v->binning->bo) {
 			fd_bo_del(v->binning->bo);
 			v->binning->bo = NULL;
 		}



More information about the mesa-commit mailing list