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
*/