{
char str[MAX_DEBUG_MESSAGE_LENGTH];
struct anv_device *device = (struct anv_device *)data;
+ struct anv_instance *instance = device->physical->instance;
- if (list_is_empty(&device->instance->debug_report_callbacks.callbacks))
+ if (list_is_empty(&instance->debug_report_callbacks.callbacks))
return;
va_list args;
(void) vsnprintf(str, MAX_DEBUG_MESSAGE_LENGTH, fmt, args);
va_end(args);
- vk_debug_report(&device->instance->debug_report_callbacks,
+ vk_debug_report(&instance->debug_report_callbacks,
VK_DEBUG_REPORT_DEBUG_BIT_EXT,
VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
0, 0, 0, "anv", str);
*/
_mesa_sha1_init(&sha1_ctx);
_mesa_sha1_update(&sha1_ctx, build_id_data(note), build_id_len);
- _mesa_sha1_update(&sha1_ctx, &device->chipset_id,
- sizeof(device->chipset_id));
+ _mesa_sha1_update(&sha1_ctx, &device->info.chipset_id,
+ sizeof(device->info.chipset_id));
_mesa_sha1_update(&sha1_ctx, &device->always_use_bindless,
sizeof(device->always_use_bindless));
_mesa_sha1_update(&sha1_ctx, &device->has_a64_buffer_access,
* some bits of ISL info to ensure that this is safe.
*/
_mesa_sha1_init(&sha1_ctx);
- _mesa_sha1_update(&sha1_ctx, &device->chipset_id,
- sizeof(device->chipset_id));
+ _mesa_sha1_update(&sha1_ctx, &device->info.chipset_id,
+ sizeof(device->info.chipset_id));
_mesa_sha1_update(&sha1_ctx, &device->isl_dev.has_bit6_swizzling,
sizeof(device->isl_dev.has_bit6_swizzling));
_mesa_sha1_final(&sha1_ctx, sha1);
#ifdef ENABLE_SHADER_CACHE
char renderer[10];
ASSERTED int len = snprintf(renderer, sizeof(renderer), "anv_%04x",
- device->chipset_id);
+ device->info.chipset_id);
assert(len == sizeof(renderer) - 2);
char timestamp[41];
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;
}
static VkResult
-anv_physical_device_init(struct anv_physical_device *device,
- struct anv_instance *instance,
- drmDevicePtr drm_device)
+anv_physical_device_try_create(struct anv_instance *instance,
+ drmDevicePtr drm_device,
+ struct anv_physical_device **device_out)
{
const char *primary_path = drm_device->nodes[DRM_NODE_PRIMARY];
const char *path = drm_device->nodes[DRM_NODE_RENDER];
if (fd < 0)
return vk_error(VK_ERROR_INCOMPATIBLE_DRIVER);
+ struct gen_device_info devinfo;
+ if (!gen_get_device_info_from_fd(fd, &devinfo)) {
+ result = vk_error(VK_ERROR_INCOMPATIBLE_DRIVER);
+ goto fail_fd;
+ }
+
+ const char *device_name = gen_get_device_name(devinfo.chipset_id);
+
+ if (devinfo.is_haswell) {
+ intel_logw("Haswell Vulkan support is incomplete");
+ } else if (devinfo.gen == 7 && !devinfo.is_baytrail) {
+ intel_logw("Ivy Bridge Vulkan support is incomplete");
+ } else if (devinfo.gen == 7 && devinfo.is_baytrail) {
+ intel_logw("Bay Trail Vulkan support is incomplete");
+ } else if (devinfo.gen >= 8 && devinfo.gen <= 11) {
+ /* Gen8-11 fully supported */
+ } else if (devinfo.gen == 12) {
+ intel_logw("Vulkan is not yet fully supported on gen12");
+ } else {
+ result = vk_errorfi(instance, NULL, VK_ERROR_INCOMPATIBLE_DRIVER,
+ "Vulkan not yet supported on %s", device_name);
+ goto fail_fd;
+ }
+
+ struct anv_physical_device *device =
+ vk_alloc(&instance->alloc, sizeof(*device), 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (device == NULL) {
+ result = vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+ goto fail_fd;
+ }
+
device->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
device->instance = instance;
assert(strlen(path) < ARRAY_SIZE(device->path));
snprintf(device->path, ARRAY_SIZE(device->path), "%s", path);
- if (!gen_get_device_info_from_fd(fd, &device->info)) {
- result = vk_error(VK_ERROR_INCOMPATIBLE_DRIVER);
- goto fail;
- }
- device->chipset_id = device->info.chipset_id;
- device->no_hw = device->info.no_hw;
+ device->info = devinfo;
+ device->name = device_name;
+ device->no_hw = device->info.no_hw;
if (getenv("INTEL_NO_HW") != NULL)
device->no_hw = true;
device->pci_info.device = drm_device->businfo.pci->dev;
device->pci_info.function = drm_device->businfo.pci->func;
- device->name = gen_get_device_name(device->chipset_id);
-
- if (device->info.is_haswell) {
- intel_logw("Haswell Vulkan support is incomplete");
- } else if (device->info.gen == 7 && !device->info.is_baytrail) {
- intel_logw("Ivy Bridge Vulkan support is incomplete");
- } else if (device->info.gen == 7 && device->info.is_baytrail) {
- intel_logw("Bay Trail Vulkan support is incomplete");
- } else if (device->info.gen >= 8 && device->info.gen <= 11) {
- /* Gen8-11 fully supported */
- } else if (device->info.gen == 12) {
- intel_logw("Vulkan is not yet fully supported on gen12");
- } else {
- result = vk_errorfi(instance, NULL, VK_ERROR_INCOMPATIBLE_DRIVER,
- "Vulkan not yet supported on %s", device->name);
- goto fail;
- }
-
device->cmd_parser_version = -1;
if (device->info.gen == 7) {
device->cmd_parser_version =
result = vk_errorfi(device->instance, NULL,
VK_ERROR_INITIALIZATION_FAILED,
"failed to get command parser version");
- goto fail;
+ goto fail_alloc;
}
}
result = vk_errorfi(device->instance, NULL,
VK_ERROR_INITIALIZATION_FAILED,
"kernel missing gem wait");
- goto fail;
+ goto fail_alloc;
}
if (!anv_gem_get_param(fd, I915_PARAM_HAS_EXECBUF2)) {
result = vk_errorfi(device->instance, NULL,
VK_ERROR_INITIALIZATION_FAILED,
"kernel missing execbuf2");
- goto fail;
+ goto fail_alloc;
}
if (!device->info.has_llc &&
result = vk_errorfi(device->instance, NULL,
VK_ERROR_INITIALIZATION_FAILED,
"kernel missing wc mmap");
- goto fail;
+ goto fail_alloc;
}
device->has_softpin = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_SOFTPIN);
result = anv_physical_device_init_heaps(device, fd);
if (result != VK_SUCCESS)
- goto fail;
+ goto fail_alloc;
device->use_softpin = device->has_softpin &&
device->supports_48bit_addresses;
*/
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) {
device->compiler = brw_compiler_create(NULL, &device->info);
if (device->compiler == NULL) {
result = vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
- goto fail;
+ goto fail_alloc;
}
device->compiler->shader_debug_log = compiler_debug_log;
device->compiler->shader_perf_log = compiler_perf_log;
result = anv_physical_device_init_uuids(device);
if (result != VK_SUCCESS)
- goto fail;
+ goto fail_compiler;
anv_physical_device_init_disk_cache(device);
device->master_fd = master_fd;
result = anv_init_wsi(device);
- if (result != VK_SUCCESS) {
- ralloc_free(device->compiler);
- anv_physical_device_free_disk_cache(device);
- goto fail;
- }
+ if (result != VK_SUCCESS)
+ goto fail_disk_cache;
device->perf = anv_get_perf(&device->info, fd);
device->local_fd = fd;
+ *device_out = device;
+
return VK_SUCCESS;
-fail:
+fail_disk_cache:
+ anv_physical_device_free_disk_cache(device);
+fail_compiler:
+ ralloc_free(device->compiler);
+fail_alloc:
+ vk_free(&instance->alloc, device);
+fail_fd:
close(fd);
if (master_fd != -1)
close(master_fd);
}
static void
-anv_physical_device_finish(struct anv_physical_device *device)
+anv_physical_device_destroy(struct anv_physical_device *device)
{
anv_finish_wsi(device);
anv_physical_device_free_disk_cache(device);
close(device->local_fd);
if (device->master_fd >= 0)
close(device->master_fd);
+ vk_free(&device->instance->alloc, device);
}
static void *
}
}
- struct anv_physical_device *pdevice = &instance->physicalDevice;
- for (unsigned i = 0; i < ARRAY_SIZE(pdevice->dispatch.entrypoints); i++) {
+ for (unsigned i = 0; i < ARRAY_SIZE(instance->physical_device_dispatch.entrypoints); i++) {
/* Vulkan requires that entrypoints for extensions which have not been
* enabled must not be advertised.
*/
if (!anv_physical_device_entrypoint_is_enabled(i, instance->app_info.api_version,
&instance->enabled_extensions)) {
- pdevice->dispatch.entrypoints[i] = NULL;
+ instance->physical_device_dispatch.entrypoints[i] = NULL;
} else {
- pdevice->dispatch.entrypoints[i] =
+ instance->physical_device_dispatch.entrypoints[i] =
anv_physical_device_dispatch_table.entrypoints[i];
}
}
}
}
- instance->physicalDeviceCount = -1;
+ instance->physical_devices_enumerated = false;
+ list_inithead(&instance->physical_devices);
result = vk_debug_report_instance_init(&instance->debug_report_callbacks);
if (result != VK_SUCCESS) {
if (!instance)
return;
- if (instance->physicalDeviceCount > 0) {
- /* We support at most one physical device. */
- assert(instance->physicalDeviceCount == 1);
- anv_physical_device_finish(&instance->physicalDevice);
- }
+ list_for_each_entry_safe(struct anv_physical_device, pdevice,
+ &instance->physical_devices, link)
+ anv_physical_device_destroy(pdevice);
vk_free(&instance->alloc, (char *)instance->app_info.app_name);
vk_free(&instance->alloc, (char *)instance->app_info.engine_name);
}
static VkResult
-anv_enumerate_devices(struct anv_instance *instance)
+anv_enumerate_physical_devices(struct anv_instance *instance)
{
+ if (instance->physical_devices_enumerated)
+ return VK_SUCCESS;
+
+ instance->physical_devices_enumerated = true;
+
/* TODO: Check for more devices ? */
drmDevicePtr devices[8];
- VkResult result = VK_ERROR_INCOMPATIBLE_DRIVER;
int max_devices;
- instance->physicalDeviceCount = 0;
-
max_devices = drmGetDevices2(0, devices, ARRAY_SIZE(devices));
if (max_devices < 1)
- return VK_ERROR_INCOMPATIBLE_DRIVER;
+ return VK_SUCCESS;
+ VkResult result = VK_SUCCESS;
for (unsigned i = 0; i < (unsigned)max_devices; i++) {
if (devices[i]->available_nodes & 1 << DRM_NODE_RENDER &&
devices[i]->bustype == DRM_BUS_PCI &&
devices[i]->deviceinfo.pci->vendor_id == 0x8086) {
- result = anv_physical_device_init(&instance->physicalDevice,
- instance, devices[i]);
- if (result != VK_ERROR_INCOMPATIBLE_DRIVER)
+ struct anv_physical_device *pdevice;
+ result = anv_physical_device_try_create(instance, devices[i],
+ &pdevice);
+ /* Incompatible DRM device, skip. */
+ if (result == VK_ERROR_INCOMPATIBLE_DRIVER) {
+ result = VK_SUCCESS;
+ continue;
+ }
+
+ /* Error creating the physical device, report the error. */
+ if (result != VK_SUCCESS)
break;
+
+ list_addtail(&pdevice->link, &instance->physical_devices);
}
}
drmFreeDevices(devices, max_devices);
- if (result == VK_SUCCESS)
- instance->physicalDeviceCount = 1;
-
+ /* If we successfully enumerated any devices, call it success */
return result;
}
-static VkResult
-anv_instance_ensure_physical_device(struct anv_instance *instance)
-{
- if (instance->physicalDeviceCount < 0) {
- VkResult result = anv_enumerate_devices(instance);
- if (result != VK_SUCCESS &&
- result != VK_ERROR_INCOMPATIBLE_DRIVER)
- return result;
- }
-
- return VK_SUCCESS;
-}
-
VkResult anv_EnumeratePhysicalDevices(
VkInstance _instance,
uint32_t* pPhysicalDeviceCount,
ANV_FROM_HANDLE(anv_instance, instance, _instance);
VK_OUTARRAY_MAKE(out, pPhysicalDevices, pPhysicalDeviceCount);
- VkResult result = anv_instance_ensure_physical_device(instance);
+ VkResult result = anv_enumerate_physical_devices(instance);
if (result != VK_SUCCESS)
return result;
- if (instance->physicalDeviceCount == 0)
- return VK_SUCCESS;
-
- assert(instance->physicalDeviceCount == 1);
- vk_outarray_append(&out, i) {
- *i = anv_physical_device_to_handle(&instance->physicalDevice);
+ list_for_each_entry(struct anv_physical_device, pdevice,
+ &instance->physical_devices, link) {
+ vk_outarray_append(&out, i) {
+ *i = anv_physical_device_to_handle(pdevice);
+ }
}
return vk_outarray_status(&out);
VK_OUTARRAY_MAKE(out, pPhysicalDeviceGroupProperties,
pPhysicalDeviceGroupCount);
- VkResult result = anv_instance_ensure_physical_device(instance);
+ VkResult result = anv_enumerate_physical_devices(instance);
if (result != VK_SUCCESS)
return result;
- if (instance->physicalDeviceCount == 0)
- return VK_SUCCESS;
-
- assert(instance->physicalDeviceCount == 1);
+ list_for_each_entry(struct anv_physical_device, pdevice,
+ &instance->physical_devices, link) {
+ vk_outarray_append(&out, p) {
+ p->physicalDeviceCount = 1;
+ memset(p->physicalDevices, 0, sizeof(p->physicalDevices));
+ p->physicalDevices[0] = anv_physical_device_to_handle(pdevice);
+ p->subsetAllocation = false;
- vk_outarray_append(&out, p) {
- p->physicalDeviceCount = 1;
- memset(p->physicalDevices, 0, sizeof(p->physicalDevices));
- p->physicalDevices[0] =
- anv_physical_device_to_handle(&instance->physicalDevice);
- p->subsetAllocation = false;
-
- vk_foreach_struct(ext, p->pNext)
- anv_debug_ignored_stype(ext->sType);
+ vk_foreach_struct(ext, p->pNext)
+ anv_debug_ignored_stype(ext->sType);
+ }
}
return vk_outarray_status(&out);
.shaderClipDistance = true,
.shaderCullDistance = true,
.shaderFloat64 = pdevice->info.gen >= 8 &&
- pdevice->info.has_64bit_types,
+ pdevice->info.has_64bit_float,
.shaderInt64 = pdevice->info.gen >= 8 &&
- pdevice->info.has_64bit_types,
+ pdevice->info.has_64bit_int,
.shaderInt16 = pdevice->info.gen >= 8,
.shaderResourceMinLod = pdevice->info.gen >= 9,
.variableMultisampleRate = true,
.apiVersion = anv_physical_device_api_version(pdevice),
.driverVersion = vk_get_driver_version(),
.vendorID = 0x8086,
- .deviceID = pdevice->chipset_id,
+ .deviceID = pdevice->info.chipset_id,
.deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
.limits = limits,
.sparseProperties = {0}, /* Broadwell doesn't do sparse. */
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)
idx = anv_get_physical_device_entrypoint_index(pName);
if (idx >= 0)
- return instance->physicalDevice.dispatch.entrypoints[idx];
+ return instance->physical_device_dispatch.entrypoints[idx];
idx = anv_get_device_entrypoint_index(pName);
if (idx >= 0)
if (idx < 0)
return NULL;
- return instance->physicalDevice.dispatch.entrypoints[idx];
+ return instance->physical_device_dispatch.entrypoints[idx];
}
static void
anv_device_init_dispatch(struct anv_device *device)
{
+ const struct anv_instance *instance = device->physical->instance;
+
const struct anv_device_dispatch_table *genX_table;
switch (device->info.gen) {
case 12:
/* Vulkan requires that entrypoints for extensions which have not been
* enabled must not be advertised.
*/
- if (!anv_device_entrypoint_is_enabled(i, device->instance->app_info.api_version,
- &device->instance->enabled_extensions,
+ if (!anv_device_entrypoint_is_enabled(i, instance->app_info.api_version,
+ &instance->enabled_extensions,
&device->enabled_extensions)) {
device->dispatch.entrypoints[i] = NULL;
} else if (genX_table->entrypoints[i]) {
.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,
}
/* 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;
}
}
}
device->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
- device->instance = physical_device->instance;
device->physical = physical_device;
- device->chipset_id = physical_device->chipset_id;
device->no_hw = physical_device->no_hw;
device->_lost = false;
*/
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);
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;
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(
}
}
+ /* 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.
*/
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
/* 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)
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;
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;
}
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)