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 <rohan.garg@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27835>
This commit is contained in:
Nanley Chery 2023-04-11 13:32:13 -07:00 committed by Marge Bot
parent 06dff45abb
commit 6d76d46154
3 changed files with 100 additions and 77 deletions

View file

@ -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

View file

@ -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.

View file

@ -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,