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;