setup_vs_output_info(isel_context* ctx, nir_shader* nir, bool export_prim_id,
bool export_clip_dists, radv_vs_output_info* outinfo)
{
- memset(outinfo->vs_output_param_offset, AC_EXP_PARAM_UNDEFINED,
- sizeof(outinfo->vs_output_param_offset));
-
- outinfo->param_exports = 0;
- int pos_written = 0x1;
- bool writes_primitive_shading_rate =
- outinfo->writes_primitive_shading_rate || ctx->options->force_vrs_rates;
- if (outinfo->writes_pointsize || outinfo->writes_viewport_index || outinfo->writes_layer ||
- writes_primitive_shading_rate)
- pos_written |= 1 << 1;
-
- uint64_t mask = nir->info.outputs_written;
- while (mask) {
- int idx = u_bit_scan64(&mask);
- if (idx >= VARYING_SLOT_VAR0 || idx == VARYING_SLOT_LAYER ||
- idx == VARYING_SLOT_PRIMITIVE_ID || idx == VARYING_SLOT_VIEWPORT ||
- ((idx == VARYING_SLOT_CLIP_DIST0 || idx == VARYING_SLOT_CLIP_DIST1) &&
- export_clip_dists)) {
- if (outinfo->vs_output_param_offset[idx] == AC_EXP_PARAM_UNDEFINED)
- outinfo->vs_output_param_offset[idx] = outinfo->param_exports++;
- }
- }
- if (outinfo->writes_layer &&
- outinfo->vs_output_param_offset[VARYING_SLOT_LAYER] == AC_EXP_PARAM_UNDEFINED) {
- /* when ctx->options->key.has_multiview_view_index = true, the layer
- * variable isn't declared in NIR and it's isel's job to get the layer */
- outinfo->vs_output_param_offset[VARYING_SLOT_LAYER] = outinfo->param_exports++;
- }
-
- if (export_prim_id) {
- assert(outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] == AC_EXP_PARAM_UNDEFINED);
- outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = outinfo->param_exports++;
- }
-
ctx->export_clip_dists = export_clip_dists;
ctx->num_clip_distances = util_bitcount(outinfo->clip_dist_mask);
ctx->num_cull_distances = util_bitcount(outinfo->cull_dist_mask);
assert(ctx->num_clip_distances + ctx->num_cull_distances <= 8);
- if (ctx->num_clip_distances + ctx->num_cull_distances > 0)
- pos_written |= 1 << 2;
- if (ctx->num_clip_distances + ctx->num_cull_distances > 4)
- pos_written |= 1 << 3;
-
- outinfo->pos_exports = util_bitcount(pos_written);
-
/* GFX10+ early rasterization:
* When there are no param exports in an NGG (or legacy VS) shader,
* RADV sets NO_PC_EXPORT=1, which means the HW will start clipping and rasterization
continue;
radv_export_param(ctx, param_count, outputs[i].values, usage_mask);
-
- assert(i < ARRAY_SIZE(outinfo->vs_output_param_offset));
- outinfo->vs_output_param_offset[slot_name] = param_count++;
}
-
- outinfo->param_exports = param_count;
}
/* Generate export instructions for hardware VS shader stage or NGG GS stage
}
}
- for (i = 0; i < 4; i++) {
- if (pos_args[i].out[0])
- outinfo->pos_exports++;
- }
-
/* GFX10 skip POS0 exports if EXEC=0 and DONE=0, causing a hang.
* Setting valid_mask=1 prevents it and has no other effect.
*/
ctx->output_mask |= 1ull << VARYING_SLOT_LAYER;
}
- memset(outinfo->vs_output_param_offset, AC_EXP_PARAM_UNDEFINED,
- sizeof(outinfo->vs_output_param_offset));
- outinfo->pos_exports = 0;
-
if (ctx->args->shader_info->so.num_outputs && !ctx->args->is_gs_copy_shader) {
/* The GS copy shader emission already emits streamout. */
radv_emit_streamout(ctx, 0);
values[j] = ctx->ac.f32_0;
radv_export_param(ctx, param_count, values, 0x1);
-
- outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = param_count++;
- outinfo->param_exports = param_count;
}
}
ac_build_endif(&ctx->ac, 6002);
unsigned num_outputs = util_bitcount64(ctx->output_mask) + export_view_index;
outputs = calloc(num_outputs, sizeof(outputs[0]));
- memset(outinfo->vs_output_param_offset, AC_EXP_PARAM_UNDEFINED,
- sizeof(outinfo->vs_output_param_offset));
- outinfo->pos_exports = 0;
-
tmp = ngg_gs_vertex_ptr(ctx, tid);
tmp = LLVMBuildLoad(builder, ngg_gs_get_emit_primflag_ptr(ctx, tmp, 1), "");
tmp = LLVMBuildZExt(builder, tmp, ctx->ac.i32, "");
#include "radv_private.h"
#include "radv_shader.h"
+#include "ac_exp_param.h"
+
static void
mark_sampler_desc(const nir_variable *var, struct radv_shader_info *info)
{
info->gs.output_streams[idx] = stream;
}
+static struct radv_vs_output_info *
+get_vs_output_info(const nir_shader *nir, struct radv_shader_info *info)
+{
+
+ switch (nir->info.stage) {
+ case MESA_SHADER_VERTEX:
+ if (!info->vs.as_ls && !info->vs.as_es)
+ return &info->vs.outinfo;
+ break;
+ case MESA_SHADER_GEOMETRY:
+ return &info->vs.outinfo;
+ break;
+ case MESA_SHADER_TESS_EVAL:
+ if (!info->tes.as_es)
+ return &info->tes.outinfo;
+ break;
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
static void
gather_info_output_decl(const nir_shader *nir, const nir_variable *var,
struct radv_shader_info *info)
{
- struct radv_vs_output_info *vs_info = NULL;
+ struct radv_vs_output_info *vs_info = get_vs_output_info(nir, info);
switch (nir->info.stage) {
case MESA_SHADER_FRAGMENT:
gather_info_output_decl_ps(nir, var, info);
break;
case MESA_SHADER_VERTEX:
- if (!info->vs.as_ls && !info->vs.as_es)
- vs_info = &info->vs.outinfo;
-
if (!info->vs.as_ls && info->is_ngg)
gather_info_output_decl_gs(nir, var, info);
break;
case MESA_SHADER_GEOMETRY:
- vs_info = &info->vs.outinfo;
gather_info_output_decl_gs(nir, var, info);
break;
case MESA_SHADER_TESS_EVAL:
- if (!info->tes.as_es)
- vs_info = &info->tes.outinfo;
break;
default:
break;
}
}
+ struct radv_vs_output_info *outinfo = get_vs_output_info(nir, info);
+ if (outinfo) {
+ bool writes_primitive_shading_rate =
+ outinfo->writes_primitive_shading_rate || device->force_vrs != RADV_FORCE_VRS_NONE;
+ int pos_written = 0x1;
+
+ if (outinfo->writes_pointsize || outinfo->writes_viewport_index || outinfo->writes_layer ||
+ writes_primitive_shading_rate)
+ pos_written |= 1 << 1;
+
+ unsigned num_clip_distances = util_bitcount(outinfo->clip_dist_mask);
+ unsigned num_cull_distances = util_bitcount(outinfo->cull_dist_mask);
+
+ if (num_clip_distances + num_cull_distances > 0)
+ pos_written |= 1 << 2;
+ if (num_clip_distances + num_cull_distances > 4)
+ pos_written |= 1 << 3;
+
+ outinfo->pos_exports = util_bitcount(pos_written);
+
+ memset(outinfo->vs_output_param_offset, AC_EXP_PARAM_UNDEFINED,
+ sizeof(outinfo->vs_output_param_offset));
+ outinfo->param_exports = 0;
+
+ uint64_t mask = nir->info.outputs_written;
+ while (mask) {
+ int idx = u_bit_scan64(&mask);
+ if (idx >= VARYING_SLOT_VAR0 || idx == VARYING_SLOT_LAYER ||
+ idx == VARYING_SLOT_PRIMITIVE_ID || idx == VARYING_SLOT_VIEWPORT ||
+ ((idx == VARYING_SLOT_CLIP_DIST0 || idx == VARYING_SLOT_CLIP_DIST1) &&
+ outinfo->export_clip_dists)) {
+ if (outinfo->vs_output_param_offset[idx] == AC_EXP_PARAM_UNDEFINED)
+ outinfo->vs_output_param_offset[idx] = outinfo->param_exports++;
+ }
+ }
+ if (outinfo->writes_layer &&
+ outinfo->vs_output_param_offset[VARYING_SLOT_LAYER] == AC_EXP_PARAM_UNDEFINED) {
+ /* when ctx->options->key.has_multiview_view_index = true, the layer
+ * variable isn't declared in NIR and it's isel's job to get the layer */
+ outinfo->vs_output_param_offset[VARYING_SLOT_LAYER] = outinfo->param_exports++;
+ }
+
+ if (outinfo->export_prim_id) {
+ assert(outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] == AC_EXP_PARAM_UNDEFINED);
+ outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = outinfo->param_exports++;
+ }
+ }
+
if (nir->info.stage == MESA_SHADER_FRAGMENT)
info->ps.num_interp = nir->num_inputs;