mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-11 00:30:44 +01:00
iris: Don't guess the aux_usage
Instead of guessing an aux_usage, then confirming it if the isl_surf_get_*_surf functions are successful, just call the ISL functions up-front. This will help us to more easily determine if a depth buffer supports HIZ_CCS. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
parent
04e5f7e8a9
commit
909030bca6
1 changed files with 72 additions and 96 deletions
|
|
@ -399,6 +399,28 @@ map_aux_addresses(struct iris_screen *screen, struct iris_resource *res)
|
|||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
want_ccs_e_for_format(const struct gen_device_info *devinfo,
|
||||
enum isl_format format)
|
||||
{
|
||||
if (!isl_format_supports_ccs_e(devinfo, format))
|
||||
return false;
|
||||
|
||||
const struct isl_format_layout *fmtl = isl_format_get_layout(format);
|
||||
|
||||
/* CCS_E seems to significantly hurt performance with 32-bit floating
|
||||
* point formats. For example, Paraview's "Wavelet Volume" case uses
|
||||
* both R32_FLOAT and R32G32B32A32_FLOAT, and enabling CCS_E for those
|
||||
* formats causes a 62% FPS drop.
|
||||
*
|
||||
* However, many benchmarks seem to use 16-bit float with no issues.
|
||||
*/
|
||||
if (fmtl->channels.r.bits == 32 && fmtl->channels.r.type == ISL_SFLOAT)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure aux for the resource, but don't allocate it. For images which
|
||||
* might be shared with modifiers, we must allocate the image and aux data in
|
||||
|
|
@ -410,22 +432,65 @@ iris_resource_configure_aux(struct iris_screen *screen,
|
|||
uint64_t *aux_size_B,
|
||||
uint32_t *alloc_flags)
|
||||
{
|
||||
struct isl_device *isl_dev = &screen->isl_dev;
|
||||
enum isl_aux_state initial_state;
|
||||
UNUSED bool ok = false;
|
||||
const struct gen_device_info *devinfo = &screen->devinfo;
|
||||
|
||||
/* Try to create the auxiliary surfaces allowed by the modifier or by
|
||||
* the user if no modifier is specified.
|
||||
*/
|
||||
assert(!res->mod_info || res->mod_info->aux_usage == ISL_AUX_USAGE_NONE ||
|
||||
res->mod_info->aux_usage == ISL_AUX_USAGE_CCS_E);
|
||||
|
||||
const bool has_mcs = !res->mod_info &&
|
||||
isl_surf_get_mcs_surf(&screen->isl_dev, &res->surf, &res->aux.surf);
|
||||
|
||||
const bool has_hiz = !res->mod_info && !(INTEL_DEBUG & DEBUG_NO_HIZ) &&
|
||||
isl_surf_get_hiz_surf(&screen->isl_dev, &res->surf, &res->aux.surf);
|
||||
|
||||
const bool has_ccs =
|
||||
((!res->mod_info && !(INTEL_DEBUG & DEBUG_NO_RBC)) ||
|
||||
(res->mod_info && res->mod_info->aux_usage != ISL_AUX_USAGE_NONE)) &&
|
||||
isl_surf_get_ccs_surf(&screen->isl_dev, &res->surf, &res->aux.surf,
|
||||
NULL, 0);
|
||||
|
||||
/* We should have at most one aux surface. */
|
||||
assert(has_mcs + has_hiz + has_ccs <= 1);
|
||||
|
||||
if (res->mod_info && has_ccs) {
|
||||
/* Only allow a CCS modifier if the aux was created successfully. */
|
||||
res->aux.possible_usages |= 1 << res->mod_info->aux_usage;
|
||||
} else if (has_mcs) {
|
||||
res->aux.possible_usages |= 1 << ISL_AUX_USAGE_MCS;
|
||||
} else if (has_hiz) {
|
||||
res->aux.possible_usages |= 1 << ISL_AUX_USAGE_HIZ;
|
||||
} else if (has_ccs) {
|
||||
if (want_ccs_e_for_format(devinfo, res->surf.format))
|
||||
res->aux.possible_usages |= 1 << ISL_AUX_USAGE_CCS_E;
|
||||
|
||||
if (isl_format_supports_ccs_d(devinfo, res->surf.format))
|
||||
res->aux.possible_usages |= 1 << ISL_AUX_USAGE_CCS_D;
|
||||
}
|
||||
|
||||
res->aux.usage = util_last_bit(res->aux.possible_usages) - 1;
|
||||
|
||||
res->aux.sampler_usages = res->aux.possible_usages;
|
||||
|
||||
/* We don't always support sampling with hiz. But when we do, it must be
|
||||
* single sampled.
|
||||
*/
|
||||
if (!devinfo->has_sample_with_hiz || res->surf.samples > 1)
|
||||
res->aux.sampler_usages &= ~(1 << ISL_AUX_USAGE_HIZ);
|
||||
|
||||
enum isl_aux_state initial_state;
|
||||
*aux_size_B = 0;
|
||||
*alloc_flags = 0;
|
||||
assert(!res->aux.bo);
|
||||
|
||||
switch (res->aux.usage) {
|
||||
case ISL_AUX_USAGE_NONE:
|
||||
res->aux.surf.size_B = 0;
|
||||
ok = true;
|
||||
break;
|
||||
/* Having no aux buffer is only okay if there's no modifier with aux. */
|
||||
return !res->mod_info || res->mod_info->aux_usage == ISL_AUX_USAGE_NONE;
|
||||
case ISL_AUX_USAGE_HIZ:
|
||||
initial_state = ISL_AUX_STATE_AUX_INVALID;
|
||||
ok = isl_surf_get_hiz_surf(isl_dev, &res->surf, &res->aux.surf);
|
||||
break;
|
||||
case ISL_AUX_USAGE_MCS:
|
||||
/* The Ivybridge PRM, Vol 2 Part 1 p326 says:
|
||||
|
|
@ -438,7 +503,6 @@ iris_resource_configure_aux(struct iris_screen *screen,
|
|||
* 1's, so we simply memset it to 0xff.
|
||||
*/
|
||||
initial_state = ISL_AUX_STATE_CLEAR;
|
||||
ok = isl_surf_get_mcs_surf(isl_dev, &res->surf, &res->aux.surf);
|
||||
break;
|
||||
case ISL_AUX_USAGE_CCS_D:
|
||||
case ISL_AUX_USAGE_CCS_E:
|
||||
|
|
@ -461,18 +525,9 @@ iris_resource_configure_aux(struct iris_screen *screen,
|
|||
else
|
||||
initial_state = ISL_AUX_STATE_PASS_THROUGH;
|
||||
*alloc_flags |= BO_ALLOC_ZEROED;
|
||||
ok = isl_surf_get_ccs_surf(isl_dev, &res->surf, &res->aux.surf, NULL, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* We should have a valid aux_surf. */
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
/* No work is needed for a zero-sized auxiliary buffer. */
|
||||
if (res->aux.surf.size_B == 0)
|
||||
return true;
|
||||
|
||||
if (!res->aux.state) {
|
||||
/* Create the aux_state for the auxiliary buffer. */
|
||||
res->aux.state = create_aux_state_map(res, initial_state);
|
||||
|
|
@ -619,55 +674,6 @@ iris_resource_finish_aux_import(struct pipe_screen *pscreen,
|
|||
res->base.next = NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
supports_mcs(const struct isl_surf *surf)
|
||||
{
|
||||
/* MCS compression only applies to multisampled resources. */
|
||||
if (surf->samples <= 1)
|
||||
return false;
|
||||
|
||||
/* Depth and stencil buffers use the IMS (interleaved) layout. */
|
||||
if (isl_surf_usage_is_depth_or_stencil(surf->usage))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
supports_ccs(const struct gen_device_info *devinfo,
|
||||
const struct isl_surf *surf)
|
||||
{
|
||||
/* CCS only supports singlesampled resources. */
|
||||
if (surf->samples > 1)
|
||||
return false;
|
||||
|
||||
/* Note: still need to check the format! */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
want_ccs_e_for_format(const struct gen_device_info *devinfo,
|
||||
enum isl_format format)
|
||||
{
|
||||
if (!isl_format_supports_ccs_e(devinfo, format))
|
||||
return false;
|
||||
|
||||
const struct isl_format_layout *fmtl = isl_format_get_layout(format);
|
||||
|
||||
/* CCS_E seems to significantly hurt performance with 32-bit floating
|
||||
* point formats. For example, Paraview's "Wavelet Volume" case uses
|
||||
* both R32_FLOAT and R32G32B32A32_FLOAT, and enabling CCS_E for those
|
||||
* formats causes a 62% FPS drop.
|
||||
*
|
||||
* However, many benchmarks seem to use 16-bit float with no issues.
|
||||
*/
|
||||
if (fmtl->channels.r.bits == 32 && fmtl->channels.r.type == ISL_SFLOAT)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct pipe_resource *
|
||||
iris_resource_create_for_buffer(struct pipe_screen *pscreen,
|
||||
const struct pipe_resource *templ)
|
||||
|
|
@ -781,33 +787,6 @@ iris_resource_create_with_modifiers(struct pipe_screen *pscreen,
|
|||
.tiling_flags = tiling_flags);
|
||||
assert(isl_surf_created_successfully);
|
||||
|
||||
if (res->mod_info) {
|
||||
res->aux.possible_usages |= 1 << res->mod_info->aux_usage;
|
||||
} else if (supports_mcs(&res->surf)) {
|
||||
res->aux.possible_usages |= 1 << ISL_AUX_USAGE_MCS;
|
||||
} else if (has_depth) {
|
||||
if (likely(!(INTEL_DEBUG & DEBUG_NO_HIZ)))
|
||||
res->aux.possible_usages |= 1 << ISL_AUX_USAGE_HIZ;
|
||||
} else if (likely(!(INTEL_DEBUG & DEBUG_NO_RBC)) &&
|
||||
supports_ccs(devinfo, &res->surf)) {
|
||||
if (want_ccs_e_for_format(devinfo, res->surf.format))
|
||||
res->aux.possible_usages |= 1 << ISL_AUX_USAGE_CCS_E;
|
||||
|
||||
if (isl_format_supports_ccs_d(devinfo, res->surf.format))
|
||||
res->aux.possible_usages |= 1 << ISL_AUX_USAGE_CCS_D;
|
||||
}
|
||||
|
||||
res->aux.usage = util_last_bit(res->aux.possible_usages) - 1;
|
||||
|
||||
res->aux.sampler_usages = res->aux.possible_usages;
|
||||
|
||||
/* We don't always support sampling with hiz. But when we do, it must be
|
||||
* single sampled.
|
||||
*/
|
||||
if (!devinfo->has_sample_with_hiz || res->surf.samples > 1) {
|
||||
res->aux.sampler_usages &= ~(1 << ISL_AUX_USAGE_HIZ);
|
||||
}
|
||||
|
||||
const char *name = "miptree";
|
||||
enum iris_memory_zone memzone = IRIS_MEMZONE_OTHER;
|
||||
|
||||
|
|
@ -1003,9 +982,6 @@ iris_resource_from_handle(struct pipe_screen *pscreen,
|
|||
if (res->mod_info->aux_usage != ISL_AUX_USAGE_NONE) {
|
||||
uint32_t alloc_flags;
|
||||
uint64_t size;
|
||||
res->aux.usage = res->mod_info->aux_usage;
|
||||
res->aux.possible_usages = 1 << res->mod_info->aux_usage;
|
||||
res->aux.sampler_usages = res->aux.possible_usages;
|
||||
bool ok = iris_resource_configure_aux(screen, res, true, &size,
|
||||
&alloc_flags);
|
||||
assert(ok);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue