summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/broadcom/vulkan/meson.build5
-rw-r--r--src/broadcom/vulkan/v3dv_device.c40
-rw-r--r--src/broadcom/vulkan/v3dv_wsi_display.c136
3 files changed, 169 insertions, 12 deletions
diff --git a/src/broadcom/vulkan/meson.build b/src/broadcom/vulkan/meson.build
index 29fc4cc665c..58f4bcee989 100644
--- a/src/broadcom/vulkan/meson.build
+++ b/src/broadcom/vulkan/meson.build
@@ -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],
diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c
index 3e1078d922c..36031caee18 100644
--- a/src/broadcom/vulkan/v3dv_device.c
+++ b/src/broadcom/vulkan/v3dv_device.c
@@ -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,23 +464,37 @@ 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
- display_fd = create_display_fd_xcb();
+ if (display_fd == -1)
+ display_fd = create_display_fd_xcb();
#endif
if (display_fd == -1) {
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 &&
- devices[i]->bustype == DRM_BUS_PCI &&
- devices[i]->deviceinfo.pci->vendor_id == 0x8086) {
+ 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);
diff --git a/src/broadcom/vulkan/v3dv_wsi_display.c b/src/broadcom/vulkan/v3dv_wsi_display.c
new file mode 100644
index 00000000000..2e43a5f6a49
--- /dev/null
+++ b/src/broadcom/vulkan/v3dv_wsi_display.c
@@ -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);
+}