v3dv: VK_KHR_display extension support

When VK_KHR_display is enabled it needs to open the primary
node on the vc4/vc5 display device, so pass it to
physical_device_init().
Extension functions call through to the wsi_common_display.c
implementations.

v2: Follow Mesa conventions for comments and char *
    Refer to vc4 display device in comments.
v3: Added Copyright © 2020 Raspberry Pi
v4: Test device has primary node when using simulator.
v5: Assert that we have a primary device. Fix trailing blank space.

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3692
This commit is contained in:
Steven Houston 2020-11-04 17:45:10 +00:00 committed by Iago Toral Quiroga
parent 46d2f2224f
commit b1188c9451
3 changed files with 169 additions and 12 deletions

View file

@ -105,6 +105,11 @@ if with_platform_x11
libv3dv_files += files('v3dv_wsi_x11.c')
endif
if system_has_kms_drm and not with_platform_android
v3dv_flags += '-DVK_USE_PLATFORM_DISPLAY_KHR'
libv3dv_files += files('v3dv_wsi_display.c')
endif
libvulkan_broadcom = shared_library(
'vulkan_broadcom',
[libv3dv_files, v3dv_entrypoints, v3dv_extensions_c, v3dv_extensions_h, sha1_h],

View file

@ -446,7 +446,8 @@ init_uuids(struct v3dv_physical_device *device)
static VkResult
physical_device_init(struct v3dv_physical_device *device,
struct v3dv_instance *instance,
drmDevicePtr drm_device)
drmDevicePtr drm_render_device,
drmDevicePtr drm_primary_device)
{
VkResult result = VK_SUCCESS;
int32_t display_fd = -1;
@ -454,7 +455,7 @@ physical_device_init(struct v3dv_physical_device *device,
device->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
device->instance = instance;
const char *path = drm_device->nodes[DRM_NODE_RENDER];
const char *path = drm_render_device->nodes[DRM_NODE_RENDER];
int32_t render_fd = open(path, O_RDWR | O_CLOEXEC);
if (render_fd < 0)
return vk_error(instance, VK_ERROR_INCOMPATIBLE_DRIVER);
@ -463,7 +464,15 @@ physical_device_init(struct v3dv_physical_device *device,
* device so we can allocate winsys BOs for the v3d core to render into.
*/
#if !using_v3d_simulator
if (instance->enabled_extensions.KHR_display) {
/* Open the primary node on the vc4 display device */
assert(drm_primary_device);
const char *primary_path = drm_primary_device->nodes[DRM_NODE_PRIMARY];
display_fd = open(primary_path, O_RDWR | O_CLOEXEC);
}
#ifdef VK_USE_PLATFORM_XCB_KHR
if (display_fd == -1)
display_fd = create_display_fd_xcb();
#endif
@ -471,15 +480,21 @@ physical_device_init(struct v3dv_physical_device *device,
result = VK_ERROR_INCOMPATIBLE_DRIVER;
goto fail;
}
#else
/* using_v3d_simulator */
if (instance->enabled_extensions.KHR_display) {
/* There is only one device with primary and render nodes.
* Open its primary node.
*/
const char *primary_path = drm_render_device->nodes[DRM_NODE_PRIMARY];
display_fd = open(primary_path, O_RDWR | O_CLOEXEC);
}
device->sim_file = v3d_simulator_init(render_fd);
#endif
device->render_fd = render_fd; /* The v3d render node */
device->display_fd = display_fd; /* The vc4 primary node */
#if using_v3d_simulator
device->sim_file = v3d_simulator_init(device->render_fd);
#endif
if (!v3d_get_device_info(device->render_fd, &device->devinfo, &v3dv_ioctl)) {
result = VK_ERROR_INCOMPATIBLE_DRIVER;
goto fail;
@ -565,11 +580,12 @@ enumerate_devices(struct v3dv_instance *instance)
for (unsigned i = 0; i < (unsigned)max_devices; i++) {
#if using_v3d_simulator
/* In the simulator, we look for an Intel render node */
if (devices[i]->available_nodes & 1 << DRM_NODE_RENDER &&
const int required_nodes = (1 << DRM_NODE_RENDER) | (1 << DRM_NODE_PRIMARY);
if ((devices[i]->available_nodes & required_nodes) == required_nodes &&
devices[i]->bustype == DRM_BUS_PCI &&
devices[i]->deviceinfo.pci->vendor_id == 0x8086) {
result = physical_device_init(&instance->physicalDevice, instance,
devices[i]);
devices[i], NULL);
if (result != VK_ERROR_INCOMPATIBLE_DRIVER)
break;
}
@ -614,7 +630,7 @@ enumerate_devices(struct v3dv_instance *instance)
result = VK_ERROR_INCOMPATIBLE_DRIVER;
else
result = physical_device_init(&instance->physicalDevice, instance,
devices[v3d_idx]);
devices[v3d_idx], devices[vc4_idx]);
#endif
drmFreeDevices(devices, max_devices);

View file

@ -0,0 +1,136 @@
/*
* Copyright © 2020 Raspberry Pi
* based on KHR_display extension code:
* Copyright © 2017 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include "v3dv_private.h"
#include "wsi_common_display.h"
VkResult
v3dv_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physical_device,
uint32_t *property_count,
VkDisplayPropertiesKHR *properties)
{
V3DV_FROM_HANDLE(v3dv_physical_device, pdevice, physical_device);
return wsi_display_get_physical_device_display_properties(
physical_device,
&pdevice->wsi_device,
property_count,
properties);
}
VkResult
v3dv_GetPhysicalDeviceDisplayPlanePropertiesKHR(
VkPhysicalDevice physical_device,
uint32_t *property_count,
VkDisplayPlanePropertiesKHR *properties)
{
V3DV_FROM_HANDLE(v3dv_physical_device, pdevice, physical_device);
return wsi_display_get_physical_device_display_plane_properties(
physical_device,
&pdevice->wsi_device,
property_count,
properties);
}
VkResult
v3dv_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physical_device,
uint32_t plane_index,
uint32_t *display_count,
VkDisplayKHR *displays)
{
V3DV_FROM_HANDLE(v3dv_physical_device, pdevice, physical_device);
return wsi_display_get_display_plane_supported_displays(
physical_device,
&pdevice->wsi_device,
plane_index,
display_count,
displays);
}
VkResult
v3dv_GetDisplayModePropertiesKHR(VkPhysicalDevice physical_device,
VkDisplayKHR display,
uint32_t *property_count,
VkDisplayModePropertiesKHR *properties)
{
V3DV_FROM_HANDLE(v3dv_physical_device, pdevice, physical_device);
return wsi_display_get_display_mode_properties(physical_device,
&pdevice->wsi_device,
display,
property_count,
properties);
}
VkResult
v3dv_CreateDisplayModeKHR(VkPhysicalDevice physical_device,
VkDisplayKHR display,
const VkDisplayModeCreateInfoKHR *create_info,
const VkAllocationCallbacks *allocator,
VkDisplayModeKHR *mode)
{
V3DV_FROM_HANDLE(v3dv_physical_device, pdevice, physical_device);
return wsi_display_create_display_mode(physical_device,
&pdevice->wsi_device,
display,
create_info,
allocator,
mode);
}
VkResult
v3dv_GetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physical_device,
VkDisplayModeKHR mode_khr,
uint32_t plane_index,
VkDisplayPlaneCapabilitiesKHR *capabilities)
{
V3DV_FROM_HANDLE(v3dv_physical_device, pdevice, physical_device);
return wsi_get_display_plane_capabilities(physical_device,
&pdevice->wsi_device,
mode_khr,
plane_index,
capabilities);
}
VkResult
v3dv_CreateDisplayPlaneSurfaceKHR(
VkInstance _instance,
const VkDisplaySurfaceCreateInfoKHR *create_info,
const VkAllocationCallbacks *allocator,
VkSurfaceKHR *surface)
{
V3DV_FROM_HANDLE(v3dv_instance, instance, _instance);
const VkAllocationCallbacks *alloc;
if (allocator)
alloc = allocator;
else
alloc = &instance->alloc;
return wsi_create_display_surface(_instance, alloc,
create_info, surface);
}