panvk: Add FS read support for PrimitiveID
Adds support for reading PrimitiveID in a fragment shader assuming the previous shader was vertex. If support for shaders that can modify PrimitiveID is added, additional changes will be required. Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35367>
This commit is contained in:
committed by
Marge Bot
parent
49a7b1a5b8
commit
e6d53fc1d8
@@ -2231,6 +2231,10 @@ bi_emit_intrinsic(bi_builder *b, nir_intrinsic_instr *instr)
|
||||
bi_load_sample_id_to(b, dst);
|
||||
break;
|
||||
|
||||
case nir_intrinsic_load_primitive_id:
|
||||
bi_mov_i32_to(b, dst, bi_preload(b, 57));
|
||||
break;
|
||||
|
||||
case nir_intrinsic_load_front_face: {
|
||||
/* (r58 & 1) == 0 means primitive is front facing */
|
||||
bi_index primitive_facing = bi_preload(b, 58);
|
||||
|
||||
@@ -143,6 +143,9 @@ pan_shader_compile(nir_shader *s, struct pan_compile_inputs *inputs,
|
||||
info->fs.reads_frag_coord =
|
||||
(s->info.inputs_read & (1 << VARYING_SLOT_POS)) ||
|
||||
BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_FRAG_COORD);
|
||||
info->fs.reads_primitive_id =
|
||||
(s->info.inputs_read & (1 << VARYING_SLOT_PRIMITIVE_ID)) ||
|
||||
BITSET_TEST(s->info.system_values_read, SYSTEM_VALUE_PRIMITIVE_ID);
|
||||
info->fs.reads_point_coord =
|
||||
s->info.inputs_read & (1 << VARYING_SLOT_PNTC);
|
||||
info->fs.reads_face =
|
||||
|
||||
@@ -206,6 +206,7 @@ struct pan_shader_info {
|
||||
struct {
|
||||
bool reads_frag_coord;
|
||||
bool reads_point_coord;
|
||||
bool reads_primitive_id;
|
||||
bool reads_face;
|
||||
bool can_discard;
|
||||
bool writes_depth;
|
||||
|
||||
@@ -2085,6 +2085,8 @@ set_tiler_idvs_flags(struct cs_builder *b, struct panvk_cmd_buffer *cmdbuf,
|
||||
if (dirty) {
|
||||
pan_pack(&tiler_idvs_flags, PRIMITIVE_FLAGS, cfg) {
|
||||
cfg.draw_mode = translate_prim_topology(ia->primitive_topology);
|
||||
cfg.primitive_index_enable =
|
||||
fs ? fs->info.fs.reads_primitive_id : false;
|
||||
|
||||
#if PAN_ARCH < 13
|
||||
cfg.point_size_array_format = writes_point_size
|
||||
|
||||
@@ -835,11 +835,14 @@ panvk_emit_tiler_primitive(struct panvk_cmd_buffer *cmdbuf,
|
||||
vs->info.vs.writes_point_size &&
|
||||
ia->primitive_topology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
|
||||
bool secondary_shader = vs->info.vs.secondary_enable && fs != NULL;
|
||||
bool fs_reads_primitive_id = fs ? fs->info.fs.reads_primitive_id : false;
|
||||
|
||||
pan_pack(prim, PRIMITIVE, cfg) {
|
||||
cfg.draw_mode = translate_prim_topology(ia->primitive_topology);
|
||||
if (writes_point_size)
|
||||
cfg.point_size_array_format = MALI_POINT_SIZE_ARRAY_FORMAT_FP16;
|
||||
cfg.primitive_index_enable = fs_reads_primitive_id;
|
||||
cfg.primitive_index_writeback = fs_reads_primitive_id;
|
||||
|
||||
cfg.first_provoking_vertex =
|
||||
cmdbuf->state.gfx.render.first_provoking_vertex != U_TRISTATE_NO;
|
||||
@@ -900,6 +903,24 @@ panvk_emit_tiler_primitive_size(struct panvk_cmd_buffer *cmdbuf,
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
primitive_vertex_count(enum mali_draw_mode in)
|
||||
{
|
||||
switch (in) {
|
||||
case MALI_DRAW_MODE_POINTS:
|
||||
return 1;
|
||||
case MALI_DRAW_MODE_LINES:
|
||||
case MALI_DRAW_MODE_LINE_STRIP:
|
||||
return 2;
|
||||
case MALI_DRAW_MODE_TRIANGLES:
|
||||
case MALI_DRAW_MODE_TRIANGLE_STRIP:
|
||||
case MALI_DRAW_MODE_TRIANGLE_FAN:
|
||||
return 3;
|
||||
default:
|
||||
unreachable("Invalid draw mode");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
panvk_emit_tiler_dcd(struct panvk_cmd_buffer *cmdbuf,
|
||||
const struct panvk_draw_data *draw,
|
||||
@@ -936,6 +957,14 @@ panvk_emit_tiler_dcd(struct panvk_cmd_buffer *cmdbuf,
|
||||
cfg.offset_start = draw->info.vertex.raw_offset;
|
||||
cfg.instance_size =
|
||||
draw->info.instance.count > 1 ? draw->padded_vertex_count : 1;
|
||||
uint32_t primitives_per_instance =
|
||||
DIV_ROUND_UP(draw->padded_vertex_count,
|
||||
primitive_vertex_count(
|
||||
translate_prim_topology(ia->primitive_topology)));
|
||||
/* instance_primitive_size has the same restrictions as
|
||||
* padded_vertex_count, so we can use pan_padded_vertex_count here. */
|
||||
cfg.instance_primitive_size =
|
||||
pan_padded_vertex_count(primitives_per_instance);
|
||||
cfg.uniform_buffers = fs_desc_state->tables[PANVK_BIFROST_DESC_TABLE_UBO];
|
||||
cfg.push_uniforms = cmdbuf->state.gfx.fs.push_uniforms;
|
||||
cfg.textures = fs_desc_state->tables[PANVK_BIFROST_DESC_TABLE_TEXTURE];
|
||||
|
||||
@@ -224,6 +224,26 @@ panvk_lower_load_vs_input(nir_builder *b, nir_intrinsic_instr *intrin,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
panvk_lower_load_fs_input(nir_builder *b, nir_intrinsic_instr *intrin,
|
||||
UNUSED void *data)
|
||||
{
|
||||
if (intrin->intrinsic != nir_intrinsic_load_input)
|
||||
return false;
|
||||
|
||||
/* Lower PrimitiveID varying loads to the equivalent intrinsic. This only
|
||||
* works since v6 and will require additional changes if PrimitiveID is
|
||||
* explicitly written to (for example by a geometry shader). */
|
||||
if (nir_intrinsic_io_semantics(intrin).location ==
|
||||
VARYING_SLOT_PRIMITIVE_ID) {
|
||||
b->cursor = nir_before_instr(&intrin->instr);
|
||||
nir_def_replace(&intrin->def, nir_load_primitive_id(b));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if PAN_ARCH <= 7
|
||||
static bool
|
||||
lower_gl_pos_layer_writes(nir_builder *b, nir_instr *instr, void *data)
|
||||
@@ -867,6 +887,9 @@ panvk_lower_nir(struct panvk_device *dev, nir_shader *nir,
|
||||
if (stage == MESA_SHADER_VERTEX)
|
||||
NIR_PASS(_, nir, nir_shader_intrinsics_pass, panvk_lower_load_vs_input,
|
||||
nir_metadata_control_flow, NULL);
|
||||
else if (stage == MESA_SHADER_FRAGMENT)
|
||||
NIR_PASS(_, nir, nir_shader_intrinsics_pass, panvk_lower_load_fs_input,
|
||||
nir_metadata_control_flow, NULL);
|
||||
|
||||
/* since valhall, panvk_per_arch(nir_lower_descriptors) separates the
|
||||
* driver set and the user sets, and does not need pan_lower_image_index
|
||||
|
||||
Reference in New Issue
Block a user