mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-10 18:38:27 +02:00
nvk: Prepare cbuf for mesh shader support
Signed-off-by: Mary Guillemard <mary@mary.zone> Reviewed-by: Mel Henning <mhenning@darkrefraction.com> Tested-by: Thomas H.P. Andersen <phomes@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27196>
This commit is contained in:
parent
3348003735
commit
3286990481
4 changed files with 59 additions and 9 deletions
|
|
@ -873,7 +873,7 @@ nvk_cmd_bind_shaders(struct vk_command_buffer *vk_cmd,
|
|||
}
|
||||
}
|
||||
|
||||
#define NVK_VK_GRAPHICS_STAGE_BITS VK_SHADER_STAGE_ALL_GRAPHICS
|
||||
#define NVK_VK_GRAPHICS_STAGE_BITS (VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_TASK_BIT_EXT | VK_SHADER_STAGE_MESH_BIT_EXT)
|
||||
|
||||
void
|
||||
nvk_cmd_dirty_cbufs_for_descriptors(struct nvk_cmd_buffer *cmd,
|
||||
|
|
@ -883,10 +883,15 @@ nvk_cmd_dirty_cbufs_for_descriptors(struct nvk_cmd_buffer *cmd,
|
|||
if (!(stages & NVK_VK_GRAPHICS_STAGE_BITS))
|
||||
return;
|
||||
|
||||
const struct nvk_shader *mesh_shader =
|
||||
cmd->state.gfx.shaders[MESA_SHADER_MESH];
|
||||
const bool has_task_shader =
|
||||
mesh_shader != NULL && mesh_shader->info.mesh.has_task_shader;
|
||||
|
||||
uint32_t groups = 0;
|
||||
u_foreach_bit(i, stages & NVK_VK_GRAPHICS_STAGE_BITS) {
|
||||
mesa_shader_stage stage = vk_to_mesa_shader_stage(1 << i);
|
||||
uint32_t g = nvk_cbuf_binding_for_stage(stage);
|
||||
uint32_t g = nvk_cbuf_binding_for_stage(stage, has_task_shader);
|
||||
groups |= BITFIELD_BIT(g);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2219,6 +2219,11 @@ nvk_cmd_flush_gfx_shaders(struct nvk_cmd_buffer *cmd)
|
|||
struct nvk_shader *type_shader[6] = { NULL, };
|
||||
uint32_t types_dirty = 0;
|
||||
|
||||
const struct nvk_shader *mesh_shader =
|
||||
cmd->state.gfx.shaders[MESA_SHADER_MESH];
|
||||
const bool has_task_shader =
|
||||
mesh_shader != NULL && mesh_shader->info.mesh.has_task_shader;
|
||||
|
||||
u_foreach_bit(s, cmd->state.gfx.shaders_dirty &
|
||||
NVK_SHADER_STAGE_GRAPHICS_BITS) {
|
||||
mesa_shader_stage stage = vk_to_mesa_shader_stage(1 << s);
|
||||
|
|
@ -2234,9 +2239,14 @@ nvk_cmd_flush_gfx_shaders(struct nvk_cmd_buffer *cmd)
|
|||
assert(type_shader[type] == NULL);
|
||||
type_shader[type] = shader;
|
||||
|
||||
/* In case of passthrough GS with mesh, we already handled binding of the geometry stage */
|
||||
if (stage == MESA_SHADER_MESH && shader->info.mesh.has_gs_sph)
|
||||
types_dirty &= ~BITFIELD_BIT(NV9097_SET_PIPELINE_SHADER_TYPE_GEOMETRY);
|
||||
|
||||
const struct nvk_cbuf_map *cbuf_map = &shader->cbuf_map;
|
||||
struct nvk_cbuf_group *cbuf_group =
|
||||
&cmd->state.gfx.cbuf_groups[nvk_cbuf_binding_for_stage(stage)];
|
||||
&cmd->state.gfx.cbuf_groups[nvk_cbuf_binding_for_stage(
|
||||
stage, has_task_shader)];
|
||||
for (uint32_t i = 0; i < cbuf_map->cbuf_count; i++) {
|
||||
if (memcmp(&cbuf_group->cbufs[i], &cbuf_map->cbufs[i],
|
||||
sizeof(cbuf_group->cbufs[i])) != 0) {
|
||||
|
|
@ -2245,6 +2255,20 @@ nvk_cmd_flush_gfx_shaders(struct nvk_cmd_buffer *cmd)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stage == MESA_SHADER_MESH) {
|
||||
/* If we change the mesh stage, this could also affect the tesselation
|
||||
* stage */
|
||||
types_dirty |=
|
||||
BITFIELD_BIT(NV9097_SET_PIPELINE_SHADER_TYPE_TESSELLATION);
|
||||
|
||||
/* If we unbind the mesh stage, this could also affect the geometry
|
||||
* stage (for per primitive passthrough header) */
|
||||
if (shader == NULL)
|
||||
types_dirty |=
|
||||
BITFIELD_BIT(NV9097_SET_PIPELINE_SHADER_TYPE_GEOMETRY);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
u_foreach_bit(type, types_dirty) {
|
||||
|
|
@ -4204,14 +4228,19 @@ nvk_cmd_flush_gfx_cbufs(struct nvk_cmd_buffer *cmd)
|
|||
const uint32_t min_cbuf_alignment = nvk_min_cbuf_alignment(&pdev->info);
|
||||
struct nvk_descriptor_state *desc = &cmd->state.gfx.descriptors;
|
||||
|
||||
const struct nvk_shader *mesh_shader =
|
||||
cmd->state.gfx.shaders[MESA_SHADER_MESH];
|
||||
const bool has_task_shader =
|
||||
mesh_shader != NULL && mesh_shader->info.mesh.has_task_shader;
|
||||
|
||||
/* Find cbuf maps for the 5 cbuf groups */
|
||||
const struct nvk_shader *cbuf_shaders[5] = { NULL, };
|
||||
for (mesa_shader_stage stage = 0; stage < MESA_SHADER_STAGES; stage++) {
|
||||
for (mesa_shader_stage stage = 0; stage < MESA_SHADER_MESH_STAGES; stage++) {
|
||||
const struct nvk_shader *shader = cmd->state.gfx.shaders[stage];
|
||||
if (shader == NULL)
|
||||
continue;
|
||||
|
||||
uint32_t group = nvk_cbuf_binding_for_stage(stage);
|
||||
uint32_t group = nvk_cbuf_binding_for_stage(stage, has_task_shader);
|
||||
assert(group < ARRAY_SIZE(cbuf_shaders));
|
||||
cbuf_shaders[group] = shader;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -700,8 +700,15 @@ mesa_to_nv9097_shader_type(mesa_shader_stage stage)
|
|||
}
|
||||
|
||||
uint32_t
|
||||
nvk_pipeline_bind_group(mesa_shader_stage stage)
|
||||
nvk_pipeline_bind_group(mesa_shader_stage stage, bool has_task_shader)
|
||||
{
|
||||
if (stage == MESA_SHADER_MESH && !has_task_shader)
|
||||
return MESA_SHADER_VERTEX;
|
||||
else if (stage == MESA_SHADER_MESH)
|
||||
return MESA_SHADER_TESS_EVAL;
|
||||
else if (stage == MESA_SHADER_TASK)
|
||||
return MESA_SHADER_VERTEX;
|
||||
|
||||
return stage;
|
||||
}
|
||||
|
||||
|
|
@ -741,6 +748,8 @@ nvk_shader_fill_push(struct nvk_device *dev,
|
|||
nv_push_init(&push, push_dw, ARRAY_SIZE(push_dw),
|
||||
nvk_queue_subchannels_from_engines(NVKMD_ENGINE_3D));
|
||||
|
||||
bool has_task_shader = shader->info.stage == MESA_SHADER_MESH &&
|
||||
shader->info.mesh.has_task_shader;
|
||||
const uint32_t type = mesa_to_nv9097_shader_type(shader->info.stage);
|
||||
|
||||
/* We always map index == type */
|
||||
|
|
@ -778,7 +787,7 @@ nvk_shader_fill_push(struct nvk_device *dev,
|
|||
P_MTHD(p, NVC397, SET_PIPELINE_REGISTER_COUNT(idx));
|
||||
P_NVC397_SET_PIPELINE_REGISTER_COUNT(p, idx, shader->info.num_gprs);
|
||||
P_NVC397_SET_PIPELINE_BINDING(p, idx,
|
||||
nvk_pipeline_bind_group(shader->info.stage));
|
||||
nvk_pipeline_bind_group(shader->info.stage, has_task_shader));
|
||||
|
||||
if (shader->info.stage == MESA_SHADER_TESS_CTRL ||
|
||||
shader->info.stage == MESA_SHADER_TESS_EVAL) {
|
||||
|
|
|
|||
|
|
@ -48,8 +48,15 @@ nvk_last_vtgm_shader_stage(VkShaderStageFlags stages)
|
|||
}
|
||||
|
||||
static inline uint32_t
|
||||
nvk_cbuf_binding_for_stage(mesa_shader_stage stage)
|
||||
nvk_cbuf_binding_for_stage(mesa_shader_stage stage, bool has_task_shader)
|
||||
{
|
||||
if (stage == MESA_SHADER_MESH && !has_task_shader)
|
||||
return MESA_SHADER_VERTEX;
|
||||
else if (stage == MESA_SHADER_MESH)
|
||||
return MESA_SHADER_TESS_EVAL;
|
||||
else if (stage == MESA_SHADER_TASK)
|
||||
return MESA_SHADER_VERTEX;
|
||||
|
||||
return stage;
|
||||
}
|
||||
|
||||
|
|
@ -155,6 +162,6 @@ nvk_compile_nir_shader(struct nvk_device *dev, nir_shader *nir,
|
|||
struct nvk_shader **shader_out);
|
||||
|
||||
uint32_t mesa_to_nv9097_shader_type(mesa_shader_stage stage);
|
||||
uint32_t nvk_pipeline_bind_group(mesa_shader_stage stage);
|
||||
uint32_t nvk_pipeline_bind_group(mesa_shader_stage stage, bool has_task_shader);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue