summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTimothy Arceri <[email protected]>2018-02-21 13:27:17 +1100
committerTimothy Arceri <[email protected]>2018-02-22 09:31:00 +1100
commit86098696fc980cd0d324d2f2c978a320f0418f38 (patch)
tree01b3055320861687b099e3dba4c0ad4a786c7b73 /src
parent79dc94828aedd0edc6085911321e6e7597815478 (diff)
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 <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/radeonsi/si_shader_nir.c56
1 files 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 4f44e968f83..d410a6c2d66 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;