panfrost/ci: Update expectations
[mesa.git] / src / gallium / drivers / tegra / tegra_screen.c
index 41bf2052f94536617017b19d9a9bd640af48736c..6e7769075d1e4af07d1a0f58200e1ae583930d72 100644 (file)
 
 #include <sys/stat.h>
 
-#include <drm_fourcc.h>
-#include <tegra_drm.h>
+#include "drm-uapi/drm_fourcc.h"
+#include "drm-uapi/tegra_drm.h"
 #include <xf86drm.h>
 
+#include "loader/loader.h"
 #include "pipe/p_state.h"
 #include "util/u_debug.h"
 #include "util/u_inlines.h"
@@ -132,12 +133,14 @@ tegra_screen_is_format_supported(struct pipe_screen *pscreen,
                                  enum pipe_format format,
                                  enum pipe_texture_target target,
                                  unsigned sample_count,
+                                 unsigned storage_sample_count,
                                  unsigned usage)
 {
    struct tegra_screen *screen = to_tegra_screen(pscreen);
 
    return screen->gpu->is_format_supported(screen->gpu, format, target,
-                                           sample_count, usage);
+                                           sample_count, storage_sample_count,
+                                           usage);
 }
 
 static boolean
@@ -161,77 +164,19 @@ tegra_screen_can_create_resource(struct pipe_screen *pscreen,
    return screen->gpu->can_create_resource(screen->gpu, template);
 }
 
-static int tegra_open_render_node(void)
-{
-   drmDevicePtr *devices, device;
-   int err, render = -ENOENT, fd;
-   unsigned int num, i;
-
-   err = drmGetDevices2(0, NULL, 0);
-   if (err < 0)
-      return err;
-
-   num = err;
-
-   devices = calloc(num, sizeof(*devices));
-   if (!devices)
-      return -ENOMEM;
-
-   err = drmGetDevices2(0, devices, num);
-   if (err < 0) {
-      render = err;
-      goto free;
-   }
-
-   for (i = 0; i < num; i++) {
-      device = devices[i];
-
-      if ((device->available_nodes & (1 << DRM_NODE_RENDER)) &&
-          (device->bustype == DRM_BUS_PLATFORM)) {
-         drmVersionPtr version;
-
-         fd = open(device->nodes[DRM_NODE_RENDER], O_RDWR | O_CLOEXEC);
-         if (fd < 0)
-            continue;
-
-         version = drmGetVersion(fd);
-         if (!version) {
-            close(fd);
-            continue;
-         }
-
-         if (strcmp(version->name, "nouveau") != 0) {
-            close(fd);
-            continue;
-         }
-
-         drmFreeVersion(version);
-         render = fd;
-         break;
-      }
-   }
-
-   drmFreeDevices(devices, num);
-
-free:
-   free(devices);
-   return render;
-}
-
 static int tegra_screen_import_resource(struct tegra_screen *screen,
                                         struct tegra_resource *resource)
 {
-   unsigned usage = PIPE_HANDLE_USAGE_READ;
    struct winsys_handle handle;
    boolean status;
    int fd, err;
 
    memset(&handle, 0, sizeof(handle));
    handle.modifier = DRM_FORMAT_MOD_INVALID;
-   handle.type = DRM_API_HANDLE_TYPE_FD;
+   handle.type = WINSYS_HANDLE_TYPE_FD;
 
    status = screen->gpu->resource_get_handle(screen->gpu, NULL, resource->gpu,
-                                             &handle, usage);
+                                             &handle, 0);
    if (!status)
       return -EINVAL;
 
@@ -260,6 +205,7 @@ tegra_screen_resource_create(struct pipe_screen *pscreen,
                              const struct pipe_resource *template)
 {
    struct tegra_screen *screen = to_tegra_screen(pscreen);
+   uint64_t modifier = DRM_FORMAT_MOD_INVALID;
    struct tegra_resource *resource;
    int err;
 
@@ -267,7 +213,23 @@ tegra_screen_resource_create(struct pipe_screen *pscreen,
    if (!resource)
       return NULL;
 
-   resource->gpu = screen->gpu->resource_create(screen->gpu, template);
+   /*
+    * Applications that create scanout resources without modifiers are very
+    * unlikely to support modifiers at all. In that case the resources need
+    * to be created with a pitch-linear layout so that they can be properly
+    * shared with scanout hardware.
+    *
+    * Technically it is possible for applications to create resources without
+    * specifying a modifier but still query the modifier associated with the
+    * resource (e.g. using gbm_bo_get_modifier()) before handing it to the
+    * framebuffer creation API (such as the DRM_IOCTL_MODE_ADDFB2 IOCTL).
+    */
+   if (template->bind & PIPE_BIND_SCANOUT)
+      modifier = DRM_FORMAT_MOD_LINEAR;
+
+   resource->gpu = screen->gpu->resource_create_with_modifiers(screen->gpu,
+                                                               template,
+                                                               &modifier, 1);
    if (!resource->gpu)
       goto free;
 
@@ -369,7 +331,7 @@ tegra_screen_resource_get_handle(struct pipe_screen *pscreen,
     * to pass buffers into Tegra DRM for display. In all other cases, return
     * the Nouveau handle, assuming they will be used for sharing in DRI2/3.
     */
-   if (handle->type == DRM_API_HANDLE_TYPE_KMS &&
+   if (handle->type == WINSYS_HANDLE_TYPE_KMS &&
        presource->bind & PIPE_BIND_SCANOUT) {
       handle->modifier = resource->modifier;
       handle->handle = resource->handle;
@@ -498,6 +460,7 @@ tegra_screen_resource_create_with_modifiers(struct pipe_screen *pscreen,
                                             int count)
 {
    struct tegra_screen *screen = to_tegra_screen(pscreen);
+   struct pipe_resource tmpl = *template;
    struct tegra_resource *resource;
    int err;
 
@@ -505,8 +468,18 @@ tegra_screen_resource_create_with_modifiers(struct pipe_screen *pscreen,
    if (!resource)
       return NULL;
 
+   /*
+    * Assume that resources created with modifiers will always be used for
+    * scanout. This is necessary because some of the APIs that are used to
+    * create resources with modifiers (e.g. gbm_bo_create_with_modifiers())
+    * can't pass along usage information. Adding that capability might be
+    * worth adding to remove this ambiguity. Not all future use-cases that
+    * involve modifiers may always be targetting scanout hardware.
+    */
+   tmpl.bind |= PIPE_BIND_SCANOUT;
+
    resource->gpu = screen->gpu->resource_create_with_modifiers(screen->gpu,
-                                                               template,
+                                                               &tmpl,
                                                                modifiers,
                                                                count);
    if (!resource->gpu)
@@ -563,7 +536,7 @@ tegra_screen_create(int fd)
 
    screen->fd = fd;
 
-   screen->gpu_fd = tegra_open_render_node();
+   screen->gpu_fd = loader_open_render_node("nouveau");
    if (screen->gpu_fd < 0) {
       if (errno != ENOENT)
          fprintf(stderr, "failed to open GPU device: %s\n", strerror(errno));