[20/26] radeonsi: allow si_shader_select_with_key to return an optimized shader or fail

Submitted by Marek Olšák on Feb. 13, 2019, 5:16 a.m.

Details

Message ID 20190213051621.6235-21-maraeo@gmail.com
State New
Headers show
Series "RadeonSI: Primitive culling with async compute" ( rev: 1 ) in Mesa

Not browsing as part of any series.

Commit Message

Marek Olšák Feb. 13, 2019, 5:16 a.m.
From: Marek Olšák <marek.olsak@amd.com>

If a prim discard compute shader hasn't finished compilation, we don't want
to any shader.
---
 src/gallium/drivers/radeonsi/si_state.h       |  7 ++++
 .../drivers/radeonsi/si_state_shaders.c       | 38 +++++++++++++------
 2 files changed, 33 insertions(+), 12 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
index aed5ea63d8b..8f3a3224edf 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -41,6 +41,7 @@ 
 
 struct si_screen;
 struct si_shader;
+struct si_shader_ctx_state;
 struct si_shader_selector;
 struct si_texture;
 struct si_qbo_state;
@@ -555,6 +556,12 @@  void si_schedule_initial_compile(struct si_context *sctx, unsigned processor,
 void si_get_active_slot_masks(const struct tgsi_shader_info *info,
 			      uint32_t *const_and_shader_buffers,
 			      uint64_t *samplers_and_images);
+int si_shader_select_with_key(struct si_screen *sscreen,
+			      struct si_shader_ctx_state *state,
+			      struct si_compiler_ctx_state *compiler_state,
+			      struct si_shader_key *key,
+			      int thread_index,
+			      bool optimized_or_none);
 
 /* si_state_draw.c */
 void si_emit_cache_flush(struct si_context *sctx);
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
index 9e052e1efce..146e0f87693 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -1771,12 +1771,19 @@  static bool si_check_missing_main_part(struct si_screen *sscreen,
 	return true;
 }
 
-/* Select the hw shader variant depending on the current state. */
-static int si_shader_select_with_key(struct si_screen *sscreen,
-				     struct si_shader_ctx_state *state,
-				     struct si_compiler_ctx_state *compiler_state,
-				     struct si_shader_key *key,
-				     int thread_index)
+/**
+ * Select a shader variant according to the shader key.
+ *
+ * \param optimized_or_none  If the key describes an optimized shader variant and
+ *                           the compilation isn't finished, don't select any
+ *                           shader and return an error.
+ */
+int si_shader_select_with_key(struct si_screen *sscreen,
+			      struct si_shader_ctx_state *state,
+			      struct si_compiler_ctx_state *compiler_state,
+			      struct si_shader_key *key,
+			      int thread_index,
+			      bool optimized_or_none)
 {
 	struct si_shader_selector *sel = state->cso;
 	struct si_shader_selector *previous_stage_sel = NULL;
@@ -1792,6 +1799,9 @@  again:
 		   memcmp(&current->key, key, sizeof(*key)) == 0)) {
 		if (unlikely(!util_queue_fence_is_signalled(&current->ready))) {
 			if (current->is_optimized) {
+				if (optimized_or_none)
+					return -1;
+
 				memset(&key->opt, 0, sizeof(key->opt));
 				goto current_not_ready;
 			}
@@ -1828,6 +1838,8 @@  current_not_ready:
 				 * shader so as not to cause a stall due to compilation.
 				 */
 				if (iter->is_optimized) {
+					if (optimized_or_none)
+						return -1;
 					memset(&key->opt, 0, sizeof(key->opt));
 					goto again;
 				}
@@ -1869,12 +1881,13 @@  current_not_ready:
 			util_queue_fence_wait(&previous_stage_sel->ready);
 	}
 
-	/* Compile the main shader part if it doesn't exist. This can happen
-	 * if the initial guess was wrong. */
 	bool is_pure_monolithic =
 		sscreen->use_monolithic_shaders ||
 		memcmp(&key->mono, &zeroed.mono, sizeof(key->mono)) != 0;
 
+	/* Compile the main shader part if it doesn't exist. This can happen
+	 * if the initial guess was wrong.
+	 */
 	if (!is_pure_monolithic) {
 		bool ok;
 
@@ -1931,9 +1944,7 @@  current_not_ready:
 		memcmp(&key->opt, &zeroed.opt, sizeof(key->opt)) != 0;
 
 	/* If it's an optimized shader, compile it asynchronously. */
-	if (shader->is_optimized &&
-	    !is_pure_monolithic &&
-	    thread_index < 0) {
+	if (shader->is_optimized && thread_index < 0) {
 		/* Compile it asynchronously. */
 		util_queue_add_job(&sscreen->shader_compiler_queue_low_priority,
 				   shader, &shader->ready,
@@ -1952,6 +1963,9 @@  current_not_ready:
 		/* Use the default (unoptimized) shader for now. */
 		memset(&key->opt, 0, sizeof(key->opt));
 		mtx_unlock(&sel->mutex);
+
+		if (optimized_or_none)
+			return -1;
 		goto again;
 	}
 
@@ -1988,7 +2002,7 @@  static int si_shader_select(struct pipe_context *ctx,
 
 	si_shader_selector_key(ctx, state->cso, &key);
 	return si_shader_select_with_key(sctx->screen, state, compiler_state,
-					 &key, -1);
+					 &key, -1, false);
 }
 
 static void si_parse_next_shader_property(const struct tgsi_shader_info *info,