mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 11:38:05 +02:00
anv: Rework init_meminfo
Instead of making LMEM the special case, unify the two paths by setting up a fake drm_i915_query_memory_regions struct and filling it out based on OS queries. The important functional change here is that we now pass system memory through the same GTT size and 3/4 filter that we were using with the OS queries. This should make behavior consistent on integrated GPUs regardless of whether or not we have the memory region query API. Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12433>
This commit is contained in:
parent
be216ae9d9
commit
5c79c545e3
1 changed files with 78 additions and 49 deletions
|
|
@ -305,13 +305,9 @@ get_device_extensions(const struct anv_physical_device *device,
|
|||
}
|
||||
|
||||
static uint64_t
|
||||
anv_compute_heap_size(int fd, uint64_t gtt_size)
|
||||
anv_compute_sys_heap_size(struct anv_physical_device *device,
|
||||
uint64_t total_ram)
|
||||
{
|
||||
/* Query the total ram from the system */
|
||||
uint64_t total_ram;
|
||||
if (!os_get_total_physical_memory(&total_ram))
|
||||
return 0;
|
||||
|
||||
/* We don't want to burn too much ram with the GPU. If the user has 4GiB
|
||||
* or less, we use at most half. If they have more than 4GiB, we use 3/4.
|
||||
*/
|
||||
|
|
@ -324,47 +320,9 @@ anv_compute_heap_size(int fd, uint64_t gtt_size)
|
|||
/* We also want to leave some padding for things we allocate in the driver,
|
||||
* so don't go over 3/4 of the GTT either.
|
||||
*/
|
||||
uint64_t available_gtt = gtt_size * 3 / 4;
|
||||
available_ram = MIN2(available_ram, device->gtt_size * 3 / 4);
|
||||
|
||||
return MIN2(available_ram, available_gtt);
|
||||
}
|
||||
|
||||
static bool
|
||||
anv_get_query_meminfo(struct anv_physical_device *device, int fd)
|
||||
{
|
||||
struct drm_i915_query_memory_regions *mem_regions =
|
||||
intel_i915_query_alloc(fd, DRM_I915_QUERY_MEMORY_REGIONS);
|
||||
if (mem_regions == NULL)
|
||||
return false;
|
||||
|
||||
for(int i = 0; i < mem_regions->num_regions; i++) {
|
||||
switch(mem_regions->regions[i].region.memory_class) {
|
||||
case I915_MEMORY_CLASS_SYSTEM:
|
||||
device->sys.region = mem_regions->regions[i].region;
|
||||
device->sys.size = mem_regions->regions[i].probed_size;
|
||||
break;
|
||||
case I915_MEMORY_CLASS_DEVICE:
|
||||
device->vram.region = mem_regions->regions[i].region;
|
||||
device->vram.size = mem_regions->regions[i].probed_size;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(mem_regions);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
anv_init_meminfo(struct anv_physical_device *device, int fd)
|
||||
{
|
||||
if (anv_get_query_meminfo(device, fd))
|
||||
return;
|
||||
|
||||
uint64_t heap_size = anv_compute_heap_size(fd, device->gtt_size);
|
||||
|
||||
if (heap_size > (2ull << 30) && !device->supports_48bit_addresses) {
|
||||
if (available_ram > (2ull << 30) && !device->supports_48bit_addresses) {
|
||||
/* When running with an overridden PCI ID, we may get a GTT size from
|
||||
* the kernel that is greater than 2 GiB but the execbuf check for 48bit
|
||||
* address support can still fail. Just clamp the address space size to
|
||||
|
|
@ -373,10 +331,78 @@ anv_init_meminfo(struct anv_physical_device *device, int fd)
|
|||
mesa_logw("%s:%d: The kernel reported a GTT size larger than 2 GiB but "
|
||||
"not support for 48-bit addresses",
|
||||
__FILE__, __LINE__);
|
||||
heap_size = 2ull << 30;
|
||||
available_ram = 2ull << 30;
|
||||
}
|
||||
|
||||
device->sys.size = heap_size;
|
||||
return available_ram;
|
||||
}
|
||||
|
||||
static VkResult MUST_CHECK
|
||||
anv_init_meminfo(struct anv_physical_device *device, int fd)
|
||||
{
|
||||
char sys_mem_regions[sizeof(struct drm_i915_query_memory_regions) +
|
||||
sizeof(struct drm_i915_memory_region_info)];
|
||||
|
||||
struct drm_i915_query_memory_regions *mem_regions =
|
||||
intel_i915_query_alloc(fd, DRM_I915_QUERY_MEMORY_REGIONS);
|
||||
if (mem_regions == NULL) {
|
||||
if (device->info.has_local_mem) {
|
||||
return vk_errorfi(device->instance, NULL,
|
||||
VK_ERROR_INCOMPATIBLE_DRIVER,
|
||||
"failed to memory regions: %m");
|
||||
}
|
||||
|
||||
uint64_t total_phys;
|
||||
if (!os_get_total_physical_memory(&total_phys)) {
|
||||
return vk_errorfi(device->instance, NULL,
|
||||
VK_ERROR_INITIALIZATION_FAILED,
|
||||
"failed to get total physical memory: %m");
|
||||
}
|
||||
|
||||
uint64_t available;
|
||||
if (!os_get_available_system_memory(&available))
|
||||
available = 0; /* Silently disable VK_EXT_memory_budget */
|
||||
|
||||
/* The kernel query failed. Fake it using OS memory queries. This
|
||||
* should be roughly the same for integrated GPUs.
|
||||
*/
|
||||
mem_regions = (void *)sys_mem_regions;
|
||||
mem_regions->num_regions = 1;
|
||||
mem_regions->regions[0] = (struct drm_i915_memory_region_info) {
|
||||
.region.memory_class = I915_MEMORY_CLASS_SYSTEM,
|
||||
.probed_size = total_phys,
|
||||
.unallocated_size = available,
|
||||
};
|
||||
}
|
||||
|
||||
for(int i = 0; i < mem_regions->num_regions; i++) {
|
||||
struct drm_i915_memory_region_info *info = &mem_regions->regions[i];
|
||||
|
||||
struct anv_memregion *region;
|
||||
switch (info->region.memory_class) {
|
||||
case I915_MEMORY_CLASS_SYSTEM:
|
||||
region = &device->sys;
|
||||
break;
|
||||
case I915_MEMORY_CLASS_DEVICE:
|
||||
region = &device->vram;
|
||||
break;
|
||||
default:
|
||||
/* We don't know what kind of memory this is */
|
||||
continue;
|
||||
}
|
||||
|
||||
uint64_t size = info->probed_size;
|
||||
if (info->region.memory_class == I915_MEMORY_CLASS_SYSTEM)
|
||||
size = anv_compute_sys_heap_size(device, size);
|
||||
|
||||
region->region = info->region;
|
||||
region->size = size;
|
||||
}
|
||||
|
||||
if (mem_regions != (void *)sys_mem_regions)
|
||||
free(mem_regions);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
|
|
@ -403,7 +429,10 @@ anv_physical_device_init_heaps(struct anv_physical_device *device, int fd)
|
|||
device->supports_48bit_addresses = (device->info.ver >= 8) &&
|
||||
device->gtt_size > (4ULL << 30 /* GiB */);
|
||||
|
||||
anv_init_meminfo(device, fd);
|
||||
VkResult result = anv_init_meminfo(device, fd);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
assert(device->sys.size != 0);
|
||||
|
||||
if (device->vram.size > 0) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue