+ if (alloc_flags & ANV_BO_ALLOC_SNOOPED) {
+ assert(alloc_flags & ANV_BO_ALLOC_MAPPED);
+ /* We don't want to change these defaults if it's going to be shared
+ * with another process.
+ */
+ assert(!(alloc_flags & ANV_BO_ALLOC_EXTERNAL));
+
+ /* Regular objects are created I915_CACHING_CACHED on LLC platforms and
+ * I915_CACHING_NONE on non-LLC platforms. For many internal state
+ * objects, we'd rather take the snooping overhead than risk forgetting
+ * a CLFLUSH somewhere. Userptr objects are always created as
+ * I915_CACHING_CACHED, which on non-LLC means snooped so there's no
+ * need to do this there.
+ */
+ if (!device->info.has_llc) {
+ anv_gem_set_caching(device, new_bo.gem_handle,
+ I915_CACHING_CACHED);
+ }
+ }
+
+ if (alloc_flags & ANV_BO_ALLOC_FIXED_ADDRESS) {
+ new_bo.has_fixed_address = true;
+ new_bo.offset = explicit_address;
+ } else if (new_bo.flags & EXEC_OBJECT_PINNED) {
+ new_bo.offset = anv_vma_alloc(device, new_bo.size + new_bo._ccs_size,
+ align, alloc_flags, explicit_address);
+ if (new_bo.offset == 0) {
+ if (new_bo.map)
+ anv_gem_munmap(device, new_bo.map, size);
+ anv_gem_close(device, new_bo.gem_handle);
+ return vk_errorf(device, NULL, VK_ERROR_OUT_OF_DEVICE_MEMORY,
+ "failed to allocate virtual address for BO");
+ }
+ } else {
+ assert(!new_bo.has_client_visible_address);
+ }
+
+ if (new_bo._ccs_size > 0) {
+ assert(device->info.has_aux_map);
+ gen_aux_map_add_mapping(device->aux_map_ctx,
+ gen_canonical_address(new_bo.offset),
+ gen_canonical_address(new_bo.offset + new_bo.size),
+ new_bo.size, 0 /* format_bits */);
+ }
+
+ assert(new_bo.gem_handle);
+
+ /* If we just got this gem_handle from anv_bo_init_new then we know no one
+ * else is touching this BO at the moment so we don't need to lock here.
+ */
+ struct anv_bo *bo = anv_device_lookup_bo(device, new_bo.gem_handle);
+ *bo = new_bo;
+
+ *bo_out = bo;
+
+ return VK_SUCCESS;
+}
+
+VkResult
+anv_device_import_bo_from_host_ptr(struct anv_device *device,
+ void *host_ptr, uint32_t size,
+ enum anv_bo_alloc_flags alloc_flags,
+ uint64_t client_address,
+ struct anv_bo **bo_out)
+{
+ assert(!(alloc_flags & (ANV_BO_ALLOC_MAPPED |
+ ANV_BO_ALLOC_SNOOPED |
+ ANV_BO_ALLOC_FIXED_ADDRESS)));
+
+ /* We can't do implicit CCS with an aux table on shared memory */
+ if (!device->physical->has_implicit_ccs || device->info.has_aux_map)
+ assert(!(alloc_flags & ANV_BO_ALLOC_IMPLICIT_CCS));
+
+ struct anv_bo_cache *cache = &device->bo_cache;
+ const uint32_t bo_flags =
+ anv_bo_alloc_flags_to_bo_flags(device, alloc_flags);
+ assert(bo_flags == (bo_flags & ANV_BO_CACHE_SUPPORTED_FLAGS));
+
+ uint32_t gem_handle = anv_gem_userptr(device, host_ptr, size);
+ if (!gem_handle)
+ return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE);