diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c index 2f8babe8781..45c4ed00a5d 100644 --- a/src/intel/vulkan/anv_cmd_buffer.c +++ b/src/intel/vulkan/anv_cmd_buffer.c @@ -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, diff --git a/src/intel/vulkan/anv_genX.h b/src/intel/vulkan/anv_genX.h index fa77cff014e..03117ace095 100644 --- a/src/intel/vulkan/anv_genX.h +++ b/src/intel/vulkan/anv_genX.h @@ -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); diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 26fd900209a..774c85d5324 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -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; diff --git a/src/intel/vulkan/genX_blorp_exec.c b/src/intel/vulkan/genX_blorp_exec.c index c5c8c0e707a..385664d428c 100644 --- a/src/intel/vulkan/genX_blorp_exec.c +++ b/src/intel/vulkan/genX_blorp_exec.c @@ -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; diff --git a/src/intel/vulkan/genX_cmd_draw.c b/src/intel/vulkan/genX_cmd_draw.c index 74060b05d95..152bca1e5f4 100644 --- a/src/intel/vulkan/genX_cmd_draw.c +++ b/src/intel/vulkan/genX_cmd_draw.c @@ -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 diff --git a/src/intel/vulkan/genX_gfx_state.c b/src/intel/vulkan/genX_gfx_state.c index 04f379959cf..cec49612fe9 100644 --- a/src/intel/vulkan/genX_gfx_state.c +++ b/src/intel/vulkan/genX_gfx_state.c @@ -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 */