anv: rework Wa_18038825448 to track state on anv_gfx_dynamic_state

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32372>
This commit is contained in:
Lionel Landwerlin 2024-11-27 12:10:02 +02:00 committed by Marge Bot
parent 337763f461
commit 6096586893
6 changed files with 51 additions and 63 deletions

View file

@ -51,7 +51,6 @@ anv_cmd_state_init(struct anv_cmd_buffer *cmd_buffer)
state->current_pipeline = UINT32_MAX;
state->gfx.restart_index = UINT32_MAX;
state->gfx.object_preemption = true;
state->gfx.coarse_pixel_active = ANV_COARSE_PIXEL_STATE_UNKNOWN;
state->gfx.dirty = 0;
memcpy(state->gfx.dyn_state.dirty,

View file

@ -147,9 +147,9 @@ genX(cmd_buffer_set_coarse_pixel_active)(struct anv_cmd_buffer *cmd_buffer,
struct anv_cmd_graphics_state *gfx =
&cmd_buffer->state.gfx;
if (intel_needs_workaround(cmd_buffer->device->info, 18038825448) &&
gfx->coarse_pixel_active != state) {
gfx->coarse_pixel_active = state;
gfx->dirty |= ANV_CMD_DIRTY_COARSE_PIXEL_ACTIVE;
gfx->dyn_state.coarse_state != state) {
gfx->dyn_state.coarse_state = state;
BITSET_SET(gfx->dyn_state.dirty, ANV_GFX_STATE_COARSE_STATE);
return true;
}
return false;
@ -190,8 +190,7 @@ genX(cmd_buffer_flush_descriptor_sets)(struct anv_cmd_buffer *cmd_buffer,
void genX(cmd_buffer_flush_gfx_hw_state)(struct anv_cmd_buffer *cmd_buffer);
anv_cmd_dirty_mask_t
genX(cmd_buffer_flush_gfx_runtime_state)(struct anv_cmd_buffer *cmd_buffer);
void genX(cmd_buffer_flush_gfx_runtime_state)(struct anv_cmd_buffer *cmd_buffer);
void genX(cmd_buffer_flush_gfx_hw_state)(struct anv_cmd_buffer *cmd_buffer);

View file

@ -1482,12 +1482,19 @@ enum anv_gfx_state_bits {
ANV_GFX_STATE_TBIMR_TILE_PASS_INFO,
ANV_GFX_STATE_FS_MSAA_FLAGS,
ANV_GFX_STATE_TCS_INPUT_VERTICES,
ANV_GFX_STATE_COARSE_STATE,
ANV_GFX_STATE_MAX,
};
const char *anv_gfx_state_bit_to_str(enum anv_gfx_state_bits state);
enum anv_coarse_pixel_state {
ANV_COARSE_PIXEL_STATE_UNKNOWN,
ANV_COARSE_PIXEL_STATE_DISABLED,
ANV_COARSE_PIXEL_STATE_ENABLED,
};
/* This structure tracks the values to program in HW instructions for
* corresponding to dynamic states of the Vulkan API. Only fields that need to
* be reemitted outside of the VkPipeline object are tracked here.
@ -1799,6 +1806,11 @@ struct anv_gfx_dynamic_state {
*/
bool wa_14018283232_toggle;
/**
* Coarse state tracking for Wa_18038825448.
*/
enum anv_coarse_pixel_state coarse_state;
BITSET_DECLARE(dirty, ANV_GFX_STATE_MAX);
};
@ -3372,8 +3384,7 @@ enum anv_cmd_dirty_bits {
ANV_CMD_DIRTY_XFB_ENABLE = 1 << 4,
ANV_CMD_DIRTY_RESTART_INDEX = 1 << 5,
ANV_CMD_DIRTY_OCCLUSION_QUERY_ACTIVE = 1 << 6,
ANV_CMD_DIRTY_COARSE_PIXEL_ACTIVE = 1 << 7,
ANV_CMD_DIRTY_INDIRECT_DATA_STRIDE = 1 << 8,
ANV_CMD_DIRTY_INDIRECT_DATA_STRIDE = 1 << 7,
};
typedef enum anv_cmd_dirty_bits anv_cmd_dirty_mask_t;
@ -3862,12 +3873,6 @@ struct anv_cmd_pipeline_state {
struct anv_pipeline *pipeline;
};
enum anv_coarse_pixel_state {
ANV_COARSE_PIXEL_STATE_UNKNOWN,
ANV_COARSE_PIXEL_STATE_DISABLED,
ANV_COARSE_PIXEL_STATE_ENABLED,
};
enum anv_depth_reg_mode {
ANV_DEPTH_REG_MODE_UNKNOWN = 0,
ANV_DEPTH_REG_MODE_HW_DEFAULT,
@ -3938,11 +3943,6 @@ struct anv_cmd_graphics_state {
*/
bool viewport_set;
/**
* State tracking for Wa_18038825448.
*/
enum anv_coarse_pixel_state coarse_pixel_active;
struct intel_urb_config urb_cfg;
uint32_t n_occlusion_queries;

View file

@ -427,8 +427,7 @@ blorp_exec_on_render(struct blorp_batch *batch,
anv_cmd_dirty_mask_t dirty = ~(ANV_CMD_DIRTY_INDEX_BUFFER |
ANV_CMD_DIRTY_XFB_ENABLE |
ANV_CMD_DIRTY_OCCLUSION_QUERY_ACTIVE |
ANV_CMD_DIRTY_RESTART_INDEX |
ANV_CMD_DIRTY_COARSE_PIXEL_ACTIVE);
ANV_CMD_DIRTY_RESTART_INDEX);
cmd_buffer->state.gfx.vb_dirty = ~0;
cmd_buffer->state.gfx.dirty |= dirty;

View file

@ -881,12 +881,9 @@ genX(cmd_buffer_flush_gfx_state)(struct anv_cmd_buffer *cmd_buffer)
}
}
/* State left dirty after flushing runtime state. */
anv_cmd_dirty_mask_t dirty_state_mask = 0;
/* Flush the runtime state into the HW state tracking */
if (cmd_buffer->state.gfx.dirty || any_dynamic_state_dirty)
dirty_state_mask = genX(cmd_buffer_flush_gfx_runtime_state)(cmd_buffer);
genX(cmd_buffer_flush_gfx_runtime_state)(cmd_buffer);
/* Flush the HW state into the commmand buffer */
if (!BITSET_IS_EMPTY(cmd_buffer->state.gfx.dyn_state.dirty))
@ -958,10 +955,7 @@ genX(cmd_buffer_flush_gfx_state)(struct anv_cmd_buffer *cmd_buffer)
}
#endif
/* When we're done, only thing left is the possible dirty state
* returned by cmd_buffer_flush_gfx_runtime_state.
*/
cmd_buffer->state.gfx.dirty = dirty_state_mask;
cmd_buffer->state.gfx.dirty = 0;
}
ALWAYS_INLINE static bool

View file

@ -787,16 +787,14 @@ update_ps(struct anv_gfx_dynamic_state *hw_state,
POSOFFSET_SAMPLE : POSOFFSET_CENTROID);
}
ALWAYS_INLINE static anv_cmd_dirty_mask_t
ALWAYS_INLINE static void
update_ps_extra_wm(struct anv_gfx_dynamic_state *hw_state,
struct anv_cmd_buffer *cmd_buffer,
const struct anv_graphics_pipeline *pipeline)
{
const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline);
anv_cmd_dirty_mask_t dirty_state_mask = 0;
if (!wm_prog_data)
return dirty_state_mask;
return;
SET(PS_EXTRA, ps_extra.PixelShaderIsPerSample,
brw_wm_prog_data_is_persample(wm_prog_data,
@ -807,25 +805,14 @@ update_ps_extra_wm(struct anv_gfx_dynamic_state *hw_state,
SET(PS_EXTRA, ps_extra.PixelShaderIsPerCoarsePixel, uses_coarse_pixel);
#endif
#if GFX_VERx10 >= 125
enum anv_coarse_pixel_state cps_state = uses_coarse_pixel ?
ANV_COARSE_PIXEL_STATE_ENABLED : ANV_COARSE_PIXEL_STATE_DISABLED;
bool cps_state_toggled =
genX(cmd_buffer_set_coarse_pixel_active)(cmd_buffer, cps_state);
if (cps_state_toggled)
dirty_state_mask |= ANV_CMD_DIRTY_COARSE_PIXEL_ACTIVE;
const bool needs_ps_dependency =
/* TODO: We should only require this when the last geometry shader
* uses a fragment shading rate that is not constant.
*/
uses_coarse_pixel || cps_state_toggled;
SET(PS_EXTRA, ps_extra.EnablePSDependencyOnCPsizeChange, needs_ps_dependency);
/* TODO: We should only require this when the last geometry shader uses a
* fragment shading rate that is not constant.
*/
SET(PS_EXTRA, ps_extra.EnablePSDependencyOnCPsizeChange, uses_coarse_pixel);
#endif
SET(WM, wm.BarycentricInterpolationMode,
wm_prog_data_barycentric_modes(wm_prog_data, hw_state->fs_msaa_flags));
return dirty_state_mask;
}
ALWAYS_INLINE static void
@ -1763,10 +1750,8 @@ update_tbimr_info(struct anv_gfx_dynamic_state *hw_state,
* reemission if the values are changing.
*
* Nothing is emitted in the batch buffer.
*
* Returns a mask for state that we want to leave dirty afterwards.
*/
static anv_cmd_dirty_mask_t
static void
cmd_buffer_flush_gfx_runtime_state(struct anv_cmd_buffer *cmd_buffer,
const struct anv_graphics_pipeline *pipeline)
{
@ -1775,7 +1760,6 @@ cmd_buffer_flush_gfx_runtime_state(struct anv_cmd_buffer *cmd_buffer,
const struct vk_dynamic_graphics_state *dyn =
&cmd_buffer->vk.dynamic_graphics_state;
struct anv_gfx_dynamic_state *hw_state = &gfx->dyn_state;
anv_cmd_dirty_mask_t dirty_state_mask = 0;
UNUSED bool fs_msaa_changed = false;
if ((gfx->dirty & ANV_CMD_DIRTY_PIPELINE) ||
@ -1785,10 +1769,9 @@ cmd_buffer_flush_gfx_runtime_state(struct anv_cmd_buffer *cmd_buffer,
update_fs_msaa_flags(hw_state, dyn, pipeline);
if ((gfx->dirty & ANV_CMD_DIRTY_PIPELINE) ||
(gfx->dirty & ANV_CMD_DIRTY_COARSE_PIXEL_ACTIVE) ||
BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_FS_MSAA_FLAGS)) {
update_ps(hw_state, device, dyn, pipeline);
dirty_state_mask |= update_ps_extra_wm(hw_state, cmd_buffer, pipeline);
update_ps_extra_wm(hw_state, pipeline);
}
if (cmd_buffer->state.gfx.dirty &
@ -1969,8 +1952,6 @@ cmd_buffer_flush_gfx_runtime_state(struct anv_cmd_buffer *cmd_buffer,
SET(TCS_INPUT_VERTICES, tcs_input_vertices, dyn->ts.patch_control_points);
vk_dynamic_graphics_state_clear_dirty(&cmd_buffer->vk.dynamic_graphics_state);
return dirty_state_mask;
}
#undef GET
@ -1984,13 +1965,11 @@ cmd_buffer_flush_gfx_runtime_state(struct anv_cmd_buffer *cmd_buffer,
* reemission if the values are changing.
*
* Nothing is emitted in the batch buffer.
*
* Returns a mask for state that we want to leave dirty afterwards.
*/
anv_cmd_dirty_mask_t
void
genX(cmd_buffer_flush_gfx_runtime_state)(struct anv_cmd_buffer *cmd_buffer)
{
return cmd_buffer_flush_gfx_runtime_state(
cmd_buffer_flush_gfx_runtime_state(
cmd_buffer,
anv_pipeline_to_graphics(cmd_buffer->state.gfx.base.pipeline));
}
@ -2283,7 +2262,8 @@ cmd_buffer_gfx_state_emission(struct anv_cmd_buffer *cmd_buffer)
}
}
if (BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_PS_EXTRA)) {
if (BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_PS_EXTRA) ||
BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_COARSE_STATE)) {
anv_batch_emit_merge(&cmd_buffer->batch, GENX(3DSTATE_PS_EXTRA),
pipeline, partial.ps_extra, pse) {
SET(pse, ps_extra, PixelShaderHasUAV);
@ -2291,10 +2271,18 @@ cmd_buffer_gfx_state_emission(struct anv_cmd_buffer *cmd_buffer)
#if GFX_VER >= 11
SET(pse, ps_extra, PixelShaderIsPerCoarsePixel);
#endif
#if GFX_VERx10 >= 125
SET(pse, ps_extra, PixelShaderKillsPixel);
#if INTEL_WA_18038825448_GFX_VER
/* Add a dependency if easier the shader needs it (because of runtime
* change through pre-rasterization shader) or if we notice a change.
*/
pse.EnablePSDependencyOnCPsizeChange =
hw_state->ps_extra.EnablePSDependencyOnCPsizeChange ||
BITSET_TEST(hw_state->dirty, ANV_GFX_STATE_COARSE_STATE);
#elif GFX_VERx10 >= 125
SET(pse, ps_extra, EnablePSDependencyOnCPsizeChange);
#endif
SET(pse, ps_extra, PixelShaderKillsPixel);
}
}
@ -2812,6 +2800,15 @@ genX(cmd_buffer_flush_gfx_hw_state)(struct anv_cmd_buffer *cmd_buffer)
BITSET_SET(hw_state->dirty, ANV_GFX_STATE_STREAMOUT);
}
#if INTEL_WA_18038825448_GFX_VER
const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline);
if (wm_prog_data) {
genX(cmd_buffer_set_coarse_pixel_active)(
cmd_buffer,
brw_wm_prog_data_is_coarse(wm_prog_data, hw_state->fs_msaa_flags));
}
#endif
/* Gfx11 undocumented issue :
* https://gitlab.freedesktop.org/mesa/mesa/-/issues/9781
*/