Updating this thread for informational purposes:
If you want to run the latest MESA git, there are several patches that are needed based on the 20.3.5 diff file from the RPiOS repository: (I kept the relevant changes that are not already upstreamed)
Without it, I ran into some display issues which I presume are the modifiers utilized in the newer libdrm pkgs.
Note: you must compile libdrm, libglvnd, and mesa for it to work.
diff --git a/src/gallium/drivers/v3d/driinfo_v3d.h b/src/gallium/drivers/v3d/driinfo_v3d.h index 147ad0b49bd..a524a03e7e5 100644 --- a/src/gallium/drivers/v3d/driinfo_v3d.h +++ b/src/gallium/drivers/v3d/driinfo_v3d.h @@ -2,4 +2,6 @@ DRI_CONF_SECTION_MISCELLANEOUS DRI_CONF_V3D_NONMSAA_TEXTURE_SIZE_LIMIT(false) + DRI_CONF_V3D_MAINTAIN_IGNORABLE_SCANOUT(false) + DRI_CONF_V3D_IGNORE_SCANOUT_USAGES_WITH_MODIFIERS(false) DRI_CONF_SECTION_END diff --git a/src/gallium/drivers/v3d/meson.build b/src/gallium/drivers/v3d/meson.build index b760ca5c025..1a537637b03 100644 --- a/src/gallium/drivers/v3d/meson.build +++ b/src/gallium/drivers/v3d/meson.build @@ -59,6 +59,16 @@ endif v3d_versions = ['33', '41'] +v3d_deps = [dep_v3dv3, dep_libdrm, dep_valgrind, idep_nir_headers] + +if with_platform_x11 + v3d_deps += dep_xcb +endif + +if with_platform_wayland + v3d_deps += dep_wayland_client +endif + per_version_libs = [] foreach ver : v3d_versions per_version_libs += static_library( @@ -70,7 +80,7 @@ foreach ver : v3d_versions ], c_args : [v3d_args, '-DV3D_VERSION=' + ver], gnu_symbol_visibility : 'hidden', - dependencies : [dep_v3dv3, dep_libdrm, dep_valgrind, idep_nir_headers], + dependencies : v3d_deps, ) endforeach @@ -93,7 +103,7 @@ libv3d = static_library( c_args : [v3d_args], cpp_args : [v3d_args], gnu_symbol_visibility : 'hidden', - dependencies : [dep_v3dv3, dep_libdrm, dep_valgrind, idep_nir_headers], + dependencies : v3d_deps, link_with: [per_version_libs], ) diff --git a/src/gallium/drivers/v3d/v3d_resource.c b/src/gallium/drivers/v3d/v3d_resource.c index 0885a2cb80f..36b6ab34d71 100644 --- a/src/gallium/drivers/v3d/v3d_resource.c +++ b/src/gallium/drivers/v3d/v3d_resource.c @@ -436,7 +436,7 @@ v3d_resource_get_handle(struct pipe_screen *pscreen, case WINSYS_HANDLE_TYPE_SHARED: return v3d_bo_flink(bo, &whandle->handle); case WINSYS_HANDLE_TYPE_KMS: - if (screen->ro) { + if (screen->ro && rsc->scanout) { if (renderonly_get_handle(rsc->scanout, whandle)) { whandle->stride = rsc->slices[0].stride; return true; @@ -750,6 +750,30 @@ v3d_resource_setup(struct pipe_screen *pscreen, return rsc; } +static bool +v3d_resource_should_scanout(struct pipe_screen *pscreen, + const struct pipe_resource *tmpl, + const uint64_t *modifiers, + int count) +{ + struct v3d_screen *screen = v3d_screen(pscreen); + + if (tmpl->bind & PIPE_BIND_SCANOUT) { + if (screen->maintain_ignorable_scanout) + return true; + if (screen->has_x_session && screen->ignore_scanout_usages) + return false; + return true; + } + + if (tmpl->bind & PIPE_BIND_SHARED) { + if (screen->ignore_scanout_usages_with_modifiers) + return false; + return true; + } + return false; +} + static struct pipe_resource * v3d_resource_create_with_modifiers(struct pipe_screen *pscreen, const struct pipe_resource *tmpl, @@ -763,6 +787,8 @@ v3d_resource_create_with_modifiers(struct pipe_screen *pscreen, struct pipe_resource *prsc = &rsc->base; /* Use a tiled layout if we can, for better 3D performance. */ bool should_tile = true; + bool should_scanout = v3d_resource_should_scanout(pscreen, tmpl, + modifiers, count); /* VBOs/PBOs are untiled (and 1 height). */ if (tmpl->target == PIPE_BUFFER) @@ -788,8 +814,8 @@ v3d_resource_create_with_modifiers(struct pipe_screen *pscreen, /* If using the old-school SCANOUT flag, we don't know what the screen * might support other than linear. Just force linear. */ - if (tmpl->bind & PIPE_BIND_SCANOUT) - should_tile = false; + if ((tmpl->bind & PIPE_BIND_SCANOUT) && should_scanout) + should_tile = false; /* No user-specified modifier; determine our own. */ if (count == 1 && modifiers[0] == DRM_FORMAT_MOD_INVALID) { @@ -818,8 +844,8 @@ v3d_resource_create_with_modifiers(struct pipe_screen *pscreen, * We always allocate this way for SHARED, because get_handle will * need a resource on the display fd. */ - if (screen->ro && (tmpl->bind & (PIPE_BIND_SCANOUT | - PIPE_BIND_SHARED))) { + + if (screen->ro && should_scanout) { struct winsys_handle handle; struct pipe_resource scanout_tmpl = { .target = prsc->target, @@ -949,7 +975,7 @@ v3d_resource_from_handle(struct pipe_screen *pscreen, } } - if (screen->ro) { + if (screen->ro && !rsc->tiled) { /* Make sure that renderonly has a handle to our buffer in the * display's fd, so that a later renderonly_get_handle() * returns correct handles or GEM names. @@ -995,7 +1021,9 @@ v3d_update_shadow_texture(struct pipe_context *pctx, assert(view->texture != pview->texture); - if (shadow->writes == orig->writes && orig->bo->private) + if (shadow->writes == orig->writes && + orig->base.sync_status == 0 && + (orig->bo->private || orig->base.sync_condition)) return; perf_debug("Updating %dx%d@%d shadow for linear texture\n", @@ -1038,6 +1066,7 @@ v3d_update_shadow_texture(struct pipe_context *pctx, } shadow->writes = orig->writes; + orig->base.sync_status = 0; } static struct pipe_surface * diff --git a/src/gallium/drivers/v3d/v3d_screen.c b/src/gallium/drivers/v3d/v3d_screen.c index 1c72dc4af0d..1ac9e8fc1d9 100644 --- a/src/gallium/drivers/v3d/v3d_screen.c +++ b/src/gallium/drivers/v3d/v3d_screen.c @@ -47,6 +47,42 @@ #include "compiler/v3d_compiler.h" #include "drm-uapi/drm_fourcc.h" +#ifdef HAVE_WAYLAND_PLATFORM +#include <wayland-client.h> +#endif + +#ifdef HAVE_X11_PLATFORM +#include <xcb/xcb.h> +#endif + +static bool +check_x_session() +{ + bool xcb_connection = false; + +#ifdef HAVE_WAYLAND_PLATFORM + struct wl_display *display; + + display = wl_display_connect(NULL); + + if (display) { + wl_display_disconnect(display); + return xcb_connection; + } +#endif + +#ifdef HAVE_X11_PLATFORM + xcb_connection_t *conn; + + conn = xcb_connect(NULL, NULL); + + if (!xcb_connection_has_error(conn)) + xcb_connection = true; + xcb_disconnect(conn); +#endif + return xcb_connection; +} + static const char * v3d_screen_get_name(struct pipe_screen *pscreen) { @@ -828,6 +864,28 @@ v3d_screen_create(int fd, const struct pipe_screen_config *config, screen->has_cache_flush = v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_CACHE_FLUSH); screen->has_perfmon = v3d_has_feature(screen, DRM_V3D_PARAM_SUPPORTS_PERFMON); + + screen->has_x_session = check_x_session(); + + screen->ignore_scanout_usages = getenv("V3D_IGNORE_SCANOUT_USAGES"); + + const char *ignore_scanout_usages_with_modifiers_name = + "v3d_ignore_scanout_usages_with_modifiers"; + screen->ignore_scanout_usages_with_modifiers = + driCheckOption(config->options, + ignore_scanout_usages_with_modifiers_name, + DRI_BOOL) && + driQueryOptionb(config->options, + ignore_scanout_usages_with_modifiers_name); + + const char *maintain_ignorable_scanout_name = + "v3d_maintain_ignorable_scanout"; + screen->maintain_ignorable_scanout = + driCheckOption(config->options, + maintain_ignorable_scanout_name, + DRI_BOOL) && + driQueryOptionb(config->options, + maintain_ignorable_scanout_name); v3d_fence_init(screen); diff --git a/src/gallium/drivers/v3d/v3d_screen.h b/src/gallium/drivers/v3d/v3d_screen.h index 9bf2a065487..afdce3f3c73 100644 --- a/src/gallium/drivers/v3d/v3d_screen.h +++ b/src/gallium/drivers/v3d/v3d_screen.h @@ -82,6 +82,12 @@ struct v3d_screen { bool has_cache_flush; bool has_perfmon; bool nonmsaa_texture_size_limit; + bool ignore_scanout_usages; + bool ignore_scanout_usages_with_modifiers; + bool maintain_ignorable_scanout; + + /* Are we running in an X session? */ + bool has_x_session; struct v3d_simulator_file *sim_file; }; diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index c96a387bab8..708bb2fad4f 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -572,6 +572,10 @@ struct pipe_resource unsigned usage:8; /**< PIPE_USAGE_x (not a bitmask) */ unsigned bind; /**< bitmask of PIPE_BIND_x */ unsigned flags; /**< bitmask of PIPE_RESOURCE_FLAG_x */ + + /* Hack for avoiding sync on v3d */ + unsigned sync_condition; + unsigned sync_status; /** * For planar images, ie. YUV EGLImage external, etc, pointer to the diff --git a/src/glx/dri_common.h b/src/glx/dri_common.h index 455e8541ed8..1fe78e73b75 100644 --- a/src/glx/dri_common.h +++ b/src/glx/dri_common.h @@ -56,6 +56,10 @@ extern struct glx_config *driConvertConfigs(const __DRIcoreExtension * core, const __DRIconfig ** configs); extern void driDestroyConfigs(const __DRIconfig **configs); + +#ifndef __GLXDRIdrawable +typedef struct __GLXDRIdrawableRec __GLXDRIdrawable; +#endif extern __GLXDRIdrawable * driFetchDrawable(struct glx_context *gc, GLXDrawable glxDrawable); diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 6de28f39112..ece789148d8 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1021,6 +1021,9 @@ struct gl_texture_object /** GL_ARB_bindless_texture */ struct util_dynarray SamplerHandles; struct util_dynarray ImageHandles; + + /* Hack for avoiding sync on v3d */ + GLboolean SyncCondition; }; diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c index 3a3ea8aae94..eb1cb561012 100644 --- a/src/mesa/main/texparam.c +++ b/src/mesa/main/texparam.c @@ -275,6 +275,13 @@ set_tex_parameteri(struct gl_context *ctx, } switch (pname) { + case GL_SYNC_CONDITION: + if (!!texObj->SyncCondition == !!params[0]) + return GL_FALSE; + texObj->SyncCondition = !!params[0]; + return GL_TRUE; + case GL_SYNC_STATUS: + return GL_TRUE; case GL_TEXTURE_MIN_FILTER: if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) goto invalid_dsa; diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 599d2099d6f..9fbab50c1d7 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -3620,6 +3620,12 @@ st_TexParameter(struct gl_context *ctx, */ st_texture_release_all_sampler_views(st, stObj); break; + case GL_SYNC_CONDITION: + stObj->pt->sync_condition = texObj->SyncCondition; + break; + case GL_SYNC_STATUS: + stObj->pt->sync_status = 1; + break; default: ; /* nothing */ } diff --git a/src/util/00-mesa-defaults.conf b/src/util/00-mesa-defaults.conf index 7e155d3e690..f0f3cadfb02 100644 --- a/src/util/00-mesa-defaults.conf +++ b/src/util/00-mesa-defaults.conf @@ -625,6 +625,7 @@ TODO: document the other workarounds. <application name="mutter" executable="mutter"> <option name="adaptive_sync" value="false" /> <option name="v3d_nonmsaa_texture_size_limit" value="true" /> + <option name="v3d_maintain_ignorable_scanout" value="true" /> </application> <application name="muffin" executable="muffin"> <option name="adaptive_sync" value="false" /> @@ -676,6 +677,7 @@ TODO: document the other workarounds. </application> <application name="Xorg" executable="Xorg"> <option name="v3d_nonmsaa_texture_size_limit" value="true" /> + <option name="v3d_ignore_scanout_usages_with_modifiers" value="true" /> </application> <application name="gfxbench" executable="testfw_app"> diff --git a/src/util/driconf.h b/src/util/driconf.h index 24726e04bd3..9f2ab7581c6 100644 --- a/src/util/driconf.h +++ b/src/util/driconf.h @@ -480,6 +480,14 @@ DRI_CONF_OPT_B(v3d_nonmsaa_texture_size_limit, def, \ "Report the non-MSAA-only texture size limit") +#define DRI_CONF_V3D_IGNORE_SCANOUT_USAGES_WITH_MODIFIERS(def) \ + DRI_CONF_OPT_B(v3d_ignore_scanout_usages_with_modifiers, def, \ + "Ignore SCANOUT usage on resource allocations with modifiers.") + +#define DRI_CONF_V3D_MAINTAIN_IGNORABLE_SCANOUT(def) \ + DRI_CONF_OPT_B(v3d_maintain_ignorable_scanout, def, \ + "Maintain SCANOUT usage on resource allocations when the environment allows ignoring SCANOUT usage.") + /** * \brief virgl specific configuration options */