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;
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) {
break;
}
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT: {
+ VkPhysicalDeviceRobustness2FeaturesEXT *features = (void *)ext;
+ features->robustBufferAccess2 = true;
+ features->robustImageAccess2 = true;
+ features->nullDescriptor = true;
+ break;
+ }
+
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES: {
VkPhysicalDeviceSamplerYcbcrConversionFeatures *features =
(VkPhysicalDeviceSamplerYcbcrConversionFeatures *) ext;
pdevice->has_bindless_images && pdevice->has_a64_buffer_access
? UINT32_MAX : MAX_BINDING_TABLE_SIZE - MAX_RTS - 1;
- const uint32_t max_workgroup_size = 32 * devinfo->max_cs_threads;
+ /* Limit max_threads to 64 for the GPGPU_WALKER command */
+ const uint32_t max_workgroup_size = 32 * MIN2(64, devinfo->max_cs_threads);
VkSampleCountFlags sample_counts =
isl_device_get_sample_counts(&pdevice->isl_dev);
break;
}
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT: {
+ VkPhysicalDeviceRobustness2PropertiesEXT *properties = (void *)ext;
+ properties->robustStorageBufferAccessSizeAlignment =
+ ANV_SSBO_BOUNDS_CHECK_ALIGNMENT;
+ properties->robustUniformBufferAccessSizeAlignment =
+ ANV_UBO_BOUNDS_CHECK_ALIGNMENT;
+ break;
+ }
+
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT: {
VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT *properties =
(VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT *)ext;
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)
.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;
}
}
if (!device)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+ vk_device_init(&device->vk, pCreateInfo,
+ &physical_device->instance->alloc, pAllocator);
+
if (INTEL_DEBUG & DEBUG_BATCH) {
const unsigned decode_flags =
GEN_BATCH_DECODE_FULL |
decode_get_bo, NULL, device);
}
- device->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
device->physical = physical_device;
device->no_hw = physical_device->no_hw;
device->_lost = false;
- if (pAllocator)
- device->alloc = *pAllocator;
- else
- device->alloc = physical_device->instance->alloc;
-
/* XXX(chadv): Can we dup() physicalDevice->fd here? */
device->fd = open(physical_device->path, O_RDWR | O_CLOEXEC);
if (device->fd == -1) {
*/
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);
if (result != VK_SUCCESS)
goto fail_workaround_bo;
+ /* Allocate a null surface state at surface state offset 0. This makes
+ * NULL descriptor handling trivial because we can just memset structures
+ * to zero and they have a valid descriptor.
+ */
+ device->null_surface_state =
+ anv_state_pool_alloc(&device->surface_state_pool,
+ device->isl_dev.ss.size,
+ device->isl_dev.ss.align);
+ isl_null_fill_state(&device->isl_dev, device->null_surface_state.map,
+ isl_extent3d(1, 1, 1) /* This shouldn't matter */);
+ assert(device->null_surface_state.offset == 0);
+
if (device->info.gen >= 10) {
result = anv_device_init_hiz_clear_value_bo(device);
if (result != VK_SUCCESS)
fail_fd:
close(device->fd);
fail_device:
- vk_free(&device->alloc, device);
+ vk_free(&device->vk.alloc, device);
return result;
}
close(device->fd);
- vk_free(&device->alloc, device);
+ vk_device_finish(&device->vk);
+ vk_free(&device->vk.alloc, device);
}
VkResult anv_EnumerateInstanceLayerProperties(
if (mem_heap_used + aligned_alloc_size > mem_heap->size)
return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
- mem = vk_alloc2(&device->alloc, pAllocator, sizeof(*mem), 8,
+ mem = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*mem), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (mem == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
return VK_SUCCESS;
fail:
- vk_free2(&device->alloc, pAllocator, mem);
+ vk_free2(&device->vk.alloc, pAllocator, mem);
return result;
}
AHardwareBuffer_release(mem->ahw);
#endif
- vk_free2(&device->alloc, pAllocator, mem);
+ vk_free2(&device->vk.alloc, pAllocator, mem);
}
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;
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;
*/
uint32_t memory_types = (1ull << device->physical->memory.type_count) - 1;
- /* We must have image allocated or imported at this point. According to the
- * specification, external images must have been bound to memory before
- * calling GetImageMemoryRequirements.
- */
- assert(image->size > 0);
-
pMemoryRequirements->size = image->size;
pMemoryRequirements->alignment = image->alignment;
pMemoryRequirements->memoryTypeBits = memory_types;
pMemoryRequirements->memoryRequirements.memoryTypeBits =
(1ull << device->physical->memory.type_count) - 1;
- /* We must have image allocated or imported at this point. According to the
- * specification, external images must have been bound to memory before
- * calling GetImageMemoryRequirements.
- */
- assert(image->planes[plane].size > 0);
-
pMemoryRequirements->memoryRequirements.size = image->planes[plane].size;
pMemoryRequirements->memoryRequirements.alignment =
image->planes[plane].alignment;
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
- buffer = vk_alloc2(&device->alloc, pAllocator, sizeof(*buffer), 8,
+ buffer = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*buffer), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (buffer == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
if (!buffer)
return;
- vk_free2(&device->alloc, pAllocator, buffer);
+ vk_free2(&device->vk.alloc, pAllocator, buffer);
}
VkDeviceAddress anv_GetBufferDeviceAddress(
sampler->bindless_state);
}
- vk_free2(&device->alloc, pAllocator, sampler);
+ vk_free2(&device->vk.alloc, pAllocator, sampler);
}
VkResult anv_CreateFramebuffer(
*/
if (!(pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR)) {
size += sizeof(struct anv_image_view *) * pCreateInfo->attachmentCount;
- framebuffer = vk_alloc2(&device->alloc, pAllocator, size, 8,
+ framebuffer = vk_alloc2(&device->vk.alloc, pAllocator, size, 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (framebuffer == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
}
framebuffer->attachment_count = pCreateInfo->attachmentCount;
} else {
- assert(device->enabled_extensions.KHR_imageless_framebuffer);
- framebuffer = vk_alloc2(&device->alloc, pAllocator, size, 8,
+ framebuffer = vk_alloc2(&device->vk.alloc, pAllocator, size, 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (framebuffer == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
if (!fb)
return;
- vk_free2(&device->alloc, pAllocator, fb);
+ vk_free2(&device->vk.alloc, pAllocator, fb);
}
static const VkTimeDomainEXT anv_time_domains[] = {