[Mesa-dev] [PATCH 13/14] radeonsi: use driver location when gathering tgsi info from nir

Timothy Arceri tarceri at itsqueeze.com
Tue Nov 21 03:37:34 UTC 2017


Otherwise we overflow the tgsi array because nir uses a separate
var for component packing of varyings, while tgsi expects everything
to be vec4.

We also need to do our own count of the total number of varyings.
---
 src/gallium/drivers/radeonsi/si_shader_nir.c | 34 ++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader_nir.c b/src/gallium/drivers/radeonsi/si_shader_nir.c
index ec748c9679..2e0e3725f7 100644
--- a/src/gallium/drivers/radeonsi/si_shader_nir.c
+++ b/src/gallium/drivers/radeonsi/si_shader_nir.c
@@ -129,54 +129,62 @@ void si_nir_scan_shader(const struct nir_shader *nir,
 	nir_function *func;
 	unsigned i;
 
 	assert(nir->info.stage == MESA_SHADER_VERTEX ||
 	       nir->info.stage == MESA_SHADER_FRAGMENT);
 
 	info->processor = pipe_shader_type_from_mesa(nir->info.stage);
 	info->num_tokens = 2; /* indicate that the shader is non-empty */
 	info->num_instructions = 2;
 
-	info->num_inputs = nir->num_inputs;
-	info->num_outputs = nir->num_outputs;
-
 	if (nir->info.stage == MESA_SHADER_GEOMETRY) {
 		info->properties[TGSI_PROPERTY_GS_INPUT_PRIM] = nir->info.gs.input_primitive;
 		info->properties[TGSI_PROPERTY_GS_OUTPUT_PRIM] = nir->info.gs.output_primitive;
 		info->properties[TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES] = nir->info.gs.vertices_out;
 		info->properties[TGSI_PROPERTY_GS_INVOCATIONS] = nir->info.gs.invocations;
 	}
 
 	i = 0;
+	uint64_t processed_inputs = 0;
+	unsigned num_inputs = 0;
 	nir_foreach_variable(variable, &nir->inputs) {
 		unsigned semantic_name, semantic_index;
 		unsigned attrib_count = glsl_count_attribute_slots(variable->type,
 								   nir->info.stage == MESA_SHADER_VERTEX);
 
 		assert(attrib_count == 1 && "not implemented");
 
 		/* Vertex shader inputs don't have semantics. The state
 		 * tracker has already mapped them to attributes via
 		 * variable->data.driver_location.
 		 */
 		if (nir->info.stage == MESA_SHADER_VERTEX)
 			continue;
 
 		/* Fragment shader position is a system value. */
 		if (nir->info.stage == MESA_SHADER_FRAGMENT &&
 		    variable->data.location == VARYING_SLOT_POS) {
 			if (variable->data.pixel_center_integer)
 				info->properties[TGSI_PROPERTY_FS_COORD_PIXEL_CENTER] =
 					TGSI_FS_COORD_PIXEL_CENTER_INTEGER;
+
+			num_inputs++;
 			continue;
 		}
 
+		i = variable->data.driver_location;
+		if (processed_inputs & ((uint64_t)1 << i))
+			continue;
+
+		processed_inputs |= ((uint64_t)1 << i);
+		num_inputs++;
+
 		tgsi_get_gl_varying_semantic(variable->data.location, true,
 					     &semantic_name, &semantic_index);
 
 		info->input_semantic_name[i] = semantic_name;
 		info->input_semantic_index[i] = semantic_index;
 
 		if (variable->data.sample)
 			info->input_interpolate_loc[i] = TGSI_INTERPOLATE_LOC_SAMPLE;
 		else if (variable->data.centroid)
 			info->input_interpolate_loc[i] = TGSI_INTERPOLATE_LOC_CENTROID;
@@ -228,36 +236,48 @@ void si_nir_scan_shader(const struct nir_shader *nir,
 		case INTERP_MODE_FLAT:
 			info->input_interpolate[i] = TGSI_INTERPOLATE_CONSTANT;
 			break;
 		}
 
 		/* TODO make this more precise */
 		if (variable->data.location == VARYING_SLOT_COL0)
 			info->colors_read |= 0x0f;
 		else if (variable->data.location == VARYING_SLOT_COL1)
 			info->colors_read |= 0xf0;
-
-		i++;
 	}
 
+	if (nir->info.stage != MESA_SHADER_VERTEX)
+		info->num_inputs = num_inputs;
+	else
+		info->num_inputs = nir->num_inputs;
+
 	i = 0;
+	uint64_t processed_outputs = 0;
+	unsigned num_outputs = 0;
 	nir_foreach_variable(variable, &nir->outputs) {
 		unsigned semantic_name, semantic_index;
 
 		if (nir->info.stage == MESA_SHADER_FRAGMENT) {
 			tgsi_get_gl_frag_result_semantic(variable->data.location,
 				&semantic_name, &semantic_index);
 		} else {
 			tgsi_get_gl_varying_semantic(variable->data.location, true,
 						     &semantic_name, &semantic_index);
 		}
 
+		i = variable->data.driver_location;
+		if (processed_outputs & ((uint64_t)1 << i))
+			continue;
+
+		processed_outputs |= ((uint64_t)1 << i);
+		num_outputs++;
+
 		info->output_semantic_name[i] = semantic_name;
 		info->output_semantic_index[i] = semantic_index;
 		info->output_usagemask[i] = TGSI_WRITEMASK_XYZW;
 
 		unsigned num_components = 4;
 		unsigned vector_elements = glsl_get_vector_elements(glsl_without_array(variable->type));
 		if (vector_elements)
 			num_components = vector_elements;
 
 		unsigned gs_out_streams;
@@ -320,24 +340,24 @@ void si_nir_scan_shader(const struct nir_shader *nir,
 		case TGSI_SEMANTIC_EDGEFLAG:
 			info->writes_edgeflag = true;
 			break;
 		case TGSI_SEMANTIC_POSITION:
 			if (info->processor == PIPE_SHADER_FRAGMENT)
 				info->writes_z = true;
 			else
 				info->writes_position = true;
 			break;
 		}
-
-		i++;
 	}
 
+	info->num_outputs = num_outputs;
+
 	nir_foreach_variable(variable, &nir->uniforms) {
 		const struct glsl_type *type = variable->type;
 		enum glsl_base_type base_type =
 			glsl_get_base_type(glsl_without_array(type));
 		unsigned aoa_size = MAX2(1, glsl_get_aoa_size(type));
 
 		/* We rely on the fact that nir_lower_samplers_as_deref has
 		 * eliminated struct dereferences.
 		 */
 		if (base_type == GLSL_TYPE_SAMPLER)
-- 
2.14.3



More information about the mesa-dev mailing list