mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-24 03:18:25 +02:00
panvk/csf: Break VS descriptor setup into a new helper
This and the previous commit are the beginning of an overall restructure of the state flushing flow. The idea is that the very first thing flushed are descriptors, including vertex and fragment attributes. Importantly, flushing descriptors does not depend on which vertex shader variant we end up picking in the end. Both the HW and SW VS will use the same descriptors. Signed-off-by: Olivia Lee <olivia.lee@collabora.com> Reviewed-by: Eric R. Smith <eric.smith@collabora.com> Reviewed-by: Christian Gmeiner <cgmeiner@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41654>
This commit is contained in:
parent
2dabb5ded3
commit
ca3d54560b
1 changed files with 63 additions and 57 deletions
|
|
@ -286,35 +286,9 @@ emit_vs_attrib(struct panvk_cmd_buffer *cmdbuf,
|
|||
}
|
||||
}
|
||||
|
||||
/* Only valid to call after prepare_vi() */
|
||||
static bool
|
||||
vs_driver_set_is_dirty(struct panvk_cmd_buffer *cmdbuf)
|
||||
{
|
||||
/* If any of the attributes change on base instance and the base instance
|
||||
* has changed, we need to re-emit regardless of what API state is dirty.
|
||||
* prepare_draw() ensures that BASE_INSTANCE is always dirty for indirect
|
||||
* draws.
|
||||
*/
|
||||
if (cmdbuf->state.gfx.vi.attribs_changing_on_base_instance &&
|
||||
gfx_state_dirty(cmdbuf, BASE_INSTANCE))
|
||||
return true;
|
||||
|
||||
return dyn_gfx_state_dirty(cmdbuf, VI) ||
|
||||
dyn_gfx_state_dirty(cmdbuf, VI_BINDINGS_VALID) ||
|
||||
dyn_gfx_state_dirty(cmdbuf, VI_BINDING_STRIDES) ||
|
||||
gfx_state_dirty(cmdbuf, VB) || gfx_state_dirty(cmdbuf, VS) ||
|
||||
gfx_state_dirty(cmdbuf, DESC_STATE);
|
||||
}
|
||||
|
||||
static VkResult
|
||||
prepare_vs_driver_set(struct panvk_cmd_buffer *cmdbuf,
|
||||
const struct panvk_draw_info *draw)
|
||||
prepare_vs_driver_set(struct panvk_cmd_buffer *cmdbuf, uint32_t repeat_count)
|
||||
{
|
||||
prepare_vi(cmdbuf);
|
||||
|
||||
if (!vs_driver_set_is_dirty(cmdbuf))
|
||||
return VK_SUCCESS;
|
||||
|
||||
const struct panvk_shader_desc_info *vs_desc_info =
|
||||
&cmdbuf->state.gfx.vs.shader->desc_info;
|
||||
struct panvk_shader_desc_state *vs_desc_state = &cmdbuf->state.gfx.vs.desc;
|
||||
|
|
@ -329,18 +303,6 @@ prepare_vs_driver_set(struct panvk_cmd_buffer *cmdbuf,
|
|||
uint32_t vb_offset = vs_desc_info->dyn_bufs.count + MAX_VS_ATTRIBS + 1;
|
||||
uint32_t desc_count = vb_offset + vb_count;
|
||||
|
||||
cmdbuf->state.gfx.vs.desc_repeat_count = 0;
|
||||
if (draw->indirect.buffer_dev_addr) {
|
||||
/* BASE_INSTANCE is always dirty for indirect draws so it's safe to look
|
||||
* at the draw info here.
|
||||
*/
|
||||
assert(gfx_state_dirty(cmdbuf, BASE_INSTANCE));
|
||||
if (cmdbuf->state.gfx.vi.attribs_changing_on_base_instance)
|
||||
cmdbuf->state.gfx.vs.desc_repeat_count = draw->indirect.draw_count;
|
||||
}
|
||||
|
||||
uint32_t repeat_count = MAX2(cmdbuf->state.gfx.vs.desc_repeat_count, 1);
|
||||
|
||||
const struct panvk_descriptor_state *desc_state =
|
||||
&cmdbuf->state.gfx.desc_state;
|
||||
struct pan_ptr driver_set = panvk_cmd_alloc_dev_mem(
|
||||
|
|
@ -397,6 +359,66 @@ prepare_vs_driver_set(struct panvk_cmd_buffer *cmdbuf,
|
|||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
/* Only valid to call after prepare_vi() */
|
||||
static bool
|
||||
vs_desc_dirty(struct panvk_cmd_buffer *cmdbuf)
|
||||
{
|
||||
/* If any of the attributes change on base instance and the base instance
|
||||
* has changed, we need to re-emit regardless of what API state is dirty.
|
||||
* prepare_draw() ensures that BASE_INSTANCE is always dirty for indirect
|
||||
* draws.
|
||||
*/
|
||||
if (cmdbuf->state.gfx.vi.attribs_changing_on_base_instance &&
|
||||
gfx_state_dirty(cmdbuf, BASE_INSTANCE))
|
||||
return true;
|
||||
|
||||
return dyn_gfx_state_dirty(cmdbuf, VI) ||
|
||||
dyn_gfx_state_dirty(cmdbuf, VI_BINDINGS_VALID) ||
|
||||
dyn_gfx_state_dirty(cmdbuf, VI_BINDING_STRIDES) ||
|
||||
gfx_state_dirty(cmdbuf, VB) || gfx_state_dirty(cmdbuf, VS) ||
|
||||
gfx_state_dirty(cmdbuf, DESC_STATE);
|
||||
}
|
||||
|
||||
static VkResult
|
||||
prepare_vs_desc(struct panvk_cmd_buffer *cmdbuf,
|
||||
const struct panvk_draw_info *draw)
|
||||
{
|
||||
prepare_vi(cmdbuf);
|
||||
|
||||
if (!vs_desc_dirty(cmdbuf))
|
||||
return VK_SUCCESS;
|
||||
|
||||
cmdbuf->state.gfx.vs.desc_repeat_count = 0;
|
||||
if (draw->indirect.buffer_dev_addr) {
|
||||
/* BASE_INSTANCE is always dirty for indirect draws so it's safe to look
|
||||
* at the draw info here.
|
||||
*/
|
||||
assert(gfx_state_dirty(cmdbuf, BASE_INSTANCE));
|
||||
if (cmdbuf->state.gfx.vi.attribs_changing_on_base_instance)
|
||||
cmdbuf->state.gfx.vs.desc_repeat_count = draw->indirect.draw_count;
|
||||
}
|
||||
|
||||
const uint32_t repeat_count =
|
||||
MAX2(cmdbuf->state.gfx.vs.desc_repeat_count, 1);
|
||||
|
||||
VkResult result = prepare_vs_driver_set(cmdbuf, repeat_count);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
const struct panvk_shader_desc_info *vs_desc_info =
|
||||
&cmdbuf->state.gfx.vs.shader->desc_info;
|
||||
const struct panvk_descriptor_state *desc_state =
|
||||
&cmdbuf->state.gfx.desc_state;
|
||||
struct panvk_shader_desc_state *vs_desc_state = &cmdbuf->state.gfx.vs.desc;
|
||||
|
||||
result = panvk_per_arch(cmd_prepare_shader_res_table)(
|
||||
cmdbuf, desc_state, vs_desc_info, vs_desc_state, repeat_count);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
emit_varying_descs(const struct panvk_cmd_buffer *cmdbuf,
|
||||
struct mali_attribute_packed *descs)
|
||||
|
|
@ -1768,32 +1790,16 @@ static VkResult
|
|||
prepare_vs(struct panvk_cmd_buffer *cmdbuf, const struct panvk_draw_info *draw,
|
||||
const struct panvk_shader_variant *vs)
|
||||
{
|
||||
struct panvk_descriptor_state *desc_state = &cmdbuf->state.gfx.desc_state;
|
||||
struct panvk_shader_desc_state *vs_desc_state = &cmdbuf->state.gfx.vs.desc;
|
||||
struct cs_builder *b =
|
||||
panvk_get_cs_builder(cmdbuf, PANVK_SUBQUEUE_VERTEX_TILER);
|
||||
bool upd_res_table = false;
|
||||
|
||||
VkResult result = prepare_vs_driver_set(cmdbuf, draw);
|
||||
VkResult result = prepare_vs_desc(cmdbuf, draw);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
if (gfx_state_dirty(cmdbuf, VS) || gfx_state_dirty(cmdbuf, DESC_STATE) ||
|
||||
vs_driver_set_is_dirty(cmdbuf)) {
|
||||
const struct panvk_shader_desc_info *vs_desc_info =
|
||||
&cmdbuf->state.gfx.vs.shader->desc_info;
|
||||
|
||||
uint32_t repeat_count = MAX2(cmdbuf->state.gfx.vs.desc_repeat_count, 1);
|
||||
result = panvk_per_arch(cmd_prepare_shader_res_table)(
|
||||
cmdbuf, desc_state, vs_desc_info, vs_desc_state, repeat_count);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
upd_res_table = true;
|
||||
}
|
||||
|
||||
cs_update_vt_ctx(b) {
|
||||
if (upd_res_table)
|
||||
if (vs_desc_dirty(cmdbuf))
|
||||
cs_move64_to(b, cs_sr_reg64(b, IDVS, VERTEX_SRT),
|
||||
vs_desc_state->res_table);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue