mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-08 21:30:23 +01:00
anv: Add gem_mmap to kmd backend
Signed-off-by: José Roberto de Souza <jose.souza@intel.com> Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21255>
This commit is contained in:
parent
32a8250b46
commit
0c8d8ae13c
7 changed files with 104 additions and 82 deletions
|
|
@ -1503,7 +1503,7 @@ anv_device_alloc_bo(struct anv_device *device,
|
|||
|
||||
if (alloc_flags & ANV_BO_ALLOC_MAPPED) {
|
||||
VkResult result = anv_device_map_bo(device, &new_bo, 0, size,
|
||||
0 /* gem_flags */, &new_bo.map);
|
||||
0 /* propertyFlags */, &new_bo.map);
|
||||
if (unlikely(result != VK_SUCCESS)) {
|
||||
device->kmd_backend->gem_close(device, new_bo.gem_handle);
|
||||
return result;
|
||||
|
|
@ -1562,16 +1562,13 @@ anv_device_map_bo(struct anv_device *device,
|
|||
struct anv_bo *bo,
|
||||
uint64_t offset,
|
||||
size_t size,
|
||||
uint32_t gem_flags,
|
||||
VkMemoryPropertyFlags property_flags,
|
||||
void **map_out)
|
||||
{
|
||||
assert(!bo->from_host_ptr);
|
||||
assert(size > 0);
|
||||
|
||||
if (bo->map_wc)
|
||||
gem_flags |= I915_MMAP_WC;
|
||||
|
||||
void *map = anv_gem_mmap(device, bo, offset, size, gem_flags);
|
||||
void *map = anv_gem_mmap(device, bo, offset, size, property_flags);
|
||||
if (unlikely(map == MAP_FAILED))
|
||||
return vk_errorf(device, VK_ERROR_MEMORY_MAP_FAILED, "mmap failed: %m");
|
||||
|
||||
|
|
|
|||
|
|
@ -4255,12 +4255,6 @@ VkResult anv_MapMemory(
|
|||
"Memory object already mapped.");
|
||||
}
|
||||
|
||||
uint32_t gem_flags = 0;
|
||||
|
||||
if (!device->info->has_llc &&
|
||||
(mem->type->propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
|
||||
gem_flags |= I915_MMAP_WC;
|
||||
|
||||
/* GEM will fail to map if the offset isn't 4k-aligned. Round down. */
|
||||
uint64_t map_offset;
|
||||
if (!device->physical->info.has_mmap_offset)
|
||||
|
|
@ -4274,8 +4268,8 @@ VkResult anv_MapMemory(
|
|||
map_size = align64(map_size, 4096);
|
||||
|
||||
void *map;
|
||||
VkResult result = anv_device_map_bo(device, mem->bo, map_offset,
|
||||
map_size, gem_flags, &map);
|
||||
VkResult result = anv_device_map_bo(device, mem->bo, map_offset, map_size,
|
||||
mem->type->propertyFlags, &map);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
|
|
|
|||
|
|
@ -32,64 +32,12 @@
|
|||
#include "anv_private.h"
|
||||
#include "common/intel_gem.h"
|
||||
|
||||
/**
|
||||
* Wrapper around DRM_IOCTL_I915_GEM_MMAP. Returns MAP_FAILED on error.
|
||||
*/
|
||||
static void*
|
||||
anv_gem_mmap_offset(struct anv_device *device, uint32_t gem_handle,
|
||||
uint64_t offset, uint64_t size, uint32_t flags)
|
||||
void *
|
||||
anv_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset,
|
||||
uint64_t size, VkMemoryPropertyFlags property_flags)
|
||||
{
|
||||
struct drm_i915_gem_mmap_offset gem_mmap = {
|
||||
.handle = gem_handle,
|
||||
.flags = device->info->has_local_mem ? I915_MMAP_OFFSET_FIXED :
|
||||
(flags & I915_MMAP_WC) ? I915_MMAP_OFFSET_WC : I915_MMAP_OFFSET_WB,
|
||||
};
|
||||
assert(offset == 0);
|
||||
|
||||
/* Get the fake offset back */
|
||||
int ret = intel_ioctl(device->fd, DRM_IOCTL_I915_GEM_MMAP_OFFSET, &gem_mmap);
|
||||
if (ret != 0)
|
||||
return MAP_FAILED;
|
||||
|
||||
/* And map it */
|
||||
void *map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
device->fd, gem_mmap.offset);
|
||||
return map;
|
||||
}
|
||||
|
||||
static void*
|
||||
anv_gem_mmap_legacy(struct anv_device *device, uint32_t gem_handle,
|
||||
uint64_t offset, uint64_t size, uint32_t flags)
|
||||
{
|
||||
assert(!device->info->has_local_mem);
|
||||
|
||||
struct drm_i915_gem_mmap gem_mmap = {
|
||||
.handle = gem_handle,
|
||||
.offset = offset,
|
||||
.size = size,
|
||||
.flags = flags,
|
||||
};
|
||||
|
||||
int ret = intel_ioctl(device->fd, DRM_IOCTL_I915_GEM_MMAP, &gem_mmap);
|
||||
if (ret != 0)
|
||||
return MAP_FAILED;
|
||||
|
||||
return (void *)(uintptr_t) gem_mmap.addr_ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper around DRM_IOCTL_I915_GEM_MMAP. Returns MAP_FAILED on error.
|
||||
*/
|
||||
void*
|
||||
anv_gem_mmap(struct anv_device *device, struct anv_bo *bo,
|
||||
uint64_t offset, uint64_t size, uint32_t flags)
|
||||
{
|
||||
uint32_t gem_handle = bo->gem_handle;
|
||||
void *map;
|
||||
if (device->physical->info.has_mmap_offset)
|
||||
map = anv_gem_mmap_offset(device, gem_handle, offset, size, flags);
|
||||
else
|
||||
map = anv_gem_mmap_legacy(device, gem_handle, offset, size, flags);
|
||||
void *map = device->kmd_backend->gem_mmap(device, bo, offset, size,
|
||||
property_flags);
|
||||
|
||||
if (map != MAP_FAILED)
|
||||
VG(VALGRIND_MALLOCLIKE_BLOCK(map, size, 0, 1));
|
||||
|
|
@ -98,7 +46,7 @@ anv_gem_mmap(struct anv_device *device, struct anv_bo *bo,
|
|||
}
|
||||
|
||||
/* This is just a wrapper around munmap, but it also notifies valgrind that
|
||||
* this map is no longer valid. Pair this with anv_gem_mmap().
|
||||
* this map is no longer valid. Pair this with gem_mmap().
|
||||
*/
|
||||
void
|
||||
anv_gem_munmap(struct anv_device *device, void *p, uint64_t size)
|
||||
|
|
|
|||
|
|
@ -48,19 +48,29 @@ stub_gem_create(struct anv_device *device,
|
|||
return fd;
|
||||
}
|
||||
|
||||
void*
|
||||
anv_gem_mmap(struct anv_device *device, struct anv_bo *bo,
|
||||
uint64_t offset, uint64_t size, uint32_t flags)
|
||||
static void *
|
||||
stub_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset,
|
||||
uint64_t size, VkMemoryPropertyFlags property_flags)
|
||||
{
|
||||
/* Ignore flags, as they're specific to I915_GEM_MMAP. */
|
||||
(void) flags;
|
||||
return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->gem_handle,
|
||||
offset);
|
||||
}
|
||||
|
||||
return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
bo->gem_handle, offset);
|
||||
void *
|
||||
anv_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset,
|
||||
uint64_t size, VkMemoryPropertyFlags property_flags)
|
||||
{
|
||||
void *map = device->kmd_backend->gem_mmap(device, bo, offset, size,
|
||||
property_flags);
|
||||
|
||||
if (map != MAP_FAILED)
|
||||
VG(VALGRIND_MALLOCLIKE_BLOCK(map, size, 0, 1));
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/* This is just a wrapper around munmap, but it also notifies valgrind that
|
||||
* this map is no longer valid. Pair this with anv_gem_mmap().
|
||||
* this map is no longer valid. Pair this with gem_mmap().
|
||||
*/
|
||||
void
|
||||
anv_gem_munmap(struct anv_device *device, void *p, uint64_t size)
|
||||
|
|
@ -123,6 +133,7 @@ const struct anv_kmd_backend *anv_stub_kmd_backend_get(void)
|
|||
static const struct anv_kmd_backend stub_backend = {
|
||||
.gem_create = stub_gem_create,
|
||||
.gem_close = stub_gem_close,
|
||||
.gem_mmap = stub_gem_mmap,
|
||||
};
|
||||
return &stub_backend;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,9 +25,12 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "vulkan/vulkan_core.h"
|
||||
|
||||
#include "dev/intel_device_info.h"
|
||||
#include "dev/intel_kmd.h"
|
||||
|
||||
struct anv_bo;
|
||||
enum anv_bo_alloc_flags;
|
||||
struct anv_device;
|
||||
|
||||
|
|
@ -41,6 +44,10 @@ struct anv_kmd_backend {
|
|||
uint16_t num_regions, uint64_t size,
|
||||
enum anv_bo_alloc_flags alloc_flags);
|
||||
void (*gem_close)(struct anv_device *device, uint32_t handle);
|
||||
/* Returns MAP_FAILED on error */
|
||||
void *(*gem_mmap)(struct anv_device *device, struct anv_bo *bo,
|
||||
uint64_t offset, uint64_t size,
|
||||
VkMemoryPropertyFlags property_flags);
|
||||
};
|
||||
|
||||
const struct anv_kmd_backend *anv_kmd_backend_get(enum intel_kmd_type type);
|
||||
|
|
|
|||
|
|
@ -1349,8 +1349,9 @@ VkResult anv_queue_submit(struct vk_queue *queue,
|
|||
VkResult anv_queue_submit_simple_batch(struct anv_queue *queue,
|
||||
struct anv_batch *batch);
|
||||
|
||||
void* anv_gem_mmap(struct anv_device *device, struct anv_bo *bo,
|
||||
uint64_t offset, uint64_t size, uint32_t flags);
|
||||
void *
|
||||
anv_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset,
|
||||
uint64_t size, VkMemoryPropertyFlags property_flags);
|
||||
void anv_gem_munmap(struct anv_device *device, void *p, uint64_t size);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "anv_private.h"
|
||||
|
||||
#include "drm-uapi/i915_drm.h"
|
||||
|
|
@ -84,12 +86,74 @@ i915_gem_close(struct anv_device *device, uint32_t handle)
|
|||
intel_ioctl(device->fd, DRM_IOCTL_GEM_CLOSE, &close);
|
||||
}
|
||||
|
||||
static void *
|
||||
i915_gem_mmap_offset(struct anv_device *device, struct anv_bo *bo,
|
||||
uint64_t size, uint32_t flags)
|
||||
{
|
||||
struct drm_i915_gem_mmap_offset gem_mmap = {
|
||||
.handle = bo->gem_handle,
|
||||
.flags = flags,
|
||||
};
|
||||
if (intel_ioctl(device->fd, DRM_IOCTL_I915_GEM_MMAP_OFFSET, &gem_mmap))
|
||||
return MAP_FAILED;
|
||||
|
||||
return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
device->fd, gem_mmap.offset);
|
||||
}
|
||||
|
||||
static void *
|
||||
i915_gem_mmap_legacy(struct anv_device *device, struct anv_bo *bo, uint64_t offset,
|
||||
uint64_t size, uint32_t flags)
|
||||
{
|
||||
struct drm_i915_gem_mmap gem_mmap = {
|
||||
.handle = bo->gem_handle,
|
||||
.offset = offset,
|
||||
.size = size,
|
||||
.flags = flags,
|
||||
};
|
||||
if (intel_ioctl(device->fd, DRM_IOCTL_I915_GEM_MMAP, &gem_mmap))
|
||||
return MAP_FAILED;
|
||||
|
||||
return (void *)(uintptr_t) gem_mmap.addr_ptr;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
mmap_calc_flags(struct anv_device *device, struct anv_bo *bo,
|
||||
VkMemoryPropertyFlags property_flags)
|
||||
{
|
||||
if (device->info->has_local_mem)
|
||||
return I915_MMAP_OFFSET_FIXED;
|
||||
|
||||
uint32_t flags = 0;
|
||||
if (!device->info->has_llc &&
|
||||
(property_flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
|
||||
flags |= I915_MMAP_WC;
|
||||
if (bo->map_wc)
|
||||
flags |= I915_MMAP_WC;
|
||||
|
||||
if (likely(device->physical->info.has_mmap_offset))
|
||||
flags = (flags & I915_MMAP_WC) ? I915_MMAP_OFFSET_WC : I915_MMAP_OFFSET_WB;
|
||||
return flags;
|
||||
}
|
||||
|
||||
static void *
|
||||
i915_gem_mmap(struct anv_device *device, struct anv_bo *bo, uint64_t offset,
|
||||
uint64_t size, VkMemoryPropertyFlags property_flags)
|
||||
{
|
||||
const uint32_t flags = mmap_calc_flags(device, bo, property_flags);
|
||||
|
||||
if (likely(device->physical->info.has_mmap_offset))
|
||||
return i915_gem_mmap_offset(device, bo, size, flags);
|
||||
return i915_gem_mmap_legacy(device, bo, offset, size, flags);
|
||||
}
|
||||
|
||||
const struct anv_kmd_backend *
|
||||
anv_i915_kmd_backend_get(void)
|
||||
{
|
||||
static const struct anv_kmd_backend i915_backend = {
|
||||
.gem_create = i915_gem_create,
|
||||
.gem_close = i915_gem_close,
|
||||
.gem_mmap = i915_gem_mmap,
|
||||
};
|
||||
return &i915_backend;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue