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',
