*/
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;
* 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;
{
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)
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)
{
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;
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;