X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fintel%2Fvulkan%2Fanv_device.c;h=c72a1006749c1bc98b8ae3085a675adb4de401c3;hb=9c9f63d1c749bfea25d6fcd78ff17ea2c49ec809;hp=639c7456c3fdb8896d8b82bb2d6b4418f211a3ed;hpb=298e054d0cfa7cac9e19bbdb5f64f0109dbcd8dc;p=mesa.git diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index 639c7456c3f..c72a1006749 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -35,7 +35,7 @@ #include "util/debug.h" #include "util/build_id.h" #include "util/mesa-sha1.h" -#include "util/vk_util.h" +#include "vk_util.h" #include "genxml/gen7_pack.h" @@ -97,6 +97,113 @@ anv_compute_heap_size(int fd, uint64_t *heap_size) return VK_SUCCESS; } +static VkResult +anv_physical_device_init_heaps(struct anv_physical_device *device, int fd) +{ + /* The kernel query only tells us whether or not the kernel supports the + * EXEC_OBJECT_SUPPORTS_48B_ADDRESS flag and not whether or not the + * hardware has actual 48bit address support. + */ + device->supports_48bit_addresses = + (device->info.gen >= 8) && anv_gem_supports_48b_addresses(fd); + + uint64_t heap_size; + VkResult result = anv_compute_heap_size(fd, &heap_size); + if (result != VK_SUCCESS) + return result; + + if (heap_size <= 3ull * (1ull << 30)) { + /* In this case, everything fits nicely into the 32-bit address space, + * so there's no need for supporting 48bit addresses on client-allocated + * memory objects. + */ + device->memory.heap_count = 1; + device->memory.heaps[0] = (struct anv_memory_heap) { + .size = heap_size, + .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT, + .supports_48bit_addresses = false, + }; + } else { + /* Not everything will fit nicely into a 32-bit address space. In this + * case we need a 64-bit heap. Advertise a small 32-bit heap and a + * larger 48-bit heap. If we're in this case, then we have a total heap + * size larger than 3GiB which most likely means they have 8 GiB of + * video memory and so carving off 1 GiB for the 32-bit heap should be + * reasonable. + */ + const uint64_t heap_size_32bit = 1ull << 30; + const uint64_t heap_size_48bit = heap_size - heap_size_32bit; + + assert(device->supports_48bit_addresses); + + device->memory.heap_count = 2; + device->memory.heaps[0] = (struct anv_memory_heap) { + .size = heap_size_48bit, + .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT, + .supports_48bit_addresses = true, + }; + device->memory.heaps[1] = (struct anv_memory_heap) { + .size = heap_size_32bit, + .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT, + .supports_48bit_addresses = false, + }; + } + + uint32_t type_count = 0; + for (uint32_t heap = 0; heap < device->memory.heap_count; heap++) { + uint32_t valid_buffer_usage = ~0; + + /* There appears to be a hardware issue in the VF cache where it only + * considers the bottom 32 bits of memory addresses. If you happen to + * have two vertex buffers which get placed exactly 4 GiB apart and use + * them in back-to-back draw calls, you can get collisions. In order to + * solve this problem, we require vertex and index buffers be bound to + * memory allocated out of the 32-bit heap. + */ + if (device->memory.heaps[heap].supports_48bit_addresses) { + valid_buffer_usage &= ~(VK_BUFFER_USAGE_INDEX_BUFFER_BIT | + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); + } + + if (device->info.has_llc) { + /* Big core GPUs share LLC with the CPU and thus one memory type can be + * both cached and coherent at the same time. + */ + device->memory.types[type_count++] = (struct anv_memory_type) { + .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | + VK_MEMORY_PROPERTY_HOST_CACHED_BIT, + .heapIndex = heap, + .valid_buffer_usage = valid_buffer_usage, + }; + } else { + /* The spec requires that we expose a host-visible, coherent memory + * type, but Atom GPUs don't share LLC. Thus we offer two memory types + * to give the application a choice between cached, but not coherent and + * coherent but uncached (WC though). + */ + device->memory.types[type_count++] = (struct anv_memory_type) { + .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + .heapIndex = heap, + .valid_buffer_usage = valid_buffer_usage, + }; + device->memory.types[type_count++] = (struct anv_memory_type) { + .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_CACHED_BIT, + .heapIndex = heap, + .valid_buffer_usage = valid_buffer_usage, + }; + } + } + device->memory.type_count = type_count; + + return VK_SUCCESS; +} + static VkResult anv_physical_device_init_uuids(struct anv_physical_device *device) { @@ -186,7 +293,7 @@ anv_physical_device_init(struct anv_physical_device *device, fprintf(stderr, "WARNING: Ivy Bridge Vulkan support is incomplete\n"); } else if (device->info.gen == 7 && device->info.is_baytrail) { fprintf(stderr, "WARNING: Bay Trail Vulkan support is incomplete\n"); - } else if (device->info.gen >= 8) { + } else if (device->info.gen >= 8 && device->info.gen <= 9) { /* Broadwell, Cherryview, Skylake, Broxton, Kabylake is as fully * supported as anything */ } else { @@ -225,9 +332,7 @@ anv_physical_device_init(struct anv_physical_device *device, goto fail; } - device->supports_48bit_addresses = anv_gem_supports_48b_addresses(fd); - - result = anv_compute_heap_size(fd, &device->heap_size); + result = anv_physical_device_init_heaps(device, fd); if (result != VK_SUCCESS) goto fail; @@ -254,8 +359,9 @@ anv_physical_device_init(struct anv_physical_device *device, if (device->info.is_cherryview && device->subslice_total > 0 && device->eu_total > 0) { - /* Logical CS threads = EUs per subslice * 7 threads per EU */ - uint32_t max_cs_threads = device->eu_total / device->subslice_total * 7; + /* Logical CS threads = EUs per subslice * num threads per EU */ + uint32_t max_cs_threads = + device->eu_total / device->subslice_total * device->info.num_thread_per_eu; /* Fuse configurations may give more threads than expected, never less. */ if (max_cs_threads > device->info.max_cs_threads) @@ -301,10 +407,18 @@ anv_physical_device_finish(struct anv_physical_device *device) } static const VkExtensionProperties global_extensions[] = { + { + .extensionName = VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, + .specVersion = 1, + }, { .extensionName = VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, .specVersion = 1, }, + { + .extensionName = VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, + .specVersion = 1, + }, { .extensionName = VK_KHR_SURFACE_EXTENSION_NAME, .specVersion = 25, @@ -312,7 +426,7 @@ static const VkExtensionProperties global_extensions[] = { #ifdef VK_USE_PLATFORM_WAYLAND_KHR { .extensionName = VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, - .specVersion = 5, + .specVersion = 6, }, #endif #ifdef VK_USE_PLATFORM_XCB_KHR @@ -327,19 +441,27 @@ static const VkExtensionProperties global_extensions[] = { .specVersion = 6, }, #endif +}; + +static const VkExtensionProperties device_extensions[] = { { - .extensionName = VK_KHX_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, + .extensionName = VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, .specVersion = 1, }, { - .extensionName = VK_KHX_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, + .extensionName = VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME, .specVersion = 1, }, -}; - -static const VkExtensionProperties device_extensions[] = { { - .extensionName = VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME, + .extensionName = VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, + .specVersion = 1, + }, + { + .extensionName = VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, + .specVersion = 1, + }, + { + .extensionName = VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, .specVersion = 1, }, { @@ -363,15 +485,15 @@ static const VkExtensionProperties device_extensions[] = { .specVersion = 1, }, { - .extensionName = VK_KHR_SWAPCHAIN_EXTENSION_NAME, - .specVersion = 68, + .extensionName = VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME, + .specVersion = 1, }, { - .extensionName = VK_KHX_EXTERNAL_MEMORY_EXTENSION_NAME, - .specVersion = 1, + .extensionName = VK_KHR_SWAPCHAIN_EXTENSION_NAME, + .specVersion = 68, }, { - .extensionName = VK_KHX_EXTERNAL_MEMORY_FD_EXTENSION_NAME, + .extensionName = VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME, .specVersion = 1, }, { @@ -502,7 +624,7 @@ anv_enumerate_devices(struct anv_instance *instance) instance->physicalDeviceCount = 0; - max_devices = drmGetDevices2(0, devices, sizeof(devices)); + max_devices = drmGetDevices2(0, devices, ARRAY_SIZE(devices)); if (max_devices < 1) return VK_ERROR_INCOMPATIBLE_DRIVER; @@ -518,6 +640,7 @@ anv_enumerate_devices(struct anv_instance *instance) break; } } + drmFreeDevices(devices, max_devices); if (result == VK_SUCCESS) instance->physicalDeviceCount = 1; @@ -629,6 +752,13 @@ void anv_GetPhysicalDeviceFeatures2KHR( break; } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR: { + VkPhysicalDeviceVariablePointerFeaturesKHR *features = (void *)ext; + features->variablePointersStorageBuffer = true; + features->variablePointers = false; + break; + } + default: anv_debug_ignored_stype(ext->sType); break; @@ -647,6 +777,9 @@ void anv_GetPhysicalDeviceProperties( const uint32_t max_raw_buffer_sz = devinfo->gen >= 7 ? (1ul << 30) : (1ul << 27); + const uint32_t max_samplers = (devinfo->gen >= 8 || devinfo->is_haswell) ? + 128 : 16; + VkSampleCountFlags sample_counts = isl_device_get_sample_counts(&pdevice->isl_dev); @@ -665,13 +798,13 @@ void anv_GetPhysicalDeviceProperties( .bufferImageGranularity = 64, /* A cache line */ .sparseAddressSpaceSize = 0, .maxBoundDescriptorSets = MAX_SETS, - .maxPerStageDescriptorSamplers = 64, + .maxPerStageDescriptorSamplers = max_samplers, .maxPerStageDescriptorUniformBuffers = 64, .maxPerStageDescriptorStorageBuffers = 64, - .maxPerStageDescriptorSampledImages = 64, + .maxPerStageDescriptorSampledImages = max_samplers, .maxPerStageDescriptorStorageImages = 64, .maxPerStageDescriptorInputAttachments = 64, - .maxPerStageResources = 128, + .maxPerStageResources = 250, .maxDescriptorSetSamplers = 256, .maxDescriptorSetUniformBuffers = 256, .maxDescriptorSetUniformBuffersDynamic = MAX_DYNAMIC_BUFFERS / 2, @@ -747,7 +880,7 @@ void anv_GetPhysicalDeviceProperties( .storageImageSampleCounts = VK_SAMPLE_COUNT_1_BIT, .maxSampleMaskWords = 1, .timestampComputeAndGraphics = false, - .timestampPeriod = devinfo->timebase_scale, + .timestampPeriod = 1000000000.0 / devinfo->timestamp_frequency, .maxClipDistances = 8, .maxCullDistances = 8, .maxCombinedClipAndCullDistances = 8, @@ -764,8 +897,8 @@ void anv_GetPhysicalDeviceProperties( }; *pProperties = (VkPhysicalDeviceProperties) { - .apiVersion = VK_MAKE_VERSION(1, 0, 42), - .driverVersion = 1, + .apiVersion = VK_MAKE_VERSION(1, 0, 54), + .driverVersion = vk_get_driver_version(), .vendorID = 0x8086, .deviceID = pdevice->chipset_id, .deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, @@ -773,7 +906,8 @@ void anv_GetPhysicalDeviceProperties( .sparseProperties = {0}, /* Broadwell doesn't do sparse. */ }; - strcpy(pProperties->deviceName, pdevice->name); + snprintf(pProperties->deviceName, sizeof(pProperties->deviceName), + "%s", pdevice->name); memcpy(pProperties->pipelineCacheUUID, pdevice->pipeline_cache_uuid, VK_UUID_SIZE); } @@ -796,9 +930,9 @@ void anv_GetPhysicalDeviceProperties2KHR( break; } - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHX: { - VkPhysicalDeviceIDPropertiesKHX *id_props = - (VkPhysicalDeviceIDPropertiesKHX *)ext; + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR: { + VkPhysicalDeviceIDPropertiesKHR *id_props = + (VkPhysicalDeviceIDPropertiesKHR *)ext; memcpy(id_props->deviceUUID, pdevice->device_uuid, VK_UUID_SIZE); memcpy(id_props->driverUUID, pdevice->driver_uuid, VK_UUID_SIZE); /* The LUID is for Windows. */ @@ -867,44 +1001,21 @@ void anv_GetPhysicalDeviceMemoryProperties( { ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice); - if (physical_device->info.has_llc) { - /* Big core GPUs share LLC with the CPU and thus one memory type can be - * both cached and coherent at the same time. - */ - pMemoryProperties->memoryTypeCount = 1; - pMemoryProperties->memoryTypes[0] = (VkMemoryType) { - .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | - VK_MEMORY_PROPERTY_HOST_CACHED_BIT, - .heapIndex = 0, - }; - } else { - /* The spec requires that we expose a host-visible, coherent memory - * type, but Atom GPUs don't share LLC. Thus we offer two memory types - * to give the application a choice between cached, but not coherent and - * coherent but uncached (WC though). - */ - pMemoryProperties->memoryTypeCount = 2; - pMemoryProperties->memoryTypes[0] = (VkMemoryType) { - .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - .heapIndex = 0, - }; - pMemoryProperties->memoryTypes[1] = (VkMemoryType) { - .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | - VK_MEMORY_PROPERTY_HOST_CACHED_BIT, - .heapIndex = 0, + pMemoryProperties->memoryTypeCount = physical_device->memory.type_count; + for (uint32_t i = 0; i < physical_device->memory.type_count; i++) { + pMemoryProperties->memoryTypes[i] = (VkMemoryType) { + .propertyFlags = physical_device->memory.types[i].propertyFlags, + .heapIndex = physical_device->memory.types[i].heapIndex, }; } - pMemoryProperties->memoryHeapCount = 1; - pMemoryProperties->memoryHeaps[0] = (VkMemoryHeap) { - .size = physical_device->heap_size, - .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT, - }; + pMemoryProperties->memoryHeapCount = physical_device->memory.heap_count; + for (uint32_t i = 0; i < physical_device->memory.heap_count; i++) { + pMemoryProperties->memoryHeaps[i] = (VkMemoryHeap) { + .size = physical_device->memory.heaps[i].size, + .flags = physical_device->memory.heaps[i].flags, + }; + } } void anv_GetPhysicalDeviceMemoryProperties2KHR( @@ -975,7 +1086,7 @@ anv_state_pool_emit_data(struct anv_state_pool *pool, size_t size, size_t align, state = anv_state_pool_alloc(pool, size, align); memcpy(state.map, p, size); - anv_state_flush(pool->block_pool->device, state); + anv_state_flush(pool->block_pool.device, state); return state; } @@ -1031,6 +1142,19 @@ VkResult anv_CreateDevice( return vk_error(VK_ERROR_EXTENSION_NOT_PRESENT); } + /* Check enabled features */ + 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); + } + } + device = vk_alloc2(&physical_device->instance->alloc, pAllocator, sizeof(*device), 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); @@ -1101,30 +1225,18 @@ VkResult anv_CreateDevice( if (result != VK_SUCCESS) goto fail_batch_bo_pool; - result = anv_block_pool_init(&device->dynamic_state_block_pool, device, - 16384); + result = anv_state_pool_init(&device->dynamic_state_pool, device, 16384); if (result != VK_SUCCESS) goto fail_bo_cache; - anv_state_pool_init(&device->dynamic_state_pool, - &device->dynamic_state_block_pool); - - result = anv_block_pool_init(&device->instruction_block_pool, device, - 1024 * 1024); + result = anv_state_pool_init(&device->instruction_state_pool, device, 16384); if (result != VK_SUCCESS) goto fail_dynamic_state_pool; - anv_state_pool_init(&device->instruction_state_pool, - &device->instruction_block_pool); - - result = anv_block_pool_init(&device->surface_state_block_pool, device, - 4096); + result = anv_state_pool_init(&device->surface_state_pool, device, 4096); if (result != VK_SUCCESS) goto fail_instruction_state_pool; - anv_state_pool_init(&device->surface_state_pool, - &device->surface_state_block_pool); - result = anv_bo_init_new(&device->workaround_bo, device, 1024); if (result != VK_SUCCESS) goto fail_surface_state_pool; @@ -1146,6 +1258,9 @@ VkResult anv_CreateDevice( case 9: result = gen9_init_device_state(device); break; + case 10: + result = gen10_init_device_state(device); + break; default: /* Shouldn't get here as we don't create physical devices for any other * gens. */ @@ -1169,13 +1284,10 @@ VkResult anv_CreateDevice( anv_gem_close(device, device->workaround_bo.gem_handle); fail_surface_state_pool: anv_state_pool_finish(&device->surface_state_pool); - anv_block_pool_finish(&device->surface_state_block_pool); fail_instruction_state_pool: anv_state_pool_finish(&device->instruction_state_pool); - anv_block_pool_finish(&device->instruction_block_pool); fail_dynamic_state_pool: anv_state_pool_finish(&device->dynamic_state_pool); - anv_block_pool_finish(&device->dynamic_state_block_pool); fail_bo_cache: anv_bo_cache_finish(&device->bo_cache); fail_batch_bo_pool: @@ -1219,11 +1331,8 @@ void anv_DestroyDevice( anv_gem_close(device, device->workaround_bo.gem_handle); anv_state_pool_finish(&device->surface_state_pool); - anv_block_pool_finish(&device->surface_state_block_pool); anv_state_pool_finish(&device->instruction_state_pool); - anv_block_pool_finish(&device->instruction_block_pool); anv_state_pool_finish(&device->dynamic_state_pool); - anv_block_pool_finish(&device->dynamic_state_block_pool); anv_bo_cache_finish(&device->bo_cache); @@ -1423,12 +1532,6 @@ anv_bo_init_new(struct anv_bo *bo, struct anv_device *device, uint64_t size) anv_bo_init(bo, gem_handle, size); - if (device->instance->physicalDevice.supports_48bit_addresses) - bo->flags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS; - - if (device->instance->physicalDevice.has_exec_async) - bo->flags |= EXEC_OBJECT_ASYNC; - return VK_SUCCESS; } @@ -1439,6 +1542,7 @@ VkResult anv_AllocateMemory( VkDeviceMemory* pMem) { ANV_FROM_HANDLE(anv_device, device, _device); + struct anv_physical_device *pdevice = &device->instance->physicalDevice; struct anv_device_memory *mem; VkResult result = VK_SUCCESS; @@ -1447,10 +1551,6 @@ VkResult anv_AllocateMemory( /* The Vulkan 1.0.33 spec says "allocationSize must be greater than 0". */ assert(pAllocateInfo->allocationSize > 0); - /* We support exactly one memory heap. */ - assert(pAllocateInfo->memoryTypeIndex == 0 || - (!device->info.has_llc && pAllocateInfo->memoryTypeIndex < 2)); - /* The kernel relocation API has a limitation of a 32-bit delta value * applied to the address before it is written which, in spite of it being * unsigned, is treated as signed . Because of the way that this maps to @@ -1478,12 +1578,13 @@ VkResult anv_AllocateMemory( if (mem == NULL) return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); - mem->type_index = pAllocateInfo->memoryTypeIndex; + assert(pAllocateInfo->memoryTypeIndex < pdevice->memory.type_count); + mem->type = &pdevice->memory.types[pAllocateInfo->memoryTypeIndex]; mem->map = NULL; mem->map_size = 0; - const VkImportMemoryFdInfoKHX *fd_info = - vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_FD_INFO_KHX); + const VkImportMemoryFdInfoKHR *fd_info = + vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_FD_INFO_KHR); /* The Vulkan spec permits handleType to be 0, in which case the struct is * ignored. @@ -1493,7 +1594,7 @@ VkResult anv_AllocateMemory( * just a GEM buffer. */ assert(fd_info->handleType == - VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX); + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR); result = anv_bo_cache_import(device, &device->bo_cache, fd_info->fd, pAllocateInfo->allocationSize, @@ -1508,6 +1609,13 @@ VkResult anv_AllocateMemory( goto fail; } + assert(mem->type->heapIndex < pdevice->memory.heap_count); + if (pdevice->memory.heaps[mem->type->heapIndex].supports_48bit_addresses) + mem->bo->flags |= EXEC_OBJECT_SUPPORTS_48B_ADDRESS; + + if (pdevice->has_exec_async) + mem->bo->flags |= EXEC_OBJECT_ASYNC; + *pMem = anv_device_memory_to_handle(mem); return VK_SUCCESS; @@ -1518,26 +1626,28 @@ VkResult anv_AllocateMemory( return result; } -VkResult anv_GetMemoryFdKHX( +VkResult anv_GetMemoryFdKHR( VkDevice device_h, - VkDeviceMemory memory_h, - VkExternalMemoryHandleTypeFlagBitsKHX handleType, + const VkMemoryGetFdInfoKHR* pGetFdInfo, int* pFd) { ANV_FROM_HANDLE(anv_device, dev, device_h); - ANV_FROM_HANDLE(anv_device_memory, mem, memory_h); + ANV_FROM_HANDLE(anv_device_memory, mem, pGetFdInfo->memory); + + assert(pGetFdInfo->sType == VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR); /* We support only one handle type. */ - assert(handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX); + assert(pGetFdInfo->handleType == + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR); return anv_bo_cache_export(dev, &dev->bo_cache, mem->bo, pFd); } -VkResult anv_GetMemoryFdPropertiesKHX( +VkResult anv_GetMemoryFdPropertiesKHR( VkDevice device_h, - VkExternalMemoryHandleTypeFlagBitsKHX handleType, + VkExternalMemoryHandleTypeFlagBitsKHR handleType, int fd, - VkMemoryFdPropertiesKHX* pMemoryFdProperties) + VkMemoryFdPropertiesKHR* pMemoryFdProperties) { /* The valid usage section for this function says: * @@ -1545,7 +1655,7 @@ VkResult anv_GetMemoryFdPropertiesKHX( * * Since we only handle opaque handles for now, there are no FD properties. */ - return VK_ERROR_INVALID_EXTERNAL_HANDLE_KHX; + return VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR; } void anv_FreeMemory( @@ -1603,7 +1713,9 @@ VkResult anv_MapMemory( * userspace. */ uint32_t gem_flags = 0; - if (!device->info.has_llc && mem->type_index == 0) + + if (!device->info.has_llc && + (mem->type->propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) gem_flags |= I915_MMAP_WC; /* GEM will fail to map if the offset isn't 4k-aligned. Round down. */ @@ -1652,7 +1764,7 @@ clflush_mapped_ranges(struct anv_device *device, if (ranges[i].offset >= mem->map_size) continue; - anv_clflush_range(mem->map + ranges[i].offset, + gen_clflush_range(mem->map + ranges[i].offset, MIN2(ranges[i].size, mem->map_size - ranges[i].offset)); } } @@ -1700,6 +1812,7 @@ void anv_GetBufferMemoryRequirements( { ANV_FROM_HANDLE(anv_buffer, buffer, _buffer); ANV_FROM_HANDLE(anv_device, device, _device); + struct anv_physical_device *pdevice = &device->instance->physicalDevice; /* The Vulkan spec (git aaed022) says: * @@ -1707,13 +1820,41 @@ void anv_GetBufferMemoryRequirements( * supported memory type for the resource. The bit `1<memoryTypeBits = device->info.has_llc ? 1 : 3; + uint32_t memory_types = 0; + for (uint32_t i = 0; i < pdevice->memory.type_count; i++) { + uint32_t valid_usage = pdevice->memory.types[i].valid_buffer_usage; + if ((valid_usage & buffer->usage) == buffer->usage) + memory_types |= (1u << i); + } pMemoryRequirements->size = buffer->size; pMemoryRequirements->alignment = 16; + pMemoryRequirements->memoryTypeBits = memory_types; +} + +void anv_GetBufferMemoryRequirements2KHR( + VkDevice _device, + const VkBufferMemoryRequirementsInfo2KHR* pInfo, + VkMemoryRequirements2KHR* pMemoryRequirements) +{ + anv_GetBufferMemoryRequirements(_device, pInfo->buffer, + &pMemoryRequirements->memoryRequirements); + + vk_foreach_struct(ext, pMemoryRequirements->pNext) { + switch (ext->sType) { + case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR: { + VkMemoryDedicatedRequirementsKHR *requirements = (void *)ext; + requirements->prefersDedicatedAllocation = VK_FALSE; + requirements->requiresDedicatedAllocation = VK_FALSE; + break; + } + + default: + anv_debug_ignored_stype(ext->sType); + break; + } + } } void anv_GetImageMemoryRequirements( @@ -1723,6 +1864,7 @@ void anv_GetImageMemoryRequirements( { ANV_FROM_HANDLE(anv_image, image, _image); ANV_FROM_HANDLE(anv_device, device, _device); + struct anv_physical_device *pdevice = &device->instance->physicalDevice; /* The Vulkan spec (git aaed022) says: * @@ -1731,12 +1873,37 @@ void anv_GetImageMemoryRequirements( * only if the memory type `i` in the VkPhysicalDeviceMemoryProperties * structure for the physical device is supported. * - * We support exactly one memory type on LLC, two on non-LLC. + * All types are currently supported for images. */ - pMemoryRequirements->memoryTypeBits = device->info.has_llc ? 1 : 3; + uint32_t memory_types = (1ull << pdevice->memory.type_count) - 1; pMemoryRequirements->size = image->size; pMemoryRequirements->alignment = image->alignment; + pMemoryRequirements->memoryTypeBits = memory_types; +} + +void anv_GetImageMemoryRequirements2KHR( + VkDevice _device, + const VkImageMemoryRequirementsInfo2KHR* pInfo, + VkMemoryRequirements2KHR* pMemoryRequirements) +{ + anv_GetImageMemoryRequirements(_device, pInfo->image, + &pMemoryRequirements->memoryRequirements); + + vk_foreach_struct(ext, pMemoryRequirements->pNext) { + switch (ext->sType) { + case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR: { + VkMemoryDedicatedRequirementsKHR *requirements = (void *)ext; + requirements->prefersDedicatedAllocation = VK_FALSE; + requirements->requiresDedicatedAllocation = VK_FALSE; + break; + } + + default: + anv_debug_ignored_stype(ext->sType); + break; + } + } } void anv_GetImageSparseMemoryRequirements( @@ -1748,6 +1915,15 @@ void anv_GetImageSparseMemoryRequirements( *pSparseMemoryRequirementCount = 0; } +void anv_GetImageSparseMemoryRequirements2KHR( + VkDevice device, + const VkImageSparseMemoryRequirementsInfo2KHR* pInfo, + uint32_t* pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements2KHR* pSparseMemoryRequirements) +{ + *pSparseMemoryRequirementCount = 0; +} + void anv_GetDeviceMemoryCommitment( VkDevice device, VkDeviceMemory memory, @@ -1766,6 +1942,7 @@ VkResult anv_BindBufferMemory( ANV_FROM_HANDLE(anv_buffer, buffer, _buffer); if (mem) { + assert((buffer->usage & mem->type->valid_buffer_usage) == buffer->usage); buffer->bo = mem->bo; buffer->offset = memoryOffset; } else {