Module: Mesa
Branch: main
Commit: de79cf05128252bb139b312fa297e2bf23059348
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=de79cf05128252bb139b312fa297e2bf23059348

Author: José Roberto de Souza <[email protected]>
Date:   Thu Jan 26 11:06:46 2023 -0800

anv: Add basic KMD backend infrastructure

Functions that are in hot paths will have a different treatment to
support i915 and Xe KMD.

Each KMD will have an anv_kmd_backend that will have the hot path
functions set, this way we can avoid branch prediction misses.

Other functions will gradually be moved to anv_kmd_backend.

Signed-off-by: José Roberto de Souza <[email protected]>
Reviewed-by: Lionel Landwerlin <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20948>

---

 src/intel/vulkan/anv_allocator.c        | 11 ++---
 src/intel/vulkan/anv_device.c           |  1 +
 src/intel/vulkan/anv_gem.c              | 50 ++------------------
 src/intel/vulkan/anv_gem_stubs.c        |  6 +--
 src/intel/vulkan/anv_kmd_backend.c      | 37 +++++++++++++++
 src/intel/vulkan/anv_kmd_backend.h      | 48 +++++++++++++++++++
 src/intel/vulkan/anv_private.h          |  8 ++--
 src/intel/vulkan/i915/anv_kmd_backend.c | 84 +++++++++++++++++++++++++++++++++
 src/intel/vulkan/meson.build            |  3 ++
 9 files changed, 190 insertions(+), 58 deletions(-)

diff --git a/src/intel/vulkan/anv_allocator.c b/src/intel/vulkan/anv_allocator.c
index 5796a2db4af..157f5792b6b 100644
--- a/src/intel/vulkan/anv_allocator.c
+++ b/src/intel/vulkan/anv_allocator.c
@@ -1452,7 +1452,7 @@ anv_device_alloc_bo(struct anv_device *device,
    }
 
    const struct intel_memory_class_instance *regions[2];
-   uint32_t nregions = 0, flags = 0;
+   uint32_t nregions = 0;
 
    /* If we have vram size, we have multiple memory regions and should choose
     * one of them.
@@ -1472,17 +1472,14 @@ anv_device_alloc_bo(struct anv_device *device,
        */
       if (!(alloc_flags & ANV_BO_ALLOC_NO_LOCAL_MEM) &&
           ((alloc_flags & ANV_BO_ALLOC_MAPPED) ||
-           (alloc_flags & ANV_BO_ALLOC_LOCAL_MEM_CPU_VISIBLE))) {
+           (alloc_flags & ANV_BO_ALLOC_LOCAL_MEM_CPU_VISIBLE)))
          regions[nregions++] = device->physical->sys.region;
-         if (device->physical->vram_non_mappable.size > 0)
-            flags |= I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS;
-      }
    } else {
       regions[nregions++] = device->physical->sys.region;
    }
 
-   uint32_t gem_handle = anv_gem_create_regions(device, size + ccs_size,
-                                                flags, nregions, regions);
+   uint32_t gem_handle = anv_gem_create(device, size + ccs_size, alloc_flags,
+                                        nregions, regions);
    if (gem_handle == 0)
       return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
 
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index 97ce7430412..d9a30052778 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -3249,6 +3249,7 @@ VkResult anv_CreateDevice(
    }
 
    anv_device_set_physical(device, physical_device);
+   device->kmd_backend = anv_kmd_backend_get(device->info->kmd_type);
 
    /* XXX(chadv): Can we dup() physicalDevice->fd here? */
    device->fd = open(physical_device->path, O_RDWR | O_CLOEXEC);
diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
index f2151ac9c3f..eacc7fb5057 100644
--- a/src/intel/vulkan/anv_gem.c
+++ b/src/intel/vulkan/anv_gem.c
@@ -43,52 +43,12 @@ anv_gem_close(struct anv_device *device, uint32_t 
gem_handle)
 }
 
 uint32_t
-anv_gem_create_regions(struct anv_device *device, uint64_t anv_bo_size,
-                       uint32_t flags, uint32_t num_regions,
-                       const struct intel_memory_class_instance **regions)
+anv_gem_create(struct anv_device *device, uint64_t anv_bo_size,
+               enum anv_bo_alloc_flags alloc_flags, uint32_t num_regions,
+               const struct intel_memory_class_instance **regions)
 {
-   if (unlikely(!device->info->mem.use_class_instance)) {
-      assert(num_regions == 1 &&
-             device->physical->sys.region == regions[0] &&
-             flags == 0);
-
-      struct drm_i915_gem_create gem_create = {
-            .size = anv_bo_size,
-      };
-      if (intel_ioctl(device->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create))
-         return 0;
-      return gem_create.handle;
-   }
-
-   struct drm_i915_gem_memory_class_instance i915_regions[2];
-   /* Check for invalid flags */
-   assert((flags & ~I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS) == 0);
-   assert(num_regions <= ARRAY_SIZE(i915_regions));
-
-   for (uint32_t i = 0; i < num_regions; i++) {
-      i915_regions[i].memory_class = regions[i]->klass;
-      i915_regions[i].memory_instance = regions[i]->instance;
-   }
-
-   struct drm_i915_gem_create_ext_memory_regions ext_regions = {
-      .base = { .name = I915_GEM_CREATE_EXT_MEMORY_REGIONS },
-      .num_regions = num_regions,
-      .regions = (uintptr_t)i915_regions,
-   };
-
-   struct drm_i915_gem_create_ext gem_create = {
-      .size = anv_bo_size,
-      .extensions = (uintptr_t) &ext_regions,
-      .flags = flags,
-   };
-
-   int ret = intel_ioctl(device->fd, DRM_IOCTL_I915_GEM_CREATE_EXT,
-                         &gem_create);
-   if (ret != 0) {
-      return 0;
-   }
-
-   return gem_create.handle;
+   return device->kmd_backend->gem_create(device, regions, num_regions,
+                                          anv_bo_size, alloc_flags);
 }
 
 /**
diff --git a/src/intel/vulkan/anv_gem_stubs.c b/src/intel/vulkan/anv_gem_stubs.c
index f82d9873cd2..82ddc41a59e 100644
--- a/src/intel/vulkan/anv_gem_stubs.c
+++ b/src/intel/vulkan/anv_gem_stubs.c
@@ -34,9 +34,9 @@ anv_gem_close(struct anv_device *device, uint32_t gem_handle)
 }
 
 uint32_t
-anv_gem_create_regions(struct anv_device *device, uint64_t size,
-                       uint32_t flags, uint32_t num_regions,
-                       const struct intel_memory_class_instance **regions)
+anv_gem_create(struct anv_device *device, uint64_t size,
+               enum anv_bo_alloc_flags alloc_flags, uint32_t num_regions,
+               const struct intel_memory_class_instance **regions)
 {
    int fd = os_create_anonymous_file(size, "fake bo");
    if (fd == -1)
diff --git a/src/intel/vulkan/anv_kmd_backend.c 
b/src/intel/vulkan/anv_kmd_backend.c
new file mode 100644
index 00000000000..1cc2aa5840a
--- /dev/null
+++ b/src/intel/vulkan/anv_kmd_backend.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2023 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <stdlib.h>
+
+#include "anv_kmd_backend.h"
+
+const struct anv_kmd_backend *
+anv_kmd_backend_get(enum intel_kmd_type type)
+{
+   switch (type) {
+   case INTEL_KMD_TYPE_I915:
+      return anv_i915_kmd_backend_get();
+   default:
+      return NULL;
+   }
+}
diff --git a/src/intel/vulkan/anv_kmd_backend.h 
b/src/intel/vulkan/anv_kmd_backend.h
new file mode 100644
index 00000000000..092cfbfc6f5
--- /dev/null
+++ b/src/intel/vulkan/anv_kmd_backend.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright © 2023 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#include "dev/intel_device_info.h"
+#include "dev/intel_kmd.h"
+
+enum anv_bo_alloc_flags;
+struct anv_device;
+
+struct anv_kmd_backend {
+   /*
+    * Create a gem buffer.
+    * Return the gem handle in case of success otherwise returns 0.
+    */
+   uint32_t (*gem_create)(struct anv_device *device,
+                          const struct intel_memory_class_instance **regions,
+                          uint16_t num_regions, uint64_t size,
+                          enum anv_bo_alloc_flags alloc_flags);
+};
+
+const struct anv_kmd_backend *anv_kmd_backend_get(enum intel_kmd_type type);
+
+/* Internal functions, should only be called by anv_kmd_backend_get() */
+const struct anv_kmd_backend *anv_i915_kmd_backend_get(void);
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index bf6d93f2dee..5435f2a9726 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -120,6 +120,7 @@ struct intel_perf_query_result;
 
 #include "anv_android.h"
 #include "anv_entrypoints.h"
+#include "anv_kmd_backend.h"
 #include "isl/isl.h"
 
 #include "dev/intel_debug.h"
@@ -1118,6 +1119,7 @@ struct anv_device {
 
     struct anv_physical_device *                physical;
     const struct intel_device_info *            info;
+    const struct anv_kmd_backend *              kmd_backend;
     struct isl_device                           isl_dev;
     uint32_t                                    context_id;
     int                                         fd;
@@ -1346,9 +1348,9 @@ void* anv_gem_mmap(struct anv_device *device, struct 
anv_bo *bo,
                    uint64_t offset, uint64_t size, uint32_t flags);
 void anv_gem_munmap(struct anv_device *device, void *p, uint64_t size);
 void anv_gem_close(struct anv_device *device, uint32_t gem_handle);
-uint32_t anv_gem_create_regions(struct anv_device *device, uint64_t 
anv_bo_size,
-                                uint32_t flags, uint32_t num_regions,
-                                const struct intel_memory_class_instance 
**regions);
+uint32_t anv_gem_create(struct anv_device *device, uint64_t anv_bo_size,
+                        enum anv_bo_alloc_flags alloc_flags, uint32_t 
num_regions,
+                        const struct intel_memory_class_instance **regions);
 uint32_t anv_gem_userptr(struct anv_device *device, void *mem, size_t size);
 int anv_gem_wait(struct anv_device *device, uint32_t gem_handle, int64_t 
*timeout_ns);
 int anv_gem_set_tiling(struct anv_device *device, uint32_t gem_handle,
diff --git a/src/intel/vulkan/i915/anv_kmd_backend.c 
b/src/intel/vulkan/i915/anv_kmd_backend.c
new file mode 100644
index 00000000000..87b9ee9683b
--- /dev/null
+++ b/src/intel/vulkan/i915/anv_kmd_backend.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright © 2023 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "anv_private.h"
+
+#include "drm-uapi/i915_drm.h"
+
+static uint32_t
+i915_gem_create(struct anv_device *device,
+                const struct intel_memory_class_instance **regions,
+                uint16_t num_regions, uint64_t size,
+                enum anv_bo_alloc_flags alloc_flags)
+{
+   if (unlikely(!device->info->mem.use_class_instance)) {
+      assert(num_regions == 1 &&
+             device->physical->sys.region == regions[0]);
+
+      struct drm_i915_gem_create gem_create = {
+            .size = size,
+      };
+      if (intel_ioctl(device->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create))
+         return 0;
+      return gem_create.handle;
+   }
+
+   struct drm_i915_gem_memory_class_instance i915_regions[2];
+   assert(num_regions <= ARRAY_SIZE(i915_regions));
+
+   for (uint16_t i = 0; i < num_regions; i++) {
+      i915_regions[i].memory_class = regions[i]->klass;
+      i915_regions[i].memory_instance = regions[i]->instance;
+   }
+
+   uint32_t flags = 0;
+   if (alloc_flags & (ANV_BO_ALLOC_MAPPED | 
ANV_BO_ALLOC_LOCAL_MEM_CPU_VISIBLE) &&
+       !(alloc_flags & ANV_BO_ALLOC_NO_LOCAL_MEM))
+      if (device->physical->vram_non_mappable.size > 0)
+         flags |= I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS;
+
+   struct drm_i915_gem_create_ext_memory_regions ext_regions = {
+      .base = { .name = I915_GEM_CREATE_EXT_MEMORY_REGIONS },
+      .num_regions = num_regions,
+      .regions = (uintptr_t)i915_regions,
+   };
+   struct drm_i915_gem_create_ext gem_create = {
+      .size = size,
+      .extensions = (uintptr_t) &ext_regions,
+      .flags = flags,
+   };
+
+   if (intel_ioctl(device->fd, DRM_IOCTL_I915_GEM_CREATE_EXT, &gem_create))
+      return 0;
+
+   return gem_create.handle;
+}
+
+const struct anv_kmd_backend *
+anv_i915_kmd_backend_get(void)
+{
+   static const struct anv_kmd_backend i915_backend = {
+      .gem_create = i915_gem_create,
+   };
+   return &i915_backend;
+}
diff --git a/src/intel/vulkan/meson.build b/src/intel/vulkan/meson.build
index ea9c468665f..1886ea0904a 100644
--- a/src/intel/vulkan/meson.build
+++ b/src/intel/vulkan/meson.build
@@ -135,6 +135,7 @@ libanv_files = files(
   'i915/anv_batch_chain.h',
   'i915/anv_device.c',
   'i915/anv_device.h',
+  'i915/anv_kmd_backend.c',
   'layers/anv_doom64.c',
   'layers/anv_hitman3.c',
   'anv_allocator.c',
@@ -149,6 +150,8 @@ libanv_files = files(
   'anv_generated_indirect_draws.c',
   'anv_genX.h',
   'anv_image.c',
+  'anv_kmd_backend.c',
+  'anv_kmd_backend.h',
   'anv_measure.c',
   'anv_measure.h',
   'anv_nir.h',

Reply via email to