mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 13:50:11 +01:00
pvr: Make display node optional
Allow the driver to work without a display (card) node by removing strict display controller checks. Signed-off-by: Ashish Chauhan <ashish.chauhan@imgtec.com> Reviewed-by: Frank Binns <frank.binns@imgtec.com> Tested-by: Icenowy Zheng <uwu@icenowy.me> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38082>
This commit is contained in:
parent
7f2c53200f
commit
8825c91dcb
2 changed files with 87 additions and 35 deletions
|
|
@ -12,7 +12,9 @@
|
||||||
|
|
||||||
#include "pvr_instance.h"
|
#include "pvr_instance.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
|
#include <xf86drmMode.h>
|
||||||
|
|
||||||
#include "vk_alloc.h"
|
#include "vk_alloc.h"
|
||||||
#include "vk_log.h"
|
#include "vk_log.h"
|
||||||
|
|
@ -38,22 +40,20 @@ struct pvr_drm_device_config {
|
||||||
struct pvr_drm_device_info {
|
struct pvr_drm_device_info {
|
||||||
const char *name;
|
const char *name;
|
||||||
size_t len;
|
size_t len;
|
||||||
} render, display;
|
} render;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEF_CONFIG(render_, display_) \
|
#define DEF_CONFIG(render_) \
|
||||||
{ \
|
{ \
|
||||||
.render = { .name = render_, .len = sizeof(render_) - 1 }, \
|
.render = { .name = render_, .len = sizeof(render_) - 1 }, \
|
||||||
.display = { .name = display_, .len = sizeof(display_) - 1 }, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is the list of supported DRM render/display driver configs. */
|
/* This is the list of supported DRM render driver configs. */
|
||||||
static const struct pvr_drm_device_config pvr_drm_configs[] = {
|
static const struct pvr_drm_device_config pvr_drm_configs[] = {
|
||||||
DEF_CONFIG("mediatek,mt8173-gpu", "mediatek-drm"),
|
DEF_CONFIG("mediatek,mt8173-gpu"),
|
||||||
DEF_CONFIG("ti,am62-gpu", "ti,am625-dss"),
|
DEF_CONFIG("ti,am62-gpu"),
|
||||||
DEF_CONFIG("ti,j721s2-gpu", "ti,j721e-dss"),
|
DEF_CONFIG("ti,j721s2-gpu"),
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef DEF_CONFIG
|
#undef DEF_CONFIG
|
||||||
|
|
||||||
static const struct vk_instance_extension_table pvr_instance_extensions = {
|
static const struct vk_instance_extension_table pvr_instance_extensions = {
|
||||||
|
|
@ -121,6 +121,56 @@ pvr_drm_device_get_config(drmDevice *const drm_dev)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool pvr_drm_device_is_compatible_display(drmDevicePtr drm_dev)
|
||||||
|
{
|
||||||
|
uint64_t has_dumb_buffer = 0;
|
||||||
|
uint64_t prime_caps = 0;
|
||||||
|
bool ret = false;
|
||||||
|
int32_t fd;
|
||||||
|
|
||||||
|
mesa_logd("Checking DRM primary node for compatibility: %s",
|
||||||
|
drm_dev->nodes[DRM_NODE_PRIMARY]);
|
||||||
|
fd = open(drm_dev->nodes[DRM_NODE_PRIMARY], O_RDWR | O_CLOEXEC);
|
||||||
|
if (fd < 0) {
|
||||||
|
mesa_logd("Failed to open display node: %s\n",
|
||||||
|
drm_dev->nodes[DRM_NODE_PRIMARY]);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Must support KMS */
|
||||||
|
if (!drmIsKMS(fd)) {
|
||||||
|
mesa_logd("DRM device does not support KMS");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Must support dumb buffers, as these are used by the PVR winsys to
|
||||||
|
* allocate device memory for PVR_WINSYS_BO_TYPE_DISPLAY buffer objects.
|
||||||
|
*/
|
||||||
|
if (drmGetCap(fd, DRM_CAP_DUMB_BUFFER, &has_dumb_buffer) ||
|
||||||
|
!has_dumb_buffer) {
|
||||||
|
mesa_logd("DRM device does not support dumb buffers");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Must support PRIME export (so GPU can import dumb buffers) */
|
||||||
|
if (drmGetCap(fd, DRM_CAP_PRIME, &prime_caps)) {
|
||||||
|
mesa_loge("Failed to query DRM_CAP_PRIME: %s", strerror(errno));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(prime_caps & DRM_PRIME_CAP_EXPORT)) {
|
||||||
|
mesa_logd("DRM device lacks PRIME export support (caps: 0x%" PRIx64 ")",
|
||||||
|
prime_caps);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
|
||||||
|
out:
|
||||||
|
close(fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static VkResult
|
static VkResult
|
||||||
pvr_physical_device_enumerate(struct vk_instance *const vk_instance)
|
pvr_physical_device_enumerate(struct vk_instance *const vk_instance)
|
||||||
{
|
{
|
||||||
|
|
@ -183,29 +233,25 @@ pvr_physical_device_enumerate(struct vk_instance *const vk_instance)
|
||||||
mesa_logd("Found compatible render device '%s'.",
|
mesa_logd("Found compatible render device '%s'.",
|
||||||
drm_render_device->nodes[DRM_NODE_RENDER]);
|
drm_render_device->nodes[DRM_NODE_RENDER]);
|
||||||
|
|
||||||
/* ...then find the compatible display node. */
|
/* ...then find a compatible display node, if available. */
|
||||||
for (int i = 0; i < num_drm_devices; i++) {
|
for (int i = 0; i < num_drm_devices; i++) {
|
||||||
drmDevice *const drm_dev = drm_devices[i];
|
drmDevice *const drm_dev = drm_devices[i];
|
||||||
|
|
||||||
|
if (drm_dev->bustype != DRM_BUS_PLATFORM)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!(drm_dev->available_nodes & BITFIELD_BIT(DRM_NODE_PRIMARY)))
|
if (!(drm_dev->available_nodes & BITFIELD_BIT(DRM_NODE_PRIMARY)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (pvr_drm_device_compatible(&config->display, drm_dev)) {
|
if (!pvr_drm_device_is_compatible_display(drm_devices[i]))
|
||||||
drm_display_device = drm_dev;
|
continue;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!drm_display_device) {
|
drm_display_device = drm_dev;
|
||||||
mesa_loge("Render device '%s' has no compatible display device.",
|
mesa_logd("Found a compatible display device: '%s'.",
|
||||||
drm_render_device->nodes[DRM_NODE_RENDER]);
|
drm_display_device->nodes[DRM_NODE_PRIMARY]);
|
||||||
result = VK_SUCCESS;
|
break;
|
||||||
goto out_free_drm_devices;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mesa_logd("Found compatible display device '%s'.",
|
|
||||||
drm_display_device->nodes[DRM_NODE_PRIMARY]);
|
|
||||||
|
|
||||||
pdevice = vk_alloc(&vk_instance->alloc,
|
pdevice = vk_alloc(&vk_instance->alloc,
|
||||||
sizeof(*pdevice),
|
sizeof(*pdevice),
|
||||||
8,
|
8,
|
||||||
|
|
@ -229,7 +275,9 @@ pvr_physical_device_enumerate(struct vk_instance *const vk_instance)
|
||||||
if (PVR_IS_DEBUG_SET(INFO)) {
|
if (PVR_IS_DEBUG_SET(INFO)) {
|
||||||
pvr_physical_device_dump_info(
|
pvr_physical_device_dump_info(
|
||||||
pdevice,
|
pdevice,
|
||||||
drm_display_device->deviceinfo.platform->compatible,
|
drm_display_device
|
||||||
|
? drm_display_device->deviceinfo.platform->compatible
|
||||||
|
: NULL,
|
||||||
drm_render_device->deviceinfo.platform->compatible);
|
drm_render_device->deviceinfo.platform->compatible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,10 +41,12 @@ pvr_physical_device_dump_info(const struct pvr_physical_device *pdevice,
|
||||||
char *const *comp_display,
|
char *const *comp_display,
|
||||||
char *const *comp_render)
|
char *const *comp_render)
|
||||||
{
|
{
|
||||||
drmVersionPtr version_display, version_render;
|
drmVersionPtr version_display = NULL, version_render;
|
||||||
struct pvr_device_dump_info info;
|
struct pvr_device_dump_info info = { 0 };
|
||||||
|
|
||||||
|
if (pdevice->ws->display_fd >= 0)
|
||||||
|
version_display = drmGetVersion(pdevice->ws->display_fd);
|
||||||
|
|
||||||
version_display = drmGetVersion(pdevice->ws->display_fd);
|
|
||||||
if (!version_display)
|
if (!version_display)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -56,12 +58,14 @@ pvr_physical_device_dump_info(const struct pvr_physical_device *pdevice,
|
||||||
|
|
||||||
info.device_info = &pdevice->dev_info;
|
info.device_info = &pdevice->dev_info;
|
||||||
info.device_runtime_info = &pdevice->dev_runtime_info;
|
info.device_runtime_info = &pdevice->dev_runtime_info;
|
||||||
info.drm_display.patchlevel = version_display->version_patchlevel;
|
if (version_display) {
|
||||||
info.drm_display.major = version_display->version_major;
|
info.drm_display.patchlevel = version_display->version_patchlevel;
|
||||||
info.drm_display.minor = version_display->version_minor;
|
info.drm_display.major = version_display->version_major;
|
||||||
info.drm_display.name = version_display->name;
|
info.drm_display.minor = version_display->version_minor;
|
||||||
info.drm_display.date = version_display->date;
|
info.drm_display.name = version_display->name;
|
||||||
info.drm_display.comp = comp_display;
|
info.drm_display.date = version_display->date;
|
||||||
|
info.drm_display.comp = comp_display;
|
||||||
|
}
|
||||||
info.drm_render.patchlevel = version_render->version_patchlevel;
|
info.drm_render.patchlevel = version_render->version_patchlevel;
|
||||||
info.drm_render.major = version_render->version_major;
|
info.drm_render.major = version_render->version_major;
|
||||||
info.drm_render.minor = version_render->version_minor;
|
info.drm_render.minor = version_render->version_minor;
|
||||||
|
|
@ -975,7 +979,7 @@ VkResult pvr_physical_device_init(struct pvr_physical_device *pdevice,
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instance->vk.enabled_extensions.KHR_display) {
|
if (instance->vk.enabled_extensions.KHR_display && drm_display_device) {
|
||||||
display_path = vk_strdup(&instance->vk.alloc,
|
display_path = vk_strdup(&instance->vk.alloc,
|
||||||
drm_display_device->nodes[DRM_NODE_PRIMARY],
|
drm_display_device->nodes[DRM_NODE_PRIMARY],
|
||||||
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
|
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue