From 6d76d46154ae8fffde26159813b55ed75c8f93f4 Mon Sep 17 00:00:00 2001 From: Nanley Chery Date: Tue, 11 Apr 2023 13:32:13 -0700 Subject: [PATCH] iris: Enable pass-through state init for gfx12 CCS The previous patch changed the gfx12 CCS initial aux state from pass-through to compressed-no-clear. This isn't always accurate. This patch determines if a CCS is in the pass-through state by inspecting the associated resources' bo field. In order to do that clearly, move aux-state initialization out of iris_resource_configure_aux (which can be called before BO creation). Split up that logic and move the pieces into iris_resource_from_handle, iris_resource_init_aux_buf, and a new function in ISL. Reviewed-by: Rohan Garg Part-of: --- src/gallium/drivers/iris/iris_resource.c | 100 ++++++----------------- src/intel/isl/isl.h | 10 +++ src/intel/isl/isl_aux_info.c | 67 +++++++++++++++ 3 files changed, 100 insertions(+), 77 deletions(-) diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c index bd6b372008f..2c6cb33874a 100644 --- a/src/gallium/drivers/iris/iris_resource.c +++ b/src/gallium/drivers/iris/iris_resource.c @@ -855,7 +855,7 @@ iris_get_ccs_surf_or_support(const struct isl_device *dev, */ static bool iris_resource_configure_aux(struct iris_screen *screen, - struct iris_resource *res, bool imported) + struct iris_resource *res) { const struct intel_device_info *devinfo = screen->devinfo; @@ -910,81 +910,10 @@ iris_resource_configure_aux(struct iris_screen *screen, } } - enum isl_aux_state initial_state; - switch (res->aux.usage) { - case ISL_AUX_USAGE_NONE: - /* Having no aux buffer is only okay if there's no modifier with aux. */ - return !res->mod_info || - !isl_drm_modifier_has_aux(res->mod_info->modifier); - case ISL_AUX_USAGE_HIZ: - case ISL_AUX_USAGE_HIZ_CCS: - case ISL_AUX_USAGE_HIZ_CCS_WT: - case ISL_AUX_USAGE_MCS: - case ISL_AUX_USAGE_MCS_CCS: - /* Leave the auxiliary buffer uninitialized. We can ambiguate it before - * accessing it later on, if needed. - */ - initial_state = ISL_AUX_STATE_AUX_INVALID; - break; - case ISL_AUX_USAGE_CCS_D: - case ISL_AUX_USAGE_CCS_E: - case ISL_AUX_USAGE_FCV_CCS_E: - case ISL_AUX_USAGE_STC_CCS: - case ISL_AUX_USAGE_MC: - if (imported) { - assert(res->aux.usage != ISL_AUX_USAGE_STC_CCS); - initial_state = - isl_drm_modifier_get_default_aux_state(res->mod_info->modifier); - } else if (devinfo->ver >= 12) { - assert(!devinfo->has_illegal_ccs_values); - /* From Bspec 47709, "MCS/CCS Buffers for Render Target(s)": - * - * "CCS surface does not require initialization. Illegal CCS - * [values] are treated as uncompressed memory." - * - * The above quote is from the render target section, but we assume - * it applies to CCS in general (e.g., STC_CCS). The uninitialized - * CCS may be in any aux state. We choose the one which is most - * convenient. - * - * We avoid states with CLEAR because stencil does not support it. - * Those states also create a dependency on the clear color, which - * can have negative performance implications. Even though some - * blocks may actually be encoded with CLEAR, we can get away with - * ignoring them - there are no known issues that require fast - * cleared blocks to be tracked and avoided. - * - * We specifically avoid the AUX_INVALID state because it could - * trigger an ambiguate. BLORP does not have support for ambiguating - * stencil. Also, ambiguating some LODs of mipmapped 8bpp surfaces - * seems to stomp on neighboring miplevels. - * - * There is only one remaining aux state which can give us correct - * behavior, COMPRESSED_NO_CLEAR. - */ - initial_state = ISL_AUX_STATE_COMPRESSED_NO_CLEAR; - } else { - /* When CCS is used, we need to ensure that it starts off in a valid - * state. From the Sky Lake PRM, "MCS Buffer for Render Target(s)": - * - * "If Software wants to enable Color Compression without Fast - * clear, Software needs to initialize MCS with zeros." - * - * A CCS surface initialized to zero is in the pass-through state. - * This state can avoid the need to ambiguate in some cases. We'll - * map and zero the CCS later on in iris_resource_init_aux_buf. - */ - initial_state = ISL_AUX_STATE_PASS_THROUGH; - } - break; - default: - unreachable("Unsupported aux mode"); - } - - /* Create the aux_state for the auxiliary buffer. */ - res->aux.state = create_aux_state_map(res, initial_state); - if (!res->aux.state) + if (res->mod_info && + isl_drm_modifier_has_aux(res->mod_info->modifier) != has_ccs) { return false; + } return true; } @@ -1010,7 +939,15 @@ iris_resource_init_aux_buf(struct iris_screen *screen, memset((char*)map + res->aux.offset, 0, res->aux.surf.size_B); iris_bo_unmap(res->bo); + + res->aux.state = create_aux_state_map(res, ISL_AUX_STATE_PASS_THROUGH); + } else { + const enum isl_aux_state initial_state = + isl_aux_get_initial_state(devinfo, res->aux.usage, res->bo->zeroed); + res->aux.state = create_aux_state_map(res, initial_state); } + if (!res->aux.state) + return false; if (res->aux.surf.size_B > 0) { res->aux.bo = res->bo; @@ -1133,7 +1070,7 @@ iris_resource_create_for_image(struct pipe_screen *pscreen, res->surf.size_B > (iris_bufmgr_sram_size(screen->bufmgr) / 2)) goto fail; - if (!iris_resource_configure_aux(screen, res, false)) + if (!iris_resource_configure_aux(screen, res)) goto fail; const char *name = "miptree"; @@ -1429,9 +1366,18 @@ iris_resource_from_handle(struct pipe_screen *pscreen, assert(main_res->bo->size >= main_res->offset + main_res->surf.size_B); - if (!iris_resource_configure_aux(screen, main_res, true)) + if (!iris_resource_configure_aux(screen, main_res)) goto fail; + if (res->aux.usage != ISL_AUX_USAGE_NONE) { + const enum isl_aux_state aux_state = + isl_drm_modifier_get_default_aux_state(modifier); + main_res->aux.state = + create_aux_state_map(main_res, aux_state); + if (!main_res->aux.state) + goto fail; + } + /* Add on a clear color BO if needed. * * Also add some padding to make sure the fast clear color state diff --git a/src/intel/isl/isl.h b/src/intel/isl/isl.h index 0901aa99060..782569e0323 100644 --- a/src/intel/isl/isl.h +++ b/src/intel/isl/isl.h @@ -2269,6 +2269,16 @@ isl_tiling_to_i915_tiling(enum isl_tiling tiling); enum isl_tiling isl_tiling_from_i915_tiling(uint32_t tiling); + +/** + * Return an isl_aux_state to describe an auxiliary surface that is either + * uninitialized or zeroed. + */ +enum isl_aux_state +isl_aux_get_initial_state(const struct intel_device_info *devinfo, + enum isl_aux_usage usage, + bool zeroed); + /** * Return an isl_aux_op needed to enable an access to occur in an * isl_aux_state suitable for the isl_aux_usage. diff --git a/src/intel/isl/isl_aux_info.c b/src/intel/isl/isl_aux_info.c index bfeb9e35ee2..619f0a30ba5 100644 --- a/src/intel/isl/isl_aux_info.c +++ b/src/intel/isl/isl_aux_info.c @@ -22,6 +22,7 @@ */ #include "isl/isl.h" +#include "dev/intel_device_info.h" #ifdef IN_UNIT_TEST /* STATIC_ASSERT is a do { ... } while(0) statement */ @@ -126,6 +127,72 @@ aux_state_possible(enum isl_aux_state state, unreachable("Invalid aux state."); } +enum isl_aux_state +isl_aux_get_initial_state(const struct intel_device_info *devinfo, + enum isl_aux_usage usage, + bool zeroed) +{ + switch (usage) { + case ISL_AUX_USAGE_HIZ: + case ISL_AUX_USAGE_HIZ_CCS: + case ISL_AUX_USAGE_HIZ_CCS_WT: + case ISL_AUX_USAGE_MCS: + case ISL_AUX_USAGE_MCS_CCS: + return ISL_AUX_STATE_AUX_INVALID; + case ISL_AUX_USAGE_CCS_D: + case ISL_AUX_USAGE_CCS_E: + case ISL_AUX_USAGE_FCV_CCS_E: + case ISL_AUX_USAGE_STC_CCS: + if (zeroed) { + /* From the Sky Lake PRM, "MCS Buffer for Render Target(s)": + * + * "If Software wants to enable Color Compression without Fast + * clear, Software needs to initialize MCS with zeros." + * + * Although MCS is mentioned, CCS seems to have been intended. This + * can be seen in Bspec 14091, in the row containing + * WaDisableCCSClearsIfRtCompressionEnabledInGT3. + * + * A CCS surface initialized to zero is in the pass-through state. + * This state can avoid the need to ambiguate in some cases. + */ + return ISL_AUX_STATE_PASS_THROUGH; + } else if (devinfo->ver >= 12) { + assert(!devinfo->has_illegal_ccs_values); + /* From Bspec 47709, "MCS/CCS Buffers for Render Target(s)": + * + * "CCS surface does not require initialization. Illegal CCS + * [values] are treated as uncompressed memory." + * + * The above quote is from the render target section, but we assume + * it applies to CCS in general (e.g., STC_CCS). The uninitialized + * CCS may be in any aux state. We choose the one which is most + * convenient. + * + * We avoid states with CLEAR because stencil does not support it. + * Those states also create a dependency on the clear color, which + * can have negative performance implications. Even though some + * blocks may actually be encoded with CLEAR, we can get away with + * ignoring them - there are no known issues that require fast + * cleared blocks to be tracked and avoided. + * + * We specifically avoid the AUX_INVALID state because it could + * trigger an ambiguate. BLORP does not have support for ambiguating + * stencil. Also, ambiguating some LODs of mipmapped 8bpp surfaces + * seems to stomp on neighboring miplevels. + * + * There is only one remaining aux state which can give us correct + * behavior, COMPRESSED_NO_CLEAR. + */ + return ISL_AUX_STATE_COMPRESSED_NO_CLEAR; + } else { + unreachable("Unsupported gfx version"); + } + default: + unreachable("Unsupported aux mode"); + } +} + enum isl_aux_op isl_aux_prepare_access(enum isl_aux_state initial_state, enum isl_aux_usage usage,