Path: blob/21.2-virgl/src/intel/vulkan/anv_device.c
4547 views
/*1* Copyright © 2015 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include <assert.h>24#include <stdbool.h>25#include <string.h>26#ifdef MAJOR_IN_MKDEV27#include <sys/mkdev.h>28#endif29#ifdef MAJOR_IN_SYSMACROS30#include <sys/sysmacros.h>31#endif32#include <sys/mman.h>33#include <sys/stat.h>34#include <unistd.h>35#include <fcntl.h>36#include "drm-uapi/drm_fourcc.h"37#include "drm-uapi/drm.h"38#include <xf86drm.h>3940#include "anv_private.h"41#include "anv_measure.h"42#include "util/debug.h"43#include "util/build_id.h"44#include "util/disk_cache.h"45#include "util/mesa-sha1.h"46#include "util/os_file.h"47#include "util/os_misc.h"48#include "util/u_atomic.h"49#include "util/u_string.h"50#include "util/driconf.h"51#include "git_sha1.h"52#include "vk_util.h"53#include "vk_deferred_operation.h"54#include "common/intel_aux_map.h"55#include "common/intel_defines.h"56#include "common/intel_uuid.h"57#include "perf/intel_perf.h"5859#include "genxml/gen7_pack.h"6061static const driOptionDescription anv_dri_options[] = {62DRI_CONF_SECTION_PERFORMANCE63DRI_CONF_VK_X11_OVERRIDE_MIN_IMAGE_COUNT(0)64DRI_CONF_VK_X11_STRICT_IMAGE_COUNT(false)65DRI_CONF_SECTION_END6667DRI_CONF_SECTION_DEBUG68DRI_CONF_ALWAYS_FLUSH_CACHE(false)69DRI_CONF_VK_WSI_FORCE_BGRA8_UNORM_FIRST(false)70DRI_CONF_SECTION_END71};7273/* This is probably far to big but it reflects the max size used for messages74* in OpenGLs KHR_debug.75*/76#define MAX_DEBUG_MESSAGE_LENGTH 40967778/* Render engine timestamp register */79#define TIMESTAMP 0x23588081/* The "RAW" clocks on Linux are called "FAST" on FreeBSD */82#if !defined(CLOCK_MONOTONIC_RAW) && defined(CLOCK_MONOTONIC_FAST)83#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC_FAST84#endif8586static void87compiler_debug_log(void *data, const char *fmt, ...)88{89char str[MAX_DEBUG_MESSAGE_LENGTH];90struct anv_device *device = (struct anv_device *)data;91struct anv_instance *instance = device->physical->instance;9293if (list_is_empty(&instance->vk.debug_report.callbacks))94return;9596va_list args;97va_start(args, fmt);98(void) vsnprintf(str, MAX_DEBUG_MESSAGE_LENGTH, fmt, args);99va_end(args);100101vk_debug_report(&instance->vk,102VK_DEBUG_REPORT_DEBUG_BIT_EXT,103NULL, 0, 0, "anv", str);104}105106static void107compiler_perf_log(void *data, const char *fmt, ...)108{109va_list args;110va_start(args, fmt);111112if (INTEL_DEBUG & DEBUG_PERF)113mesa_logd_v(fmt, args);114115va_end(args);116}117118static uint64_t119anv_compute_heap_size(int fd, uint64_t gtt_size)120{121/* Query the total ram from the system */122uint64_t total_ram;123if (!os_get_total_physical_memory(&total_ram))124return 0;125126/* We don't want to burn too much ram with the GPU. If the user has 4GiB127* or less, we use at most half. If they have more than 4GiB, we use 3/4.128*/129uint64_t available_ram;130if (total_ram <= 4ull * 1024ull * 1024ull * 1024ull)131available_ram = total_ram / 2;132else133available_ram = total_ram * 3 / 4;134135/* We also want to leave some padding for things we allocate in the driver,136* so don't go over 3/4 of the GTT either.137*/138uint64_t available_gtt = gtt_size * 3 / 4;139140return MIN2(available_ram, available_gtt);141}142143#if defined(VK_USE_PLATFORM_WAYLAND_KHR) || \144defined(VK_USE_PLATFORM_XCB_KHR) || \145defined(VK_USE_PLATFORM_XLIB_KHR) || \146defined(VK_USE_PLATFORM_DISPLAY_KHR)147#define ANV_USE_WSI_PLATFORM148#endif149150#ifdef ANDROID151#define ANV_API_VERSION VK_MAKE_VERSION(1, 1, VK_HEADER_VERSION)152#else153#define ANV_API_VERSION VK_MAKE_VERSION(1, 2, VK_HEADER_VERSION)154#endif155156VkResult anv_EnumerateInstanceVersion(157uint32_t* pApiVersion)158{159*pApiVersion = ANV_API_VERSION;160return VK_SUCCESS;161}162163static const struct vk_instance_extension_table instance_extensions = {164.KHR_device_group_creation = true,165.KHR_external_fence_capabilities = true,166.KHR_external_memory_capabilities = true,167.KHR_external_semaphore_capabilities = true,168.KHR_get_physical_device_properties2 = true,169.EXT_debug_report = true,170171#ifdef ANV_USE_WSI_PLATFORM172.KHR_get_surface_capabilities2 = true,173.KHR_surface = true,174.KHR_surface_protected_capabilities = true,175#endif176#ifdef VK_USE_PLATFORM_WAYLAND_KHR177.KHR_wayland_surface = true,178#endif179#ifdef VK_USE_PLATFORM_XCB_KHR180.KHR_xcb_surface = true,181#endif182#ifdef VK_USE_PLATFORM_XLIB_KHR183.KHR_xlib_surface = true,184#endif185#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT186.EXT_acquire_xlib_display = true,187#endif188#ifdef VK_USE_PLATFORM_DISPLAY_KHR189.KHR_display = true,190.KHR_get_display_properties2 = true,191.EXT_direct_mode_display = true,192.EXT_display_surface_counter = true,193.EXT_acquire_drm_display = true,194#endif195};196197static void198get_device_extensions(const struct anv_physical_device *device,199struct vk_device_extension_table *ext)200{201*ext = (struct vk_device_extension_table) {202.KHR_8bit_storage = device->info.ver >= 8,203.KHR_16bit_storage = device->info.ver >= 8,204.KHR_bind_memory2 = true,205.KHR_buffer_device_address = device->has_a64_buffer_access,206.KHR_copy_commands2 = true,207.KHR_create_renderpass2 = true,208.KHR_dedicated_allocation = true,209.KHR_deferred_host_operations = true,210.KHR_depth_stencil_resolve = true,211.KHR_descriptor_update_template = true,212.KHR_device_group = true,213.KHR_draw_indirect_count = true,214.KHR_driver_properties = true,215.KHR_external_fence = device->has_syncobj_wait,216.KHR_external_fence_fd = device->has_syncobj_wait,217.KHR_external_memory = true,218.KHR_external_memory_fd = true,219.KHR_external_semaphore = true,220.KHR_external_semaphore_fd = true,221.KHR_fragment_shading_rate = device->info.ver >= 11,222.KHR_get_memory_requirements2 = true,223.KHR_image_format_list = true,224.KHR_imageless_framebuffer = true,225#ifdef ANV_USE_WSI_PLATFORM226.KHR_incremental_present = true,227#endif228.KHR_maintenance1 = true,229.KHR_maintenance2 = true,230.KHR_maintenance3 = true,231.KHR_multiview = true,232.KHR_performance_query =233device->use_softpin && device->perf &&234(device->perf->i915_perf_version >= 3 ||235INTEL_DEBUG & DEBUG_NO_OACONFIG) &&236device->use_call_secondary,237.KHR_pipeline_executable_properties = true,238.KHR_push_descriptor = true,239.KHR_relaxed_block_layout = true,240.KHR_sampler_mirror_clamp_to_edge = true,241.KHR_sampler_ycbcr_conversion = true,242.KHR_separate_depth_stencil_layouts = true,243.KHR_shader_atomic_int64 = device->info.ver >= 9 &&244device->use_softpin,245.KHR_shader_clock = true,246.KHR_shader_draw_parameters = true,247.KHR_shader_float16_int8 = device->info.ver >= 8,248.KHR_shader_float_controls = device->info.ver >= 8,249.KHR_shader_non_semantic_info = true,250.KHR_shader_subgroup_extended_types = device->info.ver >= 8,251.KHR_shader_subgroup_uniform_control_flow = true,252.KHR_shader_terminate_invocation = true,253.KHR_spirv_1_4 = true,254.KHR_storage_buffer_storage_class = true,255#ifdef ANV_USE_WSI_PLATFORM256.KHR_swapchain = true,257.KHR_swapchain_mutable_format = true,258#endif259.KHR_timeline_semaphore = true,260.KHR_uniform_buffer_standard_layout = true,261.KHR_variable_pointers = true,262.KHR_vulkan_memory_model = true,263.KHR_workgroup_memory_explicit_layout = true,264.KHR_zero_initialize_workgroup_memory = true,265.EXT_4444_formats = true,266.EXT_buffer_device_address = device->has_a64_buffer_access,267.EXT_calibrated_timestamps = device->has_reg_timestamp,268.EXT_color_write_enable = true,269.EXT_conditional_rendering = device->info.verx10 >= 75,270.EXT_conservative_rasterization = device->info.ver >= 9,271.EXT_custom_border_color = device->info.ver >= 8,272.EXT_depth_clip_enable = true,273.EXT_descriptor_indexing = device->has_a64_buffer_access &&274device->has_bindless_images,275#ifdef VK_USE_PLATFORM_DISPLAY_KHR276.EXT_display_control = true,277#endif278.EXT_extended_dynamic_state = true,279.EXT_extended_dynamic_state2 = true,280.EXT_external_memory_dma_buf = true,281.EXT_external_memory_host = true,282.EXT_fragment_shader_interlock = device->info.ver >= 9,283.EXT_global_priority = device->has_context_priority,284.EXT_host_query_reset = true,285.EXT_image_robustness = true,286.EXT_image_drm_format_modifier = true,287.EXT_index_type_uint8 = true,288.EXT_inline_uniform_block = true,289.EXT_line_rasterization = true,290.EXT_memory_budget = device->has_mem_available,291.EXT_pci_bus_info = true,292.EXT_physical_device_drm = true,293.EXT_pipeline_creation_cache_control = true,294.EXT_pipeline_creation_feedback = true,295.EXT_post_depth_coverage = device->info.ver >= 9,296.EXT_private_data = true,297.EXT_provoking_vertex = true,298.EXT_queue_family_foreign = true,299.EXT_robustness2 = true,300.EXT_sample_locations = true,301.EXT_sampler_filter_minmax = device->info.ver >= 9,302.EXT_scalar_block_layout = true,303.EXT_separate_stencil_usage = true,304.EXT_shader_atomic_float = true,305.EXT_shader_demote_to_helper_invocation = true,306.EXT_shader_stencil_export = device->info.ver >= 9,307.EXT_shader_subgroup_ballot = true,308.EXT_shader_subgroup_vote = true,309.EXT_shader_viewport_index_layer = true,310.EXT_subgroup_size_control = true,311.EXT_texel_buffer_alignment = true,312.EXT_transform_feedback = true,313.EXT_vertex_attribute_divisor = true,314.EXT_ycbcr_image_arrays = true,315#ifdef ANDROID316.ANDROID_external_memory_android_hardware_buffer = true,317.ANDROID_native_buffer = true,318#endif319.GOOGLE_decorate_string = true,320.GOOGLE_hlsl_functionality1 = true,321.GOOGLE_user_type = true,322.INTEL_performance_query = device->perf &&323device->perf->i915_perf_version >= 3,324.INTEL_shader_integer_functions2 = device->info.ver >= 8,325.EXT_multi_draw = true,326.NV_compute_shader_derivatives = true,327};328}329330static bool331anv_get_query_meminfo(struct anv_physical_device *device, int fd)332{333struct drm_i915_query_memory_regions *mem_regions =334intel_i915_query_alloc(fd, DRM_I915_QUERY_MEMORY_REGIONS);335if (mem_regions == NULL)336return false;337338for(int i = 0; i < mem_regions->num_regions; i++) {339switch(mem_regions->regions[i].region.memory_class) {340case I915_MEMORY_CLASS_SYSTEM:341device->sys.region = mem_regions->regions[i].region;342device->sys.size = mem_regions->regions[i].probed_size;343break;344case I915_MEMORY_CLASS_DEVICE:345device->vram.region = mem_regions->regions[i].region;346device->vram.size = mem_regions->regions[i].probed_size;347break;348default:349break;350}351}352353free(mem_regions);354return true;355}356357static void358anv_init_meminfo(struct anv_physical_device *device, int fd)359{360if (anv_get_query_meminfo(device, fd))361return;362363uint64_t heap_size = anv_compute_heap_size(fd, device->gtt_size);364365if (heap_size > (2ull << 30) && !device->supports_48bit_addresses) {366/* When running with an overridden PCI ID, we may get a GTT size from367* the kernel that is greater than 2 GiB but the execbuf check for 48bit368* address support can still fail. Just clamp the address space size to369* 2 GiB if we don't have 48-bit support.370*/371mesa_logw("%s:%d: The kernel reported a GTT size larger than 2 GiB but "372"not support for 48-bit addresses",373__FILE__, __LINE__);374heap_size = 2ull << 30;375}376377device->sys.size = heap_size;378}379380static VkResult381anv_physical_device_init_heaps(struct anv_physical_device *device, int fd)382{383if (anv_gem_get_context_param(fd, 0, I915_CONTEXT_PARAM_GTT_SIZE,384&device->gtt_size) == -1) {385/* If, for whatever reason, we can't actually get the GTT size from the386* kernel (too old?) fall back to the aperture size.387*/388anv_perf_warn(NULL, NULL,389"Failed to get I915_CONTEXT_PARAM_GTT_SIZE: %m");390391if (intel_get_aperture_size(fd, &device->gtt_size) == -1) {392return vk_errorfi(device->instance, NULL,393VK_ERROR_INITIALIZATION_FAILED,394"failed to get aperture size: %m");395}396}397398/* We only allow 48-bit addresses with softpin because knowing the actual399* address is required for the vertex cache flush workaround.400*/401device->supports_48bit_addresses = (device->info.ver >= 8) &&402device->gtt_size > (4ULL << 30 /* GiB */);403404anv_init_meminfo(device, fd);405assert(device->sys.size != 0);406407if (device->vram.size > 0) {408/* We can create 2 different heaps when we have local memory support,409* first heap with local memory size and second with system memory size.410*/411device->memory.heap_count = 2;412device->memory.heaps[0] = (struct anv_memory_heap) {413.size = device->vram.size,414.flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,415.is_local_mem = true,416};417device->memory.heaps[1] = (struct anv_memory_heap) {418.size = device->sys.size,419.flags = 0,420.is_local_mem = false,421};422423device->memory.type_count = 3;424device->memory.types[0] = (struct anv_memory_type) {425.propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,426.heapIndex = 0,427};428device->memory.types[1] = (struct anv_memory_type) {429.propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |430VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |431VK_MEMORY_PROPERTY_HOST_CACHED_BIT,432.heapIndex = 1,433};434device->memory.types[2] = (struct anv_memory_type) {435.propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |436VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |437VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,438.heapIndex = 0,439};440} else if (device->info.has_llc) {441device->memory.heap_count = 1;442device->memory.heaps[0] = (struct anv_memory_heap) {443.size = device->sys.size,444.flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,445.is_local_mem = false,446};447448/* Big core GPUs share LLC with the CPU and thus one memory type can be449* both cached and coherent at the same time.450*/451device->memory.type_count = 1;452device->memory.types[0] = (struct anv_memory_type) {453.propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |454VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |455VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |456VK_MEMORY_PROPERTY_HOST_CACHED_BIT,457.heapIndex = 0,458};459} else {460device->memory.heap_count = 1;461device->memory.heaps[0] = (struct anv_memory_heap) {462.size = device->sys.size,463.flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,464.is_local_mem = false,465};466467/* The spec requires that we expose a host-visible, coherent memory468* type, but Atom GPUs don't share LLC. Thus we offer two memory types469* to give the application a choice between cached, but not coherent and470* coherent but uncached (WC though).471*/472device->memory.type_count = 2;473device->memory.types[0] = (struct anv_memory_type) {474.propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |475VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |476VK_MEMORY_PROPERTY_HOST_CACHED_BIT,477.heapIndex = 0,478};479device->memory.types[1] = (struct anv_memory_type) {480.propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |481VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |482VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,483.heapIndex = 0,484};485}486487device->memory.need_clflush = false;488for (unsigned i = 0; i < device->memory.type_count; i++) {489VkMemoryPropertyFlags props = device->memory.types[i].propertyFlags;490if ((props & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) &&491!(props & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))492device->memory.need_clflush = true;493}494495return VK_SUCCESS;496}497498static VkResult499anv_physical_device_init_uuids(struct anv_physical_device *device)500{501const struct build_id_note *note =502build_id_find_nhdr_for_addr(anv_physical_device_init_uuids);503if (!note) {504return vk_errorfi(device->instance, NULL,505VK_ERROR_INITIALIZATION_FAILED,506"Failed to find build-id");507}508509unsigned build_id_len = build_id_length(note);510if (build_id_len < 20) {511return vk_errorfi(device->instance, NULL,512VK_ERROR_INITIALIZATION_FAILED,513"build-id too short. It needs to be a SHA");514}515516memcpy(device->driver_build_sha1, build_id_data(note), 20);517518struct mesa_sha1 sha1_ctx;519uint8_t sha1[20];520STATIC_ASSERT(VK_UUID_SIZE <= sizeof(sha1));521522/* The pipeline cache UUID is used for determining when a pipeline cache is523* invalid. It needs both a driver build and the PCI ID of the device.524*/525_mesa_sha1_init(&sha1_ctx);526_mesa_sha1_update(&sha1_ctx, build_id_data(note), build_id_len);527_mesa_sha1_update(&sha1_ctx, &device->info.chipset_id,528sizeof(device->info.chipset_id));529_mesa_sha1_update(&sha1_ctx, &device->always_use_bindless,530sizeof(device->always_use_bindless));531_mesa_sha1_update(&sha1_ctx, &device->has_a64_buffer_access,532sizeof(device->has_a64_buffer_access));533_mesa_sha1_update(&sha1_ctx, &device->has_bindless_images,534sizeof(device->has_bindless_images));535_mesa_sha1_update(&sha1_ctx, &device->has_bindless_samplers,536sizeof(device->has_bindless_samplers));537_mesa_sha1_final(&sha1_ctx, sha1);538memcpy(device->pipeline_cache_uuid, sha1, VK_UUID_SIZE);539540intel_uuid_compute_driver_id(device->driver_uuid, &device->info, VK_UUID_SIZE);541intel_uuid_compute_device_id(device->device_uuid, &device->isl_dev, VK_UUID_SIZE);542543return VK_SUCCESS;544}545546static void547anv_physical_device_init_disk_cache(struct anv_physical_device *device)548{549#ifdef ENABLE_SHADER_CACHE550char renderer[10];551ASSERTED int len = snprintf(renderer, sizeof(renderer), "anv_%04x",552device->info.chipset_id);553assert(len == sizeof(renderer) - 2);554555char timestamp[41];556_mesa_sha1_format(timestamp, device->driver_build_sha1);557558const uint64_t driver_flags =559brw_get_compiler_config_value(device->compiler);560device->disk_cache = disk_cache_create(renderer, timestamp, driver_flags);561#else562device->disk_cache = NULL;563#endif564}565566static void567anv_physical_device_free_disk_cache(struct anv_physical_device *device)568{569#ifdef ENABLE_SHADER_CACHE570if (device->disk_cache)571disk_cache_destroy(device->disk_cache);572#else573assert(device->disk_cache == NULL);574#endif575}576577/* The ANV_QUEUE_OVERRIDE environment variable is a comma separated list of578* queue overrides.579*580* To override the number queues:581* * "gc" is for graphics queues with compute support582* * "g" is for graphics queues with no compute support583* * "c" is for compute queues with no graphics support584*585* For example, ANV_QUEUE_OVERRIDE=gc=2,c=1 would override the number of586* advertised queues to be 2 queues with graphics+compute support, and 1 queue587* with compute-only support.588*589* ANV_QUEUE_OVERRIDE=c=1 would override the number of advertised queues to590* include 1 queue with compute-only support, but it will not change the591* number of graphics+compute queues.592*593* ANV_QUEUE_OVERRIDE=gc=0,c=1 would override the number of advertised queues594* to include 1 queue with compute-only support, and it would override the595* number of graphics+compute queues to be 0.596*/597static void598anv_override_engine_counts(int *gc_count, int *g_count, int *c_count)599{600int gc_override = -1;601int g_override = -1;602int c_override = -1;603char *env = getenv("ANV_QUEUE_OVERRIDE");604605if (env == NULL)606return;607608env = strdup(env);609char *save = NULL;610char *next = strtok_r(env, ",", &save);611while (next != NULL) {612if (strncmp(next, "gc=", 3) == 0) {613gc_override = strtol(next + 3, NULL, 0);614} else if (strncmp(next, "g=", 2) == 0) {615g_override = strtol(next + 2, NULL, 0);616} else if (strncmp(next, "c=", 2) == 0) {617c_override = strtol(next + 2, NULL, 0);618} else {619mesa_logw("Ignoring unsupported ANV_QUEUE_OVERRIDE token: %s", next);620}621next = strtok_r(NULL, ",", &save);622}623free(env);624if (gc_override >= 0)625*gc_count = gc_override;626if (g_override >= 0)627*g_count = g_override;628if (*g_count > 0 && *gc_count <= 0 && (gc_override >= 0 || g_override >= 0))629mesa_logw("ANV_QUEUE_OVERRIDE: gc=0 with g > 0 violates the "630"Vulkan specification");631if (c_override >= 0)632*c_count = c_override;633}634635static void636anv_physical_device_init_queue_families(struct anv_physical_device *pdevice)637{638uint32_t family_count = 0;639640if (pdevice->engine_info) {641int gc_count =642anv_gem_count_engines(pdevice->engine_info, I915_ENGINE_CLASS_RENDER);643int g_count = 0;644int c_count = 0;645646anv_override_engine_counts(&gc_count, &g_count, &c_count);647648if (gc_count > 0) {649pdevice->queue.families[family_count++] = (struct anv_queue_family) {650.queueFlags = VK_QUEUE_GRAPHICS_BIT |651VK_QUEUE_COMPUTE_BIT |652VK_QUEUE_TRANSFER_BIT,653.queueCount = gc_count,654.engine_class = I915_ENGINE_CLASS_RENDER,655};656}657if (g_count > 0) {658pdevice->queue.families[family_count++] = (struct anv_queue_family) {659.queueFlags = VK_QUEUE_GRAPHICS_BIT |660VK_QUEUE_TRANSFER_BIT,661.queueCount = g_count,662.engine_class = I915_ENGINE_CLASS_RENDER,663};664}665if (c_count > 0) {666pdevice->queue.families[family_count++] = (struct anv_queue_family) {667.queueFlags = VK_QUEUE_COMPUTE_BIT |668VK_QUEUE_TRANSFER_BIT,669.queueCount = c_count,670.engine_class = I915_ENGINE_CLASS_RENDER,671};672}673/* Increase count below when other families are added as a reminder to674* increase the ANV_MAX_QUEUE_FAMILIES value.675*/676STATIC_ASSERT(ANV_MAX_QUEUE_FAMILIES >= 3);677} else {678/* Default to a single render queue */679pdevice->queue.families[family_count++] = (struct anv_queue_family) {680.queueFlags = VK_QUEUE_GRAPHICS_BIT |681VK_QUEUE_COMPUTE_BIT |682VK_QUEUE_TRANSFER_BIT,683.queueCount = 1,684.engine_class = I915_ENGINE_CLASS_RENDER,685};686family_count = 1;687}688assert(family_count <= ANV_MAX_QUEUE_FAMILIES);689pdevice->queue.family_count = family_count;690}691692static VkResult693anv_physical_device_try_create(struct anv_instance *instance,694drmDevicePtr drm_device,695struct anv_physical_device **device_out)696{697const char *primary_path = drm_device->nodes[DRM_NODE_PRIMARY];698const char *path = drm_device->nodes[DRM_NODE_RENDER];699VkResult result;700int fd;701int master_fd = -1;702703brw_process_intel_debug_variable();704705fd = open(path, O_RDWR | O_CLOEXEC);706if (fd < 0) {707if (errno == ENOMEM) {708return vk_errorfi(instance, NULL, VK_ERROR_OUT_OF_HOST_MEMORY,709"Unable to open device %s: out of memory", path);710}711return vk_errorfi(instance, NULL, VK_ERROR_INCOMPATIBLE_DRIVER,712"Unable to open device %s: %m", path);713}714715struct intel_device_info devinfo;716if (!intel_get_device_info_from_fd(fd, &devinfo)) {717result = vk_error(VK_ERROR_INCOMPATIBLE_DRIVER);718goto fail_fd;719}720721const char *device_name = intel_get_device_name(devinfo.chipset_id);722723if (devinfo.is_haswell) {724mesa_logw("Haswell Vulkan support is incomplete");725} else if (devinfo.ver == 7 && !devinfo.is_baytrail) {726mesa_logw("Ivy Bridge Vulkan support is incomplete");727} else if (devinfo.ver == 7 && devinfo.is_baytrail) {728mesa_logw("Bay Trail Vulkan support is incomplete");729} else if (devinfo.ver >= 8 && devinfo.ver <= 12) {730/* Gfx8-12 fully supported */731} else {732result = vk_errorfi(instance, NULL, VK_ERROR_INCOMPATIBLE_DRIVER,733"Vulkan not yet supported on %s", device_name);734goto fail_fd;735}736737struct anv_physical_device *device =738vk_zalloc(&instance->vk.alloc, sizeof(*device), 8,739VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);740if (device == NULL) {741result = vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);742goto fail_fd;743}744745struct vk_physical_device_dispatch_table dispatch_table;746vk_physical_device_dispatch_table_from_entrypoints(747&dispatch_table, &anv_physical_device_entrypoints, true);748749result = vk_physical_device_init(&device->vk, &instance->vk,750NULL, /* We set up extensions later */751&dispatch_table);752if (result != VK_SUCCESS) {753vk_error(result);754goto fail_alloc;755}756device->instance = instance;757758assert(strlen(path) < ARRAY_SIZE(device->path));759snprintf(device->path, ARRAY_SIZE(device->path), "%s", path);760761device->info = devinfo;762device->name = device_name;763764device->no_hw = device->info.no_hw;765if (getenv("INTEL_NO_HW") != NULL)766device->no_hw = true;767768device->pci_info.domain = drm_device->businfo.pci->domain;769device->pci_info.bus = drm_device->businfo.pci->bus;770device->pci_info.device = drm_device->businfo.pci->dev;771device->pci_info.function = drm_device->businfo.pci->func;772773device->cmd_parser_version = -1;774if (device->info.ver == 7) {775device->cmd_parser_version =776anv_gem_get_param(fd, I915_PARAM_CMD_PARSER_VERSION);777if (device->cmd_parser_version == -1) {778result = vk_errorfi(device->instance, NULL,779VK_ERROR_INITIALIZATION_FAILED,780"failed to get command parser version");781goto fail_base;782}783}784785if (!anv_gem_get_param(fd, I915_PARAM_HAS_WAIT_TIMEOUT)) {786result = vk_errorfi(device->instance, NULL,787VK_ERROR_INITIALIZATION_FAILED,788"kernel missing gem wait");789goto fail_base;790}791792if (!anv_gem_get_param(fd, I915_PARAM_HAS_EXECBUF2)) {793result = vk_errorfi(device->instance, NULL,794VK_ERROR_INITIALIZATION_FAILED,795"kernel missing execbuf2");796goto fail_base;797}798799if (!device->info.has_llc &&800anv_gem_get_param(fd, I915_PARAM_MMAP_VERSION) < 1) {801result = vk_errorfi(device->instance, NULL,802VK_ERROR_INITIALIZATION_FAILED,803"kernel missing wc mmap");804goto fail_base;805}806807if (device->info.ver >= 8 && !device->info.is_cherryview &&808!anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_SOFTPIN)) {809result = vk_errorfi(device->instance, NULL,810VK_ERROR_INITIALIZATION_FAILED,811"kernel missing softpin");812goto fail_alloc;813}814815device->has_exec_async = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_ASYNC);816device->has_exec_capture = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_CAPTURE);817device->has_exec_fence = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_FENCE);818device->has_syncobj = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_FENCE_ARRAY);819device->has_syncobj_wait = device->has_syncobj &&820anv_gem_supports_syncobj_wait(fd);821device->has_syncobj_wait_available =822anv_gem_get_drm_cap(fd, DRM_CAP_SYNCOBJ_TIMELINE) != 0;823824device->has_context_priority = anv_gem_has_context_priority(fd);825826/* Initialize memory regions struct to 0. */827memset(&device->vram, 0, sizeof(device->vram));828memset(&device->sys, 0, sizeof(device->sys));829830result = anv_physical_device_init_heaps(device, fd);831if (result != VK_SUCCESS)832goto fail_base;833834device->use_softpin = device->info.ver >= 8 &&835!device->info.is_cherryview;836assert(device->use_softpin == device->supports_48bit_addresses);837838device->has_context_isolation =839anv_gem_get_param(fd, I915_PARAM_HAS_CONTEXT_ISOLATION);840841device->has_exec_timeline =842anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_TIMELINE_FENCES);843if (env_var_as_boolean("ANV_QUEUE_THREAD_DISABLE", false))844device->has_exec_timeline = false;845846device->has_thread_submit =847device->has_syncobj_wait_available && device->has_exec_timeline;848849device->always_use_bindless =850env_var_as_boolean("ANV_ALWAYS_BINDLESS", false);851852device->use_call_secondary =853device->use_softpin &&854!env_var_as_boolean("ANV_DISABLE_SECONDARY_CMD_BUFFER_CALLS", false);855856/* We first got the A64 messages on broadwell and we can only use them if857* we can pass addresses directly into the shader which requires softpin.858*/859device->has_a64_buffer_access = device->info.ver >= 8 &&860device->use_softpin;861862/* We first get bindless image access on Skylake.863*/864device->has_bindless_images = device->info.ver >= 9;865866/* We've had bindless samplers since Ivy Bridge (forever in Vulkan terms)867* because it's just a matter of setting the sampler address in the sample868* message header. However, we've not bothered to wire it up for vec4 so869* we leave it disabled on gfx7.870*/871device->has_bindless_samplers = device->info.ver >= 8;872873device->has_implicit_ccs = device->info.has_aux_map;874875/* Check if we can read the GPU timestamp register from the CPU */876uint64_t u64_ignore;877device->has_reg_timestamp = anv_gem_reg_read(fd, TIMESTAMP | I915_REG_READ_8B_WA,878&u64_ignore) == 0;879880uint64_t avail_mem;881device->has_mem_available = os_get_available_system_memory(&avail_mem);882883device->always_flush_cache =884driQueryOptionb(&instance->dri_options, "always_flush_cache");885886device->has_mmap_offset =887anv_gem_get_param(fd, I915_PARAM_MMAP_GTT_VERSION) >= 4;888889/* GENs prior to 8 do not support EU/Subslice info */890device->subslice_total = intel_device_info_subslice_total(&device->info);891device->eu_total = intel_device_info_eu_total(&device->info);892893if (device->info.is_cherryview) {894/* Logical CS threads = EUs per subslice * num threads per EU */895uint32_t max_cs_threads =896device->eu_total / device->subslice_total * device->info.num_thread_per_eu;897898/* Fuse configurations may give more threads than expected, never less. */899if (max_cs_threads > device->info.max_cs_threads)900device->info.max_cs_threads = max_cs_threads;901}902903device->compiler = brw_compiler_create(NULL, &device->info);904if (device->compiler == NULL) {905result = vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);906goto fail_base;907}908device->compiler->shader_debug_log = compiler_debug_log;909device->compiler->shader_perf_log = compiler_perf_log;910device->compiler->supports_pull_constants = false;911device->compiler->constant_buffer_0_is_relative =912device->info.ver < 8 || !device->has_context_isolation;913device->compiler->supports_shader_constants = true;914device->compiler->compact_params = false;915device->compiler->indirect_ubos_use_sampler = device->info.ver < 12;916917/* Broadwell PRM says:918*919* "Before Gfx8, there was a historical configuration control field to920* swizzle address bit[6] for in X/Y tiling modes. This was set in three921* different places: TILECTL[1:0], ARB_MODE[5:4], and922* DISP_ARB_CTL[14:13].923*924* For Gfx8 and subsequent generations, the swizzle fields are all925* reserved, and the CPU's memory controller performs all address926* swizzling modifications."927*/928bool swizzled =929device->info.ver < 8 && anv_gem_get_bit6_swizzle(fd, I915_TILING_X);930931isl_device_init(&device->isl_dev, &device->info, swizzled);932933result = anv_physical_device_init_uuids(device);934if (result != VK_SUCCESS)935goto fail_compiler;936937anv_physical_device_init_disk_cache(device);938939if (instance->vk.enabled_extensions.KHR_display) {940master_fd = open(primary_path, O_RDWR | O_CLOEXEC);941if (master_fd >= 0) {942/* prod the device with a GETPARAM call which will fail if943* we don't have permission to even render on this device944*/945if (anv_gem_get_param(master_fd, I915_PARAM_CHIPSET_ID) == 0) {946close(master_fd);947master_fd = -1;948}949}950}951device->master_fd = master_fd;952953device->engine_info = anv_gem_get_engine_info(fd);954anv_physical_device_init_queue_families(device);955956result = anv_init_wsi(device);957if (result != VK_SUCCESS)958goto fail_engine_info;959960anv_physical_device_init_perf(device, fd);961962anv_measure_device_init(device);963964get_device_extensions(device, &device->vk.supported_extensions);965966device->local_fd = fd;967968anv_genX(&device->info, init_physical_device_state)(device);969970*device_out = device;971972struct stat st;973974if (stat(primary_path, &st) == 0) {975device->has_master = true;976device->master_major = major(st.st_rdev);977device->master_minor = minor(st.st_rdev);978} else {979device->has_master = false;980device->master_major = 0;981device->master_minor = 0;982}983984if (stat(path, &st) == 0) {985device->has_local = true;986device->local_major = major(st.st_rdev);987device->local_minor = minor(st.st_rdev);988} else {989device->has_local = false;990device->local_major = 0;991device->local_minor = 0;992}993994return VK_SUCCESS;995996fail_engine_info:997free(device->engine_info);998anv_physical_device_free_disk_cache(device);999fail_compiler:1000ralloc_free(device->compiler);1001fail_base:1002vk_physical_device_finish(&device->vk);1003fail_alloc:1004vk_free(&instance->vk.alloc, device);1005fail_fd:1006close(fd);1007if (master_fd != -1)1008close(master_fd);1009return result;1010}10111012static void1013anv_physical_device_destroy(struct anv_physical_device *device)1014{1015anv_finish_wsi(device);1016anv_measure_device_destroy(device);1017free(device->engine_info);1018anv_physical_device_free_disk_cache(device);1019ralloc_free(device->compiler);1020ralloc_free(device->perf);1021close(device->local_fd);1022if (device->master_fd >= 0)1023close(device->master_fd);1024vk_physical_device_finish(&device->vk);1025vk_free(&device->instance->vk.alloc, device);1026}10271028VkResult anv_EnumerateInstanceExtensionProperties(1029const char* pLayerName,1030uint32_t* pPropertyCount,1031VkExtensionProperties* pProperties)1032{1033if (pLayerName)1034return vk_error(VK_ERROR_LAYER_NOT_PRESENT);10351036return vk_enumerate_instance_extension_properties(1037&instance_extensions, pPropertyCount, pProperties);1038}10391040static void1041anv_init_dri_options(struct anv_instance *instance)1042{1043driParseOptionInfo(&instance->available_dri_options, anv_dri_options,1044ARRAY_SIZE(anv_dri_options));1045driParseConfigFiles(&instance->dri_options,1046&instance->available_dri_options, 0, "anv", NULL,1047instance->vk.app_info.app_name,1048instance->vk.app_info.app_version,1049instance->vk.app_info.engine_name,1050instance->vk.app_info.engine_version);1051}10521053VkResult anv_CreateInstance(1054const VkInstanceCreateInfo* pCreateInfo,1055const VkAllocationCallbacks* pAllocator,1056VkInstance* pInstance)1057{1058struct anv_instance *instance;1059VkResult result;10601061assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);10621063if (pAllocator == NULL)1064pAllocator = vk_default_allocator();10651066instance = vk_alloc(pAllocator, sizeof(*instance), 8,1067VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);1068if (!instance)1069return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);10701071struct vk_instance_dispatch_table dispatch_table;1072vk_instance_dispatch_table_from_entrypoints(1073&dispatch_table, &anv_instance_entrypoints, true);10741075result = vk_instance_init(&instance->vk, &instance_extensions,1076&dispatch_table, pCreateInfo, pAllocator);1077if (result != VK_SUCCESS) {1078vk_free(pAllocator, instance);1079return vk_error(result);1080}10811082instance->physical_devices_enumerated = false;1083list_inithead(&instance->physical_devices);10841085instance->pipeline_cache_enabled =1086env_var_as_boolean("ANV_ENABLE_PIPELINE_CACHE", true);10871088VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));10891090anv_init_dri_options(instance);10911092*pInstance = anv_instance_to_handle(instance);10931094return VK_SUCCESS;1095}10961097void anv_DestroyInstance(1098VkInstance _instance,1099const VkAllocationCallbacks* pAllocator)1100{1101ANV_FROM_HANDLE(anv_instance, instance, _instance);11021103if (!instance)1104return;11051106list_for_each_entry_safe(struct anv_physical_device, pdevice,1107&instance->physical_devices, link)1108anv_physical_device_destroy(pdevice);11091110VG(VALGRIND_DESTROY_MEMPOOL(instance));11111112driDestroyOptionCache(&instance->dri_options);1113driDestroyOptionInfo(&instance->available_dri_options);11141115vk_instance_finish(&instance->vk);1116vk_free(&instance->vk.alloc, instance);1117}11181119static VkResult1120anv_enumerate_physical_devices(struct anv_instance *instance)1121{1122if (instance->physical_devices_enumerated)1123return VK_SUCCESS;11241125instance->physical_devices_enumerated = true;11261127/* TODO: Check for more devices ? */1128drmDevicePtr devices[8];1129int max_devices;11301131max_devices = drmGetDevices2(0, devices, ARRAY_SIZE(devices));1132if (max_devices < 1)1133return VK_SUCCESS;11341135VkResult result = VK_SUCCESS;1136for (unsigned i = 0; i < (unsigned)max_devices; i++) {1137if (devices[i]->available_nodes & 1 << DRM_NODE_RENDER &&1138devices[i]->bustype == DRM_BUS_PCI &&1139devices[i]->deviceinfo.pci->vendor_id == 0x8086) {11401141struct anv_physical_device *pdevice;1142result = anv_physical_device_try_create(instance, devices[i],1143&pdevice);1144/* Incompatible DRM device, skip. */1145if (result == VK_ERROR_INCOMPATIBLE_DRIVER) {1146result = VK_SUCCESS;1147continue;1148}11491150/* Error creating the physical device, report the error. */1151if (result != VK_SUCCESS)1152break;11531154list_addtail(&pdevice->link, &instance->physical_devices);1155}1156}1157drmFreeDevices(devices, max_devices);11581159/* If we successfully enumerated any devices, call it success */1160return result;1161}11621163VkResult anv_EnumeratePhysicalDevices(1164VkInstance _instance,1165uint32_t* pPhysicalDeviceCount,1166VkPhysicalDevice* pPhysicalDevices)1167{1168ANV_FROM_HANDLE(anv_instance, instance, _instance);1169VK_OUTARRAY_MAKE(out, pPhysicalDevices, pPhysicalDeviceCount);11701171VkResult result = anv_enumerate_physical_devices(instance);1172if (result != VK_SUCCESS)1173return result;11741175list_for_each_entry(struct anv_physical_device, pdevice,1176&instance->physical_devices, link) {1177vk_outarray_append(&out, i) {1178*i = anv_physical_device_to_handle(pdevice);1179}1180}11811182return vk_outarray_status(&out);1183}11841185VkResult anv_EnumeratePhysicalDeviceGroups(1186VkInstance _instance,1187uint32_t* pPhysicalDeviceGroupCount,1188VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties)1189{1190ANV_FROM_HANDLE(anv_instance, instance, _instance);1191VK_OUTARRAY_MAKE(out, pPhysicalDeviceGroupProperties,1192pPhysicalDeviceGroupCount);11931194VkResult result = anv_enumerate_physical_devices(instance);1195if (result != VK_SUCCESS)1196return result;11971198list_for_each_entry(struct anv_physical_device, pdevice,1199&instance->physical_devices, link) {1200vk_outarray_append(&out, p) {1201p->physicalDeviceCount = 1;1202memset(p->physicalDevices, 0, sizeof(p->physicalDevices));1203p->physicalDevices[0] = anv_physical_device_to_handle(pdevice);1204p->subsetAllocation = false;12051206vk_foreach_struct(ext, p->pNext)1207anv_debug_ignored_stype(ext->sType);1208}1209}12101211return vk_outarray_status(&out);1212}12131214void anv_GetPhysicalDeviceFeatures(1215VkPhysicalDevice physicalDevice,1216VkPhysicalDeviceFeatures* pFeatures)1217{1218ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);12191220*pFeatures = (VkPhysicalDeviceFeatures) {1221.robustBufferAccess = true,1222.fullDrawIndexUint32 = true,1223.imageCubeArray = true,1224.independentBlend = true,1225.geometryShader = true,1226.tessellationShader = true,1227.sampleRateShading = true,1228.dualSrcBlend = true,1229.logicOp = true,1230.multiDrawIndirect = true,1231.drawIndirectFirstInstance = true,1232.depthClamp = true,1233.depthBiasClamp = true,1234.fillModeNonSolid = true,1235.depthBounds = pdevice->info.ver >= 12,1236.wideLines = true,1237.largePoints = true,1238.alphaToOne = true,1239.multiViewport = true,1240.samplerAnisotropy = true,1241.textureCompressionETC2 = pdevice->info.ver >= 8 ||1242pdevice->info.is_baytrail,1243.textureCompressionASTC_LDR = pdevice->info.ver >= 9, /* FINISHME CHV */1244.textureCompressionBC = true,1245.occlusionQueryPrecise = true,1246.pipelineStatisticsQuery = true,1247.fragmentStoresAndAtomics = true,1248.shaderTessellationAndGeometryPointSize = true,1249.shaderImageGatherExtended = true,1250.shaderStorageImageExtendedFormats = true,1251.shaderStorageImageMultisample = false,1252.shaderStorageImageReadWithoutFormat = false,1253.shaderStorageImageWriteWithoutFormat = true,1254.shaderUniformBufferArrayDynamicIndexing = true,1255.shaderSampledImageArrayDynamicIndexing = true,1256.shaderStorageBufferArrayDynamicIndexing = true,1257.shaderStorageImageArrayDynamicIndexing = true,1258.shaderClipDistance = true,1259.shaderCullDistance = true,1260.shaderFloat64 = pdevice->info.ver >= 8 &&1261pdevice->info.has_64bit_float,1262.shaderInt64 = pdevice->info.ver >= 8,1263.shaderInt16 = pdevice->info.ver >= 8,1264.shaderResourceMinLod = pdevice->info.ver >= 9,1265.variableMultisampleRate = true,1266.inheritedQueries = true,1267};12681269/* We can't do image stores in vec4 shaders */1270pFeatures->vertexPipelineStoresAndAtomics =1271pdevice->compiler->scalar_stage[MESA_SHADER_VERTEX] &&1272pdevice->compiler->scalar_stage[MESA_SHADER_GEOMETRY];12731274struct vk_app_info *app_info = &pdevice->instance->vk.app_info;12751276/* The new DOOM and Wolfenstein games require depthBounds without1277* checking for it. They seem to run fine without it so just claim it's1278* there and accept the consequences.1279*/1280if (app_info->engine_name && strcmp(app_info->engine_name, "idTech") == 0)1281pFeatures->depthBounds = true;1282}12831284static void1285anv_get_physical_device_features_1_1(struct anv_physical_device *pdevice,1286VkPhysicalDeviceVulkan11Features *f)1287{1288assert(f->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES);12891290f->storageBuffer16BitAccess = pdevice->info.ver >= 8;1291f->uniformAndStorageBuffer16BitAccess = pdevice->info.ver >= 8;1292f->storagePushConstant16 = pdevice->info.ver >= 8;1293f->storageInputOutput16 = false;1294f->multiview = true;1295f->multiviewGeometryShader = true;1296f->multiviewTessellationShader = true;1297f->variablePointersStorageBuffer = true;1298f->variablePointers = true;1299f->protectedMemory = false;1300f->samplerYcbcrConversion = true;1301f->shaderDrawParameters = true;1302}13031304static void1305anv_get_physical_device_features_1_2(struct anv_physical_device *pdevice,1306VkPhysicalDeviceVulkan12Features *f)1307{1308assert(f->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES);13091310f->samplerMirrorClampToEdge = true;1311f->drawIndirectCount = true;1312f->storageBuffer8BitAccess = pdevice->info.ver >= 8;1313f->uniformAndStorageBuffer8BitAccess = pdevice->info.ver >= 8;1314f->storagePushConstant8 = pdevice->info.ver >= 8;1315f->shaderBufferInt64Atomics = pdevice->info.ver >= 9 &&1316pdevice->use_softpin;1317f->shaderSharedInt64Atomics = false;1318f->shaderFloat16 = pdevice->info.ver >= 8;1319f->shaderInt8 = pdevice->info.ver >= 8;13201321bool descIndexing = pdevice->has_a64_buffer_access &&1322pdevice->has_bindless_images;1323f->descriptorIndexing = descIndexing;1324f->shaderInputAttachmentArrayDynamicIndexing = false;1325f->shaderUniformTexelBufferArrayDynamicIndexing = descIndexing;1326f->shaderStorageTexelBufferArrayDynamicIndexing = descIndexing;1327f->shaderUniformBufferArrayNonUniformIndexing = false;1328f->shaderSampledImageArrayNonUniformIndexing = descIndexing;1329f->shaderStorageBufferArrayNonUniformIndexing = descIndexing;1330f->shaderStorageImageArrayNonUniformIndexing = descIndexing;1331f->shaderInputAttachmentArrayNonUniformIndexing = false;1332f->shaderUniformTexelBufferArrayNonUniformIndexing = descIndexing;1333f->shaderStorageTexelBufferArrayNonUniformIndexing = descIndexing;1334f->descriptorBindingUniformBufferUpdateAfterBind = false;1335f->descriptorBindingSampledImageUpdateAfterBind = descIndexing;1336f->descriptorBindingStorageImageUpdateAfterBind = descIndexing;1337f->descriptorBindingStorageBufferUpdateAfterBind = descIndexing;1338f->descriptorBindingUniformTexelBufferUpdateAfterBind = descIndexing;1339f->descriptorBindingStorageTexelBufferUpdateAfterBind = descIndexing;1340f->descriptorBindingUpdateUnusedWhilePending = descIndexing;1341f->descriptorBindingPartiallyBound = descIndexing;1342f->descriptorBindingVariableDescriptorCount = descIndexing;1343f->runtimeDescriptorArray = descIndexing;13441345f->samplerFilterMinmax = pdevice->info.ver >= 9;1346f->scalarBlockLayout = true;1347f->imagelessFramebuffer = true;1348f->uniformBufferStandardLayout = true;1349f->shaderSubgroupExtendedTypes = true;1350f->separateDepthStencilLayouts = true;1351f->hostQueryReset = true;1352f->timelineSemaphore = true;1353f->bufferDeviceAddress = pdevice->has_a64_buffer_access;1354f->bufferDeviceAddressCaptureReplay = pdevice->has_a64_buffer_access;1355f->bufferDeviceAddressMultiDevice = false;1356f->vulkanMemoryModel = true;1357f->vulkanMemoryModelDeviceScope = true;1358f->vulkanMemoryModelAvailabilityVisibilityChains = true;1359f->shaderOutputViewportIndex = true;1360f->shaderOutputLayer = true;1361f->subgroupBroadcastDynamicId = true;1362}13631364void anv_GetPhysicalDeviceFeatures2(1365VkPhysicalDevice physicalDevice,1366VkPhysicalDeviceFeatures2* pFeatures)1367{1368ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);1369anv_GetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);13701371VkPhysicalDeviceVulkan11Features core_1_1 = {1372.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES,1373};1374anv_get_physical_device_features_1_1(pdevice, &core_1_1);13751376VkPhysicalDeviceVulkan12Features core_1_2 = {1377.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,1378};1379anv_get_physical_device_features_1_2(pdevice, &core_1_2);13801381#define CORE_FEATURE(major, minor, feature) \1382features->feature = core_##major##_##minor.feature138313841385vk_foreach_struct(ext, pFeatures->pNext) {1386switch (ext->sType) {1387case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT: {1388VkPhysicalDevice4444FormatsFeaturesEXT *features =1389(VkPhysicalDevice4444FormatsFeaturesEXT *)ext;1390features->formatA4R4G4B4 = true;1391features->formatA4B4G4R4 = false;1392break;1393}13941395case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR: {1396VkPhysicalDevice8BitStorageFeaturesKHR *features =1397(VkPhysicalDevice8BitStorageFeaturesKHR *)ext;1398CORE_FEATURE(1, 2, storageBuffer8BitAccess);1399CORE_FEATURE(1, 2, uniformAndStorageBuffer8BitAccess);1400CORE_FEATURE(1, 2, storagePushConstant8);1401break;1402}14031404case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: {1405VkPhysicalDevice16BitStorageFeatures *features =1406(VkPhysicalDevice16BitStorageFeatures *)ext;1407CORE_FEATURE(1, 1, storageBuffer16BitAccess);1408CORE_FEATURE(1, 1, uniformAndStorageBuffer16BitAccess);1409CORE_FEATURE(1, 1, storagePushConstant16);1410CORE_FEATURE(1, 1, storageInputOutput16);1411break;1412}14131414case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR: {1415VkPhysicalDeviceAccelerationStructureFeaturesKHR *features = (void *)ext;1416features->accelerationStructure = false;1417features->accelerationStructureCaptureReplay = false;1418features->accelerationStructureIndirectBuild = false;1419features->accelerationStructureHostCommands = false;1420features->descriptorBindingAccelerationStructureUpdateAfterBind = true;1421break;1422}14231424case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT: {1425VkPhysicalDeviceBufferDeviceAddressFeaturesEXT *features = (void *)ext;1426features->bufferDeviceAddress = pdevice->has_a64_buffer_access;1427features->bufferDeviceAddressCaptureReplay = false;1428features->bufferDeviceAddressMultiDevice = false;1429break;1430}14311432case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR: {1433VkPhysicalDeviceBufferDeviceAddressFeaturesKHR *features = (void *)ext;1434CORE_FEATURE(1, 2, bufferDeviceAddress);1435CORE_FEATURE(1, 2, bufferDeviceAddressCaptureReplay);1436CORE_FEATURE(1, 2, bufferDeviceAddressMultiDevice);1437break;1438}14391440case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT: {1441VkPhysicalDeviceColorWriteEnableFeaturesEXT *features =1442(VkPhysicalDeviceColorWriteEnableFeaturesEXT *)ext;1443features->colorWriteEnable = true;1444break;1445}14461447case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV: {1448VkPhysicalDeviceComputeShaderDerivativesFeaturesNV *features =1449(VkPhysicalDeviceComputeShaderDerivativesFeaturesNV *)ext;1450features->computeDerivativeGroupQuads = true;1451features->computeDerivativeGroupLinear = true;1452break;1453}14541455case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT: {1456VkPhysicalDeviceConditionalRenderingFeaturesEXT *features =1457(VkPhysicalDeviceConditionalRenderingFeaturesEXT*)ext;1458features->conditionalRendering = pdevice->info.verx10 >= 75;1459features->inheritedConditionalRendering = pdevice->info.verx10 >= 75;1460break;1461}14621463case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT: {1464VkPhysicalDeviceCustomBorderColorFeaturesEXT *features =1465(VkPhysicalDeviceCustomBorderColorFeaturesEXT *)ext;1466features->customBorderColors = pdevice->info.ver >= 8;1467features->customBorderColorWithoutFormat = pdevice->info.ver >= 8;1468break;1469}14701471case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: {1472VkPhysicalDeviceDepthClipEnableFeaturesEXT *features =1473(VkPhysicalDeviceDepthClipEnableFeaturesEXT *)ext;1474features->depthClipEnable = true;1475break;1476}14771478case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR: {1479VkPhysicalDeviceFloat16Int8FeaturesKHR *features = (void *)ext;1480CORE_FEATURE(1, 2, shaderFloat16);1481CORE_FEATURE(1, 2, shaderInt8);1482break;1483}14841485case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT: {1486VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT *features =1487(VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT *)ext;1488features->fragmentShaderSampleInterlock = pdevice->info.ver >= 9;1489features->fragmentShaderPixelInterlock = pdevice->info.ver >= 9;1490features->fragmentShaderShadingRateInterlock = false;1491break;1492}14931494case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT: {1495VkPhysicalDeviceHostQueryResetFeaturesEXT *features =1496(VkPhysicalDeviceHostQueryResetFeaturesEXT *)ext;1497CORE_FEATURE(1, 2, hostQueryReset);1498break;1499}15001501case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT: {1502VkPhysicalDeviceDescriptorIndexingFeaturesEXT *features =1503(VkPhysicalDeviceDescriptorIndexingFeaturesEXT *)ext;1504CORE_FEATURE(1, 2, shaderInputAttachmentArrayDynamicIndexing);1505CORE_FEATURE(1, 2, shaderUniformTexelBufferArrayDynamicIndexing);1506CORE_FEATURE(1, 2, shaderStorageTexelBufferArrayDynamicIndexing);1507CORE_FEATURE(1, 2, shaderUniformBufferArrayNonUniformIndexing);1508CORE_FEATURE(1, 2, shaderSampledImageArrayNonUniformIndexing);1509CORE_FEATURE(1, 2, shaderStorageBufferArrayNonUniformIndexing);1510CORE_FEATURE(1, 2, shaderStorageImageArrayNonUniformIndexing);1511CORE_FEATURE(1, 2, shaderInputAttachmentArrayNonUniformIndexing);1512CORE_FEATURE(1, 2, shaderUniformTexelBufferArrayNonUniformIndexing);1513CORE_FEATURE(1, 2, shaderStorageTexelBufferArrayNonUniformIndexing);1514CORE_FEATURE(1, 2, descriptorBindingUniformBufferUpdateAfterBind);1515CORE_FEATURE(1, 2, descriptorBindingSampledImageUpdateAfterBind);1516CORE_FEATURE(1, 2, descriptorBindingStorageImageUpdateAfterBind);1517CORE_FEATURE(1, 2, descriptorBindingStorageBufferUpdateAfterBind);1518CORE_FEATURE(1, 2, descriptorBindingUniformTexelBufferUpdateAfterBind);1519CORE_FEATURE(1, 2, descriptorBindingStorageTexelBufferUpdateAfterBind);1520CORE_FEATURE(1, 2, descriptorBindingUpdateUnusedWhilePending);1521CORE_FEATURE(1, 2, descriptorBindingPartiallyBound);1522CORE_FEATURE(1, 2, descriptorBindingVariableDescriptorCount);1523CORE_FEATURE(1, 2, runtimeDescriptorArray);1524break;1525}15261527case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR: {1528VkPhysicalDeviceFragmentShadingRateFeaturesKHR *features =1529(VkPhysicalDeviceFragmentShadingRateFeaturesKHR *)ext;1530features->attachmentFragmentShadingRate = false;1531features->pipelineFragmentShadingRate = true;1532features->primitiveFragmentShadingRate = false;1533break;1534}15351536case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT: {1537VkPhysicalDeviceImageRobustnessFeaturesEXT *features =1538(VkPhysicalDeviceImageRobustnessFeaturesEXT *)ext;1539features->robustImageAccess = true;1540break;1541}15421543case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT: {1544VkPhysicalDeviceIndexTypeUint8FeaturesEXT *features =1545(VkPhysicalDeviceIndexTypeUint8FeaturesEXT *)ext;1546features->indexTypeUint8 = true;1547break;1548}15491550case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT: {1551VkPhysicalDeviceInlineUniformBlockFeaturesEXT *features =1552(VkPhysicalDeviceInlineUniformBlockFeaturesEXT *)ext;1553features->inlineUniformBlock = true;1554features->descriptorBindingInlineUniformBlockUpdateAfterBind = true;1555break;1556}15571558case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT: {1559VkPhysicalDeviceLineRasterizationFeaturesEXT *features =1560(VkPhysicalDeviceLineRasterizationFeaturesEXT *)ext;1561features->rectangularLines = true;1562features->bresenhamLines = true;1563/* Support for Smooth lines with MSAA was removed on gfx11. From the1564* BSpec section "Multisample ModesState" table for "AA Line Support1565* Requirements":1566*1567* GFX10:BUG:######## NUM_MULTISAMPLES == 11568*1569* Fortunately, this isn't a case most people care about.1570*/1571features->smoothLines = pdevice->info.ver < 10;1572features->stippledRectangularLines = false;1573features->stippledBresenhamLines = true;1574features->stippledSmoothLines = false;1575break;1576}15771578case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES: {1579VkPhysicalDeviceMultiviewFeatures *features =1580(VkPhysicalDeviceMultiviewFeatures *)ext;1581CORE_FEATURE(1, 1, multiview);1582CORE_FEATURE(1, 1, multiviewGeometryShader);1583CORE_FEATURE(1, 1, multiviewTessellationShader);1584break;1585}15861587case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR: {1588VkPhysicalDeviceImagelessFramebufferFeaturesKHR *features =1589(VkPhysicalDeviceImagelessFramebufferFeaturesKHR *)ext;1590CORE_FEATURE(1, 2, imagelessFramebuffer);1591break;1592}15931594case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR: {1595VkPhysicalDevicePerformanceQueryFeaturesKHR *feature =1596(VkPhysicalDevicePerformanceQueryFeaturesKHR *)ext;1597feature->performanceCounterQueryPools = true;1598/* HW only supports a single configuration at a time. */1599feature->performanceCounterMultipleQueryPools = false;1600break;1601}16021603case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT: {1604VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT *features =1605(VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT *)ext;1606features->pipelineCreationCacheControl = true;1607break;1608}16091610case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR: {1611VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR *features =1612(VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR *)ext;1613features->pipelineExecutableInfo = true;1614break;1615}16161617case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT: {1618VkPhysicalDevicePrivateDataFeaturesEXT *features = (void *)ext;1619features->privateData = true;1620break;1621}16221623case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES: {1624VkPhysicalDeviceProtectedMemoryFeatures *features = (void *)ext;1625CORE_FEATURE(1, 1, protectedMemory);1626break;1627}16281629case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT: {1630VkPhysicalDeviceProvokingVertexFeaturesEXT *features =1631(VkPhysicalDeviceProvokingVertexFeaturesEXT *)ext;1632features->provokingVertexLast = true;1633features->transformFeedbackPreservesProvokingVertex = true;1634break;1635}16361637case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT: {1638VkPhysicalDeviceRobustness2FeaturesEXT *features = (void *)ext;1639features->robustBufferAccess2 = true;1640features->robustImageAccess2 = true;1641features->nullDescriptor = true;1642break;1643}16441645case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES: {1646VkPhysicalDeviceSamplerYcbcrConversionFeatures *features =1647(VkPhysicalDeviceSamplerYcbcrConversionFeatures *) ext;1648CORE_FEATURE(1, 1, samplerYcbcrConversion);1649break;1650}16511652case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT: {1653VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *features =1654(VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *)ext;1655CORE_FEATURE(1, 2, scalarBlockLayout);1656break;1657}16581659case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR: {1660VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR *features =1661(VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR *)ext;1662CORE_FEATURE(1, 2, separateDepthStencilLayouts);1663break;1664}16651666case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT: {1667VkPhysicalDeviceShaderAtomicFloatFeaturesEXT *features = (void *)ext;1668features->shaderBufferFloat32Atomics = true;1669features->shaderBufferFloat32AtomicAdd = false;1670features->shaderBufferFloat64Atomics = false;1671features->shaderBufferFloat64AtomicAdd = false;1672features->shaderSharedFloat32Atomics = true;1673features->shaderSharedFloat32AtomicAdd = false;1674features->shaderSharedFloat64Atomics = false;1675features->shaderSharedFloat64AtomicAdd = false;1676features->shaderImageFloat32Atomics = true;1677features->shaderImageFloat32AtomicAdd = false;1678features->sparseImageFloat32Atomics = false;1679features->sparseImageFloat32AtomicAdd = false;1680break;1681}16821683case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR: {1684VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *features = (void *)ext;1685CORE_FEATURE(1, 2, shaderBufferInt64Atomics);1686CORE_FEATURE(1, 2, shaderSharedInt64Atomics);1687break;1688}16891690case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT: {1691VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT *features = (void *)ext;1692features->shaderDemoteToHelperInvocation = true;1693break;1694}16951696case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR: {1697VkPhysicalDeviceShaderClockFeaturesKHR *features =1698(VkPhysicalDeviceShaderClockFeaturesKHR *)ext;1699features->shaderSubgroupClock = true;1700features->shaderDeviceClock = false;1701break;1702}17031704case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES: {1705VkPhysicalDeviceShaderDrawParametersFeatures *features = (void *)ext;1706CORE_FEATURE(1, 1, shaderDrawParameters);1707break;1708}17091710case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL: {1711VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL *features =1712(VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL *)ext;1713features->shaderIntegerFunctions2 = true;1714break;1715}17161717case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR: {1718VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR *features =1719(VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR *)ext;1720CORE_FEATURE(1, 2, shaderSubgroupExtendedTypes);1721break;1722}17231724case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR: {1725VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR *features =1726(VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR *)ext;1727features->shaderSubgroupUniformControlFlow = true;1728break;1729}17301731case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR: {1732VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR *features =1733(VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR *)ext;1734features->shaderTerminateInvocation = true;1735break;1736}17371738case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT: {1739VkPhysicalDeviceSubgroupSizeControlFeaturesEXT *features =1740(VkPhysicalDeviceSubgroupSizeControlFeaturesEXT *)ext;1741features->subgroupSizeControl = true;1742features->computeFullSubgroups = true;1743break;1744}17451746case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT: {1747VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT *features =1748(VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT *)ext;1749features->texelBufferAlignment = true;1750break;1751}17521753case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR: {1754VkPhysicalDeviceTimelineSemaphoreFeaturesKHR *features =1755(VkPhysicalDeviceTimelineSemaphoreFeaturesKHR *) ext;1756CORE_FEATURE(1, 2, timelineSemaphore);1757break;1758}17591760case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES: {1761VkPhysicalDeviceVariablePointersFeatures *features = (void *)ext;1762CORE_FEATURE(1, 1, variablePointersStorageBuffer);1763CORE_FEATURE(1, 1, variablePointers);1764break;1765}17661767case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT: {1768VkPhysicalDeviceTransformFeedbackFeaturesEXT *features =1769(VkPhysicalDeviceTransformFeedbackFeaturesEXT *)ext;1770features->transformFeedback = true;1771features->geometryStreams = true;1772break;1773}17741775case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR: {1776VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *features =1777(VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *)ext;1778CORE_FEATURE(1, 2, uniformBufferStandardLayout);1779break;1780}17811782case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: {1783VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *features =1784(VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *)ext;1785features->vertexAttributeInstanceRateDivisor = true;1786features->vertexAttributeInstanceRateZeroDivisor = true;1787break;1788}17891790case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES:1791anv_get_physical_device_features_1_1(pdevice, (void *)ext);1792break;17931794case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES:1795anv_get_physical_device_features_1_2(pdevice, (void *)ext);1796break;17971798case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR: {1799VkPhysicalDeviceVulkanMemoryModelFeaturesKHR *features = (void *)ext;1800CORE_FEATURE(1, 2, vulkanMemoryModel);1801CORE_FEATURE(1, 2, vulkanMemoryModelDeviceScope);1802CORE_FEATURE(1, 2, vulkanMemoryModelAvailabilityVisibilityChains);1803break;1804}18051806case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR: {1807VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR *features =1808(VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR *)ext;1809features->workgroupMemoryExplicitLayout = true;1810features->workgroupMemoryExplicitLayoutScalarBlockLayout = true;1811features->workgroupMemoryExplicitLayout8BitAccess = true;1812features->workgroupMemoryExplicitLayout16BitAccess = true;1813break;1814}18151816case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT: {1817VkPhysicalDeviceYcbcrImageArraysFeaturesEXT *features =1818(VkPhysicalDeviceYcbcrImageArraysFeaturesEXT *)ext;1819features->ycbcrImageArrays = true;1820break;1821}18221823case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT: {1824VkPhysicalDeviceExtendedDynamicStateFeaturesEXT *features =1825(VkPhysicalDeviceExtendedDynamicStateFeaturesEXT *)ext;1826features->extendedDynamicState = true;1827break;1828}18291830case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT: {1831VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *features =1832(VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *)ext;1833features->extendedDynamicState2 = true;1834features->extendedDynamicState2LogicOp = true;1835features->extendedDynamicState2PatchControlPoints = false;1836break;1837}18381839case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES_KHR: {1840VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR *features =1841(VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR *)ext;1842features->shaderZeroInitializeWorkgroupMemory = true;1843break;1844}18451846case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT: {1847VkPhysicalDeviceMultiDrawFeaturesEXT *features = (VkPhysicalDeviceMultiDrawFeaturesEXT *)ext;1848features->multiDraw = true;1849break;1850}18511852default:1853anv_debug_ignored_stype(ext->sType);1854break;1855}1856}18571858#undef CORE_FEATURE1859}18601861#define MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BUFFERS 6418621863#define MAX_PER_STAGE_DESCRIPTOR_INPUT_ATTACHMENTS 641864#define MAX_DESCRIPTOR_SET_INPUT_ATTACHMENTS 25618651866#define MAX_CUSTOM_BORDER_COLORS 409618671868void anv_GetPhysicalDeviceProperties(1869VkPhysicalDevice physicalDevice,1870VkPhysicalDeviceProperties* pProperties)1871{1872ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);1873const struct intel_device_info *devinfo = &pdevice->info;18741875/* See assertions made when programming the buffer surface state. */1876const uint32_t max_raw_buffer_sz = devinfo->ver >= 7 ?1877(1ul << 30) : (1ul << 27);18781879const uint32_t max_ssbos = pdevice->has_a64_buffer_access ? UINT16_MAX : 64;1880const uint32_t max_textures =1881pdevice->has_bindless_images ? UINT16_MAX : 128;1882const uint32_t max_samplers =1883pdevice->has_bindless_samplers ? UINT16_MAX :1884(devinfo->verx10 >= 75) ? 128 : 16;1885const uint32_t max_images =1886pdevice->has_bindless_images ? UINT16_MAX : MAX_IMAGES;18871888/* If we can use bindless for everything, claim a high per-stage limit,1889* otherwise use the binding table size, minus the slots reserved for1890* render targets and one slot for the descriptor buffer. */1891const uint32_t max_per_stage =1892pdevice->has_bindless_images && pdevice->has_a64_buffer_access1893? UINT32_MAX : MAX_BINDING_TABLE_SIZE - MAX_RTS - 1;18941895/* Limit max_threads to 64 for the GPGPU_WALKER command */1896const uint32_t max_workgroup_size = 32 * MIN2(64, devinfo->max_cs_threads);18971898VkSampleCountFlags sample_counts =1899isl_device_get_sample_counts(&pdevice->isl_dev);190019011902VkPhysicalDeviceLimits limits = {1903.maxImageDimension1D = (1 << 14),1904.maxImageDimension2D = (1 << 14),1905.maxImageDimension3D = (1 << 11),1906.maxImageDimensionCube = (1 << 14),1907.maxImageArrayLayers = (1 << 11),1908.maxTexelBufferElements = 128 * 1024 * 1024,1909.maxUniformBufferRange = (1ul << 27),1910.maxStorageBufferRange = max_raw_buffer_sz,1911.maxPushConstantsSize = MAX_PUSH_CONSTANTS_SIZE,1912.maxMemoryAllocationCount = UINT32_MAX,1913.maxSamplerAllocationCount = 64 * 1024,1914.bufferImageGranularity = 64, /* A cache line */1915.sparseAddressSpaceSize = 0,1916.maxBoundDescriptorSets = MAX_SETS,1917.maxPerStageDescriptorSamplers = max_samplers,1918.maxPerStageDescriptorUniformBuffers = MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BUFFERS,1919.maxPerStageDescriptorStorageBuffers = max_ssbos,1920.maxPerStageDescriptorSampledImages = max_textures,1921.maxPerStageDescriptorStorageImages = max_images,1922.maxPerStageDescriptorInputAttachments = MAX_PER_STAGE_DESCRIPTOR_INPUT_ATTACHMENTS,1923.maxPerStageResources = max_per_stage,1924.maxDescriptorSetSamplers = 6 * max_samplers, /* number of stages * maxPerStageDescriptorSamplers */1925.maxDescriptorSetUniformBuffers = 6 * MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BUFFERS, /* number of stages * maxPerStageDescriptorUniformBuffers */1926.maxDescriptorSetUniformBuffersDynamic = MAX_DYNAMIC_BUFFERS / 2,1927.maxDescriptorSetStorageBuffers = 6 * max_ssbos, /* number of stages * maxPerStageDescriptorStorageBuffers */1928.maxDescriptorSetStorageBuffersDynamic = MAX_DYNAMIC_BUFFERS / 2,1929.maxDescriptorSetSampledImages = 6 * max_textures, /* number of stages * maxPerStageDescriptorSampledImages */1930.maxDescriptorSetStorageImages = 6 * max_images, /* number of stages * maxPerStageDescriptorStorageImages */1931.maxDescriptorSetInputAttachments = MAX_DESCRIPTOR_SET_INPUT_ATTACHMENTS,1932.maxVertexInputAttributes = MAX_VBS,1933.maxVertexInputBindings = MAX_VBS,1934.maxVertexInputAttributeOffset = 2047,1935.maxVertexInputBindingStride = 2048,1936.maxVertexOutputComponents = 128,1937.maxTessellationGenerationLevel = 64,1938.maxTessellationPatchSize = 32,1939.maxTessellationControlPerVertexInputComponents = 128,1940.maxTessellationControlPerVertexOutputComponents = 128,1941.maxTessellationControlPerPatchOutputComponents = 128,1942.maxTessellationControlTotalOutputComponents = 2048,1943.maxTessellationEvaluationInputComponents = 128,1944.maxTessellationEvaluationOutputComponents = 128,1945.maxGeometryShaderInvocations = 32,1946.maxGeometryInputComponents = devinfo->ver >= 8 ? 128 : 64,1947.maxGeometryOutputComponents = 128,1948.maxGeometryOutputVertices = 256,1949.maxGeometryTotalOutputComponents = 1024,1950.maxFragmentInputComponents = 116, /* 128 components - (PSIZ, CLIP_DIST0, CLIP_DIST1) */1951.maxFragmentOutputAttachments = 8,1952.maxFragmentDualSrcAttachments = 1,1953.maxFragmentCombinedOutputResources = 8,1954.maxComputeSharedMemorySize = 64 * 1024,1955.maxComputeWorkGroupCount = { 65535, 65535, 65535 },1956.maxComputeWorkGroupInvocations = max_workgroup_size,1957.maxComputeWorkGroupSize = {1958max_workgroup_size,1959max_workgroup_size,1960max_workgroup_size,1961},1962.subPixelPrecisionBits = 8,1963.subTexelPrecisionBits = 8,1964.mipmapPrecisionBits = 8,1965.maxDrawIndexedIndexValue = UINT32_MAX,1966.maxDrawIndirectCount = UINT32_MAX,1967.maxSamplerLodBias = 16,1968.maxSamplerAnisotropy = 16,1969.maxViewports = MAX_VIEWPORTS,1970.maxViewportDimensions = { (1 << 14), (1 << 14) },1971.viewportBoundsRange = { INT16_MIN, INT16_MAX },1972.viewportSubPixelBits = 13, /* We take a float? */1973.minMemoryMapAlignment = 4096, /* A page */1974/* The dataport requires texel alignment so we need to assume a worst1975* case of R32G32B32A32 which is 16 bytes.1976*/1977.minTexelBufferOffsetAlignment = 16,1978.minUniformBufferOffsetAlignment = ANV_UBO_ALIGNMENT,1979.minStorageBufferOffsetAlignment = ANV_SSBO_ALIGNMENT,1980.minTexelOffset = -8,1981.maxTexelOffset = 7,1982.minTexelGatherOffset = -32,1983.maxTexelGatherOffset = 31,1984.minInterpolationOffset = -0.5,1985.maxInterpolationOffset = 0.4375,1986.subPixelInterpolationOffsetBits = 4,1987.maxFramebufferWidth = (1 << 14),1988.maxFramebufferHeight = (1 << 14),1989.maxFramebufferLayers = (1 << 11),1990.framebufferColorSampleCounts = sample_counts,1991.framebufferDepthSampleCounts = sample_counts,1992.framebufferStencilSampleCounts = sample_counts,1993.framebufferNoAttachmentsSampleCounts = sample_counts,1994.maxColorAttachments = MAX_RTS,1995.sampledImageColorSampleCounts = sample_counts,1996.sampledImageIntegerSampleCounts = sample_counts,1997.sampledImageDepthSampleCounts = sample_counts,1998.sampledImageStencilSampleCounts = sample_counts,1999.storageImageSampleCounts = VK_SAMPLE_COUNT_1_BIT,2000.maxSampleMaskWords = 1,2001.timestampComputeAndGraphics = true,2002.timestampPeriod = 1000000000.0 / devinfo->timestamp_frequency,2003.maxClipDistances = 8,2004.maxCullDistances = 8,2005.maxCombinedClipAndCullDistances = 8,2006.discreteQueuePriorities = 2,2007.pointSizeRange = { 0.125, 255.875 },2008.lineWidthRange = {20090.0,2010(devinfo->ver >= 9 || devinfo->is_cherryview) ?20112047.9921875 : 7.9921875,2012},2013.pointSizeGranularity = (1.0 / 8.0),2014.lineWidthGranularity = (1.0 / 128.0),2015.strictLines = false,2016.standardSampleLocations = true,2017.optimalBufferCopyOffsetAlignment = 128,2018.optimalBufferCopyRowPitchAlignment = 128,2019.nonCoherentAtomSize = 64,2020};20212022*pProperties = (VkPhysicalDeviceProperties) {2023.apiVersion = ANV_API_VERSION,2024.driverVersion = vk_get_driver_version(),2025.vendorID = 0x8086,2026.deviceID = pdevice->info.chipset_id,2027.deviceType = pdevice->info.has_local_mem ?2028VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU :2029VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,2030.limits = limits,2031.sparseProperties = {0}, /* Broadwell doesn't do sparse. */2032};20332034snprintf(pProperties->deviceName, sizeof(pProperties->deviceName),2035"%s", pdevice->name);2036memcpy(pProperties->pipelineCacheUUID,2037pdevice->pipeline_cache_uuid, VK_UUID_SIZE);2038}20392040static void2041anv_get_physical_device_properties_1_1(struct anv_physical_device *pdevice,2042VkPhysicalDeviceVulkan11Properties *p)2043{2044assert(p->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES);20452046memcpy(p->deviceUUID, pdevice->device_uuid, VK_UUID_SIZE);2047memcpy(p->driverUUID, pdevice->driver_uuid, VK_UUID_SIZE);2048memset(p->deviceLUID, 0, VK_LUID_SIZE);2049p->deviceNodeMask = 0;2050p->deviceLUIDValid = false;20512052p->subgroupSize = BRW_SUBGROUP_SIZE;2053VkShaderStageFlags scalar_stages = 0;2054for (unsigned stage = 0; stage < MESA_VULKAN_SHADER_STAGES; stage++) {2055if (pdevice->compiler->scalar_stage[stage])2056scalar_stages |= mesa_to_vk_shader_stage(stage);2057}2058p->subgroupSupportedStages = scalar_stages;2059p->subgroupSupportedOperations = VK_SUBGROUP_FEATURE_BASIC_BIT |2060VK_SUBGROUP_FEATURE_VOTE_BIT |2061VK_SUBGROUP_FEATURE_BALLOT_BIT |2062VK_SUBGROUP_FEATURE_SHUFFLE_BIT |2063VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT |2064VK_SUBGROUP_FEATURE_QUAD_BIT;2065if (pdevice->info.ver >= 8) {2066/* TODO: There's no technical reason why these can't be made to2067* work on gfx7 but they don't at the moment so it's best to leave2068* the feature disabled than enabled and broken.2069*/2070p->subgroupSupportedOperations |= VK_SUBGROUP_FEATURE_ARITHMETIC_BIT |2071VK_SUBGROUP_FEATURE_CLUSTERED_BIT;2072}2073p->subgroupQuadOperationsInAllStages = pdevice->info.ver >= 8;20742075p->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY;2076p->maxMultiviewViewCount = 16;2077p->maxMultiviewInstanceIndex = UINT32_MAX / 16;2078p->protectedNoFault = false;2079/* This value doesn't matter for us today as our per-stage descriptors are2080* the real limit.2081*/2082p->maxPerSetDescriptors = 1024;2083p->maxMemoryAllocationSize = MAX_MEMORY_ALLOCATION_SIZE;2084}20852086static void2087anv_get_physical_device_properties_1_2(struct anv_physical_device *pdevice,2088VkPhysicalDeviceVulkan12Properties *p)2089{2090assert(p->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES);20912092p->driverID = VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR;2093memset(p->driverName, 0, sizeof(p->driverName));2094snprintf(p->driverName, VK_MAX_DRIVER_NAME_SIZE_KHR,2095"Intel open-source Mesa driver");2096memset(p->driverInfo, 0, sizeof(p->driverInfo));2097snprintf(p->driverInfo, VK_MAX_DRIVER_INFO_SIZE_KHR,2098"Mesa " PACKAGE_VERSION MESA_GIT_SHA1);2099p->conformanceVersion = (VkConformanceVersionKHR) {2100.major = 1,2101.minor = 2,2102.subminor = 0,2103.patch = 0,2104};21052106p->denormBehaviorIndependence =2107VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR;2108p->roundingModeIndependence =2109VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR;21102111/* Broadwell does not support HF denorms and there are restrictions2112* other gens. According to Kabylake's PRM:2113*2114* "math - Extended Math Function2115* [...]2116* Restriction : Half-float denorms are always retained."2117*/2118p->shaderDenormFlushToZeroFloat16 = false;2119p->shaderDenormPreserveFloat16 = pdevice->info.ver > 8;2120p->shaderRoundingModeRTEFloat16 = true;2121p->shaderRoundingModeRTZFloat16 = true;2122p->shaderSignedZeroInfNanPreserveFloat16 = true;21232124p->shaderDenormFlushToZeroFloat32 = true;2125p->shaderDenormPreserveFloat32 = true;2126p->shaderRoundingModeRTEFloat32 = true;2127p->shaderRoundingModeRTZFloat32 = true;2128p->shaderSignedZeroInfNanPreserveFloat32 = true;21292130p->shaderDenormFlushToZeroFloat64 = true;2131p->shaderDenormPreserveFloat64 = true;2132p->shaderRoundingModeRTEFloat64 = true;2133p->shaderRoundingModeRTZFloat64 = true;2134p->shaderSignedZeroInfNanPreserveFloat64 = true;21352136/* It's a bit hard to exactly map our implementation to the limits2137* described by Vulkan. The bindless surface handle in the extended2138* message descriptors is 20 bits and it's an index into the table of2139* RENDER_SURFACE_STATE structs that starts at bindless surface base2140* address. This means that we can have at must 1M surface states2141* allocated at any given time. Since most image views take two2142* descriptors, this means we have a limit of about 500K image views.2143*2144* However, since we allocate surface states at vkCreateImageView time,2145* this means our limit is actually something on the order of 500K image2146* views allocated at any time. The actual limit describe by Vulkan, on2147* the other hand, is a limit of how many you can have in a descriptor set.2148* Assuming anyone using 1M descriptors will be using the same image view2149* twice a bunch of times (or a bunch of null descriptors), we can safely2150* advertise a larger limit here.2151*/2152const unsigned max_bindless_views = 1 << 20;2153p->maxUpdateAfterBindDescriptorsInAllPools = max_bindless_views;2154p->shaderUniformBufferArrayNonUniformIndexingNative = false;2155p->shaderSampledImageArrayNonUniformIndexingNative = false;2156p->shaderStorageBufferArrayNonUniformIndexingNative = true;2157p->shaderStorageImageArrayNonUniformIndexingNative = false;2158p->shaderInputAttachmentArrayNonUniformIndexingNative = false;2159p->robustBufferAccessUpdateAfterBind = true;2160p->quadDivergentImplicitLod = false;2161p->maxPerStageDescriptorUpdateAfterBindSamplers = max_bindless_views;2162p->maxPerStageDescriptorUpdateAfterBindUniformBuffers = MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BUFFERS;2163p->maxPerStageDescriptorUpdateAfterBindStorageBuffers = UINT32_MAX;2164p->maxPerStageDescriptorUpdateAfterBindSampledImages = max_bindless_views;2165p->maxPerStageDescriptorUpdateAfterBindStorageImages = max_bindless_views;2166p->maxPerStageDescriptorUpdateAfterBindInputAttachments = MAX_PER_STAGE_DESCRIPTOR_INPUT_ATTACHMENTS;2167p->maxPerStageUpdateAfterBindResources = UINT32_MAX;2168p->maxDescriptorSetUpdateAfterBindSamplers = max_bindless_views;2169p->maxDescriptorSetUpdateAfterBindUniformBuffers = 6 * MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BUFFERS;2170p->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = MAX_DYNAMIC_BUFFERS / 2;2171p->maxDescriptorSetUpdateAfterBindStorageBuffers = UINT32_MAX;2172p->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = MAX_DYNAMIC_BUFFERS / 2;2173p->maxDescriptorSetUpdateAfterBindSampledImages = max_bindless_views;2174p->maxDescriptorSetUpdateAfterBindStorageImages = max_bindless_views;2175p->maxDescriptorSetUpdateAfterBindInputAttachments = MAX_DESCRIPTOR_SET_INPUT_ATTACHMENTS;21762177/* We support all of the depth resolve modes */2178p->supportedDepthResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR |2179VK_RESOLVE_MODE_AVERAGE_BIT_KHR |2180VK_RESOLVE_MODE_MIN_BIT_KHR |2181VK_RESOLVE_MODE_MAX_BIT_KHR;2182/* Average doesn't make sense for stencil so we don't support that */2183p->supportedStencilResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR;2184if (pdevice->info.ver >= 8) {2185/* The advanced stencil resolve modes currently require stencil2186* sampling be supported by the hardware.2187*/2188p->supportedStencilResolveModes |= VK_RESOLVE_MODE_MIN_BIT_KHR |2189VK_RESOLVE_MODE_MAX_BIT_KHR;2190}2191p->independentResolveNone = true;2192p->independentResolve = true;21932194p->filterMinmaxSingleComponentFormats = pdevice->info.ver >= 9;2195p->filterMinmaxImageComponentMapping = pdevice->info.ver >= 9;21962197p->maxTimelineSemaphoreValueDifference = UINT64_MAX;21982199p->framebufferIntegerColorSampleCounts =2200isl_device_get_sample_counts(&pdevice->isl_dev);2201}22022203void anv_GetPhysicalDeviceProperties2(2204VkPhysicalDevice physicalDevice,2205VkPhysicalDeviceProperties2* pProperties)2206{2207ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);22082209anv_GetPhysicalDeviceProperties(physicalDevice, &pProperties->properties);22102211VkPhysicalDeviceVulkan11Properties core_1_1 = {2212.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES,2213};2214anv_get_physical_device_properties_1_1(pdevice, &core_1_1);22152216VkPhysicalDeviceVulkan12Properties core_1_2 = {2217.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES,2218};2219anv_get_physical_device_properties_1_2(pdevice, &core_1_2);22202221#define CORE_RENAMED_PROPERTY(major, minor, ext_property, core_property) \2222memcpy(&properties->ext_property, &core_##major##_##minor.core_property, \2223sizeof(core_##major##_##minor.core_property))22242225#define CORE_PROPERTY(major, minor, property) \2226CORE_RENAMED_PROPERTY(major, minor, property, property)22272228vk_foreach_struct(ext, pProperties->pNext) {2229switch (ext->sType) {2230case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR: {2231VkPhysicalDeviceAccelerationStructurePropertiesKHR *props = (void *)ext;2232props->maxGeometryCount = (1u << 24) - 1;2233props->maxInstanceCount = (1u << 24) - 1;2234props->maxPrimitiveCount = (1u << 29) - 1;2235props->maxPerStageDescriptorAccelerationStructures = UINT16_MAX;2236props->maxPerStageDescriptorUpdateAfterBindAccelerationStructures = UINT16_MAX;2237props->maxDescriptorSetAccelerationStructures = UINT16_MAX;2238props->maxDescriptorSetUpdateAfterBindAccelerationStructures = UINT16_MAX;2239props->minAccelerationStructureScratchOffsetAlignment = 64;2240break;2241}22422243case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT: {2244/* TODO: Real limits */2245VkPhysicalDeviceConservativeRasterizationPropertiesEXT *properties =2246(VkPhysicalDeviceConservativeRasterizationPropertiesEXT *)ext;2247/* There's nothing in the public docs about this value as far as I2248* can tell. However, this is the value the Windows driver reports2249* and there's a comment on a rejected HW feature in the internal2250* docs that says:2251*2252* "This is similar to conservative rasterization, except the2253* primitive area is not extended by 1/512 and..."2254*2255* That's a bit of an obtuse reference but it's the best we've got2256* for now.2257*/2258properties->primitiveOverestimationSize = 1.0f / 512.0f;2259properties->maxExtraPrimitiveOverestimationSize = 0.0f;2260properties->extraPrimitiveOverestimationSizeGranularity = 0.0f;2261properties->primitiveUnderestimation = false;2262properties->conservativePointAndLineRasterization = false;2263properties->degenerateTrianglesRasterized = true;2264properties->degenerateLinesRasterized = false;2265properties->fullyCoveredFragmentShaderInputVariable = false;2266properties->conservativeRasterizationPostDepthCoverage = true;2267break;2268}22692270case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT: {2271VkPhysicalDeviceCustomBorderColorPropertiesEXT *properties =2272(VkPhysicalDeviceCustomBorderColorPropertiesEXT *)ext;2273properties->maxCustomBorderColorSamplers = MAX_CUSTOM_BORDER_COLORS;2274break;2275}22762277case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR: {2278VkPhysicalDeviceDepthStencilResolvePropertiesKHR *properties =2279(VkPhysicalDeviceDepthStencilResolvePropertiesKHR *)ext;2280CORE_PROPERTY(1, 2, supportedDepthResolveModes);2281CORE_PROPERTY(1, 2, supportedStencilResolveModes);2282CORE_PROPERTY(1, 2, independentResolveNone);2283CORE_PROPERTY(1, 2, independentResolve);2284break;2285}22862287case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT: {2288VkPhysicalDeviceDescriptorIndexingPropertiesEXT *properties =2289(VkPhysicalDeviceDescriptorIndexingPropertiesEXT *)ext;2290CORE_PROPERTY(1, 2, maxUpdateAfterBindDescriptorsInAllPools);2291CORE_PROPERTY(1, 2, shaderUniformBufferArrayNonUniformIndexingNative);2292CORE_PROPERTY(1, 2, shaderSampledImageArrayNonUniformIndexingNative);2293CORE_PROPERTY(1, 2, shaderStorageBufferArrayNonUniformIndexingNative);2294CORE_PROPERTY(1, 2, shaderStorageImageArrayNonUniformIndexingNative);2295CORE_PROPERTY(1, 2, shaderInputAttachmentArrayNonUniformIndexingNative);2296CORE_PROPERTY(1, 2, robustBufferAccessUpdateAfterBind);2297CORE_PROPERTY(1, 2, quadDivergentImplicitLod);2298CORE_PROPERTY(1, 2, maxPerStageDescriptorUpdateAfterBindSamplers);2299CORE_PROPERTY(1, 2, maxPerStageDescriptorUpdateAfterBindUniformBuffers);2300CORE_PROPERTY(1, 2, maxPerStageDescriptorUpdateAfterBindStorageBuffers);2301CORE_PROPERTY(1, 2, maxPerStageDescriptorUpdateAfterBindSampledImages);2302CORE_PROPERTY(1, 2, maxPerStageDescriptorUpdateAfterBindStorageImages);2303CORE_PROPERTY(1, 2, maxPerStageDescriptorUpdateAfterBindInputAttachments);2304CORE_PROPERTY(1, 2, maxPerStageUpdateAfterBindResources);2305CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindSamplers);2306CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindUniformBuffers);2307CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindUniformBuffersDynamic);2308CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindStorageBuffers);2309CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindStorageBuffersDynamic);2310CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindSampledImages);2311CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindStorageImages);2312CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindInputAttachments);2313break;2314}23152316case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR: {2317VkPhysicalDeviceFragmentShadingRatePropertiesKHR *props =2318(VkPhysicalDeviceFragmentShadingRatePropertiesKHR *)ext;2319/* Those must be 0 if attachmentFragmentShadingRate is not2320* supported.2321*/2322props->minFragmentShadingRateAttachmentTexelSize = (VkExtent2D) { 0, 0 };2323props->maxFragmentShadingRateAttachmentTexelSize = (VkExtent2D) { 0, 0 };2324props->maxFragmentShadingRateAttachmentTexelSizeAspectRatio = 0;23252326props->primitiveFragmentShadingRateWithMultipleViewports = false;2327props->layeredShadingRateAttachments = false;2328props->fragmentShadingRateNonTrivialCombinerOps = false;2329props->maxFragmentSize = (VkExtent2D) { 4, 4 };2330props->maxFragmentSizeAspectRatio = 4;2331props->maxFragmentShadingRateCoverageSamples = 4 * 4 * 16;2332props->maxFragmentShadingRateRasterizationSamples = VK_SAMPLE_COUNT_16_BIT;2333props->fragmentShadingRateWithShaderDepthStencilWrites = false;2334props->fragmentShadingRateWithSampleMask = true;2335props->fragmentShadingRateWithShaderSampleMask = false;2336props->fragmentShadingRateWithConservativeRasterization = true;2337props->fragmentShadingRateWithFragmentShaderInterlock = true;2338props->fragmentShadingRateWithCustomSampleLocations = true;2339props->fragmentShadingRateStrictMultiplyCombiner = false;2340break;2341}23422343case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR: {2344VkPhysicalDeviceDriverPropertiesKHR *properties =2345(VkPhysicalDeviceDriverPropertiesKHR *) ext;2346CORE_PROPERTY(1, 2, driverID);2347CORE_PROPERTY(1, 2, driverName);2348CORE_PROPERTY(1, 2, driverInfo);2349CORE_PROPERTY(1, 2, conformanceVersion);2350break;2351}23522353case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT: {2354VkPhysicalDeviceDrmPropertiesEXT *props =2355(VkPhysicalDeviceDrmPropertiesEXT *)ext;23562357props->hasPrimary = pdevice->has_master;2358props->primaryMajor = pdevice->master_major;2359props->primaryMinor = pdevice->master_minor;23602361props->hasRender = pdevice->has_local;2362props->renderMajor = pdevice->local_major;2363props->renderMinor = pdevice->local_minor;23642365break;2366}23672368case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT: {2369VkPhysicalDeviceExternalMemoryHostPropertiesEXT *props =2370(VkPhysicalDeviceExternalMemoryHostPropertiesEXT *) ext;2371/* Userptr needs page aligned memory. */2372props->minImportedHostPointerAlignment = 4096;2373break;2374}23752376case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES: {2377VkPhysicalDeviceIDProperties *properties =2378(VkPhysicalDeviceIDProperties *)ext;2379CORE_PROPERTY(1, 1, deviceUUID);2380CORE_PROPERTY(1, 1, driverUUID);2381CORE_PROPERTY(1, 1, deviceLUID);2382CORE_PROPERTY(1, 1, deviceLUIDValid);2383break;2384}23852386case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT: {2387VkPhysicalDeviceInlineUniformBlockPropertiesEXT *props =2388(VkPhysicalDeviceInlineUniformBlockPropertiesEXT *)ext;2389props->maxInlineUniformBlockSize = MAX_INLINE_UNIFORM_BLOCK_SIZE;2390props->maxPerStageDescriptorInlineUniformBlocks =2391MAX_INLINE_UNIFORM_BLOCK_DESCRIPTORS;2392props->maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks =2393MAX_INLINE_UNIFORM_BLOCK_DESCRIPTORS;2394props->maxDescriptorSetInlineUniformBlocks =2395MAX_INLINE_UNIFORM_BLOCK_DESCRIPTORS;2396props->maxDescriptorSetUpdateAfterBindInlineUniformBlocks =2397MAX_INLINE_UNIFORM_BLOCK_DESCRIPTORS;2398break;2399}24002401case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT: {2402VkPhysicalDeviceLineRasterizationPropertiesEXT *props =2403(VkPhysicalDeviceLineRasterizationPropertiesEXT *)ext;2404/* In the Skylake PRM Vol. 7, subsection titled "GIQ (Diamond)2405* Sampling Rules - Legacy Mode", it says the following:2406*2407* "Note that the device divides a pixel into a 16x16 array of2408* subpixels, referenced by their upper left corners."2409*2410* This is the only known reference in the PRMs to the subpixel2411* precision of line rasterization and a "16x16 array of subpixels"2412* implies 4 subpixel precision bits. Empirical testing has shown2413* that 4 subpixel precision bits applies to all line rasterization2414* types.2415*/2416props->lineSubPixelPrecisionBits = 4;2417break;2418}24192420case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES: {2421VkPhysicalDeviceMaintenance3Properties *properties =2422(VkPhysicalDeviceMaintenance3Properties *)ext;2423/* This value doesn't matter for us today as our per-stage2424* descriptors are the real limit.2425*/2426CORE_PROPERTY(1, 1, maxPerSetDescriptors);2427CORE_PROPERTY(1, 1, maxMemoryAllocationSize);2428break;2429}24302431case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES: {2432VkPhysicalDeviceMultiviewProperties *properties =2433(VkPhysicalDeviceMultiviewProperties *)ext;2434CORE_PROPERTY(1, 1, maxMultiviewViewCount);2435CORE_PROPERTY(1, 1, maxMultiviewInstanceIndex);2436break;2437}24382439case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT: {2440VkPhysicalDevicePCIBusInfoPropertiesEXT *properties =2441(VkPhysicalDevicePCIBusInfoPropertiesEXT *)ext;2442properties->pciDomain = pdevice->pci_info.domain;2443properties->pciBus = pdevice->pci_info.bus;2444properties->pciDevice = pdevice->pci_info.device;2445properties->pciFunction = pdevice->pci_info.function;2446break;2447}24482449case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR: {2450VkPhysicalDevicePerformanceQueryPropertiesKHR *properties =2451(VkPhysicalDevicePerformanceQueryPropertiesKHR *)ext;2452/* We could support this by spawning a shader to do the equation2453* normalization.2454*/2455properties->allowCommandBufferQueryCopies = false;2456break;2457}24582459case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES: {2460VkPhysicalDevicePointClippingProperties *properties =2461(VkPhysicalDevicePointClippingProperties *) ext;2462CORE_PROPERTY(1, 1, pointClippingBehavior);2463break;2464}24652466#pragma GCC diagnostic push2467#pragma GCC diagnostic ignored "-Wswitch"2468case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID: {2469VkPhysicalDevicePresentationPropertiesANDROID *props =2470(VkPhysicalDevicePresentationPropertiesANDROID *)ext;2471props->sharedImage = VK_FALSE;2472break;2473}2474#pragma GCC diagnostic pop24752476case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES: {2477VkPhysicalDeviceProtectedMemoryProperties *properties =2478(VkPhysicalDeviceProtectedMemoryProperties *)ext;2479CORE_PROPERTY(1, 1, protectedNoFault);2480break;2481}24822483case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT: {2484VkPhysicalDeviceProvokingVertexPropertiesEXT *properties =2485(VkPhysicalDeviceProvokingVertexPropertiesEXT *)ext;2486properties->provokingVertexModePerPipeline = true;2487properties->transformFeedbackPreservesTriangleFanProvokingVertex = false;2488break;2489}24902491case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: {2492VkPhysicalDevicePushDescriptorPropertiesKHR *properties =2493(VkPhysicalDevicePushDescriptorPropertiesKHR *) ext;2494properties->maxPushDescriptors = MAX_PUSH_DESCRIPTORS;2495break;2496}24972498case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT: {2499VkPhysicalDeviceRobustness2PropertiesEXT *properties = (void *)ext;2500properties->robustStorageBufferAccessSizeAlignment =2501ANV_SSBO_BOUNDS_CHECK_ALIGNMENT;2502properties->robustUniformBufferAccessSizeAlignment =2503ANV_UBO_ALIGNMENT;2504break;2505}25062507case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT: {2508VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT *properties =2509(VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT *)ext;2510CORE_PROPERTY(1, 2, filterMinmaxImageComponentMapping);2511CORE_PROPERTY(1, 2, filterMinmaxSingleComponentFormats);2512break;2513}25142515case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES: {2516VkPhysicalDeviceSubgroupProperties *properties = (void *)ext;2517CORE_PROPERTY(1, 1, subgroupSize);2518CORE_RENAMED_PROPERTY(1, 1, supportedStages,2519subgroupSupportedStages);2520CORE_RENAMED_PROPERTY(1, 1, supportedOperations,2521subgroupSupportedOperations);2522CORE_RENAMED_PROPERTY(1, 1, quadOperationsInAllStages,2523subgroupQuadOperationsInAllStages);2524break;2525}25262527case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT: {2528VkPhysicalDeviceSubgroupSizeControlPropertiesEXT *props =2529(VkPhysicalDeviceSubgroupSizeControlPropertiesEXT *)ext;2530STATIC_ASSERT(8 <= BRW_SUBGROUP_SIZE && BRW_SUBGROUP_SIZE <= 32);2531props->minSubgroupSize = 8;2532props->maxSubgroupSize = 32;2533/* Limit max_threads to 64 for the GPGPU_WALKER command. */2534props->maxComputeWorkgroupSubgroups = MIN2(64, pdevice->info.max_cs_threads);2535props->requiredSubgroupSizeStages = VK_SHADER_STAGE_COMPUTE_BIT;2536break;2537}2538case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR : {2539VkPhysicalDeviceFloatControlsPropertiesKHR *properties = (void *)ext;2540CORE_PROPERTY(1, 2, denormBehaviorIndependence);2541CORE_PROPERTY(1, 2, roundingModeIndependence);2542CORE_PROPERTY(1, 2, shaderDenormFlushToZeroFloat16);2543CORE_PROPERTY(1, 2, shaderDenormPreserveFloat16);2544CORE_PROPERTY(1, 2, shaderRoundingModeRTEFloat16);2545CORE_PROPERTY(1, 2, shaderRoundingModeRTZFloat16);2546CORE_PROPERTY(1, 2, shaderSignedZeroInfNanPreserveFloat16);2547CORE_PROPERTY(1, 2, shaderDenormFlushToZeroFloat32);2548CORE_PROPERTY(1, 2, shaderDenormPreserveFloat32);2549CORE_PROPERTY(1, 2, shaderRoundingModeRTEFloat32);2550CORE_PROPERTY(1, 2, shaderRoundingModeRTZFloat32);2551CORE_PROPERTY(1, 2, shaderSignedZeroInfNanPreserveFloat32);2552CORE_PROPERTY(1, 2, shaderDenormFlushToZeroFloat64);2553CORE_PROPERTY(1, 2, shaderDenormPreserveFloat64);2554CORE_PROPERTY(1, 2, shaderRoundingModeRTEFloat64);2555CORE_PROPERTY(1, 2, shaderRoundingModeRTZFloat64);2556CORE_PROPERTY(1, 2, shaderSignedZeroInfNanPreserveFloat64);2557break;2558}25592560case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT: {2561VkPhysicalDeviceSampleLocationsPropertiesEXT *props =2562(VkPhysicalDeviceSampleLocationsPropertiesEXT *)ext;25632564props->sampleLocationSampleCounts =2565isl_device_get_sample_counts(&pdevice->isl_dev);25662567/* See also anv_GetPhysicalDeviceMultisamplePropertiesEXT */2568props->maxSampleLocationGridSize.width = 1;2569props->maxSampleLocationGridSize.height = 1;25702571props->sampleLocationCoordinateRange[0] = 0;2572props->sampleLocationCoordinateRange[1] = 0.9375;2573props->sampleLocationSubPixelBits = 4;25742575props->variableSampleLocations = true;2576break;2577}25782579case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT: {2580VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT *props =2581(VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT *)ext;25822583/* From the SKL PRM Vol. 2d, docs for RENDER_SURFACE_STATE::Surface2584* Base Address:2585*2586* "For SURFTYPE_BUFFER non-rendertarget surfaces, this field2587* specifies the base address of the first element of the surface,2588* computed in software by adding the surface base address to the2589* byte offset of the element in the buffer. The base address must2590* be aligned to element size."2591*2592* The typed dataport messages require that things be texel aligned.2593* Otherwise, we may just load/store the wrong data or, in the worst2594* case, there may be hangs.2595*/2596props->storageTexelBufferOffsetAlignmentBytes = 16;2597props->storageTexelBufferOffsetSingleTexelAlignment = true;25982599/* The sampler, however, is much more forgiving and it can handle2600* arbitrary byte alignment for linear and buffer surfaces. It's2601* hard to find a good PRM citation for this but years of empirical2602* experience demonstrate that this is true.2603*/2604props->uniformTexelBufferOffsetAlignmentBytes = 1;2605props->uniformTexelBufferOffsetSingleTexelAlignment = false;2606break;2607}26082609case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR: {2610VkPhysicalDeviceTimelineSemaphorePropertiesKHR *properties =2611(VkPhysicalDeviceTimelineSemaphorePropertiesKHR *) ext;2612CORE_PROPERTY(1, 2, maxTimelineSemaphoreValueDifference);2613break;2614}26152616case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT: {2617VkPhysicalDeviceTransformFeedbackPropertiesEXT *props =2618(VkPhysicalDeviceTransformFeedbackPropertiesEXT *)ext;26192620props->maxTransformFeedbackStreams = MAX_XFB_STREAMS;2621props->maxTransformFeedbackBuffers = MAX_XFB_BUFFERS;2622props->maxTransformFeedbackBufferSize = (1ull << 32);2623props->maxTransformFeedbackStreamDataSize = 128 * 4;2624props->maxTransformFeedbackBufferDataSize = 128 * 4;2625props->maxTransformFeedbackBufferDataStride = 2048;2626props->transformFeedbackQueries = true;2627props->transformFeedbackStreamsLinesTriangles = false;2628props->transformFeedbackRasterizationStreamSelect = false;2629/* This requires MI_MATH */2630props->transformFeedbackDraw = pdevice->info.verx10 >= 75;2631break;2632}26332634case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {2635VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *props =2636(VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext;2637/* We have to restrict this a bit for multiview */2638props->maxVertexAttribDivisor = UINT32_MAX / 16;2639break;2640}26412642case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT: {2643VkPhysicalDeviceMultiDrawPropertiesEXT *props = (VkPhysicalDeviceMultiDrawPropertiesEXT *)ext;2644props->maxMultiDrawCount = 2048;2645break;2646}26472648case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES:2649anv_get_physical_device_properties_1_1(pdevice, (void *)ext);2650break;26512652case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES:2653anv_get_physical_device_properties_1_2(pdevice, (void *)ext);2654break;26552656default:2657anv_debug_ignored_stype(ext->sType);2658break;2659}2660}26612662#undef CORE_RENAMED_PROPERTY2663#undef CORE_PROPERTY2664}26652666static const VkQueueFamilyProperties2667anv_queue_family_properties_template = {2668.timestampValidBits = 36, /* XXX: Real value here */2669.minImageTransferGranularity = { 1, 1, 1 },2670};26712672void anv_GetPhysicalDeviceQueueFamilyProperties(2673VkPhysicalDevice physicalDevice,2674uint32_t* pCount,2675VkQueueFamilyProperties* pQueueFamilyProperties)2676{2677ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);2678VK_OUTARRAY_MAKE(out, pQueueFamilyProperties, pCount);26792680for (uint32_t i = 0; i < pdevice->queue.family_count; i++) {2681struct anv_queue_family *queue_family = &pdevice->queue.families[i];2682vk_outarray_append(&out, p) {2683*p = anv_queue_family_properties_template;2684p->queueFlags = queue_family->queueFlags;2685p->queueCount = queue_family->queueCount;2686}2687}2688}26892690void anv_GetPhysicalDeviceQueueFamilyProperties2(2691VkPhysicalDevice physicalDevice,2692uint32_t* pQueueFamilyPropertyCount,2693VkQueueFamilyProperties2* pQueueFamilyProperties)2694{2695ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);2696VK_OUTARRAY_MAKE(out, pQueueFamilyProperties, pQueueFamilyPropertyCount);26972698for (uint32_t i = 0; i < pdevice->queue.family_count; i++) {2699struct anv_queue_family *queue_family = &pdevice->queue.families[i];2700vk_outarray_append(&out, p) {2701p->queueFamilyProperties = anv_queue_family_properties_template;2702p->queueFamilyProperties.queueFlags = queue_family->queueFlags;2703p->queueFamilyProperties.queueCount = queue_family->queueCount;27042705vk_foreach_struct(s, p->pNext) {2706anv_debug_ignored_stype(s->sType);2707}2708}2709}2710}27112712void anv_GetPhysicalDeviceMemoryProperties(2713VkPhysicalDevice physicalDevice,2714VkPhysicalDeviceMemoryProperties* pMemoryProperties)2715{2716ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);27172718pMemoryProperties->memoryTypeCount = physical_device->memory.type_count;2719for (uint32_t i = 0; i < physical_device->memory.type_count; i++) {2720pMemoryProperties->memoryTypes[i] = (VkMemoryType) {2721.propertyFlags = physical_device->memory.types[i].propertyFlags,2722.heapIndex = physical_device->memory.types[i].heapIndex,2723};2724}27252726pMemoryProperties->memoryHeapCount = physical_device->memory.heap_count;2727for (uint32_t i = 0; i < physical_device->memory.heap_count; i++) {2728pMemoryProperties->memoryHeaps[i] = (VkMemoryHeap) {2729.size = physical_device->memory.heaps[i].size,2730.flags = physical_device->memory.heaps[i].flags,2731};2732}2733}27342735static void2736anv_get_memory_budget(VkPhysicalDevice physicalDevice,2737VkPhysicalDeviceMemoryBudgetPropertiesEXT *memoryBudget)2738{2739ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);2740uint64_t sys_available;2741ASSERTED bool has_available_memory =2742os_get_available_system_memory(&sys_available);2743assert(has_available_memory);27442745VkDeviceSize total_heaps_size = 0;2746for (size_t i = 0; i < device->memory.heap_count; i++)2747total_heaps_size += device->memory.heaps[i].size;27482749for (size_t i = 0; i < device->memory.heap_count; i++) {2750VkDeviceSize heap_size = device->memory.heaps[i].size;2751VkDeviceSize heap_used = device->memory.heaps[i].used;2752VkDeviceSize heap_budget;27532754double heap_proportion = (double) heap_size / total_heaps_size;2755VkDeviceSize sys_available_prop = sys_available * heap_proportion;27562757/*2758* Let's not incite the app to starve the system: report at most 90% of2759* available system memory.2760*/2761uint64_t heap_available = sys_available_prop * 9 / 10;2762heap_budget = MIN2(heap_size, heap_used + heap_available);27632764/*2765* Round down to the nearest MB2766*/2767heap_budget &= ~((1ull << 20) - 1);27682769/*2770* The heapBudget value must be non-zero for array elements less than2771* VkPhysicalDeviceMemoryProperties::memoryHeapCount. The heapBudget2772* value must be less than or equal to VkMemoryHeap::size for each heap.2773*/2774assert(0 < heap_budget && heap_budget <= heap_size);27752776memoryBudget->heapUsage[i] = heap_used;2777memoryBudget->heapBudget[i] = heap_budget;2778}27792780/* The heapBudget and heapUsage values must be zero for array elements2781* greater than or equal to VkPhysicalDeviceMemoryProperties::memoryHeapCount2782*/2783for (uint32_t i = device->memory.heap_count; i < VK_MAX_MEMORY_HEAPS; i++) {2784memoryBudget->heapBudget[i] = 0;2785memoryBudget->heapUsage[i] = 0;2786}2787}27882789void anv_GetPhysicalDeviceMemoryProperties2(2790VkPhysicalDevice physicalDevice,2791VkPhysicalDeviceMemoryProperties2* pMemoryProperties)2792{2793anv_GetPhysicalDeviceMemoryProperties(physicalDevice,2794&pMemoryProperties->memoryProperties);27952796vk_foreach_struct(ext, pMemoryProperties->pNext) {2797switch (ext->sType) {2798case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT:2799anv_get_memory_budget(physicalDevice, (void*)ext);2800break;2801default:2802anv_debug_ignored_stype(ext->sType);2803break;2804}2805}2806}28072808void2809anv_GetDeviceGroupPeerMemoryFeatures(2810VkDevice device,2811uint32_t heapIndex,2812uint32_t localDeviceIndex,2813uint32_t remoteDeviceIndex,2814VkPeerMemoryFeatureFlags* pPeerMemoryFeatures)2815{2816assert(localDeviceIndex == 0 && remoteDeviceIndex == 0);2817*pPeerMemoryFeatures = VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT |2818VK_PEER_MEMORY_FEATURE_COPY_DST_BIT |2819VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT |2820VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;2821}28222823PFN_vkVoidFunction anv_GetInstanceProcAddr(2824VkInstance _instance,2825const char* pName)2826{2827ANV_FROM_HANDLE(anv_instance, instance, _instance);2828return vk_instance_get_proc_addr(&instance->vk,2829&anv_instance_entrypoints,2830pName);2831}28322833/* With version 1+ of the loader interface the ICD should expose2834* vk_icdGetInstanceProcAddr to work around certain LD_PRELOAD issues seen in apps.2835*/2836PUBLIC2837VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(2838VkInstance instance,2839const char* pName);28402841PUBLIC2842VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(2843VkInstance instance,2844const char* pName)2845{2846return anv_GetInstanceProcAddr(instance, pName);2847}28482849/* With version 4+ of the loader interface the ICD should expose2850* vk_icdGetPhysicalDeviceProcAddr()2851*/2852PUBLIC2853VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(2854VkInstance _instance,2855const char* pName);28562857PFN_vkVoidFunction vk_icdGetPhysicalDeviceProcAddr(2858VkInstance _instance,2859const char* pName)2860{2861ANV_FROM_HANDLE(anv_instance, instance, _instance);2862return vk_instance_get_physical_device_proc_addr(&instance->vk, pName);2863}28642865static struct anv_state2866anv_state_pool_emit_data(struct anv_state_pool *pool, size_t size, size_t align, const void *p)2867{2868struct anv_state state;28692870state = anv_state_pool_alloc(pool, size, align);2871memcpy(state.map, p, size);28722873return state;2874}28752876static void2877anv_device_init_border_colors(struct anv_device *device)2878{2879if (device->info.is_haswell) {2880static const struct hsw_border_color border_colors[] = {2881[VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] = { .float32 = { 0.0, 0.0, 0.0, 0.0 } },2882[VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] = { .float32 = { 0.0, 0.0, 0.0, 1.0 } },2883[VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] = { .float32 = { 1.0, 1.0, 1.0, 1.0 } },2884[VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] = { .uint32 = { 0, 0, 0, 0 } },2885[VK_BORDER_COLOR_INT_OPAQUE_BLACK] = { .uint32 = { 0, 0, 0, 1 } },2886[VK_BORDER_COLOR_INT_OPAQUE_WHITE] = { .uint32 = { 1, 1, 1, 1 } },2887};28882889device->border_colors =2890anv_state_pool_emit_data(&device->dynamic_state_pool,2891sizeof(border_colors), 512, border_colors);2892} else {2893static const struct gfx8_border_color border_colors[] = {2894[VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] = { .float32 = { 0.0, 0.0, 0.0, 0.0 } },2895[VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] = { .float32 = { 0.0, 0.0, 0.0, 1.0 } },2896[VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] = { .float32 = { 1.0, 1.0, 1.0, 1.0 } },2897[VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] = { .uint32 = { 0, 0, 0, 0 } },2898[VK_BORDER_COLOR_INT_OPAQUE_BLACK] = { .uint32 = { 0, 0, 0, 1 } },2899[VK_BORDER_COLOR_INT_OPAQUE_WHITE] = { .uint32 = { 1, 1, 1, 1 } },2900};29012902device->border_colors =2903anv_state_pool_emit_data(&device->dynamic_state_pool,2904sizeof(border_colors), 64, border_colors);2905}2906}29072908static VkResult2909anv_device_init_trivial_batch(struct anv_device *device)2910{2911VkResult result = anv_device_alloc_bo(device, "trivial-batch", 4096,2912ANV_BO_ALLOC_MAPPED,29130 /* explicit_address */,2914&device->trivial_batch_bo);2915if (result != VK_SUCCESS)2916return result;29172918struct anv_batch batch = {2919.start = device->trivial_batch_bo->map,2920.next = device->trivial_batch_bo->map,2921.end = device->trivial_batch_bo->map + 4096,2922};29232924anv_batch_emit(&batch, GFX7_MI_BATCH_BUFFER_END, bbe);2925anv_batch_emit(&batch, GFX7_MI_NOOP, noop);29262927if (!device->info.has_llc)2928intel_clflush_range(batch.start, batch.next - batch.start);29292930return VK_SUCCESS;2931}29322933static int2934vk_priority_to_gen(int priority)2935{2936switch (priority) {2937case VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT:2938return INTEL_CONTEXT_LOW_PRIORITY;2939case VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT:2940return INTEL_CONTEXT_MEDIUM_PRIORITY;2941case VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT:2942return INTEL_CONTEXT_HIGH_PRIORITY;2943case VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT:2944return INTEL_CONTEXT_REALTIME_PRIORITY;2945default:2946unreachable("Invalid priority");2947}2948}29492950static bool2951get_bo_from_pool(struct intel_batch_decode_bo *ret,2952struct anv_block_pool *pool,2953uint64_t address)2954{2955anv_block_pool_foreach_bo(bo, pool) {2956uint64_t bo_address = intel_48b_address(bo->offset);2957if (address >= bo_address && address < (bo_address + bo->size)) {2958*ret = (struct intel_batch_decode_bo) {2959.addr = bo_address,2960.size = bo->size,2961.map = bo->map,2962};2963return true;2964}2965}2966return false;2967}29682969/* Finding a buffer for batch decoding */2970static struct intel_batch_decode_bo2971decode_get_bo(void *v_batch, bool ppgtt, uint64_t address)2972{2973struct anv_device *device = v_batch;2974struct intel_batch_decode_bo ret_bo = {};29752976assert(ppgtt);29772978if (get_bo_from_pool(&ret_bo, &device->dynamic_state_pool.block_pool, address))2979return ret_bo;2980if (get_bo_from_pool(&ret_bo, &device->instruction_state_pool.block_pool, address))2981return ret_bo;2982if (get_bo_from_pool(&ret_bo, &device->binding_table_pool.block_pool, address))2983return ret_bo;2984if (get_bo_from_pool(&ret_bo, &device->surface_state_pool.block_pool, address))2985return ret_bo;29862987if (!device->cmd_buffer_being_decoded)2988return (struct intel_batch_decode_bo) { };29892990struct anv_batch_bo **bo;29912992u_vector_foreach(bo, &device->cmd_buffer_being_decoded->seen_bbos) {2993/* The decoder zeroes out the top 16 bits, so we need to as well */2994uint64_t bo_address = (*bo)->bo->offset & (~0ull >> 16);29952996if (address >= bo_address && address < bo_address + (*bo)->bo->size) {2997return (struct intel_batch_decode_bo) {2998.addr = bo_address,2999.size = (*bo)->bo->size,3000.map = (*bo)->bo->map,3001};3002}3003}30043005return (struct intel_batch_decode_bo) { };3006}30073008struct intel_aux_map_buffer {3009struct intel_buffer base;3010struct anv_state state;3011};30123013static struct intel_buffer *3014intel_aux_map_buffer_alloc(void *driver_ctx, uint32_t size)3015{3016struct intel_aux_map_buffer *buf = malloc(sizeof(struct intel_aux_map_buffer));3017if (!buf)3018return NULL;30193020struct anv_device *device = (struct anv_device*)driver_ctx;3021assert(device->physical->supports_48bit_addresses &&3022device->physical->use_softpin);30233024struct anv_state_pool *pool = &device->dynamic_state_pool;3025buf->state = anv_state_pool_alloc(pool, size, size);30263027buf->base.gpu = pool->block_pool.bo->offset + buf->state.offset;3028buf->base.gpu_end = buf->base.gpu + buf->state.alloc_size;3029buf->base.map = buf->state.map;3030buf->base.driver_bo = &buf->state;3031return &buf->base;3032}30333034static void3035intel_aux_map_buffer_free(void *driver_ctx, struct intel_buffer *buffer)3036{3037struct intel_aux_map_buffer *buf = (struct intel_aux_map_buffer*)buffer;3038struct anv_device *device = (struct anv_device*)driver_ctx;3039struct anv_state_pool *pool = &device->dynamic_state_pool;3040anv_state_pool_free(pool, buf->state);3041free(buf);3042}30433044static struct intel_mapped_pinned_buffer_alloc aux_map_allocator = {3045.alloc = intel_aux_map_buffer_alloc,3046.free = intel_aux_map_buffer_free,3047};30483049static VkResult3050check_physical_device_features(VkPhysicalDevice physicalDevice,3051const VkPhysicalDeviceFeatures *features)3052{3053VkPhysicalDeviceFeatures supported_features;3054anv_GetPhysicalDeviceFeatures(physicalDevice, &supported_features);3055VkBool32 *supported_feature = (VkBool32 *)&supported_features;3056VkBool32 *enabled_feature = (VkBool32 *)features;3057unsigned num_features = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);3058for (uint32_t i = 0; i < num_features; i++) {3059if (enabled_feature[i] && !supported_feature[i])3060return vk_error(VK_ERROR_FEATURE_NOT_PRESENT);3061}30623063return VK_SUCCESS;3064}30653066VkResult anv_CreateDevice(3067VkPhysicalDevice physicalDevice,3068const VkDeviceCreateInfo* pCreateInfo,3069const VkAllocationCallbacks* pAllocator,3070VkDevice* pDevice)3071{3072ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);3073VkResult result;3074struct anv_device *device;30753076assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);30773078/* Check enabled features */3079bool robust_buffer_access = false;3080if (pCreateInfo->pEnabledFeatures) {3081result = check_physical_device_features(physicalDevice,3082pCreateInfo->pEnabledFeatures);3083if (result != VK_SUCCESS)3084return result;30853086if (pCreateInfo->pEnabledFeatures->robustBufferAccess)3087robust_buffer_access = true;3088}30893090vk_foreach_struct_const(ext, pCreateInfo->pNext) {3091switch (ext->sType) {3092case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2: {3093const VkPhysicalDeviceFeatures2 *features = (const void *)ext;3094result = check_physical_device_features(physicalDevice,3095&features->features);3096if (result != VK_SUCCESS)3097return result;30983099if (features->features.robustBufferAccess)3100robust_buffer_access = true;3101break;3102}31033104default:3105/* Don't warn */3106break;3107}3108}31093110/* Check requested queues and fail if we are requested to create any3111* queues with flags we don't support.3112*/3113assert(pCreateInfo->queueCreateInfoCount > 0);3114for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {3115if (pCreateInfo->pQueueCreateInfos[i].flags != 0)3116return vk_error(VK_ERROR_INITIALIZATION_FAILED);3117}31183119/* Check if client specified queue priority. */3120const VkDeviceQueueGlobalPriorityCreateInfoEXT *queue_priority =3121vk_find_struct_const(pCreateInfo->pQueueCreateInfos[0].pNext,3122DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT);31233124VkQueueGlobalPriorityEXT priority =3125queue_priority ? queue_priority->globalPriority :3126VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT;31273128device = vk_alloc2(&physical_device->instance->vk.alloc, pAllocator,3129sizeof(*device), 8,3130VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);3131if (!device)3132return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);31333134struct vk_device_dispatch_table dispatch_table;3135vk_device_dispatch_table_from_entrypoints(&dispatch_table,3136anv_genX(&physical_device->info, device_entrypoints), true);3137vk_device_dispatch_table_from_entrypoints(&dispatch_table,3138&anv_device_entrypoints, false);31393140result = vk_device_init(&device->vk, &physical_device->vk,3141&dispatch_table, pCreateInfo, pAllocator);3142if (result != VK_SUCCESS) {3143vk_error(result);3144goto fail_alloc;3145}31463147if (INTEL_DEBUG & DEBUG_BATCH) {3148const unsigned decode_flags =3149INTEL_BATCH_DECODE_FULL |3150((INTEL_DEBUG & DEBUG_COLOR) ? INTEL_BATCH_DECODE_IN_COLOR : 0) |3151INTEL_BATCH_DECODE_OFFSETS |3152INTEL_BATCH_DECODE_FLOATS;31533154intel_batch_decode_ctx_init(&device->decoder_ctx,3155&physical_device->info,3156stderr, decode_flags, NULL,3157decode_get_bo, NULL, device);3158}31593160device->physical = physical_device;3161device->no_hw = physical_device->no_hw;3162device->_lost = false;31633164/* XXX(chadv): Can we dup() physicalDevice->fd here? */3165device->fd = open(physical_device->path, O_RDWR | O_CLOEXEC);3166if (device->fd == -1) {3167result = vk_error(VK_ERROR_INITIALIZATION_FAILED);3168goto fail_device;3169}31703171uint32_t num_queues = 0;3172for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)3173num_queues += pCreateInfo->pQueueCreateInfos[i].queueCount;31743175if (device->physical->engine_info) {3176/* The kernel API supports at most 64 engines */3177assert(num_queues <= 64);3178uint16_t engine_classes[64];3179int engine_count = 0;3180for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {3181const VkDeviceQueueCreateInfo *queueCreateInfo =3182&pCreateInfo->pQueueCreateInfos[i];31833184assert(queueCreateInfo->queueFamilyIndex <3185physical_device->queue.family_count);3186struct anv_queue_family *queue_family =3187&physical_device->queue.families[queueCreateInfo->queueFamilyIndex];31883189for (uint32_t j = 0; j < queueCreateInfo->queueCount; j++)3190engine_classes[engine_count++] = queue_family->engine_class;3191}3192device->context_id =3193anv_gem_create_context_engines(device,3194physical_device->engine_info,3195engine_count, engine_classes);3196} else {3197assert(num_queues == 1);3198device->context_id = anv_gem_create_context(device);3199}3200if (device->context_id == -1) {3201result = vk_error(VK_ERROR_INITIALIZATION_FAILED);3202goto fail_fd;3203}32043205device->has_thread_submit = physical_device->has_thread_submit;32063207device->queues =3208vk_zalloc(&device->vk.alloc, num_queues * sizeof(*device->queues), 8,3209VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);3210if (device->queues == NULL) {3211result = vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);3212goto fail_context_id;3213}32143215device->queue_count = 0;3216for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {3217const VkDeviceQueueCreateInfo *queueCreateInfo =3218&pCreateInfo->pQueueCreateInfos[i];32193220for (uint32_t j = 0; j < queueCreateInfo->queueCount; j++) {3221/* When using legacy contexts, we use I915_EXEC_RENDER but, with3222* engine-based contexts, the bottom 6 bits of exec_flags are used3223* for the engine ID.3224*/3225uint32_t exec_flags = device->physical->engine_info ?3226device->queue_count : I915_EXEC_RENDER;32273228result = anv_queue_init(device, &device->queues[device->queue_count],3229exec_flags, queueCreateInfo);3230if (result != VK_SUCCESS)3231goto fail_queues;32323233device->queue_count++;3234}3235}32363237if (physical_device->use_softpin) {3238if (pthread_mutex_init(&device->vma_mutex, NULL) != 0) {3239result = vk_error(VK_ERROR_INITIALIZATION_FAILED);3240goto fail_queues;3241}32423243/* keep the page with address zero out of the allocator */3244util_vma_heap_init(&device->vma_lo,3245LOW_HEAP_MIN_ADDRESS, LOW_HEAP_SIZE);32463247util_vma_heap_init(&device->vma_cva, CLIENT_VISIBLE_HEAP_MIN_ADDRESS,3248CLIENT_VISIBLE_HEAP_SIZE);32493250/* Leave the last 4GiB out of the high vma range, so that no state3251* base address + size can overflow 48 bits. For more information see3252* the comment about Wa32bitGeneralStateOffset in anv_allocator.c3253*/3254util_vma_heap_init(&device->vma_hi, HIGH_HEAP_MIN_ADDRESS,3255physical_device->gtt_size - (1ull << 32) -3256HIGH_HEAP_MIN_ADDRESS);3257}32583259list_inithead(&device->memory_objects);32603261/* As per spec, the driver implementation may deny requests to acquire3262* a priority above the default priority (MEDIUM) if the caller does not3263* have sufficient privileges. In this scenario VK_ERROR_NOT_PERMITTED_EXT3264* is returned.3265*/3266if (physical_device->has_context_priority) {3267int err = anv_gem_set_context_param(device->fd, device->context_id,3268I915_CONTEXT_PARAM_PRIORITY,3269vk_priority_to_gen(priority));3270if (err != 0 && priority > VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT) {3271result = vk_error(VK_ERROR_NOT_PERMITTED_EXT);3272goto fail_vmas;3273}3274}32753276device->info = physical_device->info;3277device->isl_dev = physical_device->isl_dev;32783279/* On Broadwell and later, we can use batch chaining to more efficiently3280* implement growing command buffers. Prior to Haswell, the kernel3281* command parser gets in the way and we have to fall back to growing3282* the batch.3283*/3284device->can_chain_batches = device->info.ver >= 8;32853286device->robust_buffer_access = robust_buffer_access;32873288if (pthread_mutex_init(&device->mutex, NULL) != 0) {3289result = vk_error(VK_ERROR_INITIALIZATION_FAILED);3290goto fail_queues;3291}32923293pthread_condattr_t condattr;3294if (pthread_condattr_init(&condattr) != 0) {3295result = vk_error(VK_ERROR_INITIALIZATION_FAILED);3296goto fail_mutex;3297}3298if (pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC) != 0) {3299pthread_condattr_destroy(&condattr);3300result = vk_error(VK_ERROR_INITIALIZATION_FAILED);3301goto fail_mutex;3302}3303if (pthread_cond_init(&device->queue_submit, &condattr) != 0) {3304pthread_condattr_destroy(&condattr);3305result = vk_error(VK_ERROR_INITIALIZATION_FAILED);3306goto fail_mutex;3307}3308pthread_condattr_destroy(&condattr);33093310result = anv_bo_cache_init(&device->bo_cache);3311if (result != VK_SUCCESS)3312goto fail_queue_cond;33133314anv_bo_pool_init(&device->batch_bo_pool, device, "batch");33153316/* Because scratch is also relative to General State Base Address, we leave3317* the base address 0 and start the pool memory at an offset. This way we3318* get the correct offsets in the anv_states that get allocated from it.3319*/3320result = anv_state_pool_init(&device->general_state_pool, device,3321"general pool",33220, GENERAL_STATE_POOL_MIN_ADDRESS, 16384);3323if (result != VK_SUCCESS)3324goto fail_batch_bo_pool;33253326result = anv_state_pool_init(&device->dynamic_state_pool, device,3327"dynamic pool",3328DYNAMIC_STATE_POOL_MIN_ADDRESS, 0, 16384);3329if (result != VK_SUCCESS)3330goto fail_general_state_pool;33313332if (device->info.ver >= 8) {3333/* The border color pointer is limited to 24 bits, so we need to make3334* sure that any such color used at any point in the program doesn't3335* exceed that limit.3336* We achieve that by reserving all the custom border colors we support3337* right off the bat, so they are close to the base address.3338*/3339anv_state_reserved_pool_init(&device->custom_border_colors,3340&device->dynamic_state_pool,3341MAX_CUSTOM_BORDER_COLORS,3342sizeof(struct gfx8_border_color), 64);3343}33443345result = anv_state_pool_init(&device->instruction_state_pool, device,3346"instruction pool",3347INSTRUCTION_STATE_POOL_MIN_ADDRESS, 0, 16384);3348if (result != VK_SUCCESS)3349goto fail_dynamic_state_pool;33503351result = anv_state_pool_init(&device->surface_state_pool, device,3352"surface state pool",3353SURFACE_STATE_POOL_MIN_ADDRESS, 0, 4096);3354if (result != VK_SUCCESS)3355goto fail_instruction_state_pool;33563357if (physical_device->use_softpin) {3358int64_t bt_pool_offset = (int64_t)BINDING_TABLE_POOL_MIN_ADDRESS -3359(int64_t)SURFACE_STATE_POOL_MIN_ADDRESS;3360assert(INT32_MIN < bt_pool_offset && bt_pool_offset < 0);3361result = anv_state_pool_init(&device->binding_table_pool, device,3362"binding table pool",3363SURFACE_STATE_POOL_MIN_ADDRESS,3364bt_pool_offset, 4096);3365if (result != VK_SUCCESS)3366goto fail_surface_state_pool;3367}33683369if (device->info.has_aux_map) {3370device->aux_map_ctx = intel_aux_map_init(device, &aux_map_allocator,3371&physical_device->info);3372if (!device->aux_map_ctx)3373goto fail_binding_table_pool;3374}33753376result = anv_device_alloc_bo(device, "workaround", 4096,3377ANV_BO_ALLOC_CAPTURE | ANV_BO_ALLOC_MAPPED |3378ANV_BO_ALLOC_LOCAL_MEM /* flags */,33790 /* explicit_address */,3380&device->workaround_bo);3381if (result != VK_SUCCESS)3382goto fail_surface_aux_map_pool;33833384device->workaround_address = (struct anv_address) {3385.bo = device->workaround_bo,3386.offset = align_u32(3387intel_debug_write_identifiers(device->workaround_bo->map,3388device->workaround_bo->size,3389"Anv") + 8, 8),3390};33913392device->debug_frame_desc =3393intel_debug_get_identifier_block(device->workaround_bo->map,3394device->workaround_bo->size,3395INTEL_DEBUG_BLOCK_TYPE_FRAME);33963397result = anv_device_init_trivial_batch(device);3398if (result != VK_SUCCESS)3399goto fail_workaround_bo;34003401/* Allocate a null surface state at surface state offset 0. This makes3402* NULL descriptor handling trivial because we can just memset structures3403* to zero and they have a valid descriptor.3404*/3405device->null_surface_state =3406anv_state_pool_alloc(&device->surface_state_pool,3407device->isl_dev.ss.size,3408device->isl_dev.ss.align);3409isl_null_fill_state(&device->isl_dev, device->null_surface_state.map,3410.size = isl_extent3d(1, 1, 1) /* This shouldn't matter */);3411assert(device->null_surface_state.offset == 0);34123413anv_scratch_pool_init(device, &device->scratch_pool);34143415/* TODO(RT): Do we want some sort of data structure for this? */3416memset(device->rt_scratch_bos, 0, sizeof(device->rt_scratch_bos));34173418result = anv_genX(&device->info, init_device_state)(device);3419if (result != VK_SUCCESS)3420goto fail_trivial_batch_bo_and_scratch_pool;34213422anv_pipeline_cache_init(&device->default_pipeline_cache, device,3423true /* cache_enabled */, false /* external_sync */);34243425result = anv_device_init_rt_shaders(device);3426if (result != VK_SUCCESS)3427goto fail_rt_trampoline;34283429anv_device_init_blorp(device);34303431anv_device_init_border_colors(device);34323433anv_device_perf_init(device);34343435*pDevice = anv_device_to_handle(device);34363437return VK_SUCCESS;34383439fail_rt_trampoline:3440anv_pipeline_cache_finish(&device->default_pipeline_cache);3441fail_trivial_batch_bo_and_scratch_pool:3442anv_scratch_pool_finish(device, &device->scratch_pool);3443anv_device_release_bo(device, device->trivial_batch_bo);3444fail_workaround_bo:3445anv_device_release_bo(device, device->workaround_bo);3446fail_surface_aux_map_pool:3447if (device->info.has_aux_map) {3448intel_aux_map_finish(device->aux_map_ctx);3449device->aux_map_ctx = NULL;3450}3451fail_binding_table_pool:3452if (physical_device->use_softpin)3453anv_state_pool_finish(&device->binding_table_pool);3454fail_surface_state_pool:3455anv_state_pool_finish(&device->surface_state_pool);3456fail_instruction_state_pool:3457anv_state_pool_finish(&device->instruction_state_pool);3458fail_dynamic_state_pool:3459if (device->info.ver >= 8)3460anv_state_reserved_pool_finish(&device->custom_border_colors);3461anv_state_pool_finish(&device->dynamic_state_pool);3462fail_general_state_pool:3463anv_state_pool_finish(&device->general_state_pool);3464fail_batch_bo_pool:3465anv_bo_pool_finish(&device->batch_bo_pool);3466anv_bo_cache_finish(&device->bo_cache);3467fail_queue_cond:3468pthread_cond_destroy(&device->queue_submit);3469fail_mutex:3470pthread_mutex_destroy(&device->mutex);3471fail_vmas:3472if (physical_device->use_softpin) {3473util_vma_heap_finish(&device->vma_hi);3474util_vma_heap_finish(&device->vma_cva);3475util_vma_heap_finish(&device->vma_lo);3476}3477fail_queues:3478for (uint32_t i = 0; i < device->queue_count; i++)3479anv_queue_finish(&device->queues[i]);3480vk_free(&device->vk.alloc, device->queues);3481fail_context_id:3482anv_gem_destroy_context(device, device->context_id);3483fail_fd:3484close(device->fd);3485fail_device:3486vk_device_finish(&device->vk);3487fail_alloc:3488vk_free(&device->vk.alloc, device);34893490return result;3491}34923493void anv_DestroyDevice(3494VkDevice _device,3495const VkAllocationCallbacks* pAllocator)3496{3497ANV_FROM_HANDLE(anv_device, device, _device);34983499if (!device)3500return;35013502anv_device_finish_blorp(device);35033504anv_device_finish_rt_shaders(device);35053506anv_pipeline_cache_finish(&device->default_pipeline_cache);35073508#ifdef HAVE_VALGRIND3509/* We only need to free these to prevent valgrind errors. The backing3510* BO will go away in a couple of lines so we don't actually leak.3511*/3512if (device->info.ver >= 8)3513anv_state_reserved_pool_finish(&device->custom_border_colors);3514anv_state_pool_free(&device->dynamic_state_pool, device->border_colors);3515anv_state_pool_free(&device->dynamic_state_pool, device->slice_hash);3516#endif35173518for (unsigned i = 0; i < ARRAY_SIZE(device->rt_scratch_bos); i++) {3519if (device->rt_scratch_bos[i] != NULL)3520anv_device_release_bo(device, device->rt_scratch_bos[i]);3521}35223523anv_scratch_pool_finish(device, &device->scratch_pool);35243525anv_device_release_bo(device, device->workaround_bo);3526anv_device_release_bo(device, device->trivial_batch_bo);35273528if (device->info.has_aux_map) {3529intel_aux_map_finish(device->aux_map_ctx);3530device->aux_map_ctx = NULL;3531}35323533if (device->physical->use_softpin)3534anv_state_pool_finish(&device->binding_table_pool);3535anv_state_pool_finish(&device->surface_state_pool);3536anv_state_pool_finish(&device->instruction_state_pool);3537anv_state_pool_finish(&device->dynamic_state_pool);3538anv_state_pool_finish(&device->general_state_pool);35393540anv_bo_pool_finish(&device->batch_bo_pool);35413542anv_bo_cache_finish(&device->bo_cache);35433544if (device->physical->use_softpin) {3545util_vma_heap_finish(&device->vma_hi);3546util_vma_heap_finish(&device->vma_cva);3547util_vma_heap_finish(&device->vma_lo);3548}35493550pthread_cond_destroy(&device->queue_submit);3551pthread_mutex_destroy(&device->mutex);35523553for (uint32_t i = 0; i < device->queue_count; i++)3554anv_queue_finish(&device->queues[i]);3555vk_free(&device->vk.alloc, device->queues);35563557anv_gem_destroy_context(device, device->context_id);35583559if (INTEL_DEBUG & DEBUG_BATCH)3560intel_batch_decode_ctx_finish(&device->decoder_ctx);35613562close(device->fd);35633564vk_device_finish(&device->vk);3565vk_free(&device->vk.alloc, device);3566}35673568VkResult anv_EnumerateInstanceLayerProperties(3569uint32_t* pPropertyCount,3570VkLayerProperties* pProperties)3571{3572if (pProperties == NULL) {3573*pPropertyCount = 0;3574return VK_SUCCESS;3575}35763577/* None supported at this time */3578return vk_error(VK_ERROR_LAYER_NOT_PRESENT);3579}35803581void anv_GetDeviceQueue2(3582VkDevice _device,3583const VkDeviceQueueInfo2* pQueueInfo,3584VkQueue* pQueue)3585{3586ANV_FROM_HANDLE(anv_device, device, _device);3587struct anv_physical_device *pdevice = device->physical;35883589assert(pQueueInfo->queueFamilyIndex < pdevice->queue.family_count);3590struct anv_queue_family *queue_family =3591&pdevice->queue.families[pQueueInfo->queueFamilyIndex];35923593int idx_in_family = 0;3594struct anv_queue *queue = NULL;3595for (uint32_t i = 0; i < device->queue_count; i++) {3596if (device->queues[i].family != queue_family)3597continue;35983599if (idx_in_family == pQueueInfo->queueIndex) {3600queue = &device->queues[i];3601break;3602}36033604idx_in_family++;3605}3606assert(queue != NULL);36073608if (queue && queue->flags == pQueueInfo->flags)3609*pQueue = anv_queue_to_handle(queue);3610else3611*pQueue = NULL;3612}36133614void3615_anv_device_report_lost(struct anv_device *device)3616{3617assert(p_atomic_read(&device->_lost) > 0);36183619device->lost_reported = true;36203621for (uint32_t i = 0; i < device->queue_count; i++) {3622struct anv_queue *queue = &device->queues[i];3623if (queue->lost) {3624__vk_errorf(device->physical->instance, &device->vk.base,3625VK_ERROR_DEVICE_LOST,3626queue->error_file, queue->error_line,3627"%s", queue->error_msg);3628}3629}3630}36313632VkResult3633_anv_device_set_lost(struct anv_device *device,3634const char *file, int line,3635const char *msg, ...)3636{3637VkResult err;3638va_list ap;36393640if (p_atomic_read(&device->_lost) > 0)3641return VK_ERROR_DEVICE_LOST;36423643p_atomic_inc(&device->_lost);3644device->lost_reported = true;36453646va_start(ap, msg);3647err = __vk_errorv(device->physical->instance, &device->vk.base,3648VK_ERROR_DEVICE_LOST, file, line, msg, ap);3649va_end(ap);36503651if (env_var_as_boolean("ANV_ABORT_ON_DEVICE_LOSS", false))3652abort();36533654return err;3655}36563657VkResult3658_anv_queue_set_lost(struct anv_queue *queue,3659const char *file, int line,3660const char *msg, ...)3661{3662va_list ap;36633664if (queue->lost)3665return VK_ERROR_DEVICE_LOST;36663667queue->lost = true;36683669queue->error_file = file;3670queue->error_line = line;3671va_start(ap, msg);3672vsnprintf(queue->error_msg, sizeof(queue->error_msg),3673msg, ap);3674va_end(ap);36753676p_atomic_inc(&queue->device->_lost);36773678if (env_var_as_boolean("ANV_ABORT_ON_DEVICE_LOSS", false))3679abort();36803681return VK_ERROR_DEVICE_LOST;3682}36833684VkResult3685anv_device_query_status(struct anv_device *device)3686{3687/* This isn't likely as most of the callers of this function already check3688* for it. However, it doesn't hurt to check and it potentially lets us3689* avoid an ioctl.3690*/3691if (anv_device_is_lost(device))3692return VK_ERROR_DEVICE_LOST;36933694uint32_t active, pending;3695int ret = anv_gem_context_get_reset_stats(device->fd, device->context_id,3696&active, &pending);3697if (ret == -1) {3698/* We don't know the real error. */3699return anv_device_set_lost(device, "get_reset_stats failed: %m");3700}37013702if (active) {3703return anv_device_set_lost(device, "GPU hung on one of our command buffers");3704} else if (pending) {3705return anv_device_set_lost(device, "GPU hung with commands in-flight");3706}37073708return VK_SUCCESS;3709}37103711VkResult3712anv_device_bo_busy(struct anv_device *device, struct anv_bo *bo)3713{3714/* Note: This only returns whether or not the BO is in use by an i915 GPU.3715* Other usages of the BO (such as on different hardware) will not be3716* flagged as "busy" by this ioctl. Use with care.3717*/3718int ret = anv_gem_busy(device, bo->gem_handle);3719if (ret == 1) {3720return VK_NOT_READY;3721} else if (ret == -1) {3722/* We don't know the real error. */3723return anv_device_set_lost(device, "gem wait failed: %m");3724}37253726/* Query for device status after the busy call. If the BO we're checking3727* got caught in a GPU hang we don't want to return VK_SUCCESS to the3728* client because it clearly doesn't have valid data. Yes, this most3729* likely means an ioctl, but we just did an ioctl to query the busy status3730* so it's no great loss.3731*/3732return anv_device_query_status(device);3733}37343735VkResult3736anv_device_wait(struct anv_device *device, struct anv_bo *bo,3737int64_t timeout)3738{3739int ret = anv_gem_wait(device, bo->gem_handle, &timeout);3740if (ret == -1 && errno == ETIME) {3741return VK_TIMEOUT;3742} else if (ret == -1) {3743/* We don't know the real error. */3744return anv_device_set_lost(device, "gem wait failed: %m");3745}37463747/* Query for device status after the wait. If the BO we're waiting on got3748* caught in a GPU hang we don't want to return VK_SUCCESS to the client3749* because it clearly doesn't have valid data. Yes, this most likely means3750* an ioctl, but we just did an ioctl to wait so it's no great loss.3751*/3752return anv_device_query_status(device);3753}37543755VkResult anv_DeviceWaitIdle(3756VkDevice _device)3757{3758ANV_FROM_HANDLE(anv_device, device, _device);37593760if (anv_device_is_lost(device))3761return VK_ERROR_DEVICE_LOST;37623763for (uint32_t i = 0; i < device->queue_count; i++) {3764VkResult res = anv_queue_submit_simple_batch(&device->queues[i], NULL);3765if (res != VK_SUCCESS)3766return res;3767}37683769return VK_SUCCESS;3770}37713772uint64_t3773anv_vma_alloc(struct anv_device *device,3774uint64_t size, uint64_t align,3775enum anv_bo_alloc_flags alloc_flags,3776uint64_t client_address)3777{3778pthread_mutex_lock(&device->vma_mutex);37793780uint64_t addr = 0;37813782if (alloc_flags & ANV_BO_ALLOC_CLIENT_VISIBLE_ADDRESS) {3783if (client_address) {3784if (util_vma_heap_alloc_addr(&device->vma_cva,3785client_address, size)) {3786addr = client_address;3787}3788} else {3789addr = util_vma_heap_alloc(&device->vma_cva, size, align);3790}3791/* We don't want to fall back to other heaps */3792goto done;3793}37943795assert(client_address == 0);37963797if (!(alloc_flags & ANV_BO_ALLOC_32BIT_ADDRESS))3798addr = util_vma_heap_alloc(&device->vma_hi, size, align);37993800if (addr == 0)3801addr = util_vma_heap_alloc(&device->vma_lo, size, align);38023803done:3804pthread_mutex_unlock(&device->vma_mutex);38053806assert(addr == intel_48b_address(addr));3807return intel_canonical_address(addr);3808}38093810void3811anv_vma_free(struct anv_device *device,3812uint64_t address, uint64_t size)3813{3814const uint64_t addr_48b = intel_48b_address(address);38153816pthread_mutex_lock(&device->vma_mutex);38173818if (addr_48b >= LOW_HEAP_MIN_ADDRESS &&3819addr_48b <= LOW_HEAP_MAX_ADDRESS) {3820util_vma_heap_free(&device->vma_lo, addr_48b, size);3821} else if (addr_48b >= CLIENT_VISIBLE_HEAP_MIN_ADDRESS &&3822addr_48b <= CLIENT_VISIBLE_HEAP_MAX_ADDRESS) {3823util_vma_heap_free(&device->vma_cva, addr_48b, size);3824} else {3825assert(addr_48b >= HIGH_HEAP_MIN_ADDRESS);3826util_vma_heap_free(&device->vma_hi, addr_48b, size);3827}38283829pthread_mutex_unlock(&device->vma_mutex);3830}38313832VkResult anv_AllocateMemory(3833VkDevice _device,3834const VkMemoryAllocateInfo* pAllocateInfo,3835const VkAllocationCallbacks* pAllocator,3836VkDeviceMemory* pMem)3837{3838ANV_FROM_HANDLE(anv_device, device, _device);3839struct anv_physical_device *pdevice = device->physical;3840struct anv_device_memory *mem;3841VkResult result = VK_SUCCESS;38423843assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);38443845/* The Vulkan 1.0.33 spec says "allocationSize must be greater than 0". */3846assert(pAllocateInfo->allocationSize > 0);38473848VkDeviceSize aligned_alloc_size =3849align_u64(pAllocateInfo->allocationSize, 4096);38503851if (aligned_alloc_size > MAX_MEMORY_ALLOCATION_SIZE)3852return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);38533854assert(pAllocateInfo->memoryTypeIndex < pdevice->memory.type_count);3855struct anv_memory_type *mem_type =3856&pdevice->memory.types[pAllocateInfo->memoryTypeIndex];3857assert(mem_type->heapIndex < pdevice->memory.heap_count);3858struct anv_memory_heap *mem_heap =3859&pdevice->memory.heaps[mem_type->heapIndex];38603861uint64_t mem_heap_used = p_atomic_read(&mem_heap->used);3862if (mem_heap_used + aligned_alloc_size > mem_heap->size)3863return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);38643865mem = vk_object_alloc(&device->vk, pAllocator, sizeof(*mem),3866VK_OBJECT_TYPE_DEVICE_MEMORY);3867if (mem == NULL)3868return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);38693870mem->type = mem_type;3871mem->map = NULL;3872mem->map_size = 0;3873mem->ahw = NULL;3874mem->host_ptr = NULL;38753876enum anv_bo_alloc_flags alloc_flags = 0;38773878const VkExportMemoryAllocateInfo *export_info = NULL;3879const VkImportAndroidHardwareBufferInfoANDROID *ahw_import_info = NULL;3880const VkImportMemoryFdInfoKHR *fd_info = NULL;3881const VkImportMemoryHostPointerInfoEXT *host_ptr_info = NULL;3882const VkMemoryDedicatedAllocateInfo *dedicated_info = NULL;3883VkMemoryAllocateFlags vk_flags = 0;3884uint64_t client_address = 0;38853886vk_foreach_struct_const(ext, pAllocateInfo->pNext) {3887switch (ext->sType) {3888case VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO:3889export_info = (void *)ext;3890break;38913892case VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID:3893ahw_import_info = (void *)ext;3894break;38953896case VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR:3897fd_info = (void *)ext;3898break;38993900case VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT:3901host_ptr_info = (void *)ext;3902break;39033904case VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO: {3905const VkMemoryAllocateFlagsInfo *flags_info = (void *)ext;3906vk_flags = flags_info->flags;3907break;3908}39093910case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO:3911dedicated_info = (void *)ext;3912break;39133914case VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR: {3915const VkMemoryOpaqueCaptureAddressAllocateInfoKHR *addr_info =3916(const VkMemoryOpaqueCaptureAddressAllocateInfoKHR *)ext;3917client_address = addr_info->opaqueCaptureAddress;3918break;3919}39203921default:3922anv_debug_ignored_stype(ext->sType);3923break;3924}3925}39263927/* By default, we want all VkDeviceMemory objects to support CCS */3928if (device->physical->has_implicit_ccs)3929alloc_flags |= ANV_BO_ALLOC_IMPLICIT_CCS;39303931if (vk_flags & VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR)3932alloc_flags |= ANV_BO_ALLOC_CLIENT_VISIBLE_ADDRESS;39333934if ((export_info && export_info->handleTypes) ||3935(fd_info && fd_info->handleType) ||3936(host_ptr_info && host_ptr_info->handleType)) {3937/* Anything imported or exported is EXTERNAL */3938alloc_flags |= ANV_BO_ALLOC_EXTERNAL;39393940/* We can't have implicit CCS on external memory with an AUX-table.3941* Doing so would require us to sync the aux tables across processes3942* which is impractical.3943*/3944if (device->info.has_aux_map)3945alloc_flags &= ~ANV_BO_ALLOC_IMPLICIT_CCS;3946}39473948/* Check if we need to support Android HW buffer export. If so,3949* create AHardwareBuffer and import memory from it.3950*/3951bool android_export = false;3952if (export_info && export_info->handleTypes &3953VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)3954android_export = true;39553956if (ahw_import_info) {3957result = anv_import_ahw_memory(_device, mem, ahw_import_info);3958if (result != VK_SUCCESS)3959goto fail;39603961goto success;3962} else if (android_export) {3963result = anv_create_ahw_memory(_device, mem, pAllocateInfo);3964if (result != VK_SUCCESS)3965goto fail;39663967goto success;3968}39693970/* The Vulkan spec permits handleType to be 0, in which case the struct is3971* ignored.3972*/3973if (fd_info && fd_info->handleType) {3974/* At the moment, we support only the below handle types. */3975assert(fd_info->handleType ==3976VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ||3977fd_info->handleType ==3978VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);39793980result = anv_device_import_bo(device, fd_info->fd, alloc_flags,3981client_address, &mem->bo);3982if (result != VK_SUCCESS)3983goto fail;39843985/* For security purposes, we reject importing the bo if it's smaller3986* than the requested allocation size. This prevents a malicious client3987* from passing a buffer to a trusted client, lying about the size, and3988* telling the trusted client to try and texture from an image that goes3989* out-of-bounds. This sort of thing could lead to GPU hangs or worse3990* in the trusted client. The trusted client can protect itself against3991* this sort of attack but only if it can trust the buffer size.3992*/3993if (mem->bo->size < aligned_alloc_size) {3994result = vk_errorf(device, &device->vk.base,3995VK_ERROR_INVALID_EXTERNAL_HANDLE,3996"aligned allocationSize too large for "3997"VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT: "3998"%"PRIu64"B > %"PRIu64"B",3999aligned_alloc_size, mem->bo->size);4000anv_device_release_bo(device, mem->bo);4001goto fail;4002}40034004/* From the Vulkan spec:4005*4006* "Importing memory from a file descriptor transfers ownership of4007* the file descriptor from the application to the Vulkan4008* implementation. The application must not perform any operations on4009* the file descriptor after a successful import."4010*4011* If the import fails, we leave the file descriptor open.4012*/4013close(fd_info->fd);4014goto success;4015}40164017if (host_ptr_info && host_ptr_info->handleType) {4018if (host_ptr_info->handleType ==4019VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT) {4020result = vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE);4021goto fail;4022}40234024assert(host_ptr_info->handleType ==4025VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT);40264027result = anv_device_import_bo_from_host_ptr(device,4028host_ptr_info->pHostPointer,4029pAllocateInfo->allocationSize,4030alloc_flags,4031client_address,4032&mem->bo);4033if (result != VK_SUCCESS)4034goto fail;40354036mem->host_ptr = host_ptr_info->pHostPointer;4037goto success;4038}40394040/* Set ALLOC_LOCAL_MEM flag if heap has device local bit set and requested4041* memory property flag has DEVICE_LOCAL_BIT set.4042*/4043if (mem_type->propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)4044alloc_flags |= ANV_BO_ALLOC_LOCAL_MEM;40454046/* Regular allocate (not importing memory). */40474048result = anv_device_alloc_bo(device, "user", pAllocateInfo->allocationSize,4049alloc_flags, client_address, &mem->bo);4050if (result != VK_SUCCESS)4051goto fail;40524053if (dedicated_info && dedicated_info->image != VK_NULL_HANDLE) {4054ANV_FROM_HANDLE(anv_image, image, dedicated_info->image);40554056/* Some legacy (non-modifiers) consumers need the tiling to be set on4057* the BO. In this case, we have a dedicated allocation.4058*/4059if (image->needs_set_tiling) {4060const uint32_t i915_tiling =4061isl_tiling_to_i915_tiling(image->planes[0].primary_surface.isl.tiling);4062int ret = anv_gem_set_tiling(device, mem->bo->gem_handle,4063image->planes[0].primary_surface.isl.row_pitch_B,4064i915_tiling);4065if (ret) {4066anv_device_release_bo(device, mem->bo);4067result = vk_errorf(device, &device->vk.base,4068VK_ERROR_OUT_OF_DEVICE_MEMORY,4069"failed to set BO tiling: %m");4070goto fail;4071}4072}4073}40744075success:4076mem_heap_used = p_atomic_add_return(&mem_heap->used, mem->bo->size);4077if (mem_heap_used > mem_heap->size) {4078p_atomic_add(&mem_heap->used, -mem->bo->size);4079anv_device_release_bo(device, mem->bo);4080result = vk_errorf(device, &device->vk.base,4081VK_ERROR_OUT_OF_DEVICE_MEMORY,4082"Out of heap memory");4083goto fail;4084}40854086pthread_mutex_lock(&device->mutex);4087list_addtail(&mem->link, &device->memory_objects);4088pthread_mutex_unlock(&device->mutex);40894090*pMem = anv_device_memory_to_handle(mem);40914092return VK_SUCCESS;40934094fail:4095vk_object_free(&device->vk, pAllocator, mem);40964097return result;4098}40994100VkResult anv_GetMemoryFdKHR(4101VkDevice device_h,4102const VkMemoryGetFdInfoKHR* pGetFdInfo,4103int* pFd)4104{4105ANV_FROM_HANDLE(anv_device, dev, device_h);4106ANV_FROM_HANDLE(anv_device_memory, mem, pGetFdInfo->memory);41074108assert(pGetFdInfo->sType == VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR);41094110assert(pGetFdInfo->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ||4111pGetFdInfo->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);41124113return anv_device_export_bo(dev, mem->bo, pFd);4114}41154116VkResult anv_GetMemoryFdPropertiesKHR(4117VkDevice _device,4118VkExternalMemoryHandleTypeFlagBits handleType,4119int fd,4120VkMemoryFdPropertiesKHR* pMemoryFdProperties)4121{4122ANV_FROM_HANDLE(anv_device, device, _device);41234124switch (handleType) {4125case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:4126/* dma-buf can be imported as any memory type */4127pMemoryFdProperties->memoryTypeBits =4128(1 << device->physical->memory.type_count) - 1;4129return VK_SUCCESS;41304131default:4132/* The valid usage section for this function says:4133*4134* "handleType must not be one of the handle types defined as4135* opaque."4136*4137* So opaque handle types fall into the default "unsupported" case.4138*/4139return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE);4140}4141}41424143VkResult anv_GetMemoryHostPointerPropertiesEXT(4144VkDevice _device,4145VkExternalMemoryHandleTypeFlagBits handleType,4146const void* pHostPointer,4147VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties)4148{4149ANV_FROM_HANDLE(anv_device, device, _device);41504151assert(pMemoryHostPointerProperties->sType ==4152VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT);41534154switch (handleType) {4155case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:4156/* Host memory can be imported as any memory type. */4157pMemoryHostPointerProperties->memoryTypeBits =4158(1ull << device->physical->memory.type_count) - 1;41594160return VK_SUCCESS;41614162default:4163return VK_ERROR_INVALID_EXTERNAL_HANDLE;4164}4165}41664167void anv_FreeMemory(4168VkDevice _device,4169VkDeviceMemory _mem,4170const VkAllocationCallbacks* pAllocator)4171{4172ANV_FROM_HANDLE(anv_device, device, _device);4173ANV_FROM_HANDLE(anv_device_memory, mem, _mem);41744175if (mem == NULL)4176return;41774178pthread_mutex_lock(&device->mutex);4179list_del(&mem->link);4180pthread_mutex_unlock(&device->mutex);41814182if (mem->map)4183anv_UnmapMemory(_device, _mem);41844185p_atomic_add(&device->physical->memory.heaps[mem->type->heapIndex].used,4186-mem->bo->size);41874188anv_device_release_bo(device, mem->bo);41894190#if defined(ANDROID) && ANDROID_API_LEVEL >= 264191if (mem->ahw)4192AHardwareBuffer_release(mem->ahw);4193#endif41944195vk_object_free(&device->vk, pAllocator, mem);4196}41974198VkResult anv_MapMemory(4199VkDevice _device,4200VkDeviceMemory _memory,4201VkDeviceSize offset,4202VkDeviceSize size,4203VkMemoryMapFlags flags,4204void** ppData)4205{4206ANV_FROM_HANDLE(anv_device, device, _device);4207ANV_FROM_HANDLE(anv_device_memory, mem, _memory);42084209if (mem == NULL) {4210*ppData = NULL;4211return VK_SUCCESS;4212}42134214if (mem->host_ptr) {4215*ppData = mem->host_ptr + offset;4216return VK_SUCCESS;4217}42184219if (size == VK_WHOLE_SIZE)4220size = mem->bo->size - offset;42214222/* From the Vulkan spec version 1.0.32 docs for MapMemory:4223*4224* * If size is not equal to VK_WHOLE_SIZE, size must be greater than 04225* assert(size != 0);4226* * If size is not equal to VK_WHOLE_SIZE, size must be less than or4227* equal to the size of the memory minus offset4228*/4229assert(size > 0);4230assert(offset + size <= mem->bo->size);42314232/* FIXME: Is this supposed to be thread safe? Since vkUnmapMemory() only4233* takes a VkDeviceMemory pointer, it seems like only one map of the memory4234* at a time is valid. We could just mmap up front and return an offset4235* pointer here, but that may exhaust virtual memory on 32 bit4236* userspace. */42374238uint32_t gem_flags = 0;42394240if (!device->info.has_llc &&4241(mem->type->propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))4242gem_flags |= I915_MMAP_WC;42434244/* GEM will fail to map if the offset isn't 4k-aligned. Round down. */4245uint64_t map_offset;4246if (!device->physical->has_mmap_offset)4247map_offset = offset & ~4095ull;4248else4249map_offset = 0;4250assert(offset >= map_offset);4251uint64_t map_size = (offset + size) - map_offset;42524253/* Let's map whole pages */4254map_size = align_u64(map_size, 4096);42554256void *map = anv_gem_mmap(device, mem->bo->gem_handle,4257map_offset, map_size, gem_flags);4258if (map == MAP_FAILED)4259return vk_error(VK_ERROR_MEMORY_MAP_FAILED);42604261mem->map = map;4262mem->map_size = map_size;42634264*ppData = mem->map + (offset - map_offset);42654266return VK_SUCCESS;4267}42684269void anv_UnmapMemory(4270VkDevice _device,4271VkDeviceMemory _memory)4272{4273ANV_FROM_HANDLE(anv_device, device, _device);4274ANV_FROM_HANDLE(anv_device_memory, mem, _memory);42754276if (mem == NULL || mem->host_ptr)4277return;42784279anv_gem_munmap(device, mem->map, mem->map_size);42804281mem->map = NULL;4282mem->map_size = 0;4283}42844285static void4286clflush_mapped_ranges(struct anv_device *device,4287uint32_t count,4288const VkMappedMemoryRange *ranges)4289{4290for (uint32_t i = 0; i < count; i++) {4291ANV_FROM_HANDLE(anv_device_memory, mem, ranges[i].memory);4292if (ranges[i].offset >= mem->map_size)4293continue;42944295if (mem->type->propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)4296continue;42974298intel_clflush_range(mem->map + ranges[i].offset,4299MIN2(ranges[i].size, mem->map_size - ranges[i].offset));4300}4301}43024303VkResult anv_FlushMappedMemoryRanges(4304VkDevice _device,4305uint32_t memoryRangeCount,4306const VkMappedMemoryRange* pMemoryRanges)4307{4308ANV_FROM_HANDLE(anv_device, device, _device);43094310if (!device->physical->memory.need_clflush)4311return VK_SUCCESS;43124313/* Make sure the writes we're flushing have landed. */4314__builtin_ia32_mfence();43154316clflush_mapped_ranges(device, memoryRangeCount, pMemoryRanges);43174318return VK_SUCCESS;4319}43204321VkResult anv_InvalidateMappedMemoryRanges(4322VkDevice _device,4323uint32_t memoryRangeCount,4324const VkMappedMemoryRange* pMemoryRanges)4325{4326ANV_FROM_HANDLE(anv_device, device, _device);43274328if (!device->physical->memory.need_clflush)4329return VK_SUCCESS;43304331clflush_mapped_ranges(device, memoryRangeCount, pMemoryRanges);43324333/* Make sure no reads get moved up above the invalidate. */4334__builtin_ia32_mfence();43354336return VK_SUCCESS;4337}43384339void anv_GetBufferMemoryRequirements2(4340VkDevice _device,4341const VkBufferMemoryRequirementsInfo2* pInfo,4342VkMemoryRequirements2* pMemoryRequirements)4343{4344ANV_FROM_HANDLE(anv_device, device, _device);4345ANV_FROM_HANDLE(anv_buffer, buffer, pInfo->buffer);43464347/* The Vulkan spec (git aaed022) says:4348*4349* memoryTypeBits is a bitfield and contains one bit set for every4350* supported memory type for the resource. The bit `1<<i` is set if and4351* only if the memory type `i` in the VkPhysicalDeviceMemoryProperties4352* structure for the physical device is supported.4353*/4354uint32_t memory_types = (1ull << device->physical->memory.type_count) - 1;43554356/* Base alignment requirement of a cache line */4357uint32_t alignment = 16;43584359if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)4360alignment = MAX2(alignment, ANV_UBO_ALIGNMENT);43614362pMemoryRequirements->memoryRequirements.size = buffer->size;4363pMemoryRequirements->memoryRequirements.alignment = alignment;43644365/* Storage and Uniform buffers should have their size aligned to4366* 32-bits to avoid boundary checks when last DWord is not complete.4367* This would ensure that not internal padding would be needed for4368* 16-bit types.4369*/4370if (device->robust_buffer_access &&4371(buffer->usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ||4372buffer->usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT))4373pMemoryRequirements->memoryRequirements.size = align_u64(buffer->size, 4);43744375pMemoryRequirements->memoryRequirements.memoryTypeBits = memory_types;43764377vk_foreach_struct(ext, pMemoryRequirements->pNext) {4378switch (ext->sType) {4379case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {4380VkMemoryDedicatedRequirements *requirements = (void *)ext;4381requirements->prefersDedicatedAllocation = false;4382requirements->requiresDedicatedAllocation = false;4383break;4384}43854386default:4387anv_debug_ignored_stype(ext->sType);4388break;4389}4390}4391}43924393void anv_GetDeviceMemoryCommitment(4394VkDevice device,4395VkDeviceMemory memory,4396VkDeviceSize* pCommittedMemoryInBytes)4397{4398*pCommittedMemoryInBytes = 0;4399}44004401static void4402anv_bind_buffer_memory(const VkBindBufferMemoryInfo *pBindInfo)4403{4404ANV_FROM_HANDLE(anv_device_memory, mem, pBindInfo->memory);4405ANV_FROM_HANDLE(anv_buffer, buffer, pBindInfo->buffer);44064407assert(pBindInfo->sType == VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO);44084409if (mem) {4410assert(pBindInfo->memoryOffset < mem->bo->size);4411assert(mem->bo->size - pBindInfo->memoryOffset >= buffer->size);4412buffer->address = (struct anv_address) {4413.bo = mem->bo,4414.offset = pBindInfo->memoryOffset,4415};4416} else {4417buffer->address = ANV_NULL_ADDRESS;4418}4419}44204421VkResult anv_BindBufferMemory2(4422VkDevice device,4423uint32_t bindInfoCount,4424const VkBindBufferMemoryInfo* pBindInfos)4425{4426for (uint32_t i = 0; i < bindInfoCount; i++)4427anv_bind_buffer_memory(&pBindInfos[i]);44284429return VK_SUCCESS;4430}44314432VkResult anv_QueueBindSparse(4433VkQueue _queue,4434uint32_t bindInfoCount,4435const VkBindSparseInfo* pBindInfo,4436VkFence fence)4437{4438ANV_FROM_HANDLE(anv_queue, queue, _queue);4439if (anv_device_is_lost(queue->device))4440return VK_ERROR_DEVICE_LOST;44414442return vk_error(VK_ERROR_FEATURE_NOT_PRESENT);4443}44444445// Event functions44464447VkResult anv_CreateEvent(4448VkDevice _device,4449const VkEventCreateInfo* pCreateInfo,4450const VkAllocationCallbacks* pAllocator,4451VkEvent* pEvent)4452{4453ANV_FROM_HANDLE(anv_device, device, _device);4454struct anv_event *event;44554456assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_EVENT_CREATE_INFO);44574458event = vk_object_alloc(&device->vk, pAllocator, sizeof(*event),4459VK_OBJECT_TYPE_EVENT);4460if (event == NULL)4461return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);44624463event->state = anv_state_pool_alloc(&device->dynamic_state_pool,4464sizeof(uint64_t), 8);4465*(uint64_t *)event->state.map = VK_EVENT_RESET;44664467*pEvent = anv_event_to_handle(event);44684469return VK_SUCCESS;4470}44714472void anv_DestroyEvent(4473VkDevice _device,4474VkEvent _event,4475const VkAllocationCallbacks* pAllocator)4476{4477ANV_FROM_HANDLE(anv_device, device, _device);4478ANV_FROM_HANDLE(anv_event, event, _event);44794480if (!event)4481return;44824483anv_state_pool_free(&device->dynamic_state_pool, event->state);44844485vk_object_free(&device->vk, pAllocator, event);4486}44874488VkResult anv_GetEventStatus(4489VkDevice _device,4490VkEvent _event)4491{4492ANV_FROM_HANDLE(anv_device, device, _device);4493ANV_FROM_HANDLE(anv_event, event, _event);44944495if (anv_device_is_lost(device))4496return VK_ERROR_DEVICE_LOST;44974498return *(uint64_t *)event->state.map;4499}45004501VkResult anv_SetEvent(4502VkDevice _device,4503VkEvent _event)4504{4505ANV_FROM_HANDLE(anv_event, event, _event);45064507*(uint64_t *)event->state.map = VK_EVENT_SET;45084509return VK_SUCCESS;4510}45114512VkResult anv_ResetEvent(4513VkDevice _device,4514VkEvent _event)4515{4516ANV_FROM_HANDLE(anv_event, event, _event);45174518*(uint64_t *)event->state.map = VK_EVENT_RESET;45194520return VK_SUCCESS;4521}45224523// Buffer functions45244525VkResult anv_CreateBuffer(4526VkDevice _device,4527const VkBufferCreateInfo* pCreateInfo,4528const VkAllocationCallbacks* pAllocator,4529VkBuffer* pBuffer)4530{4531ANV_FROM_HANDLE(anv_device, device, _device);4532struct anv_buffer *buffer;45334534/* Don't allow creating buffers bigger than our address space. The real4535* issue here is that we may align up the buffer size and we don't want4536* doing so to cause roll-over. However, no one has any business4537* allocating a buffer larger than our GTT size.4538*/4539if (pCreateInfo->size > device->physical->gtt_size)4540return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);45414542assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);45434544buffer = vk_object_alloc(&device->vk, pAllocator, sizeof(*buffer),4545VK_OBJECT_TYPE_BUFFER);4546if (buffer == NULL)4547return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);45484549buffer->create_flags = pCreateInfo->flags;4550buffer->size = pCreateInfo->size;4551buffer->usage = pCreateInfo->usage;4552buffer->address = ANV_NULL_ADDRESS;45534554*pBuffer = anv_buffer_to_handle(buffer);45554556return VK_SUCCESS;4557}45584559void anv_DestroyBuffer(4560VkDevice _device,4561VkBuffer _buffer,4562const VkAllocationCallbacks* pAllocator)4563{4564ANV_FROM_HANDLE(anv_device, device, _device);4565ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);45664567if (!buffer)4568return;45694570vk_object_free(&device->vk, pAllocator, buffer);4571}45724573VkDeviceAddress anv_GetBufferDeviceAddress(4574VkDevice device,4575const VkBufferDeviceAddressInfoKHR* pInfo)4576{4577ANV_FROM_HANDLE(anv_buffer, buffer, pInfo->buffer);45784579assert(!anv_address_is_null(buffer->address));4580assert(buffer->address.bo->flags & EXEC_OBJECT_PINNED);45814582return anv_address_physical(buffer->address);4583}45844585uint64_t anv_GetBufferOpaqueCaptureAddress(4586VkDevice device,4587const VkBufferDeviceAddressInfoKHR* pInfo)4588{4589return 0;4590}45914592uint64_t anv_GetDeviceMemoryOpaqueCaptureAddress(4593VkDevice device,4594const VkDeviceMemoryOpaqueCaptureAddressInfoKHR* pInfo)4595{4596ANV_FROM_HANDLE(anv_device_memory, memory, pInfo->memory);45974598assert(memory->bo->flags & EXEC_OBJECT_PINNED);4599assert(memory->bo->has_client_visible_address);46004601return intel_48b_address(memory->bo->offset);4602}46034604void4605anv_fill_buffer_surface_state(struct anv_device *device, struct anv_state state,4606enum isl_format format,4607isl_surf_usage_flags_t usage,4608struct anv_address address,4609uint32_t range, uint32_t stride)4610{4611isl_buffer_fill_state(&device->isl_dev, state.map,4612.address = anv_address_physical(address),4613.mocs = isl_mocs(&device->isl_dev, usage,4614address.bo && address.bo->is_external),4615.size_B = range,4616.format = format,4617.swizzle = ISL_SWIZZLE_IDENTITY,4618.stride_B = stride);4619}46204621void anv_DestroySampler(4622VkDevice _device,4623VkSampler _sampler,4624const VkAllocationCallbacks* pAllocator)4625{4626ANV_FROM_HANDLE(anv_device, device, _device);4627ANV_FROM_HANDLE(anv_sampler, sampler, _sampler);46284629if (!sampler)4630return;46314632if (sampler->bindless_state.map) {4633anv_state_pool_free(&device->dynamic_state_pool,4634sampler->bindless_state);4635}46364637if (sampler->custom_border_color.map) {4638anv_state_reserved_pool_free(&device->custom_border_colors,4639sampler->custom_border_color);4640}46414642vk_object_free(&device->vk, pAllocator, sampler);4643}46444645VkResult anv_CreateFramebuffer(4646VkDevice _device,4647const VkFramebufferCreateInfo* pCreateInfo,4648const VkAllocationCallbacks* pAllocator,4649VkFramebuffer* pFramebuffer)4650{4651ANV_FROM_HANDLE(anv_device, device, _device);4652struct anv_framebuffer *framebuffer;46534654assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);46554656size_t size = sizeof(*framebuffer);46574658/* VK_KHR_imageless_framebuffer extension says:4659*4660* If flags includes VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR,4661* parameter pAttachments is ignored.4662*/4663if (!(pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR))4664size += sizeof(struct anv_image_view *) * pCreateInfo->attachmentCount;46654666framebuffer = vk_object_alloc(&device->vk, pAllocator, size,4667VK_OBJECT_TYPE_FRAMEBUFFER);4668if (framebuffer == NULL)4669return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);46704671framebuffer->width = pCreateInfo->width;4672framebuffer->height = pCreateInfo->height;4673framebuffer->layers = pCreateInfo->layers;46744675if (!(pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR)) {4676for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {4677ANV_FROM_HANDLE(anv_image_view, iview, pCreateInfo->pAttachments[i]);4678framebuffer->attachments[i] = iview;4679}4680framebuffer->attachment_count = pCreateInfo->attachmentCount;4681}46824683*pFramebuffer = anv_framebuffer_to_handle(framebuffer);46844685return VK_SUCCESS;4686}46874688void anv_DestroyFramebuffer(4689VkDevice _device,4690VkFramebuffer _fb,4691const VkAllocationCallbacks* pAllocator)4692{4693ANV_FROM_HANDLE(anv_device, device, _device);4694ANV_FROM_HANDLE(anv_framebuffer, fb, _fb);46954696if (!fb)4697return;46984699vk_object_free(&device->vk, pAllocator, fb);4700}47014702static const VkTimeDomainEXT anv_time_domains[] = {4703VK_TIME_DOMAIN_DEVICE_EXT,4704VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,4705#ifdef CLOCK_MONOTONIC_RAW4706VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,4707#endif4708};47094710VkResult anv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(4711VkPhysicalDevice physicalDevice,4712uint32_t *pTimeDomainCount,4713VkTimeDomainEXT *pTimeDomains)4714{4715int d;4716VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);47174718for (d = 0; d < ARRAY_SIZE(anv_time_domains); d++) {4719vk_outarray_append(&out, i) {4720*i = anv_time_domains[d];4721}4722}47234724return vk_outarray_status(&out);4725}47264727static uint64_t4728anv_clock_gettime(clockid_t clock_id)4729{4730struct timespec current;4731int ret;47324733ret = clock_gettime(clock_id, ¤t);4734#ifdef CLOCK_MONOTONIC_RAW4735if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)4736ret = clock_gettime(CLOCK_MONOTONIC, ¤t);4737#endif4738if (ret < 0)4739return 0;47404741return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;4742}47434744VkResult anv_GetCalibratedTimestampsEXT(4745VkDevice _device,4746uint32_t timestampCount,4747const VkCalibratedTimestampInfoEXT *pTimestampInfos,4748uint64_t *pTimestamps,4749uint64_t *pMaxDeviation)4750{4751ANV_FROM_HANDLE(anv_device, device, _device);4752uint64_t timestamp_frequency = device->info.timestamp_frequency;4753int ret;4754int d;4755uint64_t begin, end;4756uint64_t max_clock_period = 0;47574758#ifdef CLOCK_MONOTONIC_RAW4759begin = anv_clock_gettime(CLOCK_MONOTONIC_RAW);4760#else4761begin = anv_clock_gettime(CLOCK_MONOTONIC);4762#endif47634764for (d = 0; d < timestampCount; d++) {4765switch (pTimestampInfos[d].timeDomain) {4766case VK_TIME_DOMAIN_DEVICE_EXT:4767ret = anv_gem_reg_read(device->fd, TIMESTAMP | I915_REG_READ_8B_WA,4768&pTimestamps[d]);47694770if (ret != 0) {4771return anv_device_set_lost(device, "Failed to read the TIMESTAMP "4772"register: %m");4773}4774uint64_t device_period = DIV_ROUND_UP(1000000000, timestamp_frequency);4775max_clock_period = MAX2(max_clock_period, device_period);4776break;4777case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:4778pTimestamps[d] = anv_clock_gettime(CLOCK_MONOTONIC);4779max_clock_period = MAX2(max_clock_period, 1);4780break;47814782#ifdef CLOCK_MONOTONIC_RAW4783case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:4784pTimestamps[d] = begin;4785break;4786#endif4787default:4788pTimestamps[d] = 0;4789break;4790}4791}47924793#ifdef CLOCK_MONOTONIC_RAW4794end = anv_clock_gettime(CLOCK_MONOTONIC_RAW);4795#else4796end = anv_clock_gettime(CLOCK_MONOTONIC);4797#endif47984799/*4800* The maximum deviation is the sum of the interval over which we4801* perform the sampling and the maximum period of any sampled4802* clock. That's because the maximum skew between any two sampled4803* clock edges is when the sampled clock with the largest period is4804* sampled at the end of that period but right at the beginning of the4805* sampling interval and some other clock is sampled right at the4806* begining of its sampling period and right at the end of the4807* sampling interval. Let's assume the GPU has the longest clock4808* period and that the application is sampling GPU and monotonic:4809*4810* s e4811* w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e f4812* Raw -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-4813*4814* g4815* 0 1 2 34816* GPU -----_____-----_____-----_____-----_____4817*4818* m4819* x y z 0 1 2 3 4 5 6 7 8 9 a b c4820* Monotonic -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-4821*4822* Interval <----------------->4823* Deviation <-------------------------->4824*4825* s = read(raw) 24826* g = read(GPU) 14827* m = read(monotonic) 24828* e = read(raw) b4829*4830* We round the sample interval up by one tick to cover sampling error4831* in the interval clock4832*/48334834uint64_t sample_interval = end - begin + 1;48354836*pMaxDeviation = sample_interval + max_clock_period;48374838return VK_SUCCESS;4839}48404841void anv_GetPhysicalDeviceMultisamplePropertiesEXT(4842VkPhysicalDevice physicalDevice,4843VkSampleCountFlagBits samples,4844VkMultisamplePropertiesEXT* pMultisampleProperties)4845{4846ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);48474848assert(pMultisampleProperties->sType ==4849VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT);48504851VkExtent2D grid_size;4852if (samples & isl_device_get_sample_counts(&physical_device->isl_dev)) {4853grid_size.width = 1;4854grid_size.height = 1;4855} else {4856grid_size.width = 0;4857grid_size.height = 0;4858}4859pMultisampleProperties->maxSampleLocationGridSize = grid_size;48604861vk_foreach_struct(ext, pMultisampleProperties->pNext)4862anv_debug_ignored_stype(ext->sType);4863}48644865/* vk_icd.h does not declare this function, so we declare it here to4866* suppress Wmissing-prototypes.4867*/4868PUBLIC VKAPI_ATTR VkResult VKAPI_CALL4869vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion);48704871PUBLIC VKAPI_ATTR VkResult VKAPI_CALL4872vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion)4873{4874/* For the full details on loader interface versioning, see4875* <https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/loader/LoaderAndLayerInterface.md>.4876* What follows is a condensed summary, to help you navigate the large and4877* confusing official doc.4878*4879* - Loader interface v0 is incompatible with later versions. We don't4880* support it.4881*4882* - In loader interface v1:4883* - The first ICD entrypoint called by the loader is4884* vk_icdGetInstanceProcAddr(). The ICD must statically expose this4885* entrypoint.4886* - The ICD must statically expose no other Vulkan symbol unless it is4887* linked with -Bsymbolic.4888* - Each dispatchable Vulkan handle created by the ICD must be4889* a pointer to a struct whose first member is VK_LOADER_DATA. The4890* ICD must initialize VK_LOADER_DATA.loadMagic to ICD_LOADER_MAGIC.4891* - The loader implements vkCreate{PLATFORM}SurfaceKHR() and4892* vkDestroySurfaceKHR(). The ICD must be capable of working with4893* such loader-managed surfaces.4894*4895* - Loader interface v2 differs from v1 in:4896* - The first ICD entrypoint called by the loader is4897* vk_icdNegotiateLoaderICDInterfaceVersion(). The ICD must4898* statically expose this entrypoint.4899*4900* - Loader interface v3 differs from v2 in:4901* - The ICD must implement vkCreate{PLATFORM}SurfaceKHR(),4902* vkDestroySurfaceKHR(), and other API which uses VKSurfaceKHR,4903* because the loader no longer does so.4904*4905* - Loader interface v4 differs from v3 in:4906* - The ICD must implement vk_icdGetPhysicalDeviceProcAddr().4907*/4908*pSupportedVersion = MIN2(*pSupportedVersion, 4u);4909return VK_SUCCESS;4910}49114912VkResult anv_GetPhysicalDeviceFragmentShadingRatesKHR(4913VkPhysicalDevice physicalDevice,4914uint32_t* pFragmentShadingRateCount,4915VkPhysicalDeviceFragmentShadingRateKHR* pFragmentShadingRates)4916{4917ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);4918VK_OUTARRAY_MAKE(out, pFragmentShadingRates, pFragmentShadingRateCount);49194920#define append_rate(_samples, _width, _height) \4921do { \4922vk_outarray_append(&out, __r) { \4923__r->sampleCounts = _samples; \4924__r->fragmentSize = (VkExtent2D) { \4925.width = _width, \4926.height = _height, \4927}; \4928} \4929} while (0)49304931VkSampleCountFlags sample_counts =4932isl_device_get_sample_counts(&physical_device->isl_dev);49334934for (uint32_t x = 4; x >= 1; x /= 2) {4935for (uint32_t y = 4; y >= 1; y /= 2) {4936/* For size {1, 1}, the sample count must be ~0 */4937if (x == 1 && y == 1)4938append_rate(~0, x, y);4939else4940append_rate(sample_counts, x, y);4941}4942}49434944#undef append_rate49454946return vk_outarray_status(&out);4947}494849494950