[Mesa-dev] [PATCH 18/20] radeonsi: record information about all written and read varyings

Marek Olšák maraeo at gmail.com
Wed Nov 16 18:38:41 UTC 2016


From: Marek Olšák <marek.olsak at amd.com>

It's just tgsi_shader_info with DEFAULT_VAL varyings removed.
---
 src/gallium/drivers/radeonsi/si_shader.c        | 22 ++++++++
 src/gallium/drivers/radeonsi/si_shader.h        | 10 ++--
 src/gallium/drivers/radeonsi/si_state_shaders.c | 69 +++++++++++++++++++++++++
 3 files changed, 98 insertions(+), 3 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index b250053..f8de049 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -134,20 +134,42 @@ unsigned si_shader_io_get_unique_index(unsigned semantic_name, unsigned index)
 		return 1;
 	case TGSI_SEMANTIC_PATCH:
 		return 2 + index;
 
 	default:
 		assert(!"invalid semantic name");
 		return 0;
 	}
 }
 
+unsigned si_shader_io_get_unique_index2(unsigned name, unsigned index)
+{
+	switch (name) {
+	case TGSI_SEMANTIC_FOG:
+		return 0;
+	case TGSI_SEMANTIC_LAYER:
+		return 1;
+	case TGSI_SEMANTIC_VIEWPORT_INDEX:
+		return 2;
+	case TGSI_SEMANTIC_PRIMID:
+		return 3;
+	case TGSI_SEMANTIC_COLOR: /* these alias */
+	case TGSI_SEMANTIC_BCOLOR:
+		return 4 + index;
+	case TGSI_SEMANTIC_TEXCOORD:
+		return 6 + index;
+	default:
+		assert(!"invalid semantic name");
+		return 0;
+	}
+}
+
 /**
  * Get the value of a shader input parameter and extract a bitfield.
  */
 static LLVMValueRef unpack_param(struct si_shader_context *ctx,
 				 unsigned param, unsigned rshift,
 				 unsigned bitwidth)
 {
 	struct gallivm_state *gallivm = &ctx->gallivm;
 	LLVMValueRef value = LLVMGetParam(ctx->main_fn,
 					  param);
diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
index 4cbd1c2..fc9c913 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -288,23 +288,26 @@ struct si_shader_selector {
 	unsigned	color_attr_index[2];
 	unsigned	db_shader_control;
 	/* Set 0xf or 0x0 (4 bits) per each written output.
 	 * ANDed with spi_shader_col_format.
 	 */
 	unsigned	colors_written_4bit;
 
 	/* CS parameters */
 	unsigned local_size;
 
-	/* masks of "get_unique_index" bits */
-	uint64_t	outputs_written;
-	uint32_t	patch_outputs_written;
+	uint64_t	outputs_written;	/* "get_unique_index" bits */
+	uint32_t	patch_outputs_written;	/* "get_unique_index" bits */
+	uint32_t	outputs_written2;	/* "get_unique_index2" bits */
+
+	uint64_t	inputs_read;		/* "get_unique_index" bits */
+	uint32_t	inputs_read2;		/* "get_unique_index2" bits */
 };
 
 /* Valid shader configurations:
  *
  * API shaders       VS | TCS | TES | GS |pass| PS
  * are compiled as:     |     |     |    |thru|
  *                      |     |     |    |    |
  * Only VS & PS:     VS | --  | --  | -- | -- | PS
  * With GS:          ES | --  | --  | GS | VS | PS
  * With Tessel.:     LS | HS  | VS  | -- | -- | PS
@@ -532,20 +535,21 @@ int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm,
 int si_compile_llvm(struct si_screen *sscreen,
 		    struct radeon_shader_binary *binary,
 		    struct si_shader_config *conf,
 		    LLVMTargetMachineRef tm,
 		    LLVMModuleRef mod,
 		    struct pipe_debug_callback *debug,
 		    unsigned processor,
 		    const char *name);
 void si_shader_destroy(struct si_shader *shader);
 unsigned si_shader_io_get_unique_index(unsigned semantic_name, unsigned index);
+unsigned si_shader_io_get_unique_index2(unsigned name, unsigned index);
 int si_shader_binary_upload(struct si_screen *sscreen, struct si_shader *shader);
 void si_shader_dump(struct si_screen *sscreen, struct si_shader *shader,
 		    struct pipe_debug_callback *debug, unsigned processor,
 		    FILE *f);
 void si_shader_apply_scratch_relocs(struct si_context *sctx,
 			struct si_shader *shader,
 			struct si_shader_config *config,
 			uint64_t scratch_va);
 void si_shader_binary_read_config(struct radeon_shader_binary *binary,
 				  struct si_shader_config *conf,
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
index d10084d..e4d8747 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -1289,20 +1289,65 @@ void si_init_shader_selector_async(void *job, int thread_index)
 
 			if (tgsi_binary) {
 				pipe_mutex_lock(sscreen->shader_cache_mutex);
 				if (!si_shader_cache_insert_shader(sscreen, tgsi_binary, shader))
 					FREE(tgsi_binary);
 				pipe_mutex_unlock(sscreen->shader_cache_mutex);
 			}
 		}
 
 		sel->main_shader_part = shader;
+
+		/* Unset "outputs_written" flags for outputs converted to
+		 * DEFAULT_VAL, so that later inter-shader optimizations don't
+		 * try to eliminate outputs that don't exist in the final
+		 * shader.
+		 *
+		 * This is only done if non-monolithic shaders are enabled.
+		 */
+		if ((sel->type == PIPE_SHADER_VERTEX ||
+		     sel->type == PIPE_SHADER_TESS_EVAL) &&
+		    !shader->key.as_ls &&
+		    !shader->key.as_es) {
+			unsigned i;
+
+			for (i = 0; i < sel->info.num_outputs; i++) {
+				unsigned offset = shader->info.vs_output_param_offset[i];
+
+				if (offset <= EXP_PARAM_OFFSET_31)
+					continue;
+
+				unsigned name = sel->info.output_semantic_name[i];
+				unsigned index = sel->info.output_semantic_index[i];
+				unsigned id;
+
+				switch (name) {
+				case TGSI_SEMANTIC_GENERIC:
+					/* don't process indices the function can't handle */
+					if (index >= 60)
+						break;
+					/* fall through */
+				case TGSI_SEMANTIC_CLIPDIST:
+					id = si_shader_io_get_unique_index(name, index);
+					sel->outputs_written &= ~(1ull << id);
+					break;
+				case TGSI_SEMANTIC_POSITION: /* ignore these */
+				case TGSI_SEMANTIC_PSIZE:
+				case TGSI_SEMANTIC_CLIPVERTEX:
+				case TGSI_SEMANTIC_EDGEFLAG:
+					break;
+				default:
+					id = si_shader_io_get_unique_index2(name, index);
+					sel->outputs_written2 &= ~(1u << id);
+				}
+			}
+		}
 	}
 
 	/* Pre-compilation. */
 	if (sscreen->b.debug_flags & DBG_PRECOMPILE) {
 		struct si_shader_ctx_state state = {sel};
 		struct si_shader_key key;
 
 		memset(&key, 0, sizeof(key));
 		si_parse_next_shader_property(&sel->info, &key);
 
@@ -1430,26 +1475,50 @@ static void *si_create_shader_selector(struct pipe_context *ctx,
 				/* don't process indices the function can't handle */
 				if (index >= 60)
 					break;
 				/* fall through */
 			case TGSI_SEMANTIC_POSITION:
 			case TGSI_SEMANTIC_PSIZE:
 			case TGSI_SEMANTIC_CLIPDIST:
 				sel->outputs_written |=
 					1llu << si_shader_io_get_unique_index(name, index);
 				break;
+			case TGSI_SEMANTIC_CLIPVERTEX: /* ignore these */
+			case TGSI_SEMANTIC_EDGEFLAG:
+				break;
+			default:
+				sel->outputs_written2 |=
+					1u << si_shader_io_get_unique_index2(name, index);
 			}
 		}
 		sel->esgs_itemsize = util_last_bit64(sel->outputs_written) * 16;
 		break;
 
 	case PIPE_SHADER_FRAGMENT:
+		for (i = 0; i < sel->info.num_inputs; i++) {
+			unsigned name = sel->info.input_semantic_name[i];
+			unsigned index = sel->info.input_semantic_index[i];
+
+			switch (name) {
+			case TGSI_SEMANTIC_CLIPDIST:
+			case TGSI_SEMANTIC_GENERIC:
+				sel->inputs_read |=
+					1llu << si_shader_io_get_unique_index(name, index);
+				break;
+			case TGSI_SEMANTIC_PCOORD: /* ignore this */
+				break;
+			default:
+				sel->inputs_read2 |=
+					1u << si_shader_io_get_unique_index2(name, index);
+			}
+		}
+
 		for (i = 0; i < 8; i++)
 			if (sel->info.colors_written & (1 << i))
 				sel->colors_written_4bit |= 0xf << (4 * i);
 
 		for (i = 0; i < sel->info.num_inputs; i++) {
 			if (sel->info.input_semantic_name[i] == TGSI_SEMANTIC_COLOR) {
 				int index = sel->info.input_semantic_index[i];
 				sel->color_attr_index[index] = i;
 			}
 		}
-- 
2.7.4



More information about the mesa-dev mailing list