iris: Add aux.sampler_usages.

We want to skip some types of aux usages (for instance,
ISL_AUX_USAGE_HIZ when the hardware doesn't support it, or when we have
multisampling) when sampling from the surface.

Instead of checking for those cases while filling the surface state and
leaving it blank, let's have a version of aux.possible_usages for
sampling. This way we can also avoid allocating surface state for the
cases we don't use.

Fixes: a8b5ea8ef0 "iris: Add function to update clear color in surface state."
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
Rafael Antognolli 2019-03-27 14:42:12 -07:00
parent dfc5620a41
commit 7339660e80
3 changed files with 34 additions and 16 deletions

View file

@ -243,6 +243,7 @@ iris_resource_disable_aux(struct iris_resource *res)
res->aux.usage = ISL_AUX_USAGE_NONE; res->aux.usage = ISL_AUX_USAGE_NONE;
res->aux.possible_usages = 1 << ISL_AUX_USAGE_NONE; res->aux.possible_usages = 1 << ISL_AUX_USAGE_NONE;
res->aux.sampler_usages = 1 << ISL_AUX_USAGE_NONE;
res->aux.surf.size_B = 0; res->aux.surf.size_B = 0;
res->aux.bo = NULL; res->aux.bo = NULL;
res->aux.clear_color_bo = NULL; res->aux.clear_color_bo = NULL;
@ -274,6 +275,7 @@ iris_alloc_resource(struct pipe_screen *pscreen,
pipe_reference_init(&res->base.reference, 1); pipe_reference_init(&res->base.reference, 1);
res->aux.possible_usages = 1 << ISL_AUX_USAGE_NONE; res->aux.possible_usages = 1 << ISL_AUX_USAGE_NONE;
res->aux.sampler_usages = 1 << ISL_AUX_USAGE_NONE;
return res; return res;
} }
@ -645,6 +647,15 @@ iris_resource_create_with_modifiers(struct pipe_screen *pscreen,
res->aux.usage = util_last_bit(res->aux.possible_usages) - 1; 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"; const char *name = "miptree";
enum iris_memory_zone memzone = IRIS_MEMZONE_OTHER; enum iris_memory_zone memzone = IRIS_MEMZONE_OTHER;

View file

@ -116,6 +116,11 @@ struct iris_resource {
*/ */
unsigned possible_usages; unsigned possible_usages;
/**
* Same as possible_usages, but only with modes supported for sampling.
*/
unsigned sampler_usages;
/** /**
* \brief Maps miptree slices to their current aux state. * \brief Maps miptree slices to their current aux state.
* *

View file

@ -1712,7 +1712,7 @@ iris_create_sampler_view(struct pipe_context *ctx,
void *map = alloc_surface_states(ice->state.surface_uploader, void *map = alloc_surface_states(ice->state.surface_uploader,
&isv->surface_state, &isv->surface_state,
isv->res->aux.possible_usages); isv->res->aux.sampler_usages);
if (!unlikely(map)) if (!unlikely(map))
return NULL; return NULL;
@ -1747,17 +1747,15 @@ iris_create_sampler_view(struct pipe_context *ctx,
isv->view.array_len = isv->view.array_len =
tmpl->u.tex.last_layer - tmpl->u.tex.first_layer + 1; tmpl->u.tex.last_layer - tmpl->u.tex.first_layer + 1;
unsigned aux_modes = isv->res->aux.possible_usages; unsigned aux_modes = isv->res->aux.sampler_usages;
while (aux_modes) { while (aux_modes) {
enum isl_aux_usage aux_usage = u_bit_scan(&aux_modes); enum isl_aux_usage aux_usage = u_bit_scan(&aux_modes);
/* If we have a multisampled depth buffer, do not create a sampler /* If we have a multisampled depth buffer, do not create a sampler
* surface state with HiZ. * surface state with HiZ.
*/ */
if (!(aux_usage == ISL_AUX_USAGE_HIZ && isv->res->surf.samples > 1)) {
fill_surface_state(&screen->isl_dev, map, isv->res, &isv->view, fill_surface_state(&screen->isl_dev, map, isv->res, &isv->view,
aux_usage); aux_usage);
}
map += SURFACE_STATE_ALIGNMENT; map += SURFACE_STATE_ALIGNMENT;
} }
@ -3753,6 +3751,7 @@ use_null_fb_surface(struct iris_batch *batch, struct iris_context *ice)
static uint32_t static uint32_t
surf_state_offset_for_aux(struct iris_resource *res, surf_state_offset_for_aux(struct iris_resource *res,
unsigned aux_modes,
enum isl_aux_usage aux_usage) enum isl_aux_usage aux_usage)
{ {
return SURFACE_STATE_ALIGNMENT * return SURFACE_STATE_ALIGNMENT *
@ -3763,6 +3762,7 @@ static void
surf_state_update_clear_value(struct iris_batch *batch, surf_state_update_clear_value(struct iris_batch *batch,
struct iris_resource *res, struct iris_resource *res,
struct iris_state_ref *state, struct iris_state_ref *state,
unsigned aux_modes,
enum isl_aux_usage aux_usage) enum isl_aux_usage aux_usage)
{ {
struct isl_device *isl_dev = &batch->screen->isl_dev; struct isl_device *isl_dev = &batch->screen->isl_dev;
@ -3772,7 +3772,7 @@ surf_state_update_clear_value(struct iris_batch *batch,
uint32_t offset_into_bo = real_offset - state_bo->gtt_offset; uint32_t offset_into_bo = real_offset - state_bo->gtt_offset;
uint32_t clear_offset = offset_into_bo + uint32_t clear_offset = offset_into_bo +
isl_dev->ss.clear_value_offset + isl_dev->ss.clear_value_offset +
surf_state_offset_for_aux(res, aux_usage); surf_state_offset_for_aux(res, aux_modes, aux_usage);
batch->vtbl->copy_mem_mem(batch, state_bo, clear_offset, batch->vtbl->copy_mem_mem(batch, state_bo, clear_offset,
res->aux.clear_color_bo, res->aux.clear_color_bo,
@ -3785,6 +3785,7 @@ update_clear_value(struct iris_context *ice,
struct iris_batch *batch, struct iris_batch *batch,
struct iris_resource *res, struct iris_resource *res,
struct iris_state_ref *state, struct iris_state_ref *state,
unsigned aux_modes,
struct isl_view *view) struct isl_view *view)
{ {
struct iris_screen *screen = batch->screen; struct iris_screen *screen = batch->screen;
@ -3796,15 +3797,15 @@ update_clear_value(struct iris_context *ice,
if (devinfo->gen > 9) if (devinfo->gen > 9)
return; return;
unsigned aux_modes = res->aux.possible_usages;
if (devinfo->gen == 9) { if (devinfo->gen == 9) {
/* Skip updating the ISL_AUX_USAGE_NONE surface state */ /* Skip updating the ISL_AUX_USAGE_NONE surface state */
aux_modes &= ~(1 << ISL_AUX_USAGE_NONE); aux_modes &= ~(1 << ISL_AUX_USAGE_NONE);
while (aux_modes) { while (aux_modes) {
enum isl_aux_usage aux_usage = u_bit_scan(&aux_modes); enum isl_aux_usage aux_usage = u_bit_scan(&aux_modes);
surf_state_update_clear_value(batch, res, state, aux_usage);
surf_state_update_clear_value(batch, res, state, aux_modes,
aux_usage);
} }
} else if (devinfo->gen == 8) { } else if (devinfo->gen == 8) {
pipe_resource_reference(&state->res, NULL); pipe_resource_reference(&state->res, NULL);
@ -3844,14 +3845,14 @@ use_surface(struct iris_context *ice,
if (memcmp(&res->aux.clear_color, &surf->clear_color, if (memcmp(&res->aux.clear_color, &surf->clear_color,
sizeof(surf->clear_color)) != 0) { sizeof(surf->clear_color)) != 0) {
update_clear_value(ice, batch, res, update_clear_value(ice, batch, res, &surf->surface_state,
&surf->surface_state, &surf->view); res->aux.possible_usages, &surf->view);
surf->clear_color = res->aux.clear_color; surf->clear_color = res->aux.clear_color;
} }
} }
return surf->surface_state.offset + return surf->surface_state.offset +
surf_state_offset_for_aux(res, aux_usage); surf_state_offset_for_aux(res, res->aux.possible_usages, aux_usage);
} }
static uint32_t static uint32_t
@ -3872,14 +3873,15 @@ use_sampler_view(struct iris_context *ice,
iris_use_pinned_bo(batch, isv->res->aux.clear_color_bo, false); iris_use_pinned_bo(batch, isv->res->aux.clear_color_bo, false);
if (memcmp(&isv->res->aux.clear_color, &isv->clear_color, if (memcmp(&isv->res->aux.clear_color, &isv->clear_color,
sizeof(isv->clear_color)) != 0) { sizeof(isv->clear_color)) != 0) {
update_clear_value(ice, batch, isv->res, update_clear_value(ice, batch, isv->res, &isv->surface_state,
&isv->surface_state, &isv->view); isv->res->aux.sampler_usages, &isv->view);
isv->clear_color = isv->res->aux.clear_color; isv->clear_color = isv->res->aux.clear_color;
} }
} }
return isv->surface_state.offset + return isv->surface_state.offset +
surf_state_offset_for_aux(isv->res, aux_usage); surf_state_offset_for_aux(isv->res, isv->res->aux.sampler_usages,
aux_usage);
} }
static uint32_t static uint32_t