radv: handle primitive id input into fragment shader with no geom shader
Fixes: dEQP-VK.pipeline.framebuffer_attachment.no_attachments dEQP-VK.pipeline.framebuffer_attachment.no_attachments_ms Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
@@ -5124,6 +5124,7 @@ si_llvm_init_export_args(struct nir_to_llvm_context *ctx,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
handle_vs_outputs_post(struct nir_to_llvm_context *ctx,
|
handle_vs_outputs_post(struct nir_to_llvm_context *ctx,
|
||||||
|
bool export_prim_id,
|
||||||
struct ac_vs_output_info *outinfo)
|
struct ac_vs_output_info *outinfo)
|
||||||
{
|
{
|
||||||
uint32_t param_count = 0;
|
uint32_t param_count = 0;
|
||||||
@@ -5265,6 +5266,23 @@ handle_vs_outputs_post(struct nir_to_llvm_context *ctx,
|
|||||||
ac_build_export(&ctx->ac, &pos_args[i]);
|
ac_build_export(&ctx->ac, &pos_args[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (export_prim_id) {
|
||||||
|
LLVMValueRef values[4];
|
||||||
|
target = V_008DFC_SQ_EXP_PARAM + param_count;
|
||||||
|
outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = param_count;
|
||||||
|
param_count++;
|
||||||
|
|
||||||
|
values[0] = ctx->vs_prim_id;
|
||||||
|
ctx->shader_info->vs.vgpr_comp_cnt = MAX2(2,
|
||||||
|
ctx->shader_info->vs.vgpr_comp_cnt);
|
||||||
|
for (unsigned j = 1; j < 4; j++)
|
||||||
|
values[j] = ctx->f32zero;
|
||||||
|
si_llvm_init_export_args(ctx, values, target, &args);
|
||||||
|
ac_build_export(&ctx->ac, &args);
|
||||||
|
outinfo->export_prim_id = true;
|
||||||
|
}
|
||||||
|
|
||||||
outinfo->pos_exports = num_pos_exports;
|
outinfo->pos_exports = num_pos_exports;
|
||||||
outinfo->param_exports = param_count;
|
outinfo->param_exports = param_count;
|
||||||
}
|
}
|
||||||
@@ -5700,7 +5718,8 @@ handle_shader_outputs_post(struct nir_to_llvm_context *ctx)
|
|||||||
else if (ctx->options->key.vs.as_es)
|
else if (ctx->options->key.vs.as_es)
|
||||||
handle_es_outputs_post(ctx, &ctx->shader_info->vs.es_info);
|
handle_es_outputs_post(ctx, &ctx->shader_info->vs.es_info);
|
||||||
else
|
else
|
||||||
handle_vs_outputs_post(ctx, &ctx->shader_info->vs.outinfo);
|
handle_vs_outputs_post(ctx, ctx->options->key.vs.export_prim_id,
|
||||||
|
&ctx->shader_info->vs.outinfo);
|
||||||
break;
|
break;
|
||||||
case MESA_SHADER_FRAGMENT:
|
case MESA_SHADER_FRAGMENT:
|
||||||
handle_fs_outputs_post(ctx);
|
handle_fs_outputs_post(ctx);
|
||||||
@@ -5715,7 +5734,8 @@ handle_shader_outputs_post(struct nir_to_llvm_context *ctx)
|
|||||||
if (ctx->options->key.tes.as_es)
|
if (ctx->options->key.tes.as_es)
|
||||||
handle_es_outputs_post(ctx, &ctx->shader_info->tes.es_info);
|
handle_es_outputs_post(ctx, &ctx->shader_info->tes.es_info);
|
||||||
else
|
else
|
||||||
handle_vs_outputs_post(ctx, &ctx->shader_info->tes.outinfo);
|
handle_vs_outputs_post(ctx, ctx->options->key.tes.export_prim_id,
|
||||||
|
&ctx->shader_info->tes.outinfo);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -6191,7 +6211,7 @@ ac_gs_copy_shader_emit(struct nir_to_llvm_context *ctx)
|
|||||||
}
|
}
|
||||||
idx += slot_inc;
|
idx += slot_inc;
|
||||||
}
|
}
|
||||||
handle_vs_outputs_post(ctx, &ctx->shader_info->vs.outinfo);
|
handle_vs_outputs_post(ctx, false, &ctx->shader_info->vs.outinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ac_create_gs_copy_shader(LLVMTargetMachineRef tm,
|
void ac_create_gs_copy_shader(LLVMTargetMachineRef tm,
|
||||||
|
@@ -41,10 +41,12 @@ struct ac_vs_variant_key {
|
|||||||
uint32_t instance_rate_inputs;
|
uint32_t instance_rate_inputs;
|
||||||
uint32_t as_es:1;
|
uint32_t as_es:1;
|
||||||
uint32_t as_ls:1;
|
uint32_t as_ls:1;
|
||||||
|
uint32_t export_prim_id:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ac_tes_variant_key {
|
struct ac_tes_variant_key {
|
||||||
uint32_t as_es:1;
|
uint32_t as_es:1;
|
||||||
|
uint32_t export_prim_id:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ac_tcs_variant_key {
|
struct ac_tcs_variant_key {
|
||||||
@@ -128,6 +130,7 @@ struct ac_vs_output_info {
|
|||||||
bool writes_pointsize;
|
bool writes_pointsize;
|
||||||
bool writes_layer;
|
bool writes_layer;
|
||||||
bool writes_viewport_index;
|
bool writes_viewport_index;
|
||||||
|
bool export_prim_id;
|
||||||
uint32_t export_mask;
|
uint32_t export_mask;
|
||||||
unsigned pos_exports;
|
unsigned pos_exports;
|
||||||
};
|
};
|
||||||
|
@@ -669,7 +669,7 @@ radv_emit_vertex_shader(struct radv_cmd_buffer *cmd_buffer,
|
|||||||
else
|
else
|
||||||
radv_emit_hw_vs(cmd_buffer, pipeline, vs, &vs->info.vs.outinfo);
|
radv_emit_hw_vs(cmd_buffer, pipeline, vs, &vs->info.vs.outinfo);
|
||||||
|
|
||||||
radeon_set_context_reg(cmd_buffer->cs, R_028A84_VGT_PRIMITIVEID_EN, 0);
|
radeon_set_context_reg(cmd_buffer->cs, R_028A84_VGT_PRIMITIVEID_EN, pipeline->graphics.vgt_primitiveid_en);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -605,11 +605,14 @@ radv_pipeline_compile(struct radv_pipeline *pipeline,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static union ac_shader_variant_key
|
static union ac_shader_variant_key
|
||||||
radv_compute_tes_key(bool as_es)
|
radv_compute_tes_key(bool as_es, bool export_prim_id)
|
||||||
{
|
{
|
||||||
union ac_shader_variant_key key;
|
union ac_shader_variant_key key;
|
||||||
memset(&key, 0, sizeof(key));
|
memset(&key, 0, sizeof(key));
|
||||||
key.tes.as_es = as_es;
|
key.tes.as_es = as_es;
|
||||||
|
/* export prim id only happens when no geom shader */
|
||||||
|
if (!as_es)
|
||||||
|
key.tes.export_prim_id = export_prim_id;
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -640,10 +643,12 @@ radv_tess_pipeline_compile(struct radv_pipeline *pipeline,
|
|||||||
nir_shader *tes_nir, *tcs_nir;
|
nir_shader *tes_nir, *tcs_nir;
|
||||||
void *tes_code = NULL, *tcs_code = NULL;
|
void *tes_code = NULL, *tcs_code = NULL;
|
||||||
unsigned tes_code_size = 0, tcs_code_size = 0;
|
unsigned tes_code_size = 0, tcs_code_size = 0;
|
||||||
union ac_shader_variant_key tes_key = radv_compute_tes_key(radv_pipeline_has_gs(pipeline));
|
union ac_shader_variant_key tes_key;
|
||||||
union ac_shader_variant_key tcs_key;
|
union ac_shader_variant_key tcs_key;
|
||||||
bool dump = (pipeline->device->debug_flags & RADV_DEBUG_DUMP_SHADERS);
|
bool dump = (pipeline->device->debug_flags & RADV_DEBUG_DUMP_SHADERS);
|
||||||
|
|
||||||
|
tes_key = radv_compute_tes_key(radv_pipeline_has_gs(pipeline),
|
||||||
|
pipeline->shaders[MESA_SHADER_FRAGMENT]->info.fs.prim_id_input);
|
||||||
if (tes_module->nir)
|
if (tes_module->nir)
|
||||||
_mesa_sha1_compute(tes_module->nir->info.name,
|
_mesa_sha1_compute(tes_module->nir->info.name,
|
||||||
strlen(tes_module->nir->info.name),
|
strlen(tes_module->nir->info.name),
|
||||||
@@ -1606,7 +1611,7 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static union ac_shader_variant_key
|
static union ac_shader_variant_key
|
||||||
radv_compute_vs_key(const VkGraphicsPipelineCreateInfo *pCreateInfo, bool as_es, bool as_ls)
|
radv_compute_vs_key(const VkGraphicsPipelineCreateInfo *pCreateInfo, bool as_es, bool as_ls, bool export_prim_id)
|
||||||
{
|
{
|
||||||
union ac_shader_variant_key key;
|
union ac_shader_variant_key key;
|
||||||
const VkPipelineVertexInputStateCreateInfo *input_state =
|
const VkPipelineVertexInputStateCreateInfo *input_state =
|
||||||
@@ -1616,6 +1621,7 @@ radv_compute_vs_key(const VkGraphicsPipelineCreateInfo *pCreateInfo, bool as_es,
|
|||||||
key.vs.instance_rate_inputs = 0;
|
key.vs.instance_rate_inputs = 0;
|
||||||
key.vs.as_es = as_es;
|
key.vs.as_es = as_es;
|
||||||
key.vs.as_ls = as_ls;
|
key.vs.as_ls = as_ls;
|
||||||
|
key.vs.export_prim_id = export_prim_id;
|
||||||
|
|
||||||
for (unsigned i = 0; i < input_state->vertexAttributeDescriptionCount; ++i) {
|
for (unsigned i = 0; i < input_state->vertexAttributeDescriptionCount; ++i) {
|
||||||
unsigned binding;
|
unsigned binding;
|
||||||
@@ -1857,6 +1863,24 @@ static uint32_t si_vgt_gs_mode(struct radv_shader_variant *gs)
|
|||||||
S_028A40_GS_WRITE_OPTIMIZE(1);
|
S_028A40_GS_WRITE_OPTIMIZE(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void calculate_vgt_gs_mode(struct radv_pipeline *pipeline)
|
||||||
|
{
|
||||||
|
struct radv_shader_variant *vs;
|
||||||
|
vs = radv_pipeline_has_gs(pipeline) ? pipeline->gs_copy_shader : (radv_pipeline_has_tess(pipeline) ? pipeline->shaders[MESA_SHADER_TESS_EVAL] : pipeline->shaders[MESA_SHADER_VERTEX]);
|
||||||
|
|
||||||
|
struct ac_vs_output_info *outinfo = &vs->info.vs.outinfo;
|
||||||
|
|
||||||
|
pipeline->graphics.vgt_primitiveid_en = false;
|
||||||
|
pipeline->graphics.vgt_gs_mode = 0;
|
||||||
|
|
||||||
|
if (radv_pipeline_has_gs(pipeline)) {
|
||||||
|
pipeline->graphics.vgt_gs_mode = si_vgt_gs_mode(pipeline->shaders[MESA_SHADER_GEOMETRY]);
|
||||||
|
} else if (outinfo->export_prim_id) {
|
||||||
|
pipeline->graphics.vgt_gs_mode = S_028A40_MODE(V_028A40_GS_SCENARIO_A);
|
||||||
|
pipeline->graphics.vgt_primitiveid_en = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void calculate_pa_cl_vs_out_cntl(struct radv_pipeline *pipeline)
|
static void calculate_pa_cl_vs_out_cntl(struct radv_pipeline *pipeline)
|
||||||
{
|
{
|
||||||
struct radv_shader_variant *vs;
|
struct radv_shader_variant *vs;
|
||||||
@@ -2018,11 +2042,14 @@ radv_pipeline_init(struct radv_pipeline *pipeline,
|
|||||||
if (modules[MESA_SHADER_VERTEX]) {
|
if (modules[MESA_SHADER_VERTEX]) {
|
||||||
bool as_es = false;
|
bool as_es = false;
|
||||||
bool as_ls = false;
|
bool as_ls = false;
|
||||||
|
bool export_prim_id = false;
|
||||||
if (modules[MESA_SHADER_TESS_CTRL])
|
if (modules[MESA_SHADER_TESS_CTRL])
|
||||||
as_ls = true;
|
as_ls = true;
|
||||||
else if (modules[MESA_SHADER_GEOMETRY])
|
else if (modules[MESA_SHADER_GEOMETRY])
|
||||||
as_es = true;
|
as_es = true;
|
||||||
union ac_shader_variant_key key = radv_compute_vs_key(pCreateInfo, as_es, as_ls);
|
else if (pipeline->shaders[MESA_SHADER_FRAGMENT]->info.fs.prim_id_input)
|
||||||
|
export_prim_id = true;
|
||||||
|
union ac_shader_variant_key key = radv_compute_vs_key(pCreateInfo, as_es, as_ls, export_prim_id);
|
||||||
|
|
||||||
pipeline->shaders[MESA_SHADER_VERTEX] =
|
pipeline->shaders[MESA_SHADER_VERTEX] =
|
||||||
radv_pipeline_compile(pipeline, cache, modules[MESA_SHADER_VERTEX],
|
radv_pipeline_compile(pipeline, cache, modules[MESA_SHADER_VERTEX],
|
||||||
@@ -2035,7 +2062,7 @@ radv_pipeline_init(struct radv_pipeline *pipeline,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (modules[MESA_SHADER_GEOMETRY]) {
|
if (modules[MESA_SHADER_GEOMETRY]) {
|
||||||
union ac_shader_variant_key key = radv_compute_vs_key(pCreateInfo, false, false);
|
union ac_shader_variant_key key = radv_compute_vs_key(pCreateInfo, false, false, false);
|
||||||
|
|
||||||
pipeline->shaders[MESA_SHADER_GEOMETRY] =
|
pipeline->shaders[MESA_SHADER_GEOMETRY] =
|
||||||
radv_pipeline_compile(pipeline, cache, modules[MESA_SHADER_GEOMETRY],
|
radv_pipeline_compile(pipeline, cache, modules[MESA_SHADER_GEOMETRY],
|
||||||
@@ -2045,10 +2072,7 @@ radv_pipeline_init(struct radv_pipeline *pipeline,
|
|||||||
pipeline->layout, &key);
|
pipeline->layout, &key);
|
||||||
|
|
||||||
pipeline->active_stages |= mesa_to_vk_shader_stage(MESA_SHADER_GEOMETRY);
|
pipeline->active_stages |= mesa_to_vk_shader_stage(MESA_SHADER_GEOMETRY);
|
||||||
|
}
|
||||||
pipeline->graphics.vgt_gs_mode = si_vgt_gs_mode(pipeline->shaders[MESA_SHADER_GEOMETRY]);
|
|
||||||
} else
|
|
||||||
pipeline->graphics.vgt_gs_mode = 0;
|
|
||||||
|
|
||||||
if (modules[MESA_SHADER_TESS_EVAL]) {
|
if (modules[MESA_SHADER_TESS_EVAL]) {
|
||||||
assert(modules[MESA_SHADER_TESS_CTRL]);
|
assert(modules[MESA_SHADER_TESS_CTRL]);
|
||||||
@@ -2130,6 +2154,7 @@ radv_pipeline_init(struct radv_pipeline *pipeline,
|
|||||||
ps->info.fs.writes_z ? V_028710_SPI_SHADER_32_R :
|
ps->info.fs.writes_z ? V_028710_SPI_SHADER_32_R :
|
||||||
V_028710_SPI_SHADER_ZERO;
|
V_028710_SPI_SHADER_ZERO;
|
||||||
|
|
||||||
|
calculate_vgt_gs_mode(pipeline);
|
||||||
calculate_pa_cl_vs_out_cntl(pipeline);
|
calculate_pa_cl_vs_out_cntl(pipeline);
|
||||||
calculate_ps_inputs(pipeline);
|
calculate_ps_inputs(pipeline);
|
||||||
|
|
||||||
|
@@ -1071,6 +1071,7 @@ struct radv_pipeline {
|
|||||||
unsigned prim;
|
unsigned prim;
|
||||||
unsigned gs_out;
|
unsigned gs_out;
|
||||||
uint32_t vgt_gs_mode;
|
uint32_t vgt_gs_mode;
|
||||||
|
bool vgt_primitiveid_en;
|
||||||
bool prim_restart_enable;
|
bool prim_restart_enable;
|
||||||
unsigned esgs_ring_size;
|
unsigned esgs_ring_size;
|
||||||
unsigned gsvs_ring_size;
|
unsigned gsvs_ring_size;
|
||||||
|
@@ -700,6 +700,9 @@ si_get_ia_multi_vgt_param(struct radv_cmd_buffer *cmd_buffer,
|
|||||||
|
|
||||||
multi_instances_smaller_than_primgroup = indirect_draw || (instanced_draw &&
|
multi_instances_smaller_than_primgroup = indirect_draw || (instanced_draw &&
|
||||||
num_prims < primgroup_size);
|
num_prims < primgroup_size);
|
||||||
|
if (cmd_buffer->state.pipeline->shaders[MESA_SHADER_FRAGMENT]->info.fs.prim_id_input)
|
||||||
|
ia_switch_on_eoi = true;
|
||||||
|
|
||||||
if (radv_pipeline_has_tess(cmd_buffer->state.pipeline)) {
|
if (radv_pipeline_has_tess(cmd_buffer->state.pipeline)) {
|
||||||
/* SWITCH_ON_EOI must be set if PrimID is used. */
|
/* SWITCH_ON_EOI must be set if PrimID is used. */
|
||||||
if (cmd_buffer->state.pipeline->shaders[MESA_SHADER_TESS_CTRL]->info.tcs.uses_prim_id ||
|
if (cmd_buffer->state.pipeline->shaders[MESA_SHADER_TESS_CTRL]->info.tcs.uses_prim_id ||
|
||||||
|
Reference in New Issue
Block a user