anv: Drop an assert
[mesa.git] / src / intel / vulkan / anv_device.c
index 1bfc14ccd838b5b20d6c64c7caa4b3581ba60ea9..7d5b3a2a839ed25d4867c741b89930219214f5d7 100644 (file)
@@ -308,7 +308,7 @@ anv_physical_device_free_disk_cache(struct anv_physical_device *device)
 static uint64_t
 get_available_system_memory()
 {
-   char *meminfo = os_read_file("/proc/meminfo");
+   char *meminfo = os_read_file("/proc/meminfo", NULL);
    if (!meminfo)
       return 0;
 
@@ -470,23 +470,15 @@ anv_physical_device_try_create(struct anv_instance *instance,
     */
    device->has_bindless_samplers = device->info.gen >= 8;
 
+   device->has_implicit_ccs = device->info.has_aux_map;
+
    device->has_mem_available = get_available_system_memory() != 0;
 
    device->always_flush_cache =
       driQueryOptionb(&instance->dri_options, "always_flush_cache");
 
-   /* Starting with Gen10, the timestamp frequency of the command streamer may
-    * vary from one part to another. We can query the value from the kernel.
-    */
-   if (device->info.gen >= 10) {
-      int timestamp_frequency =
-         anv_gem_get_param(fd, I915_PARAM_CS_TIMESTAMP_FREQUENCY);
-
-      if (timestamp_frequency < 0)
-         intel_logw("Kernel 4.16-rc1+ required to properly query CS timestamp frequency");
-      else
-         device->info.timestamp_frequency = timestamp_frequency;
-   }
+   device->has_mmap_offset =
+      anv_gem_get_param(fd, I915_PARAM_MMAP_GTT_VERSION) >= 4;
 
    /* GENs prior to 8 do not support EU/Subslice info */
    if (device->info.gen >= 8) {
@@ -2212,6 +2204,11 @@ PFN_vkVoidFunction anv_GetInstanceProcAddr(
    LOOKUP_ANV_ENTRYPOINT(EnumerateInstanceVersion);
    LOOKUP_ANV_ENTRYPOINT(CreateInstance);
 
+   /* GetInstanceProcAddr() can also be called with a NULL instance.
+    * See https://gitlab.khronos.org/vulkan/vulkan/issues/2057
+    */
+   LOOKUP_ANV_ENTRYPOINT(GetInstanceProcAddr);
+
 #undef LOOKUP_ANV_ENTRYPOINT
 
    if (instance == NULL)
@@ -2628,6 +2625,23 @@ static struct gen_mapped_pinned_buffer_alloc aux_map_allocator = {
    .free = gen_aux_map_buffer_free,
 };
 
+static VkResult
+check_physical_device_features(VkPhysicalDevice physicalDevice,
+                               const VkPhysicalDeviceFeatures *features)
+{
+   VkPhysicalDeviceFeatures supported_features;
+   anv_GetPhysicalDeviceFeatures(physicalDevice, &supported_features);
+   VkBool32 *supported_feature = (VkBool32 *)&supported_features;
+   VkBool32 *enabled_feature = (VkBool32 *)features;
+   unsigned num_features = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
+   for (uint32_t i = 0; i < num_features; i++) {
+      if (enabled_feature[i] && !supported_feature[i])
+         return vk_error(VK_ERROR_FEATURE_NOT_PRESENT);
+   }
+
+   return VK_SUCCESS;
+}
+
 VkResult anv_CreateDevice(
     VkPhysicalDevice                            physicalDevice,
     const VkDeviceCreateInfo*                   pCreateInfo,
@@ -2659,15 +2673,34 @@ VkResult anv_CreateDevice(
    }
 
    /* Check enabled features */
+   bool robust_buffer_access = false;
    if (pCreateInfo->pEnabledFeatures) {
-      VkPhysicalDeviceFeatures supported_features;
-      anv_GetPhysicalDeviceFeatures(physicalDevice, &supported_features);
-      VkBool32 *supported_feature = (VkBool32 *)&supported_features;
-      VkBool32 *enabled_feature = (VkBool32 *)pCreateInfo->pEnabledFeatures;
-      unsigned num_features = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
-      for (uint32_t i = 0; i < num_features; i++) {
-         if (enabled_feature[i] && !supported_feature[i])
-            return vk_error(VK_ERROR_FEATURE_NOT_PRESENT);
+      result = check_physical_device_features(physicalDevice,
+                                              pCreateInfo->pEnabledFeatures);
+      if (result != VK_SUCCESS)
+         return result;
+
+      if (pCreateInfo->pEnabledFeatures->robustBufferAccess)
+         robust_buffer_access = true;
+   }
+
+   vk_foreach_struct_const(ext, pCreateInfo->pNext) {
+      switch (ext->sType) {
+      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2: {
+         const VkPhysicalDeviceFeatures2 *features = (const void *)ext;
+         result = check_physical_device_features(physicalDevice,
+                                                 &features->features);
+         if (result != VK_SUCCESS)
+            return result;
+
+         if (features->features.robustBufferAccess)
+            robust_buffer_access = true;
+         break;
+      }
+
+      default:
+         /* Don't warn */
+         break;
       }
    }
 
@@ -2784,8 +2817,7 @@ VkResult anv_CreateDevice(
     */
    device->can_chain_batches = device->info.gen >= 8;
 
-   device->robust_buffer_access = pCreateInfo->pEnabledFeatures &&
-      pCreateInfo->pEnabledFeatures->robustBufferAccess;
+   device->robust_buffer_access = robust_buffer_access;
    device->enabled_extensions = enabled_extensions;
 
    anv_device_init_dispatch(device);
@@ -3201,40 +3233,24 @@ VkResult anv_DeviceWaitIdle(
    return anv_queue_submit_simple_batch(&device->queue, NULL);
 }
 
-bool
-anv_vma_alloc(struct anv_device *device, struct anv_bo *bo,
+uint64_t
+anv_vma_alloc(struct anv_device *device,
+              uint64_t size, uint64_t align,
+              enum anv_bo_alloc_flags alloc_flags,
               uint64_t client_address)
 {
-   const struct gen_device_info *devinfo = &device->info;
-   /* Gen12 CCS surface addresses need to be 64K aligned. We have no way of
-    * telling what this allocation is for so pick the largest alignment.
-    */
-   const uint32_t vma_alignment =
-      devinfo->gen >= 12 ? (64 * 1024) : (4 * 1024);
-
-   if (!(bo->flags & EXEC_OBJECT_PINNED)) {
-      assert(!(bo->has_client_visible_address));
-      return true;
-   }
-
    pthread_mutex_lock(&device->vma_mutex);
 
-   bo->offset = 0;
+   uint64_t addr = 0;
 
-   if (bo->has_client_visible_address) {
-      assert(bo->flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS);
+   if (alloc_flags & ANV_BO_ALLOC_CLIENT_VISIBLE_ADDRESS) {
       if (client_address) {
          if (util_vma_heap_alloc_addr(&device->vma_cva,
-                                      client_address, bo->size)) {
-            bo->offset = gen_canonical_address(client_address);
+                                      client_address, size)) {
+            addr = client_address;
          }
       } else {
-         uint64_t addr =
-            util_vma_heap_alloc(&device->vma_cva, bo->size, vma_alignment);
-         if (addr) {
-            bo->offset = gen_canonical_address(addr);
-            assert(addr == gen_48b_address(bo->offset));
-         }
+         addr = util_vma_heap_alloc(&device->vma_cva, size, align);
       }
       /* We don't want to fall back to other heaps */
       goto done;
@@ -3242,54 +3258,39 @@ anv_vma_alloc(struct anv_device *device, struct anv_bo *bo,
 
    assert(client_address == 0);
 
-   if (bo->flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS) {
-      uint64_t addr =
-         util_vma_heap_alloc(&device->vma_hi, bo->size, vma_alignment);
-      if (addr) {
-         bo->offset = gen_canonical_address(addr);
-         assert(addr == gen_48b_address(bo->offset));
-      }
-   }
+   if (!(alloc_flags & ANV_BO_ALLOC_32BIT_ADDRESS))
+      addr = util_vma_heap_alloc(&device->vma_hi, size, align);
 
-   if (bo->offset == 0) {
-      uint64_t addr =
-         util_vma_heap_alloc(&device->vma_lo, bo->size, vma_alignment);
-      if (addr) {
-         bo->offset = gen_canonical_address(addr);
-         assert(addr == gen_48b_address(bo->offset));
-      }
-   }
+   if (addr == 0)
+      addr = util_vma_heap_alloc(&device->vma_lo, size, align);
 
 done:
    pthread_mutex_unlock(&device->vma_mutex);
 
-   return bo->offset != 0;
+   assert(addr == gen_48b_address(addr));
+   return gen_canonical_address(addr);
 }
 
 void
-anv_vma_free(struct anv_device *device, struct anv_bo *bo)
+anv_vma_free(struct anv_device *device,
+             uint64_t address, uint64_t size)
 {
-   if (!(bo->flags & EXEC_OBJECT_PINNED))
-      return;
-
-   const uint64_t addr_48b = gen_48b_address(bo->offset);
+   const uint64_t addr_48b = gen_48b_address(address);
 
    pthread_mutex_lock(&device->vma_mutex);
 
    if (addr_48b >= LOW_HEAP_MIN_ADDRESS &&
        addr_48b <= LOW_HEAP_MAX_ADDRESS) {
-      util_vma_heap_free(&device->vma_lo, addr_48b, bo->size);
+      util_vma_heap_free(&device->vma_lo, addr_48b, size);
    } else if (addr_48b >= CLIENT_VISIBLE_HEAP_MIN_ADDRESS &&
               addr_48b <= CLIENT_VISIBLE_HEAP_MAX_ADDRESS) {
-      util_vma_heap_free(&device->vma_cva, addr_48b, bo->size);
+      util_vma_heap_free(&device->vma_cva, addr_48b, size);
    } else {
       assert(addr_48b >= HIGH_HEAP_MIN_ADDRESS);
-      util_vma_heap_free(&device->vma_hi, addr_48b, bo->size);
+      util_vma_heap_free(&device->vma_hi, addr_48b, size);
    }
 
    pthread_mutex_unlock(&device->vma_mutex);
-
-   bo->offset = 0;
 }
 
 VkResult anv_AllocateMemory(
@@ -3388,9 +3389,27 @@ VkResult anv_AllocateMemory(
       }
    }
 
+   /* By default, we want all VkDeviceMemory objects to support CCS */
+   if (device->physical->has_implicit_ccs)
+      alloc_flags |= ANV_BO_ALLOC_IMPLICIT_CCS;
+
    if (vk_flags & VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR)
       alloc_flags |= ANV_BO_ALLOC_CLIENT_VISIBLE_ADDRESS;
 
+   if ((export_info && export_info->handleTypes) ||
+       (fd_info && fd_info->handleType) ||
+       (host_ptr_info && host_ptr_info->handleType)) {
+      /* Anything imported or exported is EXTERNAL */
+      alloc_flags |= ANV_BO_ALLOC_EXTERNAL;
+
+      /* We can't have implicit CCS on external memory with an AUX-table.
+       * Doing so would require us to sync the aux tables across processes
+       * which is impractical.
+       */
+      if (device->info.has_aux_map)
+         alloc_flags &= ~ANV_BO_ALLOC_IMPLICIT_CCS;
+   }
+
    /* Check if we need to support Android HW buffer export. If so,
     * create AHardwareBuffer and import memory from it.
     */
@@ -3435,9 +3454,6 @@ VkResult anv_AllocateMemory(
       if (result != VK_SUCCESS)
          goto fail;
 
-      VkDeviceSize aligned_alloc_size =
-         align_u64(pAllocateInfo->allocationSize, 4096);
-
       /* For security purposes, we reject importing the bo if it's smaller
        * than the requested allocation size.  This prevents a malicious client
        * from passing a buffer to a trusted client, lying about the size, and
@@ -3494,9 +3510,6 @@ VkResult anv_AllocateMemory(
 
    /* Regular allocate (not importing memory). */
 
-   if (export_info && export_info->handleTypes)
-      alloc_flags |= ANV_BO_ALLOC_EXTERNAL;
-
    result = anv_device_alloc_bo(device, pAllocateInfo->allocationSize,
                                 alloc_flags, client_address, &mem->bo);
    if (result != VK_SUCCESS)
@@ -3692,7 +3705,11 @@ VkResult anv_MapMemory(
       gem_flags |= I915_MMAP_WC;
 
    /* GEM will fail to map if the offset isn't 4k-aligned.  Round down. */
-   uint64_t map_offset = offset & ~4095ull;
+   uint64_t map_offset;
+   if (!device->physical->has_mmap_offset)
+      map_offset = offset & ~4095ull;
+   else
+      map_offset = 0;
    assert(offset >= map_offset);
    uint64_t map_size = (offset + size) - map_offset;
 
@@ -3716,12 +3733,13 @@ void anv_UnmapMemory(
     VkDevice                                    _device,
     VkDeviceMemory                              _memory)
 {
+   ANV_FROM_HANDLE(anv_device, device, _device);
    ANV_FROM_HANDLE(anv_device_memory, mem, _memory);
 
    if (mem == NULL || mem->host_ptr)
       return;
 
-   anv_gem_munmap(mem->map, mem->map_size);
+   anv_gem_munmap(device, mem->map, mem->map_size);
 
    mem->map = NULL;
    mem->map_size = 0;
@@ -4281,7 +4299,6 @@ VkResult anv_CreateFramebuffer(
       }
       framebuffer->attachment_count = pCreateInfo->attachmentCount;
    } else {
-      assert(device->enabled_extensions.KHR_imageless_framebuffer);
       framebuffer = vk_alloc2(&device->alloc, pAllocator, size, 8,
                               VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
       if (framebuffer == NULL)