X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Firis%2Firis_resource.c;h=e0811827692b5cc84a8d3d697f13512ac4a15cac;hb=82b46667836647226387442b2feb9d7f1475bd36;hp=8142c42f3dcea035049033abce4a5604a8c798ba;hpb=ff1f0a720d8edcfc09aa41c720ba8de3afe88d72;p=mesa.git diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c index 8142c42f3dc..e0811827692 100644 --- a/src/gallium/drivers/iris/iris_resource.c +++ b/src/gallium/drivers/iris/iris_resource.c @@ -59,6 +59,7 @@ enum modifier_priority { MODIFIER_PRIORITY_X, MODIFIER_PRIORITY_Y, MODIFIER_PRIORITY_Y_CCS, + MODIFIER_PRIORITY_Y_GEN12_RC_CCS, }; static const uint64_t priority_to_modifier[] = { @@ -67,14 +68,35 @@ static const uint64_t priority_to_modifier[] = { [MODIFIER_PRIORITY_X] = I915_FORMAT_MOD_X_TILED, [MODIFIER_PRIORITY_Y] = I915_FORMAT_MOD_Y_TILED, [MODIFIER_PRIORITY_Y_CCS] = I915_FORMAT_MOD_Y_TILED_CCS, + [MODIFIER_PRIORITY_Y_GEN12_RC_CCS] = I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS, }; static bool modifier_is_supported(const struct gen_device_info *devinfo, enum pipe_format pfmt, uint64_t modifier) { - /* XXX: do something real */ + /* Check for basic device support. */ switch (modifier) { + case DRM_FORMAT_MOD_LINEAR: + case I915_FORMAT_MOD_X_TILED: + case I915_FORMAT_MOD_Y_TILED: + break; + case I915_FORMAT_MOD_Y_TILED_CCS: + if (devinfo->gen <= 8 || devinfo->gen >= 12) + return false; + break; + case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: + if (devinfo->gen != 12) + return false; + break; + case DRM_FORMAT_MOD_INVALID: + default: + return false; + } + + /* Check remaining requirements. */ + switch (modifier) { + case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: case I915_FORMAT_MOD_Y_TILED_CCS: { if (unlikely(INTEL_DEBUG & DEBUG_NO_RBC)) return false; @@ -83,22 +105,15 @@ modifier_is_supported(const struct gen_device_info *devinfo, iris_format_for_usage(devinfo, pfmt, ISL_SURF_USAGE_RENDER_TARGET_BIT).fmt; - enum isl_format linear_format = isl_format_srgb_to_linear(rt_format); - - if (linear_format == ISL_FORMAT_UNSUPPORTED || - !isl_format_supports_ccs_e(devinfo, linear_format)) + if (rt_format == ISL_FORMAT_UNSUPPORTED || + !isl_format_supports_ccs_e(devinfo, rt_format)) return false; - - return devinfo->gen >= 9 && devinfo->gen <= 11; } - case I915_FORMAT_MOD_Y_TILED: - case I915_FORMAT_MOD_X_TILED: - case DRM_FORMAT_MOD_LINEAR: - return true; - case DRM_FORMAT_MOD_INVALID: default: - return false; + break; } + + return true; } static uint64_t @@ -113,6 +128,9 @@ select_best_modifier(struct gen_device_info *devinfo, enum pipe_format pfmt, continue; switch (modifiers[i]) { + case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: + prio = MAX2(prio, MODIFIER_PRIORITY_Y_GEN12_RC_CCS); + break; case I915_FORMAT_MOD_Y_TILED_CCS: prio = MAX2(prio, MODIFIER_PRIORITY_Y_CCS); break; @@ -172,6 +190,7 @@ iris_query_dmabuf_modifiers(struct pipe_screen *pscreen, I915_FORMAT_MOD_X_TILED, I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_Y_TILED_CCS, + I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS, }; int supported_mods = 0; @@ -208,12 +227,38 @@ pipe_bind_to_isl_usage(unsigned bindings) if (bindings & (PIPE_BIND_SHADER_IMAGE | PIPE_BIND_SHADER_BUFFER)) usage |= ISL_SURF_USAGE_STORAGE_BIT; - if (bindings & PIPE_BIND_DISPLAY_TARGET) + if (bindings & PIPE_BIND_SCANOUT) usage |= ISL_SURF_USAGE_DISPLAY_BIT; return usage; } +enum isl_format +iris_image_view_get_format(struct iris_context *ice, + const struct pipe_image_view *img) +{ + struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen; + const struct gen_device_info *devinfo = &screen->devinfo; + + isl_surf_usage_flags_t usage = ISL_SURF_USAGE_STORAGE_BIT; + enum isl_format isl_fmt = + iris_format_for_usage(devinfo, img->format, usage).fmt; + + if (img->shader_access & PIPE_IMAGE_ACCESS_READ) { + /* On Gen8, try to use typed surfaces reads (which support a + * limited number of formats), and if not possible, fall back + * to untyped reads. + */ + if (devinfo->gen == 8 && + !isl_has_matching_typed_storage_image_format(devinfo, isl_fmt)) + return ISL_FORMAT_RAW; + else + return isl_lower_storage_image_format(devinfo, isl_fmt); + } + + return isl_fmt; +} + struct pipe_resource * iris_resource_get_separate_stencil(struct pipe_resource *p_res) { @@ -314,6 +359,8 @@ iris_resource_destroy(struct pipe_screen *screen, iris_resource_disable_aux(res); iris_bo_unreference(res->bo); + iris_pscreen_unref(res->base.screen); + free(res); } @@ -326,7 +373,7 @@ iris_alloc_resource(struct pipe_screen *pscreen, return NULL; res->base = *templ; - res->base.screen = pscreen; + res->base.screen = iris_pscreen_ref(pscreen); pipe_reference_init(&res->base.reference, 1); res->aux.possible_usages = 1 << ISL_AUX_USAGE_NONE; @@ -446,8 +493,10 @@ iris_resource_configure_aux(struct iris_screen *screen, /* 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); + assert(!res->mod_info || + res->mod_info->aux_usage == ISL_AUX_USAGE_NONE || + res->mod_info->aux_usage == ISL_AUX_USAGE_CCS_E || + res->mod_info->aux_usage == ISL_AUX_USAGE_GEN12_CCS_E); const bool has_mcs = !res->mod_info && isl_surf_get_mcs_surf(&screen->isl_dev, &res->surf, &res->aux.surf); @@ -492,12 +541,15 @@ iris_resource_configure_aux(struct iris_screen *screen, } else { res->aux.possible_usages |= 1 << ISL_AUX_USAGE_HIZ_CCS; } + } else if (has_ccs && isl_surf_usage_is_stencil(res->surf.usage)) { + res->aux.possible_usages |= 1 << ISL_AUX_USAGE_STC_CCS; } 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)) + if (want_ccs_e_for_format(devinfo, res->surf.format)) { + res->aux.possible_usages |= devinfo->gen < 12 ? + 1 << ISL_AUX_USAGE_CCS_E : 1 << ISL_AUX_USAGE_GEN12_CCS_E; + } else 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; @@ -542,6 +594,8 @@ iris_resource_configure_aux(struct iris_screen *screen, break; case ISL_AUX_USAGE_CCS_D: case ISL_AUX_USAGE_CCS_E: + case ISL_AUX_USAGE_GEN12_CCS_E: + case ISL_AUX_USAGE_STC_CCS: /* When CCS_E is used, we need to ensure that the CCS starts off in * a valid state. From the Sky Lake PRM, "MCS Buffer for Render * Target(s)": @@ -555,11 +609,13 @@ 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. */ - if (imported) + if (imported) { + assert(res->aux.usage != ISL_AUX_USAGE_STC_CCS); initial_state = isl_drm_modifier_get_default_aux_state(res->mod_info->modifier); - else + } else { initial_state = ISL_AUX_STATE_PASS_THROUGH; + } *alloc_flags |= BO_ALLOC_ZEROED; break; case ISL_AUX_USAGE_MC: @@ -637,20 +693,8 @@ iris_resource_init_aux_buf(struct iris_resource *res, uint32_t alloc_flags, res->aux.surf.size_B); } - /* Bspec section titled : MCS/CCS Buffers for Render Target(s) states: - * - If Software wants to enable Color Compression without Fast clear, - * Software needs to initialize MCS with zeros. - * - Lossless compression and CCS initialized to all F (using HW Fast - * Clear or SW direct Clear) - * - * We think, the first bullet point above is referring to CCS aux - * surface. Since we initialize the MCS in the clear state, we also - * initialize the CCS in the clear state (via SW direct clear) to keep - * the two in sync. - */ memset((char*)map + res->aux.extra_aux.offset, - isl_aux_usage_has_mcs(res->aux.usage) ? 0xFF : 0, - res->aux.extra_aux.surf.size_B); + 0, res->aux.extra_aux.surf.size_B); /* Zero the indirect clear color to match ::fast_clear_color. */ memset((char *)map + res->aux.clear_color_offset, 0, @@ -743,6 +787,8 @@ iris_resource_finish_aux_import(struct pipe_screen *pscreen, iris_resource_destroy(&screen->base, res->base.next); res->base.next = NULL; + + map_aux_addresses(screen, res); } static struct pipe_resource * @@ -780,6 +826,9 @@ iris_resource_create_for_buffer(struct pipe_screen *pscreen, return NULL; } + if (templ->bind & PIPE_BIND_SHARED) + iris_bo_make_external(res->bo); + return &res->base; } @@ -816,10 +865,14 @@ iris_resource_create_with_modifiers(struct pipe_screen *pscreen, /* Use linear for staging buffers */ if (templ->usage == PIPE_USAGE_STAGING || - templ->bind & (PIPE_BIND_LINEAR | PIPE_BIND_CURSOR) ) + templ->bind & (PIPE_BIND_LINEAR | PIPE_BIND_CURSOR) ) { tiling_flags = ISL_TILING_LINEAR_BIT; - else if (templ->bind & PIPE_BIND_SCANOUT) - tiling_flags = ISL_TILING_X_BIT; + } else if (templ->bind & PIPE_BIND_SCANOUT) { + if (devinfo->has_tiling_uapi) + tiling_flags = ISL_TILING_X_BIT; + else + tiling_flags = ISL_TILING_LINEAR_BIT; + } } isl_surf_usage_flags_t usage = pipe_bind_to_isl_usage(templ->bind); @@ -903,6 +956,9 @@ iris_resource_create_with_modifiers(struct pipe_screen *pscreen, map_aux_addresses(screen, res); } + if (templ->bind & PIPE_BIND_SHARED) + iris_bo_make_external(res->bo); + return &res->base; fail: @@ -954,7 +1010,7 @@ iris_resource_from_user_memory(struct pipe_screen *pscreen, user_memory, templ->width0, IRIS_MEMZONE_OTHER); if (!res->bo) { - free(res); + iris_resource_destroy(pscreen, &res->base); return NULL; } @@ -975,7 +1031,7 @@ iris_resource_from_handle(struct pipe_screen *pscreen, struct iris_resource *res = iris_alloc_resource(pscreen, templ); const struct isl_drm_modifier_info *mod_inf = isl_drm_modifier_get_info(whandle->modifier); - uint32_t tiling; + int tiling; if (!res) return NULL; @@ -985,7 +1041,7 @@ iris_resource_from_handle(struct pipe_screen *pscreen, if (mod_inf) tiling = isl_tiling_to_i915_tiling(mod_inf->tiling); else - tiling = I915_TILING_LAST + 1; + tiling = -1; res->bo = iris_bo_import_dmabuf(bufmgr, whandle->handle, tiling, whandle->stride); break; @@ -997,7 +1053,7 @@ iris_resource_from_handle(struct pipe_screen *pscreen, unreachable("invalid winsys handle type"); } if (!res->bo) - return NULL; + goto fail; res->offset = whandle->offset; @@ -1081,11 +1137,10 @@ static void iris_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource) { struct iris_context *ice = (struct iris_context *)ctx; - struct iris_batch *render_batch = &ice->batches[IRIS_BATCH_RENDER]; struct iris_resource *res = (void *) resource; const struct isl_drm_modifier_info *mod = res->mod_info; - iris_resource_prepare_access(ice, render_batch, res, + iris_resource_prepare_access(ice, res, 0, INTEL_REMAINING_LEVELS, 0, INTEL_REMAINING_LAYERS, mod ? mod->aux_usage : ISL_AUX_USAGE_NONE, @@ -1112,7 +1167,7 @@ iris_resource_disable_aux_on_first_query(struct pipe_resource *resource, } static bool -iris_resource_get_param(struct pipe_screen *screen, +iris_resource_get_param(struct pipe_screen *pscreen, struct pipe_context *context, struct pipe_resource *resource, unsigned plane, @@ -1121,6 +1176,7 @@ iris_resource_get_param(struct pipe_screen *screen, unsigned handle_usage, uint64_t *value) { + struct iris_screen *screen = (struct iris_screen *)pscreen; struct iris_resource *res = (struct iris_resource *)resource; bool mod_with_aux = res->mod_info && res->mod_info->aux_usage != ISL_AUX_USAGE_NONE; @@ -1129,7 +1185,7 @@ iris_resource_get_param(struct pipe_screen *screen, unsigned handle; if (iris_resource_unfinished_aux_import(res)) - iris_resource_finish_aux_import(screen, res); + iris_resource_finish_aux_import(pscreen, res); struct iris_bo *bo = wants_aux ? res->aux.bo : res->bo; @@ -1161,9 +1217,19 @@ iris_resource_get_param(struct pipe_screen *screen, if (result) *value = handle; return result; - case PIPE_RESOURCE_PARAM_HANDLE_TYPE_KMS: - *value = iris_bo_export_gem_handle(bo); + case PIPE_RESOURCE_PARAM_HANDLE_TYPE_KMS: { + /* Because we share the same drm file across multiple iris_screen, when + * we export a GEM handle we must make sure it is valid in the DRM file + * descriptor the caller is using (this is the FD given at screen + * creation). + */ + uint32_t handle; + if (iris_bo_export_gem_handle_for_device(bo, screen->winsys_fd, &handle)) + return false; + *value = handle; return true; + } + case PIPE_RESOURCE_PARAM_HANDLE_TYPE_FD: result = iris_bo_export_dmabuf(bo, (int *) &handle) == 0; if (result) @@ -1181,6 +1247,7 @@ iris_resource_get_handle(struct pipe_screen *pscreen, struct winsys_handle *whandle, unsigned usage) { + struct iris_screen *screen = (struct iris_screen *) pscreen; struct iris_resource *res = (struct iris_resource *)resource; bool mod_with_aux = res->mod_info && res->mod_info->aux_usage != ISL_AUX_USAGE_NONE; @@ -1218,9 +1285,18 @@ iris_resource_get_handle(struct pipe_screen *pscreen, switch (whandle->type) { case WINSYS_HANDLE_TYPE_SHARED: return iris_bo_flink(bo, &whandle->handle) == 0; - case WINSYS_HANDLE_TYPE_KMS: - whandle->handle = iris_bo_export_gem_handle(bo); + case WINSYS_HANDLE_TYPE_KMS: { + /* Because we share the same drm file across multiple iris_screen, when + * we export a GEM handle we must make sure it is valid in the DRM file + * descriptor the caller is using (this is the FD given at screen + * creation). + */ + uint32_t handle; + if (iris_bo_export_gem_handle_for_device(bo, screen->winsys_fd, &handle)) + return false; + whandle->handle = handle; return true; + } case WINSYS_HANDLE_TYPE_FD: return iris_bo_export_dmabuf(bo, (int *) &whandle->handle) == 0; } @@ -1286,7 +1362,7 @@ iris_invalidate_resource(struct pipe_context *ctx, /* Rebind the buffer, replacing any state referring to the old BO's * address, and marking state dirty so it's reemitted. */ - ice->vtbl.rebind_buffer(ice, res); + screen->vtbl.rebind_buffer(ice, res); util_range_set_empty(&res->valid_buffer_range); @@ -1783,6 +1859,9 @@ iris_transfer_map(struct pipe_context *ctx, struct iris_resource *res = (struct iris_resource *)resource; struct isl_surf *surf = &res->surf; + if (iris_resource_unfinished_aux_import(res)) + iris_resource_finish_aux_import(ctx->screen, res); + if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) { /* Replace the backing storage with a fresh buffer for non-async maps */ if (!(usage & (PIPE_TRANSFER_UNSYNCHRONIZED | @@ -1803,13 +1882,17 @@ iris_transfer_map(struct pipe_context *ctx, if (resource->target != PIPE_BUFFER) { bool need_hiz_resolve = iris_resource_level_has_hiz(res, level); + bool need_stencil_resolve = res->aux.usage == ISL_AUX_USAGE_STC_CCS; need_color_resolve = (res->aux.usage == ISL_AUX_USAGE_CCS_D || - res->aux.usage == ISL_AUX_USAGE_CCS_E) && + res->aux.usage == ISL_AUX_USAGE_CCS_E || + res->aux.usage == ISL_AUX_USAGE_GEN12_CCS_E) && iris_has_color_unresolved(res, level, 1, box->z, box->depth); - need_resolve = need_color_resolve || need_hiz_resolve; + need_resolve = need_color_resolve || + need_hiz_resolve || + need_stencil_resolve; } bool map_would_stall = false; @@ -1874,7 +1957,9 @@ iris_transfer_map(struct pipe_context *ctx, if (fmtl->txc == ISL_TXC_ASTC) no_gpu = true; - if ((map_would_stall || res->aux.usage == ISL_AUX_USAGE_CCS_E) && !no_gpu) { + if ((map_would_stall || + res->aux.usage == ISL_AUX_USAGE_CCS_E || + res->aux.usage == ISL_AUX_USAGE_GEN12_CCS_E) && !no_gpu) { /* If we need a synchronous mapping and the resource is busy, or needs * resolving, we copy to/from a linear temporary buffer using the GPU. */ @@ -1885,8 +1970,7 @@ iris_transfer_map(struct pipe_context *ctx, /* Otherwise we're free to map on the CPU. */ if (need_resolve) { - iris_resource_access_raw(ice, &ice->batches[IRIS_BATCH_RENDER], res, - level, box->z, box->depth, + iris_resource_access_raw(ice, res, level, box->z, box->depth, usage & PIPE_TRANSFER_WRITE); } @@ -1983,13 +2067,14 @@ void iris_dirty_for_history(struct iris_context *ice, struct iris_resource *res) { - uint64_t dirty = 0ull; + uint64_t stage_dirty = 0ull; if (res->bind_history & PIPE_BIND_CONSTANT_BUFFER) { - dirty |= ((uint64_t)res->bind_stages) << IRIS_SHIFT_FOR_DIRTY_CONSTANTS; + stage_dirty |= ((uint64_t)res->bind_stages) + << IRIS_SHIFT_FOR_STAGE_DIRTY_CONSTANTS; } - ice->state.dirty |= dirty; + ice->state.stage_dirty |= stage_dirty; } /**