<div dir="ltr">On 18 March 2017 at 04:24, Jason Ekstrand <span dir="ltr"><<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Instead of just advertising the aperture size, we do something more<br>
intelligent.  On systems with a full 48-bit PPGTT, we can address 100%<br>
of the available system RAM from the GPU.  In order to keep clients from<br>
burning 100% of your available RAM for graphics resources, we have a<br>
nice little heuristic (which has received exactly zero tuning) to keep<br>
things under a reasonable level of control.<br>
<br>
Cc: Alex Smith <<a href="mailto:asmith@feralinteractive.com" target="_blank">asmith@feralinteractive.com</a>><br>
---<br>
 src/intel/vulkan/anv_device.c<wbr>  | 61 ++++++++++++++++++++++++++++++<wbr>+++---------<br>
 src/intel/vulkan/anv_gem.c     | 16 +++++++++++<br>
 src/intel/vulkan/anv_private.<wbr>h | 13 ++++++++-<br>
 3 files changed, 76 insertions(+), 14 deletions(-)<br></blockquote><div><br></div><div>Thanks Jason, tested here and it seems to be working fine, and doesn't cause any issues as far as I can see. For the series:</div><div><br></div><div>Tested-by: Alex Smith <<a href="mailto:asmith@feralinteractive.com" target="_blank">asmith@feralinteractive.com</a>></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
diff --git a/src/intel/vulkan/anv_device.<wbr>c b/src/intel/vulkan/anv_device.<wbr>c<br>
index 8994e70..fd71a23 100644<br>
--- a/src/intel/vulkan/anv_device.<wbr>c<br>
+++ b/src/intel/vulkan/anv_device.<wbr>c<br>
@@ -25,6 +25,7 @@<br>
 #include <stdbool.h><br>
 #include <string.h><br>
 #include <sys/mman.h><br>
+#include <sys/sysinfo.h><br>
 #include <unistd.h><br>
 #include <fcntl.h><br>
 #include <xf86drm.h><br>
@@ -53,6 +54,48 @@ compiler_perf_log(void *data, const char *fmt, ...)<br>
    va_end(args);<br>
 }<br>
<br>
+static VkResult<br>
+anv_compute_heap_size(int fd, uint64_t *heap_size)<br>
+{<br>
+   uint64_t gtt_size;<br>
+   if (anv_gem_get_context_param(fd, 0, I915_CONTEXT_PARAM_GTT_SIZE,<br>
+                                 &gtt_size) == -1) {<br>
+      /* If, for whatever reason, we can't actually get the GTT size from the<br>
+       * kernel (too old?) fall back to the aperture size.<br>
+       */<br>
+      anv_perf_warn("Failed to get I915_CONTEXT_PARAM_GTT_SIZE: %m");<br>
+<br>
+      if (anv_gem_get_aperture(fd, &gtt_size) == -1) {<br>
+         return vk_errorf(VK_ERROR_INITIALIZAT<wbr>ION_FAILED,<br>
+                          "failed to get aperture size: %m");<br>
+      }<br>
+   }<br>
+<br>
+   /* Query the total ram from the system */<br>
+   struct sysinfo info;<br>
+   sysinfo(&info);<br>
+<br>
+   uint64_t total_ram = (uint64_t)info.totalram * (uint64_t)info.mem_unit;<br>
+<br>
+   /* We don't want to burn too much ram with the GPU.  If the user has 4GiB<br>
+    * or less, we use at most half.  If they have more than 4GiB, we use 3/4.<br>
+    */<br>
+   uint64_t available_ram;<br>
+   if (total_ram < 4ull * 1024ull * 1024ull * 1024ull)<br>
+      available_ram = total_ram / 2;<br>
+   else<br>
+      available_ram = total_ram * 3 / 4;<br>
+<br>
+   /* We also want to leave some padding for things we allocate in the driver,<br>
+    * so don't go over 3/4 of the GTT either.<br>
+    */<br>
+   uint64_t available_gtt = gtt_size * 3 / 4;<br>
+<br>
+   *heap_size = MIN2(available_ram, available_gtt);<br>
+<br>
+   return VK_SUCCESS;<br>
+}<br>
+<br>
 static bool<br>
 anv_device_get_cache_uuid(voi<wbr>d *uuid)<br>
 {<br>
@@ -124,12 +167,6 @@ anv_physical_device_init(struc<wbr>t anv_physical_device *device,<br>
       }<br>
    }<br>
<br>
-   if (anv_gem_get_aperture(fd, &device->aperture_size) == -1) {<br>
-      result = vk_errorf(VK_ERROR_INITIALIZAT<wbr>ION_FAILED,<br>
-                         "failed to get aperture size: %m");<br>
-      goto fail;<br>
-   }<br>
-<br>
    if (!anv_gem_get_param(fd, I915_PARAM_HAS_WAIT_TIMEOUT)) {<br>
       result = vk_errorf(VK_ERROR_INITIALIZAT<wbr>ION_FAILED,<br>
                          "kernel missing gem wait");<br>
@@ -151,6 +188,10 @@ anv_physical_device_init(struc<wbr>t anv_physical_device *device,<br>
<br>
    device->supports_48bit_address<wbr>es = anv_gem_supports_48b_addresses<wbr>(fd);<br>
<br>
+   result = anv_compute_heap_size(fd, &device->heap_size);<br>
+   if (result != VK_SUCCESS)<br>
+      goto fail;<br>
+<br>
    if (!anv_device_get_cache_uuid(de<wbr>vice->uuid)) {<br>
       result = vk_errorf(VK_ERROR_INITIALIZAT<wbr>ION_FAILED,<br>
                          "cannot generate UUID");<br>
@@ -731,12 +772,6 @@ void anv_GetPhysicalDeviceMemoryPro<wbr>perties(<br>
     VkPhysicalDeviceMemoryPropert<wbr>ies*           pMemoryProperties)<br>
 {<br>
    ANV_FROM_HANDLE(anv_physical_d<wbr>evice, physical_device, physicalDevice);<br>
-   VkDeviceSize heap_size;<br>
-<br>
-   /* Reserve some wiggle room for the driver by exposing only 75% of the<br>
-    * aperture to the heap.<br>
-    */<br>
-   heap_size = 3 * physical_device->aperture_size / 4;<br>
<br>
    if (physical_device->info.has_llc<wbr>) {<br>
       /* Big core GPUs share LLC with the CPU and thus one memory type can be<br>
@@ -773,7 +808,7 @@ void anv_GetPhysicalDeviceMemoryPro<wbr>perties(<br>
<br>
    pMemoryProperties->memoryHeapC<wbr>ount = 1;<br>
    pMemoryProperties->memoryHeaps<wbr>[0] = (VkMemoryHeap) {<br>
-      .size = heap_size,<br>
+      .size = physical_device->heap_size,<br>
       .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BI<wbr>T,<br>
    };<br>
 }<br>
diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c<br>
index 3d45243..5f478b5 100644<br>
--- a/src/intel/vulkan/anv_gem.c<br>
+++ b/src/intel/vulkan/anv_gem.c<br>
@@ -288,6 +288,22 @@ anv_gem_destroy_context(struct anv_device *device, int context)<br>
 }<br>
<br>
 int<br>
+anv_gem_get_context_param(int fd, int context, uint32_t param, uint64_t *value)<br>
+{<br>
+   struct drm_i915_gem_context_param gp = {<br>
+      .ctx_id = context,<br>
+      .param = param,<br>
+   };<br>
+<br>
+   int ret = anv_ioctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_GET<wbr>PARAM, &gp);<br>
+   if (ret == -1)<br>
+      return -1;<br>
+<br>
+   *value = gp.value;<br>
+   return 0;<br>
+}<br>
+<br>
+int<br>
 anv_gem_get_aperture(int fd, uint64_t *size)<br>
 {<br>
    struct drm_i915_gem_get_aperture aperture = { 0 };<br>
diff --git a/src/intel/vulkan/anv_private<wbr>.h b/src/intel/vulkan/anv_private<wbr>.h<br>
index 99277f0..64653bc 100644<br>
--- a/src/intel/vulkan/anv_private<wbr>.h<br>
+++ b/src/intel/vulkan/anv_private<wbr>.h<br>
@@ -525,7 +525,16 @@ struct anv_physical_device {<br>
     char                                        path[20];<br>
     const char *                                name;<br>
     struct gen_device_info                      info;<br>
-    uint64_t                                    aperture_size;<br>
+    /** Amount of "GPU memory" we want to advertise<br>
+     *<br>
+     * Clearly, this value is bogus since Intel is a UMA architecture.  On<br>
+     * gen7 platforms, we are limited by GTT size unless we want to implement<br>
+     * fine-grained tracking and GTT splitting.  On Broadwell and above we are<br>
+     * practically unlimited.  However, we will never report more than 3/4 of<br>
+     * the total system ram to try and avoid running out of RAM.<br>
+     */<br>
+    uint64_t                                    heap_size;<br>
+    bool                                        supports_48bit_addresses;<br>
     struct brw_compiler *                       compiler;<br>
     struct isl_device                           isl_dev;<br>
     int                                         cmd_parser_version;<br>
@@ -656,6 +665,8 @@ int anv_gem_set_tiling(struct anv_device *device, uint32_t gem_handle,<br>
                        uint32_t stride, uint32_t tiling);<br>
 int anv_gem_create_context(struct anv_device *device);<br>
 int anv_gem_destroy_context(struct anv_device *device, int context);<br>
+int anv_gem_get_context_param(int fd, int context, uint32_t param,<br>
+                              uint64_t *value);<br>
 int anv_gem_get_param(int fd, uint32_t param);<br>
 bool anv_gem_get_bit6_swizzle(int fd, uint32_t tiling);<br>
 int anv_gem_get_aperture(int fd, uint64_t *size);<br>
<span class="m_8005437526164167152gmail-m_2593854454078732708HOEnZb"><font color="#888888">--<br>
2.5.0.400.gff86faf<br>
<br>
</font></span></blockquote></div><br></div></div>