radv: determine the VS output parameters in the shader info pass
This can be determined earlier instead of duplicating code in both compiler backends. Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Timur Kristóf <timur.kristof@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13119>
This commit is contained in:
parent
89f1117c62
commit
2aa705ec87
|
@ -278,53 +278,12 @@ void
|
||||||
setup_vs_output_info(isel_context* ctx, nir_shader* nir, bool export_prim_id,
|
setup_vs_output_info(isel_context* ctx, nir_shader* nir, bool export_prim_id,
|
||||||
bool export_clip_dists, radv_vs_output_info* outinfo)
|
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->export_clip_dists = export_clip_dists;
|
||||||
ctx->num_clip_distances = util_bitcount(outinfo->clip_dist_mask);
|
ctx->num_clip_distances = util_bitcount(outinfo->clip_dist_mask);
|
||||||
ctx->num_cull_distances = util_bitcount(outinfo->cull_dist_mask);
|
ctx->num_cull_distances = util_bitcount(outinfo->cull_dist_mask);
|
||||||
|
|
||||||
assert(ctx->num_clip_distances + ctx->num_cull_distances <= 8);
|
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:
|
/* GFX10+ early rasterization:
|
||||||
* When there are no param exports in an NGG (or legacy VS) shader,
|
* 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
|
* RADV sets NO_PC_EXPORT=1, which means the HW will start clipping and rasterization
|
||||||
|
|
|
@ -1197,12 +1197,7 @@ radv_build_param_exports(struct radv_shader_context *ctx, struct radv_shader_out
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
radv_export_param(ctx, param_count, outputs[i].values, usage_mask);
|
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
|
/* Generate export instructions for hardware VS shader stage or NGG GS stage
|
||||||
|
@ -1325,11 +1320,6 @@ radv_llvm_export_vs(struct radv_shader_context *ctx, struct radv_shader_output_v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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.
|
/* GFX10 skip POS0 exports if EXEC=0 and DONE=0, causing a hang.
|
||||||
* Setting valid_mask=1 prevents it and has no other effect.
|
* Setting valid_mask=1 prevents it and has no other effect.
|
||||||
*/
|
*/
|
||||||
|
@ -1375,10 +1365,6 @@ handle_vs_outputs_post(struct radv_shader_context *ctx, bool export_prim_id, boo
|
||||||
ctx->output_mask |= 1ull << VARYING_SLOT_LAYER;
|
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) {
|
if (ctx->args->shader_info->so.num_outputs && !ctx->args->is_gs_copy_shader) {
|
||||||
/* The GS copy shader emission already emits streamout. */
|
/* The GS copy shader emission already emits streamout. */
|
||||||
radv_emit_streamout(ctx, 0);
|
radv_emit_streamout(ctx, 0);
|
||||||
|
@ -1695,9 +1681,6 @@ handle_ngg_outputs_post_2(struct radv_shader_context *ctx)
|
||||||
values[j] = ctx->ac.f32_0;
|
values[j] = ctx->ac.f32_0;
|
||||||
|
|
||||||
radv_export_param(ctx, param_count, values, 0x1);
|
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);
|
ac_build_endif(&ctx->ac, 6002);
|
||||||
|
@ -1957,10 +1940,6 @@ gfx10_ngg_gs_emit_epilogue_2(struct radv_shader_context *ctx)
|
||||||
unsigned num_outputs = util_bitcount64(ctx->output_mask) + export_view_index;
|
unsigned num_outputs = util_bitcount64(ctx->output_mask) + export_view_index;
|
||||||
outputs = calloc(num_outputs, sizeof(outputs[0]));
|
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 = ngg_gs_vertex_ptr(ctx, tid);
|
||||||
tmp = LLVMBuildLoad(builder, ngg_gs_get_emit_primflag_ptr(ctx, tmp, 1), "");
|
tmp = LLVMBuildLoad(builder, ngg_gs_get_emit_primflag_ptr(ctx, tmp, 1), "");
|
||||||
tmp = LLVMBuildZExt(builder, tmp, ctx->ac.i32, "");
|
tmp = LLVMBuildZExt(builder, tmp, ctx->ac.i32, "");
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include "radv_private.h"
|
#include "radv_private.h"
|
||||||
#include "radv_shader.h"
|
#include "radv_shader.h"
|
||||||
|
|
||||||
|
#include "ac_exp_param.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mark_sampler_desc(const nir_variable *var, struct radv_shader_info *info)
|
mark_sampler_desc(const nir_variable *var, struct radv_shader_info *info)
|
||||||
{
|
{
|
||||||
|
@ -459,30 +461,47 @@ gather_info_output_decl_gs(const nir_shader *nir, const nir_variable *var,
|
||||||
info->gs.output_streams[idx] = stream;
|
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
|
static void
|
||||||
gather_info_output_decl(const nir_shader *nir, const nir_variable *var,
|
gather_info_output_decl(const nir_shader *nir, const nir_variable *var,
|
||||||
struct radv_shader_info *info)
|
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) {
|
switch (nir->info.stage) {
|
||||||
case MESA_SHADER_FRAGMENT:
|
case MESA_SHADER_FRAGMENT:
|
||||||
gather_info_output_decl_ps(nir, var, info);
|
gather_info_output_decl_ps(nir, var, info);
|
||||||
break;
|
break;
|
||||||
case MESA_SHADER_VERTEX:
|
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)
|
if (!info->vs.as_ls && info->is_ngg)
|
||||||
gather_info_output_decl_gs(nir, var, info);
|
gather_info_output_decl_gs(nir, var, info);
|
||||||
break;
|
break;
|
||||||
case MESA_SHADER_GEOMETRY:
|
case MESA_SHADER_GEOMETRY:
|
||||||
vs_info = &info->vs.outinfo;
|
|
||||||
gather_info_output_decl_gs(nir, var, info);
|
gather_info_output_decl_gs(nir, var, info);
|
||||||
break;
|
break;
|
||||||
case MESA_SHADER_TESS_EVAL:
|
case MESA_SHADER_TESS_EVAL:
|
||||||
if (!info->tes.as_es)
|
|
||||||
vs_info = &info->tes.outinfo;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -603,6 +622,54 @@ radv_nir_shader_info_pass(struct radv_device *device, const struct nir_shader *n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
if (nir->info.stage == MESA_SHADER_FRAGMENT)
|
||||||
info->ps.num_interp = nir->num_inputs;
|
info->ps.num_interp = nir->num_inputs;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue