radv: Add last_vgt_api_stage and use it to simplify some code.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11711>
This commit is contained in:
Timur Kristóf
2021-07-05 08:51:09 +02:00
parent c6d677ce3d
commit 00d11c2065
4 changed files with 34 additions and 41 deletions

View File

@@ -144,32 +144,26 @@ radv_pipeline_get_color_blend_state(const VkGraphicsPipelineCreateInfo *pCreateI
static bool
radv_pipeline_has_ngg(const struct radv_pipeline *pipeline)
{
struct radv_shader_variant *variant = NULL;
if (pipeline->shaders[MESA_SHADER_GEOMETRY])
variant = pipeline->shaders[MESA_SHADER_GEOMETRY];
else if (pipeline->shaders[MESA_SHADER_TESS_EVAL])
variant = pipeline->shaders[MESA_SHADER_TESS_EVAL];
else if (pipeline->shaders[MESA_SHADER_VERTEX])
variant = pipeline->shaders[MESA_SHADER_VERTEX];
else
if (pipeline->graphics.last_vgt_api_stage == MESA_SHADER_NONE)
return false;
struct radv_shader_variant *variant =
pipeline->shaders[pipeline->graphics.last_vgt_api_stage];
return variant->info.is_ngg;
}
bool
radv_pipeline_has_ngg_passthrough(const struct radv_pipeline *pipeline)
{
if (pipeline->graphics.last_vgt_api_stage == MESA_SHADER_NONE)
return false;
assert(radv_pipeline_has_ngg(pipeline));
struct radv_shader_variant *variant = NULL;
if (pipeline->shaders[MESA_SHADER_GEOMETRY])
variant = pipeline->shaders[MESA_SHADER_GEOMETRY];
else if (pipeline->shaders[MESA_SHADER_TESS_EVAL])
variant = pipeline->shaders[MESA_SHADER_TESS_EVAL];
else if (pipeline->shaders[MESA_SHADER_VERTEX])
variant = pipeline->shaders[MESA_SHADER_VERTEX];
else
return false;
struct radv_shader_variant *variant =
pipeline->shaders[pipeline->graphics.last_vgt_api_stage];
return variant->info.is_ngg_passthrough;
}
@@ -2423,9 +2417,6 @@ radv_set_driver_locations(struct radv_pipeline *pipeline, nir_shader **shaders,
unsigned vs_info_idx = MESA_SHADER_VERTEX;
unsigned tes_info_idx = MESA_SHADER_TESS_EVAL;
/* Which stage is the last in the vertex, tess, geometry pipeline */
unsigned last_vtg_stage = MESA_SHADER_VERTEX;
if (pipeline->device->physical_device->rad_info.chip_class >= GFX9) {
/* These are merged into the next stage */
vs_info_idx = has_tess ? MESA_SHADER_TESS_CTRL : MESA_SHADER_GEOMETRY;
@@ -2463,11 +2454,6 @@ radv_set_driver_locations(struct radv_pipeline *pipeline, nir_shader **shaders,
/* Copy data to merged stage */
infos[tes_info_idx].tes.num_linked_outputs = tes2gs.num_linked_io_vars;
last_vtg_stage = MESA_SHADER_GEOMETRY;
} else {
last_vtg_stage = MESA_SHADER_TESS_EVAL;
}
} else if (has_gs) {
nir_linked_io_var_info vs2gs = nir_assign_linked_io_var_locations(
@@ -2475,13 +2461,13 @@ radv_set_driver_locations(struct radv_pipeline *pipeline, nir_shader **shaders,
infos[MESA_SHADER_VERTEX].vs.num_linked_outputs = vs2gs.num_linked_io_vars;
infos[MESA_SHADER_GEOMETRY].gs.num_linked_inputs = vs2gs.num_linked_io_vars;
last_vtg_stage = MESA_SHADER_GEOMETRY;
/* Copy data to merged stage */
infos[vs_info_idx].vs.num_linked_outputs = vs2gs.num_linked_io_vars;
}
nir_foreach_shader_out_variable(var, shaders[last_vtg_stage])
assert(pipeline->graphics.last_vgt_api_stage != MESA_SHADER_NONE);
nir_foreach_shader_out_variable(var, shaders[pipeline->graphics.last_vgt_api_stage])
{
var->data.driver_location = var->data.location;
}
@@ -3282,6 +3268,8 @@ radv_create_shaders(struct radv_pipeline *pipeline, struct radv_device *device,
modules[i]->sha1);
pipeline->active_stages |= mesa_to_vk_shader_stage(i);
if (i < MESA_SHADER_FRAGMENT)
pipeline->graphics.last_vgt_api_stage = i;
}
}
@@ -3456,7 +3444,10 @@ radv_create_shaders(struct radv_pipeline *pipeline, struct radv_device *device,
/* Lower I/O intrinsics to memory instructions. */
bool io_to_mem = radv_lower_io_to_mem(device, nir[i], &infos[i], pipeline_key);
bool lowered_ngg = radv_lower_ngg(device, nir[i], !!nir[MESA_SHADER_GEOMETRY], &infos[i], pipeline_key, &keys[i]);
bool lowered_ngg = pipeline_has_ngg && i == pipeline->graphics.last_vgt_api_stage &&
!radv_use_llvm_for_stage(device, i);
if (lowered_ngg)
radv_lower_ngg(device, nir[i], &infos[i], pipeline_key, &keys[i]);
/* optimize the lowered ALU operations */
bool more_algebraic = true;
@@ -5380,6 +5371,7 @@ radv_pipeline_init(struct radv_pipeline *pipeline, struct radv_device *device,
pipeline->device = device;
pipeline->layout = radv_pipeline_layout_from_handle(pCreateInfo->layout);
pipeline->graphics.last_vgt_api_stage = MESA_SHADER_NONE;
assert(pipeline->layout);
struct radv_blend_state blend = radv_pipeline_init_blend_state(pipeline, pCreateInfo, extra);
@@ -5649,6 +5641,7 @@ radv_compute_pipeline_create(VkDevice _device, VkPipelineCache _cache,
vk_object_base_init(&device->vk, &pipeline->base, VK_OBJECT_TYPE_PIPELINE);
pipeline->device = device;
pipeline->graphics.last_vgt_api_stage = MESA_SHADER_NONE;
pipeline->layout = radv_pipeline_layout_from_handle(pCreateInfo->layout);
assert(pipeline->layout);

View File

@@ -1766,6 +1766,9 @@ struct radv_pipeline {
/* Whether the pipeline uses NGG (GFX10+). */
bool is_ngg;
/* Last pre-PS API stage */
gl_shader_stage last_vgt_api_stage;
} graphics;
};

View File

@@ -810,14 +810,17 @@ radv_lower_io_to_mem(struct radv_device *device, struct nir_shader *nir,
return false;
}
bool radv_lower_ngg(struct radv_device *device, struct nir_shader *nir, bool has_gs,
void radv_lower_ngg(struct radv_device *device, struct nir_shader *nir,
struct radv_shader_info *info,
const struct radv_pipeline_key *pl_key,
struct radv_shader_variant_key *key)
{
/* TODO: support the LLVM backend with the NIR lowering */
if (radv_use_llvm_for_stage(device, nir->info.stage))
return false;
assert(!radv_use_llvm_for_stage(device, nir->info.stage));
assert(nir->info.stage == MESA_SHADER_VERTEX ||
nir->info.stage == MESA_SHADER_TESS_EVAL ||
nir->info.stage == MESA_SHADER_GEOMETRY);
ac_nir_ngg_config out_conf = {0};
const struct gfx10_ngg_info *ngg_info = &info->ngg_info;
@@ -832,8 +835,7 @@ bool radv_lower_ngg(struct radv_device *device, struct nir_shader *nir, bool has
if (nir->info.stage == MESA_SHADER_VERTEX ||
nir->info.stage == MESA_SHADER_TESS_EVAL) {
if (has_gs || !key->vs_common_out.as_ngg)
return false;
assert(key->vs_common_out.as_ngg);
unsigned num_vertices_per_prim = 3;
@@ -862,21 +864,16 @@ bool radv_lower_ngg(struct radv_device *device, struct nir_shader *nir, bool has
info->is_ngg_passthrough = out_conf.passthrough;
key->vs_common_out.as_ngg_passthrough = out_conf.passthrough;
} else if (nir->info.stage == MESA_SHADER_GEOMETRY) {
if (!info->is_ngg)
return false;
assert(info->is_ngg);
ac_nir_lower_ngg_gs(
nir, info->wave_size, max_workgroup_size,
info->ngg_info.esgs_ring_size,
info->gs.gsvs_vertex_size,
info->ngg_info.ngg_emit_size * 4u,
key->vs.provoking_vtx_last);
return true;
} else {
return false;
unreachable("invalid SW stage passed to radv_lower_ngg");
}
return true;
}
static void *

View File

@@ -560,7 +560,7 @@ void radv_lower_io(struct radv_device *device, nir_shader *nir);
bool radv_lower_io_to_mem(struct radv_device *device, struct nir_shader *nir,
struct radv_shader_info *info, const struct radv_pipeline_key *pl_key);
bool radv_lower_ngg(struct radv_device *device, struct nir_shader *nir, bool has_gs,
void radv_lower_ngg(struct radv_device *device, struct nir_shader *nir,
struct radv_shader_info *info,
const struct radv_pipeline_key *pl_key,
struct radv_shader_variant_key *key);