mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-03 15:50:17 +01:00
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:
parent
337763f461
commit
6096586893
6 changed files with 51 additions and 63 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue