summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/iris/iris_blit.c2
-rw-r--r--src/gallium/drivers/iris/iris_resource.c123
-rw-r--r--src/gallium/drivers/iris/iris_resource.h10
-rw-r--r--src/gallium/drivers/iris/iris_state.c8
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.
*/