diff options
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/iris/iris_blit.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/iris/iris_resource.c | 123 | ||||
-rw-r--r-- | src/gallium/drivers/iris/iris_resource.h | 10 | ||||
-rw-r--r-- | src/gallium/drivers/iris/iris_state.c | 8 |
4 files changed, 118 insertions, 25 deletions
diff --git a/src/gallium/drivers/iris/iris_blit.c b/src/gallium/drivers/iris/iris_blit.c index 6fa452c68b1..3f9bee19085 100644 --- a/src/gallium/drivers/iris/iris_blit.c +++ b/src/gallium/drivers/iris/iris_blit.c @@ -238,6 +238,8 @@ iris_blorp_surf_for_resource(struct iris_vtable *vtbl, { struct iris_resource *res = (void *) p_res; + assert(!iris_resource_unfinished_aux_import(res)); + if (aux_usage == ISL_AUX_USAGE_HIZ && !iris_resource_level_has_hiz(res, level)) aux_usage = ISL_AUX_USAGE_NONE; diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c index 6296996f643..8255c5e7988 100644 --- a/src/gallium/drivers/iris/iris_resource.c +++ b/src/gallium/drivers/iris/iris_resource.c @@ -364,7 +364,8 @@ iris_get_aux_clear_color_state_size(struct iris_screen *screen) */ static bool iris_resource_configure_aux(struct iris_screen *screen, - struct iris_resource *res, uint64_t *aux_size_B, + struct iris_resource *res, bool imported, + uint64_t *aux_size_B, uint32_t *alloc_flags) { struct isl_device *isl_dev = &screen->isl_dev; @@ -412,7 +413,11 @@ iris_resource_configure_aux(struct iris_screen *screen, * For CCS_D, do the same thing. On Gen9+, this avoids having any * undefined bits in the aux buffer. */ - initial_state = ISL_AUX_STATE_PASS_THROUGH; + if (imported) + initial_state = + isl_drm_modifier_get_default_aux_state(res->mod_info->modifier); + 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, 0); break; @@ -506,7 +511,7 @@ iris_resource_alloc_separate_aux(struct iris_screen *screen, { uint32_t alloc_flags; uint64_t size; - if (!iris_resource_configure_aux(screen, res, &size, &alloc_flags)) + if (!iris_resource_configure_aux(screen, res, false, &size, &alloc_flags)) return false; if (size == 0) @@ -531,6 +536,44 @@ iris_resource_alloc_separate_aux(struct iris_screen *screen, return true; } +void +iris_resource_finish_aux_import(struct pipe_screen *pscreen, + struct iris_resource *res) +{ + struct iris_screen *screen = (struct iris_screen *)pscreen; + assert(iris_resource_unfinished_aux_import(res)); + assert(!res->mod_info->supports_clear_color); + + struct iris_resource *aux_res = (void *) res->base.next; + assert(aux_res->aux.surf.row_pitch_B && aux_res->aux.offset && + aux_res->aux.bo); + + assert(res->bo == aux_res->aux.bo); + iris_bo_reference(aux_res->aux.bo); + res->aux.bo = aux_res->aux.bo; + + res->aux.offset = aux_res->aux.offset; + + assert(res->bo->size >= (res->aux.offset + res->aux.surf.size_B)); + assert(res->aux.clear_color_bo == NULL); + res->aux.clear_color_offset = 0; + + assert(aux_res->aux.surf.row_pitch_B == res->aux.surf.row_pitch_B); + + unsigned clear_color_state_size = + iris_get_aux_clear_color_state_size(screen); + + if (clear_color_state_size > 0) { + res->aux.clear_color_bo = + iris_bo_alloc(screen->bufmgr, "clear color buffer", + clear_color_state_size, IRIS_MEMZONE_OTHER); + res->aux.clear_color_offset = 0; + } + + iris_resource_destroy(&screen->base, res->base.next); + res->base.next = NULL; +} + static bool supports_mcs(const struct isl_surf *surf) { @@ -728,7 +771,7 @@ iris_resource_create_with_modifiers(struct pipe_screen *pscreen, uint32_t aux_preferred_alloc_flags; uint64_t aux_size = 0; bool aux_enabled = - iris_resource_configure_aux(screen, res, &aux_size, + iris_resource_configure_aux(screen, res, false, &aux_size, &aux_preferred_alloc_flags); aux_enabled = aux_enabled && res->aux.surf.size_B > 0; const bool separate_aux = aux_enabled && !res->mod_info; @@ -878,27 +921,57 @@ iris_resource_from_handle(struct pipe_screen *pscreen, if (templ->target == PIPE_BUFFER) { res->surf.tiling = ISL_TILING_LINEAR; } else { - UNUSED const bool isl_surf_created_successfully = - isl_surf_init(&screen->isl_dev, &res->surf, - .dim = target_to_isl_surf_dim(templ->target), - .format = fmt.fmt, - .width = templ->width0, - .height = templ->height0, - .depth = templ->depth0, - .levels = templ->last_level + 1, - .array_len = templ->array_size, - .samples = MAX2(templ->nr_samples, 1), - .min_alignment_B = 0, - .row_pitch_B = whandle->stride, - .usage = isl_usage, - .tiling_flags = 1 << res->mod_info->tiling); - assert(isl_surf_created_successfully); - assert(res->bo->tiling_mode == - isl_tiling_to_i915_tiling(res->surf.tiling)); - - // XXX: create_ccs_buf_for_image? - if (!iris_resource_alloc_separate_aux(screen, res)) - goto fail; + if (whandle->modifier == DRM_FORMAT_MOD_INVALID || whandle->plane == 0) { + UNUSED const bool isl_surf_created_successfully = + isl_surf_init(&screen->isl_dev, &res->surf, + .dim = target_to_isl_surf_dim(templ->target), + .format = fmt.fmt, + .width = templ->width0, + .height = templ->height0, + .depth = templ->depth0, + .levels = templ->last_level + 1, + .array_len = templ->array_size, + .samples = MAX2(templ->nr_samples, 1), + .min_alignment_B = 0, + .row_pitch_B = whandle->stride, + .usage = isl_usage, + .tiling_flags = 1 << res->mod_info->tiling); + assert(isl_surf_created_successfully); + assert(res->bo->tiling_mode == + isl_tiling_to_i915_tiling(res->surf.tiling)); + + // XXX: create_ccs_buf_for_image? + if (whandle->modifier == DRM_FORMAT_MOD_INVALID) { + if (!iris_resource_alloc_separate_aux(screen, res)) + goto fail; + } else { + 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); + /* The gallium dri layer will create a separate plane resource + * for the aux image. iris_resource_finish_aux_import will + * merge the separate aux parameters back into a single + * iris_resource. + */ + } + } + } else { + /* Save modifier import information to reconstruct later. After + * import, this will be available under a second image accessible + * from the main image with res->base.next. See + * iris_resource_finish_aux_import. + */ + res->aux.surf.row_pitch_B = whandle->stride; + res->aux.offset = whandle->offset; + res->aux.bo = res->bo; + res->bo = NULL; + } } return &res->base; diff --git a/src/gallium/drivers/iris/iris_resource.h b/src/gallium/drivers/iris/iris_resource.h index 45e00ede7e9..a233d57e32b 100644 --- a/src/gallium/drivers/iris/iris_resource.h +++ b/src/gallium/drivers/iris/iris_resource.h @@ -407,6 +407,16 @@ void iris_resource_prepare_image(struct iris_context *ice, struct iris_batch *batch, struct iris_resource *res); +static inline bool +iris_resource_unfinished_aux_import(struct iris_resource *res) +{ + return res->base.next != NULL && res->mod_info && + res->mod_info->aux_usage != ISL_AUX_USAGE_NONE; +} + +void iris_resource_finish_aux_import(struct pipe_screen *pscreen, + struct iris_resource *res); + bool iris_has_color_unresolved(const struct iris_resource *res, unsigned start_level, unsigned num_levels, unsigned start_layer, unsigned num_layers); diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index a3d93b769ce..bfc29d71496 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -1749,6 +1749,8 @@ fill_surface_state(struct isl_device *isl_dev, .address = res->bo->gtt_offset + res->offset, }; + assert(!iris_resource_unfinished_aux_import(res)); + if (aux_usage != ISL_AUX_USAGE_NONE) { f.aux_surf = &res->aux.surf; f.aux_usage = aux_usage; @@ -1839,6 +1841,9 @@ iris_create_sampler_view(struct pipe_context *ctx, isv->view.array_len = tmpl->u.tex.last_layer - tmpl->u.tex.first_layer + 1; + if (iris_resource_unfinished_aux_import(isv->res)) + iris_resource_finish_aux_import(&screen->base, isv->res); + unsigned aux_modes = isv->res->aux.sampler_usages; while (aux_modes) { enum isl_aux_usage aux_usage = u_bit_scan(&aux_modes); @@ -1949,6 +1954,9 @@ iris_create_surface(struct pipe_context *ctx, return NULL; if (!isl_format_is_compressed(res->surf.format)) { + if (iris_resource_unfinished_aux_import(res)) + iris_resource_finish_aux_import(&screen->base, res); + /* This is a normal surface. Fill out a SURFACE_STATE for each possible * auxiliary surface mode and return the pipe_surface. */ |