Mesa (master): radeonsi/nir: collect more accurate output_usagemask

Timothy Arceri tarceri at kemper.freedesktop.org
Wed Feb 21 22:31:13 UTC 2018


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

Author: Timothy Arceri <tarceri at itsqueeze.com>
Date:   Wed Feb 21 13:27:17 2018 +1100

radeonsi/nir: collect more accurate output_usagemask

Fixes assert in the glsl-1.50-gs-max-output-components piglit test.

Note that the double handling will only work for doubles that
don't take up multiple slots i.e. double and dvec2. However
dual slot double handling is an existing bug which is made no
worse by this patch.

Reviewed-by: Marek Olšák <marek.olsak at amd.com>

---

 src/gallium/drivers/radeonsi/si_shader_nir.c | 56 +++++++++++++++++++++-------
 1 file changed, 43 insertions(+), 13 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader_nir.c b/src/gallium/drivers/radeonsi/si_shader_nir.c
index 4f44e968f8..d410a6c2d6 100644
--- a/src/gallium/drivers/radeonsi/si_shader_nir.c
+++ b/src/gallium/drivers/radeonsi/si_shader_nir.c
@@ -446,21 +446,35 @@ void si_nir_scan_shader(const struct nir_shader *nir,
 		}
 
 		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;
 
+		if (glsl_type_is_64bit(glsl_without_array(variable->type)))
+			num_components = MIN2(num_components * 2, 4);
+
+		ubyte usagemask = 0;
+		for (unsigned j = 0; j < num_components; j++) {
+			switch (j + variable->data.location_frac) {
+				case 0:
+					usagemask |= TGSI_WRITEMASK_X;
+					break;
+				case 1:
+					usagemask |= TGSI_WRITEMASK_Y;
+					break;
+				case 2:
+					usagemask |= TGSI_WRITEMASK_Z;
+					break;
+				case 3:
+					usagemask |= TGSI_WRITEMASK_W;
+					break;
+				default:
+					unreachable("error calculating component index");
+			}
+		}
+
 		unsigned gs_out_streams;
 		if (variable->data.stream & (1u << 31)) {
 			gs_out_streams = variable->data.stream & ~(1u << 31);
@@ -476,23 +490,39 @@ void si_nir_scan_shader(const struct nir_shader *nir,
 		unsigned streamz = (gs_out_streams >> 4) & 3;
 		unsigned streamw = (gs_out_streams >> 6) & 3;
 
-		if (info->output_usagemask[i] & TGSI_WRITEMASK_X) {
+		if (usagemask & TGSI_WRITEMASK_X) {
+			info->output_usagemask[i] |= TGSI_WRITEMASK_X;
 			info->output_streams[i] |= streamx;
 			info->num_stream_output_components[streamx]++;
 		}
-		if (info->output_usagemask[i] & TGSI_WRITEMASK_Y) {
+		if (usagemask & TGSI_WRITEMASK_Y) {
+			info->output_usagemask[i] |= TGSI_WRITEMASK_Y;
 			info->output_streams[i] |= streamy << 2;
 			info->num_stream_output_components[streamy]++;
 		}
-		if (info->output_usagemask[i] & TGSI_WRITEMASK_Z) {
+		if (usagemask & TGSI_WRITEMASK_Z) {
+			info->output_usagemask[i] |= TGSI_WRITEMASK_Z;
 			info->output_streams[i] |= streamz << 4;
 			info->num_stream_output_components[streamz]++;
 		}
-		if (info->output_usagemask[i] & TGSI_WRITEMASK_W) {
+		if (usagemask & TGSI_WRITEMASK_W) {
+			info->output_usagemask[i] |= TGSI_WRITEMASK_W;
 			info->output_streams[i] |= streamw << 6;
 			info->num_stream_output_components[streamw]++;
 		}
 
+		/* make sure we only count this location once against the
+		 * num_outputs counter.
+		 */
+		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;
+
 		switch (semantic_name) {
 		case TGSI_SEMANTIC_PRIMID:
 			info->writes_primid = true;




More information about the mesa-commit mailing list