101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2015 Intel Corporation 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2101e04c3fSmrg * IN THE SOFTWARE. 2201e04c3fSmrg */ 2301e04c3fSmrg 2401e04c3fSmrg#include <assert.h> 2501e04c3fSmrg#include <stdbool.h> 2601e04c3fSmrg#include <string.h> 277ec681f3Smrg#ifdef MAJOR_IN_MKDEV 287ec681f3Smrg#include <sys/mkdev.h> 297ec681f3Smrg#endif 307ec681f3Smrg#ifdef MAJOR_IN_SYSMACROS 317ec681f3Smrg#include <sys/sysmacros.h> 327ec681f3Smrg#endif 3301e04c3fSmrg#include <sys/mman.h> 347ec681f3Smrg#include <sys/stat.h> 3501e04c3fSmrg#include <unistd.h> 3601e04c3fSmrg#include <fcntl.h> 379f464c52Smaya#include "drm-uapi/drm_fourcc.h" 387ec681f3Smrg#include "drm-uapi/drm.h" 397ec681f3Smrg#include <xf86drm.h> 4001e04c3fSmrg 4101e04c3fSmrg#include "anv_private.h" 427ec681f3Smrg#include "anv_measure.h" 4301e04c3fSmrg#include "util/debug.h" 4401e04c3fSmrg#include "util/build_id.h" 4501e04c3fSmrg#include "util/disk_cache.h" 4601e04c3fSmrg#include "util/mesa-sha1.h" 479f464c52Smaya#include "util/os_file.h" 487ec681f3Smrg#include "util/os_misc.h" 499f464c52Smaya#include "util/u_atomic.h" 5001e04c3fSmrg#include "util/u_string.h" 517ec681f3Smrg#include "util/driconf.h" 5201e04c3fSmrg#include "git_sha1.h" 5301e04c3fSmrg#include "vk_util.h" 547ec681f3Smrg#include "vk_deferred_operation.h" 557ec681f3Smrg#include "common/intel_aux_map.h" 567ec681f3Smrg#include "common/intel_defines.h" 577ec681f3Smrg#include "common/intel_uuid.h" 587ec681f3Smrg#include "perf/intel_perf.h" 5901e04c3fSmrg 6001e04c3fSmrg#include "genxml/gen7_pack.h" 6101e04c3fSmrg 627ec681f3Smrgstatic const driOptionDescription anv_dri_options[] = { 639f464c52Smaya DRI_CONF_SECTION_PERFORMANCE 649f464c52Smaya DRI_CONF_VK_X11_OVERRIDE_MIN_IMAGE_COUNT(0) 657ec681f3Smrg DRI_CONF_VK_X11_STRICT_IMAGE_COUNT(false) 667ec681f3Smrg DRI_CONF_VK_XWAYLAND_WAIT_READY(true) 679f464c52Smaya DRI_CONF_SECTION_END 687ec681f3Smrg 697ec681f3Smrg DRI_CONF_SECTION_DEBUG 707ec681f3Smrg DRI_CONF_ALWAYS_FLUSH_CACHE(false) 717ec681f3Smrg DRI_CONF_VK_WSI_FORCE_BGRA8_UNORM_FIRST(false) 727ec681f3Smrg DRI_CONF_SECTION_END 737ec681f3Smrg}; 749f464c52Smaya 759f464c52Smaya/* This is probably far to big but it reflects the max size used for messages 769f464c52Smaya * in OpenGLs KHR_debug. 779f464c52Smaya */ 789f464c52Smaya#define MAX_DEBUG_MESSAGE_LENGTH 4096 799f464c52Smaya 807ec681f3Smrg/* Render engine timestamp register */ 817ec681f3Smrg#define TIMESTAMP 0x2358 827ec681f3Smrg 837ec681f3Smrg/* The "RAW" clocks on Linux are called "FAST" on FreeBSD */ 847ec681f3Smrg#if !defined(CLOCK_MONOTONIC_RAW) && defined(CLOCK_MONOTONIC_FAST) 857ec681f3Smrg#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC_FAST 867ec681f3Smrg#endif 877ec681f3Smrg 8801e04c3fSmrgstatic void 897ec681f3Smrgcompiler_debug_log(void *data, UNUSED unsigned *id, const char *fmt, ...) 909f464c52Smaya{ 919f464c52Smaya char str[MAX_DEBUG_MESSAGE_LENGTH]; 929f464c52Smaya struct anv_device *device = (struct anv_device *)data; 937ec681f3Smrg struct anv_instance *instance = device->physical->instance; 949f464c52Smaya 959f464c52Smaya va_list args; 969f464c52Smaya va_start(args, fmt); 979f464c52Smaya (void) vsnprintf(str, MAX_DEBUG_MESSAGE_LENGTH, fmt, args); 989f464c52Smaya va_end(args); 999f464c52Smaya 1007ec681f3Smrg vk_logd(VK_LOG_NO_OBJS(&instance->vk), "%s", str); 1019f464c52Smaya} 10201e04c3fSmrg 10301e04c3fSmrgstatic void 1047ec681f3Smrgcompiler_perf_log(UNUSED void *data, UNUSED unsigned *id, const char *fmt, ...) 10501e04c3fSmrg{ 10601e04c3fSmrg va_list args; 10701e04c3fSmrg va_start(args, fmt); 10801e04c3fSmrg 1097ec681f3Smrg if (INTEL_DEBUG(DEBUG_PERF)) 1107ec681f3Smrg mesa_logd_v(fmt, args); 11101e04c3fSmrg 11201e04c3fSmrg va_end(args); 11301e04c3fSmrg} 11401e04c3fSmrg 1157ec681f3Smrg#if defined(VK_USE_PLATFORM_WAYLAND_KHR) || \ 1167ec681f3Smrg defined(VK_USE_PLATFORM_XCB_KHR) || \ 1177ec681f3Smrg defined(VK_USE_PLATFORM_XLIB_KHR) || \ 1187ec681f3Smrg defined(VK_USE_PLATFORM_DISPLAY_KHR) 1197ec681f3Smrg#define ANV_USE_WSI_PLATFORM 1207ec681f3Smrg#endif 1217ec681f3Smrg 1227ec681f3Smrg#ifdef ANDROID 1237ec681f3Smrg#define ANV_API_VERSION VK_MAKE_VERSION(1, 1, VK_HEADER_VERSION) 1247ec681f3Smrg#else 1257ec681f3Smrg#define ANV_API_VERSION VK_MAKE_VERSION(1, 2, VK_HEADER_VERSION) 1267ec681f3Smrg#endif 1277ec681f3Smrg 1287ec681f3SmrgVkResult anv_EnumerateInstanceVersion( 1297ec681f3Smrg uint32_t* pApiVersion) 13001e04c3fSmrg{ 1317ec681f3Smrg *pApiVersion = ANV_API_VERSION; 1327ec681f3Smrg return VK_SUCCESS; 1337ec681f3Smrg} 13401e04c3fSmrg 1357ec681f3Smrgstatic const struct vk_instance_extension_table instance_extensions = { 1367ec681f3Smrg .KHR_device_group_creation = true, 1377ec681f3Smrg .KHR_external_fence_capabilities = true, 1387ec681f3Smrg .KHR_external_memory_capabilities = true, 1397ec681f3Smrg .KHR_external_semaphore_capabilities = true, 1407ec681f3Smrg .KHR_get_physical_device_properties2 = true, 1417ec681f3Smrg .EXT_debug_report = true, 1427ec681f3Smrg 1437ec681f3Smrg#ifdef ANV_USE_WSI_PLATFORM 1447ec681f3Smrg .KHR_get_surface_capabilities2 = true, 1457ec681f3Smrg .KHR_surface = true, 1467ec681f3Smrg .KHR_surface_protected_capabilities = true, 1477ec681f3Smrg#endif 1487ec681f3Smrg#ifdef VK_USE_PLATFORM_WAYLAND_KHR 1497ec681f3Smrg .KHR_wayland_surface = true, 1507ec681f3Smrg#endif 1517ec681f3Smrg#ifdef VK_USE_PLATFORM_XCB_KHR 1527ec681f3Smrg .KHR_xcb_surface = true, 1537ec681f3Smrg#endif 1547ec681f3Smrg#ifdef VK_USE_PLATFORM_XLIB_KHR 1557ec681f3Smrg .KHR_xlib_surface = true, 1567ec681f3Smrg#endif 1577ec681f3Smrg#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT 1587ec681f3Smrg .EXT_acquire_xlib_display = true, 1597ec681f3Smrg#endif 1607ec681f3Smrg#ifdef VK_USE_PLATFORM_DISPLAY_KHR 1617ec681f3Smrg .KHR_display = true, 1627ec681f3Smrg .KHR_get_display_properties2 = true, 1637ec681f3Smrg .EXT_direct_mode_display = true, 1647ec681f3Smrg .EXT_display_surface_counter = true, 1657ec681f3Smrg .EXT_acquire_drm_display = true, 1667ec681f3Smrg#endif 1677ec681f3Smrg}; 1687ec681f3Smrg 1697ec681f3Smrgstatic void 1707ec681f3Smrgget_device_extensions(const struct anv_physical_device *device, 1717ec681f3Smrg struct vk_device_extension_table *ext) 1727ec681f3Smrg{ 1737ec681f3Smrg *ext = (struct vk_device_extension_table) { 1747ec681f3Smrg .KHR_8bit_storage = device->info.ver >= 8, 1757ec681f3Smrg .KHR_16bit_storage = device->info.ver >= 8, 1767ec681f3Smrg .KHR_bind_memory2 = true, 1777ec681f3Smrg .KHR_buffer_device_address = device->has_a64_buffer_access, 1787ec681f3Smrg .KHR_copy_commands2 = true, 1797ec681f3Smrg .KHR_create_renderpass2 = true, 1807ec681f3Smrg .KHR_dedicated_allocation = true, 1817ec681f3Smrg .KHR_deferred_host_operations = true, 1827ec681f3Smrg .KHR_depth_stencil_resolve = true, 1837ec681f3Smrg .KHR_descriptor_update_template = true, 1847ec681f3Smrg .KHR_device_group = true, 1857ec681f3Smrg .KHR_draw_indirect_count = true, 1867ec681f3Smrg .KHR_driver_properties = true, 1877ec681f3Smrg .KHR_external_fence = device->has_syncobj_wait, 1887ec681f3Smrg .KHR_external_fence_fd = device->has_syncobj_wait, 1897ec681f3Smrg .KHR_external_memory = true, 1907ec681f3Smrg .KHR_external_memory_fd = true, 1917ec681f3Smrg .KHR_external_semaphore = true, 1927ec681f3Smrg .KHR_external_semaphore_fd = true, 1937ec681f3Smrg .KHR_format_feature_flags2 = true, 1947ec681f3Smrg .KHR_fragment_shading_rate = device->info.ver >= 11, 1957ec681f3Smrg .KHR_get_memory_requirements2 = true, 1967ec681f3Smrg .KHR_image_format_list = true, 1977ec681f3Smrg .KHR_imageless_framebuffer = true, 1987ec681f3Smrg#ifdef ANV_USE_WSI_PLATFORM 1997ec681f3Smrg .KHR_incremental_present = true, 2007ec681f3Smrg#endif 2017ec681f3Smrg .KHR_maintenance1 = true, 2027ec681f3Smrg .KHR_maintenance2 = true, 2037ec681f3Smrg .KHR_maintenance3 = true, 2047ec681f3Smrg .KHR_maintenance4 = true, 2057ec681f3Smrg .KHR_multiview = true, 2067ec681f3Smrg .KHR_performance_query = 2077ec681f3Smrg device->use_softpin && device->perf && 2087ec681f3Smrg (device->perf->i915_perf_version >= 3 || 2097ec681f3Smrg INTEL_DEBUG(DEBUG_NO_OACONFIG)) && 2107ec681f3Smrg device->use_call_secondary, 2117ec681f3Smrg .KHR_pipeline_executable_properties = true, 2127ec681f3Smrg .KHR_push_descriptor = true, 2137ec681f3Smrg .KHR_relaxed_block_layout = true, 2147ec681f3Smrg .KHR_sampler_mirror_clamp_to_edge = true, 2157ec681f3Smrg .KHR_sampler_ycbcr_conversion = true, 2167ec681f3Smrg .KHR_separate_depth_stencil_layouts = true, 2177ec681f3Smrg .KHR_shader_atomic_int64 = device->info.ver >= 9 && 2187ec681f3Smrg device->use_softpin, 2197ec681f3Smrg .KHR_shader_clock = true, 2207ec681f3Smrg .KHR_shader_draw_parameters = true, 2217ec681f3Smrg .KHR_shader_float16_int8 = device->info.ver >= 8, 2227ec681f3Smrg .KHR_shader_float_controls = device->info.ver >= 8, 2237ec681f3Smrg .KHR_shader_integer_dot_product = true, 2247ec681f3Smrg .KHR_shader_non_semantic_info = true, 2257ec681f3Smrg .KHR_shader_subgroup_extended_types = device->info.ver >= 8, 2267ec681f3Smrg .KHR_shader_subgroup_uniform_control_flow = true, 2277ec681f3Smrg .KHR_shader_terminate_invocation = true, 2287ec681f3Smrg .KHR_spirv_1_4 = true, 2297ec681f3Smrg .KHR_storage_buffer_storage_class = true, 2307ec681f3Smrg#ifdef ANV_USE_WSI_PLATFORM 2317ec681f3Smrg .KHR_swapchain = true, 2327ec681f3Smrg .KHR_swapchain_mutable_format = true, 2337ec681f3Smrg#endif 2347ec681f3Smrg .KHR_synchronization2 = true, 2357ec681f3Smrg .KHR_timeline_semaphore = true, 2367ec681f3Smrg .KHR_uniform_buffer_standard_layout = true, 2377ec681f3Smrg .KHR_variable_pointers = true, 2387ec681f3Smrg .KHR_vulkan_memory_model = true, 2397ec681f3Smrg .KHR_workgroup_memory_explicit_layout = true, 2407ec681f3Smrg .KHR_zero_initialize_workgroup_memory = true, 2417ec681f3Smrg .EXT_4444_formats = true, 2427ec681f3Smrg .EXT_buffer_device_address = device->has_a64_buffer_access, 2437ec681f3Smrg .EXT_calibrated_timestamps = device->has_reg_timestamp, 2447ec681f3Smrg .EXT_color_write_enable = true, 2457ec681f3Smrg .EXT_conditional_rendering = device->info.verx10 >= 75, 2467ec681f3Smrg .EXT_conservative_rasterization = device->info.ver >= 9, 2477ec681f3Smrg .EXT_custom_border_color = device->info.ver >= 8, 2487ec681f3Smrg .EXT_depth_clip_enable = true, 2497ec681f3Smrg .EXT_descriptor_indexing = device->has_a64_buffer_access && 2507ec681f3Smrg device->has_bindless_images, 2517ec681f3Smrg#ifdef VK_USE_PLATFORM_DISPLAY_KHR 2527ec681f3Smrg .EXT_display_control = true, 2537ec681f3Smrg#endif 2547ec681f3Smrg .EXT_extended_dynamic_state = true, 2557ec681f3Smrg .EXT_extended_dynamic_state2 = true, 2567ec681f3Smrg .EXT_external_memory_dma_buf = true, 2577ec681f3Smrg .EXT_external_memory_host = true, 2587ec681f3Smrg .EXT_fragment_shader_interlock = device->info.ver >= 9, 2597ec681f3Smrg .EXT_global_priority = device->has_context_priority, 2607ec681f3Smrg .EXT_host_query_reset = true, 2617ec681f3Smrg .EXT_image_robustness = true, 2627ec681f3Smrg .EXT_image_drm_format_modifier = true, 2637ec681f3Smrg .EXT_index_type_uint8 = true, 2647ec681f3Smrg .EXT_inline_uniform_block = true, 2657ec681f3Smrg .EXT_line_rasterization = true, 2667ec681f3Smrg .EXT_memory_budget = device->sys.available, 2677ec681f3Smrg .EXT_pci_bus_info = true, 2687ec681f3Smrg .EXT_physical_device_drm = true, 2697ec681f3Smrg .EXT_pipeline_creation_cache_control = true, 2707ec681f3Smrg .EXT_pipeline_creation_feedback = true, 2717ec681f3Smrg .EXT_post_depth_coverage = device->info.ver >= 9, 2727ec681f3Smrg .EXT_primitive_topology_list_restart = true, 2737ec681f3Smrg .EXT_private_data = true, 2747ec681f3Smrg .EXT_provoking_vertex = true, 2757ec681f3Smrg .EXT_queue_family_foreign = true, 2767ec681f3Smrg .EXT_robustness2 = true, 2777ec681f3Smrg .EXT_sample_locations = true, 2787ec681f3Smrg .EXT_sampler_filter_minmax = device->info.ver >= 9, 2797ec681f3Smrg .EXT_scalar_block_layout = true, 2807ec681f3Smrg .EXT_separate_stencil_usage = true, 2817ec681f3Smrg .EXT_shader_atomic_float = true, 2827ec681f3Smrg .EXT_shader_atomic_float2 = device->info.ver >= 9, 2837ec681f3Smrg .EXT_shader_demote_to_helper_invocation = true, 2847ec681f3Smrg .EXT_shader_stencil_export = device->info.ver >= 9, 2857ec681f3Smrg .EXT_shader_subgroup_ballot = true, 2867ec681f3Smrg .EXT_shader_subgroup_vote = true, 2877ec681f3Smrg .EXT_shader_viewport_index_layer = true, 2887ec681f3Smrg .EXT_subgroup_size_control = true, 2897ec681f3Smrg .EXT_texel_buffer_alignment = true, 2907ec681f3Smrg .EXT_transform_feedback = true, 2917ec681f3Smrg .EXT_vertex_attribute_divisor = true, 2927ec681f3Smrg .EXT_ycbcr_image_arrays = true, 2937ec681f3Smrg#ifdef ANDROID 2947ec681f3Smrg .ANDROID_external_memory_android_hardware_buffer = true, 2957ec681f3Smrg .ANDROID_native_buffer = true, 2967ec681f3Smrg#endif 2977ec681f3Smrg .GOOGLE_decorate_string = true, 2987ec681f3Smrg .GOOGLE_hlsl_functionality1 = true, 2997ec681f3Smrg .GOOGLE_user_type = true, 3007ec681f3Smrg .INTEL_performance_query = device->perf && 3017ec681f3Smrg device->perf->i915_perf_version >= 3, 3027ec681f3Smrg .INTEL_shader_integer_functions2 = device->info.ver >= 8, 3037ec681f3Smrg .EXT_multi_draw = true, 3047ec681f3Smrg .NV_compute_shader_derivatives = true, 3057ec681f3Smrg }; 3067ec681f3Smrg} 30701e04c3fSmrg 3087ec681f3Smrgstatic uint64_t 3097ec681f3Smrganv_compute_sys_heap_size(struct anv_physical_device *device, 3107ec681f3Smrg uint64_t total_ram) 3117ec681f3Smrg{ 31201e04c3fSmrg /* We don't want to burn too much ram with the GPU. If the user has 4GiB 31301e04c3fSmrg * or less, we use at most half. If they have more than 4GiB, we use 3/4. 31401e04c3fSmrg */ 31501e04c3fSmrg uint64_t available_ram; 31601e04c3fSmrg if (total_ram <= 4ull * 1024ull * 1024ull * 1024ull) 31701e04c3fSmrg available_ram = total_ram / 2; 31801e04c3fSmrg else 31901e04c3fSmrg available_ram = total_ram * 3 / 4; 32001e04c3fSmrg 32101e04c3fSmrg /* We also want to leave some padding for things we allocate in the driver, 32201e04c3fSmrg * so don't go over 3/4 of the GTT either. 32301e04c3fSmrg */ 3247ec681f3Smrg available_ram = MIN2(available_ram, device->gtt_size * 3 / 4); 3257ec681f3Smrg 3267ec681f3Smrg if (available_ram > (2ull << 30) && !device->supports_48bit_addresses) { 3277ec681f3Smrg /* When running with an overridden PCI ID, we may get a GTT size from 3287ec681f3Smrg * the kernel that is greater than 2 GiB but the execbuf check for 48bit 3297ec681f3Smrg * address support can still fail. Just clamp the address space size to 3307ec681f3Smrg * 2 GiB if we don't have 48-bit support. 3317ec681f3Smrg */ 3327ec681f3Smrg mesa_logw("%s:%d: The kernel reported a GTT size larger than 2 GiB but " 3337ec681f3Smrg "not support for 48-bit addresses", 3347ec681f3Smrg __FILE__, __LINE__); 3357ec681f3Smrg available_ram = 2ull << 30; 3367ec681f3Smrg } 3377ec681f3Smrg 3387ec681f3Smrg return available_ram; 3397ec681f3Smrg} 3407ec681f3Smrg 3417ec681f3Smrgstatic VkResult MUST_CHECK 3427ec681f3Smrganv_gather_meminfo(struct anv_physical_device *device, int fd, bool update) 3437ec681f3Smrg{ 3447ec681f3Smrg char sys_mem_regions[sizeof(struct drm_i915_query_memory_regions) + 3457ec681f3Smrg sizeof(struct drm_i915_memory_region_info)]; 3467ec681f3Smrg 3477ec681f3Smrg struct drm_i915_query_memory_regions *mem_regions = 3487ec681f3Smrg intel_i915_query_alloc(fd, DRM_I915_QUERY_MEMORY_REGIONS); 3497ec681f3Smrg if (mem_regions == NULL) { 3507ec681f3Smrg if (device->info.has_local_mem) { 3517ec681f3Smrg return vk_errorf(device, VK_ERROR_INCOMPATIBLE_DRIVER, 3527ec681f3Smrg "failed to memory regions: %m"); 3537ec681f3Smrg } 3547ec681f3Smrg 3557ec681f3Smrg uint64_t total_phys; 3567ec681f3Smrg if (!os_get_total_physical_memory(&total_phys)) { 3577ec681f3Smrg return vk_errorf(device, VK_ERROR_INITIALIZATION_FAILED, 3587ec681f3Smrg "failed to get total physical memory: %m"); 3597ec681f3Smrg } 3607ec681f3Smrg 3617ec681f3Smrg uint64_t available; 3627ec681f3Smrg if (!os_get_available_system_memory(&available)) 3637ec681f3Smrg available = 0; /* Silently disable VK_EXT_memory_budget */ 3647ec681f3Smrg 3657ec681f3Smrg /* The kernel query failed. Fake it using OS memory queries. This 3667ec681f3Smrg * should be roughly the same for integrated GPUs. 3677ec681f3Smrg */ 3687ec681f3Smrg mem_regions = (void *)sys_mem_regions; 3697ec681f3Smrg mem_regions->num_regions = 1; 3707ec681f3Smrg mem_regions->regions[0] = (struct drm_i915_memory_region_info) { 3717ec681f3Smrg .region.memory_class = I915_MEMORY_CLASS_SYSTEM, 3727ec681f3Smrg .probed_size = total_phys, 3737ec681f3Smrg .unallocated_size = available, 3747ec681f3Smrg }; 3757ec681f3Smrg } 3767ec681f3Smrg 3777ec681f3Smrg for(int i = 0; i < mem_regions->num_regions; i++) { 3787ec681f3Smrg struct drm_i915_memory_region_info *info = &mem_regions->regions[i]; 3797ec681f3Smrg 3807ec681f3Smrg struct anv_memregion *region; 3817ec681f3Smrg switch (info->region.memory_class) { 3827ec681f3Smrg case I915_MEMORY_CLASS_SYSTEM: 3837ec681f3Smrg region = &device->sys; 3847ec681f3Smrg break; 3857ec681f3Smrg case I915_MEMORY_CLASS_DEVICE: 3867ec681f3Smrg region = &device->vram; 3877ec681f3Smrg break; 3887ec681f3Smrg default: 3897ec681f3Smrg /* We don't know what kind of memory this is */ 3907ec681f3Smrg continue; 3917ec681f3Smrg } 3927ec681f3Smrg 3937ec681f3Smrg uint64_t size = info->probed_size; 3947ec681f3Smrg if (info->region.memory_class == I915_MEMORY_CLASS_SYSTEM) 3957ec681f3Smrg size = anv_compute_sys_heap_size(device, size); 3967ec681f3Smrg 3977ec681f3Smrg uint64_t available = MIN2(size, info->unallocated_size); 3987ec681f3Smrg 3997ec681f3Smrg if (update) { 4007ec681f3Smrg assert(region->region.memory_class == info->region.memory_class); 4017ec681f3Smrg assert(region->region.memory_instance == info->region.memory_instance); 4027ec681f3Smrg assert(region->size == size); 4037ec681f3Smrg } else { 4047ec681f3Smrg region->region = info->region; 4057ec681f3Smrg region->size = size; 4067ec681f3Smrg } 4077ec681f3Smrg region->available = available; 4087ec681f3Smrg } 40901e04c3fSmrg 4107ec681f3Smrg if (mem_regions != (void *)sys_mem_regions) 4117ec681f3Smrg free(mem_regions); 4127ec681f3Smrg 4137ec681f3Smrg return VK_SUCCESS; 4147ec681f3Smrg} 4157ec681f3Smrg 4167ec681f3Smrgstatic VkResult MUST_CHECK 4177ec681f3Smrganv_init_meminfo(struct anv_physical_device *device, int fd) 4187ec681f3Smrg{ 4197ec681f3Smrg return anv_gather_meminfo(device, fd, false); 4207ec681f3Smrg} 4217ec681f3Smrg 4227ec681f3Smrgstatic void 4237ec681f3Smrganv_update_meminfo(struct anv_physical_device *device, int fd) 4247ec681f3Smrg{ 4257ec681f3Smrg ASSERTED VkResult result = anv_gather_meminfo(device, fd, true); 4267ec681f3Smrg assert(result == VK_SUCCESS); 42701e04c3fSmrg} 42801e04c3fSmrg 4297ec681f3Smrg 43001e04c3fSmrgstatic VkResult 43101e04c3fSmrganv_physical_device_init_heaps(struct anv_physical_device *device, int fd) 43201e04c3fSmrg{ 43301e04c3fSmrg if (anv_gem_get_context_param(fd, 0, I915_CONTEXT_PARAM_GTT_SIZE, 4347ec681f3Smrg &device->gtt_size) == -1) { 43501e04c3fSmrg /* If, for whatever reason, we can't actually get the GTT size from the 43601e04c3fSmrg * kernel (too old?) fall back to the aperture size. 43701e04c3fSmrg */ 4387ec681f3Smrg anv_perf_warn(VK_LOG_NO_OBJS(&device->instance->vk), 43901e04c3fSmrg "Failed to get I915_CONTEXT_PARAM_GTT_SIZE: %m"); 44001e04c3fSmrg 4417ec681f3Smrg if (intel_get_aperture_size(fd, &device->gtt_size) == -1) { 4427ec681f3Smrg return vk_errorf(device, VK_ERROR_INITIALIZATION_FAILED, 44301e04c3fSmrg "failed to get aperture size: %m"); 44401e04c3fSmrg } 44501e04c3fSmrg } 44601e04c3fSmrg 4477ec681f3Smrg /* We only allow 48-bit addresses with softpin because knowing the actual 4487ec681f3Smrg * address is required for the vertex cache flush workaround. 4497ec681f3Smrg */ 4507ec681f3Smrg device->supports_48bit_addresses = (device->info.ver >= 8) && 4517ec681f3Smrg device->gtt_size > (4ULL << 30 /* GiB */); 45201e04c3fSmrg 4537ec681f3Smrg VkResult result = anv_init_meminfo(device, fd); 4547ec681f3Smrg if (result != VK_SUCCESS) 4557ec681f3Smrg return result; 45601e04c3fSmrg 4577ec681f3Smrg assert(device->sys.size != 0); 45801e04c3fSmrg 4597ec681f3Smrg if (device->vram.size > 0) { 4607ec681f3Smrg /* We can create 2 different heaps when we have local memory support, 4617ec681f3Smrg * first heap with local memory size and second with system memory size. 46201e04c3fSmrg */ 4637ec681f3Smrg device->memory.heap_count = 2; 46401e04c3fSmrg device->memory.heaps[0] = (struct anv_memory_heap) { 4657ec681f3Smrg .size = device->vram.size, 46601e04c3fSmrg .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT, 4677ec681f3Smrg .is_local_mem = true, 4687ec681f3Smrg }; 4697ec681f3Smrg device->memory.heaps[1] = (struct anv_memory_heap) { 4707ec681f3Smrg .size = device->sys.size, 4717ec681f3Smrg .flags = 0, 4727ec681f3Smrg .is_local_mem = false, 47301e04c3fSmrg }; 47401e04c3fSmrg 4757ec681f3Smrg device->memory.type_count = 3; 4767ec681f3Smrg device->memory.types[0] = (struct anv_memory_type) { 4777ec681f3Smrg .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 4787ec681f3Smrg .heapIndex = 0, 4797ec681f3Smrg }; 4807ec681f3Smrg device->memory.types[1] = (struct anv_memory_type) { 4817ec681f3Smrg .propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | 4827ec681f3Smrg VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | 4837ec681f3Smrg VK_MEMORY_PROPERTY_HOST_CACHED_BIT, 4847ec681f3Smrg .heapIndex = 1, 4857ec681f3Smrg }; 4867ec681f3Smrg device->memory.types[2] = (struct anv_memory_type) { 4877ec681f3Smrg .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | 4887ec681f3Smrg VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | 4897ec681f3Smrg VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 4907ec681f3Smrg .heapIndex = 0, 4917ec681f3Smrg }; 4927ec681f3Smrg } else if (device->info.has_llc) { 4937ec681f3Smrg device->memory.heap_count = 1; 49401e04c3fSmrg device->memory.heaps[0] = (struct anv_memory_heap) { 4957ec681f3Smrg .size = device->sys.size, 49601e04c3fSmrg .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT, 4977ec681f3Smrg .is_local_mem = false, 49801e04c3fSmrg }; 4997ec681f3Smrg 5007ec681f3Smrg /* Big core GPUs share LLC with the CPU and thus one memory type can be 5017ec681f3Smrg * both cached and coherent at the same time. 5027ec681f3Smrg */ 5037ec681f3Smrg device->memory.type_count = 1; 5047ec681f3Smrg device->memory.types[0] = (struct anv_memory_type) { 5057ec681f3Smrg .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | 5067ec681f3Smrg VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | 5077ec681f3Smrg VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | 5087ec681f3Smrg VK_MEMORY_PROPERTY_HOST_CACHED_BIT, 5097ec681f3Smrg .heapIndex = 0, 5107ec681f3Smrg }; 5117ec681f3Smrg } else { 5127ec681f3Smrg device->memory.heap_count = 1; 5137ec681f3Smrg device->memory.heaps[0] = (struct anv_memory_heap) { 5147ec681f3Smrg .size = device->sys.size, 51501e04c3fSmrg .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT, 5167ec681f3Smrg .is_local_mem = false, 51701e04c3fSmrg }; 51801e04c3fSmrg 5197ec681f3Smrg /* The spec requires that we expose a host-visible, coherent memory 5207ec681f3Smrg * type, but Atom GPUs don't share LLC. Thus we offer two memory types 5217ec681f3Smrg * to give the application a choice between cached, but not coherent and 5227ec681f3Smrg * coherent but uncached (WC though). 52301e04c3fSmrg */ 5247ec681f3Smrg device->memory.type_count = 2; 5257ec681f3Smrg device->memory.types[0] = (struct anv_memory_type) { 5267ec681f3Smrg .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | 5277ec681f3Smrg VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | 5287ec681f3Smrg VK_MEMORY_PROPERTY_HOST_CACHED_BIT, 5297ec681f3Smrg .heapIndex = 0, 5307ec681f3Smrg }; 5317ec681f3Smrg device->memory.types[1] = (struct anv_memory_type) { 5327ec681f3Smrg .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | 5337ec681f3Smrg VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | 5347ec681f3Smrg VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 5357ec681f3Smrg .heapIndex = 0, 5367ec681f3Smrg }; 5377ec681f3Smrg } 53801e04c3fSmrg 5397ec681f3Smrg device->memory.need_clflush = false; 5407ec681f3Smrg for (unsigned i = 0; i < device->memory.type_count; i++) { 5417ec681f3Smrg VkMemoryPropertyFlags props = device->memory.types[i].propertyFlags; 5427ec681f3Smrg if ((props & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) && 5437ec681f3Smrg !(props & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) 5447ec681f3Smrg device->memory.need_clflush = true; 54501e04c3fSmrg } 54601e04c3fSmrg 54701e04c3fSmrg return VK_SUCCESS; 54801e04c3fSmrg} 54901e04c3fSmrg 55001e04c3fSmrgstatic VkResult 55101e04c3fSmrganv_physical_device_init_uuids(struct anv_physical_device *device) 55201e04c3fSmrg{ 55301e04c3fSmrg const struct build_id_note *note = 55401e04c3fSmrg build_id_find_nhdr_for_addr(anv_physical_device_init_uuids); 55501e04c3fSmrg if (!note) { 5567ec681f3Smrg return vk_errorf(device, VK_ERROR_INITIALIZATION_FAILED, 55701e04c3fSmrg "Failed to find build-id"); 55801e04c3fSmrg } 55901e04c3fSmrg 56001e04c3fSmrg unsigned build_id_len = build_id_length(note); 56101e04c3fSmrg if (build_id_len < 20) { 5627ec681f3Smrg return vk_errorf(device, VK_ERROR_INITIALIZATION_FAILED, 56301e04c3fSmrg "build-id too short. It needs to be a SHA"); 56401e04c3fSmrg } 56501e04c3fSmrg 56601e04c3fSmrg memcpy(device->driver_build_sha1, build_id_data(note), 20); 56701e04c3fSmrg 56801e04c3fSmrg struct mesa_sha1 sha1_ctx; 56901e04c3fSmrg uint8_t sha1[20]; 57001e04c3fSmrg STATIC_ASSERT(VK_UUID_SIZE <= sizeof(sha1)); 57101e04c3fSmrg 57201e04c3fSmrg /* The pipeline cache UUID is used for determining when a pipeline cache is 57301e04c3fSmrg * invalid. It needs both a driver build and the PCI ID of the device. 57401e04c3fSmrg */ 57501e04c3fSmrg _mesa_sha1_init(&sha1_ctx); 57601e04c3fSmrg _mesa_sha1_update(&sha1_ctx, build_id_data(note), build_id_len); 5777ec681f3Smrg _mesa_sha1_update(&sha1_ctx, &device->info.chipset_id, 5787ec681f3Smrg sizeof(device->info.chipset_id)); 5799f464c52Smaya _mesa_sha1_update(&sha1_ctx, &device->always_use_bindless, 5809f464c52Smaya sizeof(device->always_use_bindless)); 5819f464c52Smaya _mesa_sha1_update(&sha1_ctx, &device->has_a64_buffer_access, 5829f464c52Smaya sizeof(device->has_a64_buffer_access)); 5839f464c52Smaya _mesa_sha1_update(&sha1_ctx, &device->has_bindless_images, 5849f464c52Smaya sizeof(device->has_bindless_images)); 5859f464c52Smaya _mesa_sha1_update(&sha1_ctx, &device->has_bindless_samplers, 5869f464c52Smaya sizeof(device->has_bindless_samplers)); 58701e04c3fSmrg _mesa_sha1_final(&sha1_ctx, sha1); 58801e04c3fSmrg memcpy(device->pipeline_cache_uuid, sha1, VK_UUID_SIZE); 58901e04c3fSmrg 5907ec681f3Smrg intel_uuid_compute_driver_id(device->driver_uuid, &device->info, VK_UUID_SIZE); 5917ec681f3Smrg intel_uuid_compute_device_id(device->device_uuid, &device->isl_dev, VK_UUID_SIZE); 59201e04c3fSmrg 59301e04c3fSmrg return VK_SUCCESS; 59401e04c3fSmrg} 59501e04c3fSmrg 59601e04c3fSmrgstatic void 59701e04c3fSmrganv_physical_device_init_disk_cache(struct anv_physical_device *device) 59801e04c3fSmrg{ 59901e04c3fSmrg#ifdef ENABLE_SHADER_CACHE 60001e04c3fSmrg char renderer[10]; 6017ec681f3Smrg ASSERTED int len = snprintf(renderer, sizeof(renderer), "anv_%04x", 6027ec681f3Smrg device->info.chipset_id); 60301e04c3fSmrg assert(len == sizeof(renderer) - 2); 60401e04c3fSmrg 60501e04c3fSmrg char timestamp[41]; 60601e04c3fSmrg _mesa_sha1_format(timestamp, device->driver_build_sha1); 60701e04c3fSmrg 60801e04c3fSmrg const uint64_t driver_flags = 60901e04c3fSmrg brw_get_compiler_config_value(device->compiler); 61001e04c3fSmrg device->disk_cache = disk_cache_create(renderer, timestamp, driver_flags); 61101e04c3fSmrg#else 61201e04c3fSmrg device->disk_cache = NULL; 61301e04c3fSmrg#endif 61401e04c3fSmrg} 61501e04c3fSmrg 61601e04c3fSmrgstatic void 61701e04c3fSmrganv_physical_device_free_disk_cache(struct anv_physical_device *device) 61801e04c3fSmrg{ 61901e04c3fSmrg#ifdef ENABLE_SHADER_CACHE 62001e04c3fSmrg if (device->disk_cache) 62101e04c3fSmrg disk_cache_destroy(device->disk_cache); 62201e04c3fSmrg#else 62301e04c3fSmrg assert(device->disk_cache == NULL); 62401e04c3fSmrg#endif 62501e04c3fSmrg} 62601e04c3fSmrg 6277ec681f3Smrg/* The ANV_QUEUE_OVERRIDE environment variable is a comma separated list of 6287ec681f3Smrg * queue overrides. 6297ec681f3Smrg * 6307ec681f3Smrg * To override the number queues: 6317ec681f3Smrg * * "gc" is for graphics queues with compute support 6327ec681f3Smrg * * "g" is for graphics queues with no compute support 6337ec681f3Smrg * * "c" is for compute queues with no graphics support 6347ec681f3Smrg * 6357ec681f3Smrg * For example, ANV_QUEUE_OVERRIDE=gc=2,c=1 would override the number of 6367ec681f3Smrg * advertised queues to be 2 queues with graphics+compute support, and 1 queue 6377ec681f3Smrg * with compute-only support. 6387ec681f3Smrg * 6397ec681f3Smrg * ANV_QUEUE_OVERRIDE=c=1 would override the number of advertised queues to 6407ec681f3Smrg * include 1 queue with compute-only support, but it will not change the 6417ec681f3Smrg * number of graphics+compute queues. 6427ec681f3Smrg * 6437ec681f3Smrg * ANV_QUEUE_OVERRIDE=gc=0,c=1 would override the number of advertised queues 6447ec681f3Smrg * to include 1 queue with compute-only support, and it would override the 6457ec681f3Smrg * number of graphics+compute queues to be 0. 6467ec681f3Smrg */ 6477ec681f3Smrgstatic void 6487ec681f3Smrganv_override_engine_counts(int *gc_count, int *g_count, int *c_count) 6499f464c52Smaya{ 6507ec681f3Smrg int gc_override = -1; 6517ec681f3Smrg int g_override = -1; 6527ec681f3Smrg int c_override = -1; 6537ec681f3Smrg char *env = getenv("ANV_QUEUE_OVERRIDE"); 6549f464c52Smaya 6557ec681f3Smrg if (env == NULL) 6567ec681f3Smrg return; 6579f464c52Smaya 6587ec681f3Smrg env = strdup(env); 6597ec681f3Smrg char *save = NULL; 6607ec681f3Smrg char *next = strtok_r(env, ",", &save); 6617ec681f3Smrg while (next != NULL) { 6627ec681f3Smrg if (strncmp(next, "gc=", 3) == 0) { 6637ec681f3Smrg gc_override = strtol(next + 3, NULL, 0); 6647ec681f3Smrg } else if (strncmp(next, "g=", 2) == 0) { 6657ec681f3Smrg g_override = strtol(next + 2, NULL, 0); 6667ec681f3Smrg } else if (strncmp(next, "c=", 2) == 0) { 6677ec681f3Smrg c_override = strtol(next + 2, NULL, 0); 6687ec681f3Smrg } else { 6697ec681f3Smrg mesa_logw("Ignoring unsupported ANV_QUEUE_OVERRIDE token: %s", next); 6707ec681f3Smrg } 6717ec681f3Smrg next = strtok_r(NULL, ",", &save); 6729f464c52Smaya } 6737ec681f3Smrg free(env); 6747ec681f3Smrg if (gc_override >= 0) 6757ec681f3Smrg *gc_count = gc_override; 6767ec681f3Smrg if (g_override >= 0) 6777ec681f3Smrg *g_count = g_override; 6787ec681f3Smrg if (*g_count > 0 && *gc_count <= 0 && (gc_override >= 0 || g_override >= 0)) 6797ec681f3Smrg mesa_logw("ANV_QUEUE_OVERRIDE: gc=0 with g > 0 violates the " 6807ec681f3Smrg "Vulkan specification"); 6817ec681f3Smrg if (c_override >= 0) 6827ec681f3Smrg *c_count = c_override; 6837ec681f3Smrg} 6849f464c52Smaya 6857ec681f3Smrgstatic void 6867ec681f3Smrganv_physical_device_init_queue_families(struct anv_physical_device *pdevice) 6877ec681f3Smrg{ 6887ec681f3Smrg uint32_t family_count = 0; 6897ec681f3Smrg 6907ec681f3Smrg if (pdevice->engine_info) { 6917ec681f3Smrg int gc_count = 6927ec681f3Smrg anv_gem_count_engines(pdevice->engine_info, I915_ENGINE_CLASS_RENDER); 6937ec681f3Smrg int g_count = 0; 6947ec681f3Smrg int c_count = 0; 6957ec681f3Smrg 6967ec681f3Smrg anv_override_engine_counts(&gc_count, &g_count, &c_count); 6977ec681f3Smrg 6987ec681f3Smrg if (gc_count > 0) { 6997ec681f3Smrg pdevice->queue.families[family_count++] = (struct anv_queue_family) { 7007ec681f3Smrg .queueFlags = VK_QUEUE_GRAPHICS_BIT | 7017ec681f3Smrg VK_QUEUE_COMPUTE_BIT | 7027ec681f3Smrg VK_QUEUE_TRANSFER_BIT, 7037ec681f3Smrg .queueCount = gc_count, 7047ec681f3Smrg .engine_class = I915_ENGINE_CLASS_RENDER, 7057ec681f3Smrg }; 7067ec681f3Smrg } 7077ec681f3Smrg if (g_count > 0) { 7087ec681f3Smrg pdevice->queue.families[family_count++] = (struct anv_queue_family) { 7097ec681f3Smrg .queueFlags = VK_QUEUE_GRAPHICS_BIT | 7107ec681f3Smrg VK_QUEUE_TRANSFER_BIT, 7117ec681f3Smrg .queueCount = g_count, 7127ec681f3Smrg .engine_class = I915_ENGINE_CLASS_RENDER, 7137ec681f3Smrg }; 7147ec681f3Smrg } 7157ec681f3Smrg if (c_count > 0) { 7167ec681f3Smrg pdevice->queue.families[family_count++] = (struct anv_queue_family) { 7177ec681f3Smrg .queueFlags = VK_QUEUE_COMPUTE_BIT | 7187ec681f3Smrg VK_QUEUE_TRANSFER_BIT, 7197ec681f3Smrg .queueCount = c_count, 7207ec681f3Smrg .engine_class = I915_ENGINE_CLASS_RENDER, 7217ec681f3Smrg }; 7227ec681f3Smrg } 7237ec681f3Smrg /* Increase count below when other families are added as a reminder to 7247ec681f3Smrg * increase the ANV_MAX_QUEUE_FAMILIES value. 7257ec681f3Smrg */ 7267ec681f3Smrg STATIC_ASSERT(ANV_MAX_QUEUE_FAMILIES >= 3); 7277ec681f3Smrg } else { 7287ec681f3Smrg /* Default to a single render queue */ 7297ec681f3Smrg pdevice->queue.families[family_count++] = (struct anv_queue_family) { 7307ec681f3Smrg .queueFlags = VK_QUEUE_GRAPHICS_BIT | 7317ec681f3Smrg VK_QUEUE_COMPUTE_BIT | 7327ec681f3Smrg VK_QUEUE_TRANSFER_BIT, 7337ec681f3Smrg .queueCount = 1, 7347ec681f3Smrg .engine_class = I915_ENGINE_CLASS_RENDER, 7357ec681f3Smrg }; 7367ec681f3Smrg family_count = 1; 7377ec681f3Smrg } 7387ec681f3Smrg assert(family_count <= ANV_MAX_QUEUE_FAMILIES); 7397ec681f3Smrg pdevice->queue.family_count = family_count; 7409f464c52Smaya} 7419f464c52Smaya 74201e04c3fSmrgstatic VkResult 7437ec681f3Smrganv_physical_device_try_create(struct anv_instance *instance, 7447ec681f3Smrg drmDevicePtr drm_device, 7457ec681f3Smrg struct anv_physical_device **device_out) 74601e04c3fSmrg{ 74701e04c3fSmrg const char *primary_path = drm_device->nodes[DRM_NODE_PRIMARY]; 74801e04c3fSmrg const char *path = drm_device->nodes[DRM_NODE_RENDER]; 74901e04c3fSmrg VkResult result; 75001e04c3fSmrg int fd; 75101e04c3fSmrg int master_fd = -1; 75201e04c3fSmrg 75301e04c3fSmrg brw_process_intel_debug_variable(); 75401e04c3fSmrg 75501e04c3fSmrg fd = open(path, O_RDWR | O_CLOEXEC); 7567ec681f3Smrg if (fd < 0) { 7577ec681f3Smrg if (errno == ENOMEM) { 7587ec681f3Smrg return vk_errorf(instance, VK_ERROR_OUT_OF_HOST_MEMORY, 7597ec681f3Smrg "Unable to open device %s: out of memory", path); 7607ec681f3Smrg } 7617ec681f3Smrg return vk_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER, 7627ec681f3Smrg "Unable to open device %s: %m", path); 7637ec681f3Smrg } 76401e04c3fSmrg 7657ec681f3Smrg struct intel_device_info devinfo; 7667ec681f3Smrg if (!intel_get_device_info_from_fd(fd, &devinfo)) { 7677ec681f3Smrg result = vk_error(instance, VK_ERROR_INCOMPATIBLE_DRIVER); 7687ec681f3Smrg goto fail_fd; 7697ec681f3Smrg } 7707ec681f3Smrg 7717ec681f3Smrg bool is_alpha = true; 7727ec681f3Smrg if (devinfo.is_haswell) { 7737ec681f3Smrg mesa_logw("Haswell Vulkan support is incomplete"); 7747ec681f3Smrg } else if (devinfo.ver == 7 && !devinfo.is_baytrail) { 7757ec681f3Smrg mesa_logw("Ivy Bridge Vulkan support is incomplete"); 7767ec681f3Smrg } else if (devinfo.ver == 7 && devinfo.is_baytrail) { 7777ec681f3Smrg mesa_logw("Bay Trail Vulkan support is incomplete"); 7787ec681f3Smrg } else if (devinfo.ver >= 8 && devinfo.ver <= 12) { 7797ec681f3Smrg /* Gfx8-12 fully supported */ 7807ec681f3Smrg is_alpha = false; 7817ec681f3Smrg } else { 7827ec681f3Smrg result = vk_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER, 7837ec681f3Smrg "Vulkan not yet supported on %s", devinfo.name); 7847ec681f3Smrg goto fail_fd; 7857ec681f3Smrg } 7867ec681f3Smrg 7877ec681f3Smrg struct anv_physical_device *device = 7887ec681f3Smrg vk_zalloc(&instance->vk.alloc, sizeof(*device), 8, 7897ec681f3Smrg VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); 7907ec681f3Smrg if (device == NULL) { 7917ec681f3Smrg result = vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY); 7927ec681f3Smrg goto fail_fd; 7937ec681f3Smrg } 7947ec681f3Smrg 7957ec681f3Smrg struct vk_physical_device_dispatch_table dispatch_table; 7967ec681f3Smrg vk_physical_device_dispatch_table_from_entrypoints( 7977ec681f3Smrg &dispatch_table, &anv_physical_device_entrypoints, true); 7987ec681f3Smrg vk_physical_device_dispatch_table_from_entrypoints( 7997ec681f3Smrg &dispatch_table, &wsi_physical_device_entrypoints, false); 8007ec681f3Smrg 8017ec681f3Smrg result = vk_physical_device_init(&device->vk, &instance->vk, 8027ec681f3Smrg NULL, /* We set up extensions later */ 8037ec681f3Smrg &dispatch_table); 8047ec681f3Smrg if (result != VK_SUCCESS) { 8057ec681f3Smrg vk_error(instance, result); 8067ec681f3Smrg goto fail_alloc; 8077ec681f3Smrg } 80801e04c3fSmrg device->instance = instance; 80901e04c3fSmrg 81001e04c3fSmrg assert(strlen(path) < ARRAY_SIZE(device->path)); 81101e04c3fSmrg snprintf(device->path, ARRAY_SIZE(device->path), "%s", path); 81201e04c3fSmrg 8137ec681f3Smrg device->info = devinfo; 8147ec681f3Smrg device->is_alpha = is_alpha; 81501e04c3fSmrg 81601e04c3fSmrg device->pci_info.domain = drm_device->businfo.pci->domain; 81701e04c3fSmrg device->pci_info.bus = drm_device->businfo.pci->bus; 81801e04c3fSmrg device->pci_info.device = drm_device->businfo.pci->dev; 81901e04c3fSmrg device->pci_info.function = drm_device->businfo.pci->func; 82001e04c3fSmrg 82101e04c3fSmrg device->cmd_parser_version = -1; 8227ec681f3Smrg if (device->info.ver == 7) { 82301e04c3fSmrg device->cmd_parser_version = 82401e04c3fSmrg anv_gem_get_param(fd, I915_PARAM_CMD_PARSER_VERSION); 82501e04c3fSmrg if (device->cmd_parser_version == -1) { 8267ec681f3Smrg result = vk_errorf(device, VK_ERROR_INITIALIZATION_FAILED, 82701e04c3fSmrg "failed to get command parser version"); 8287ec681f3Smrg goto fail_base; 82901e04c3fSmrg } 83001e04c3fSmrg } 83101e04c3fSmrg 83201e04c3fSmrg if (!anv_gem_get_param(fd, I915_PARAM_HAS_WAIT_TIMEOUT)) { 8337ec681f3Smrg result = vk_errorf(device, VK_ERROR_INITIALIZATION_FAILED, 83401e04c3fSmrg "kernel missing gem wait"); 8357ec681f3Smrg goto fail_base; 83601e04c3fSmrg } 83701e04c3fSmrg 83801e04c3fSmrg if (!anv_gem_get_param(fd, I915_PARAM_HAS_EXECBUF2)) { 8397ec681f3Smrg result = vk_errorf(device, VK_ERROR_INITIALIZATION_FAILED, 84001e04c3fSmrg "kernel missing execbuf2"); 8417ec681f3Smrg goto fail_base; 84201e04c3fSmrg } 84301e04c3fSmrg 84401e04c3fSmrg if (!device->info.has_llc && 84501e04c3fSmrg anv_gem_get_param(fd, I915_PARAM_MMAP_VERSION) < 1) { 8467ec681f3Smrg result = vk_errorf(device, VK_ERROR_INITIALIZATION_FAILED, 84701e04c3fSmrg "kernel missing wc mmap"); 8487ec681f3Smrg goto fail_base; 84901e04c3fSmrg } 85001e04c3fSmrg 8517ec681f3Smrg if (device->info.ver >= 8 && !device->info.is_cherryview && 8527ec681f3Smrg !anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_SOFTPIN)) { 8537ec681f3Smrg result = vk_errorf(device, VK_ERROR_INITIALIZATION_FAILED, 8547ec681f3Smrg "kernel missing softpin"); 8557ec681f3Smrg goto fail_alloc; 8567ec681f3Smrg } 8577ec681f3Smrg 8587ec681f3Smrg if (!anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_FENCE_ARRAY)) { 8597ec681f3Smrg result = vk_errorf(device, VK_ERROR_INITIALIZATION_FAILED, 8607ec681f3Smrg "kernel missing syncobj support"); 8617ec681f3Smrg goto fail_base; 8627ec681f3Smrg } 86301e04c3fSmrg 86401e04c3fSmrg device->has_exec_async = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_ASYNC); 86501e04c3fSmrg device->has_exec_capture = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_CAPTURE); 86601e04c3fSmrg device->has_exec_fence = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_FENCE); 8677ec681f3Smrg device->has_syncobj_wait = anv_gem_supports_syncobj_wait(fd); 8687ec681f3Smrg device->has_syncobj_wait_available = 8697ec681f3Smrg anv_gem_get_drm_cap(fd, DRM_CAP_SYNCOBJ_TIMELINE) != 0; 8707ec681f3Smrg 87101e04c3fSmrg device->has_context_priority = anv_gem_has_context_priority(fd); 87201e04c3fSmrg 8737ec681f3Smrg /* Initialize memory regions struct to 0. */ 8747ec681f3Smrg memset(&device->vram, 0, sizeof(device->vram)); 8757ec681f3Smrg memset(&device->sys, 0, sizeof(device->sys)); 8767ec681f3Smrg 8777ec681f3Smrg result = anv_physical_device_init_heaps(device, fd); 8787ec681f3Smrg if (result != VK_SUCCESS) 8797ec681f3Smrg goto fail_base; 8807ec681f3Smrg 8817ec681f3Smrg device->use_softpin = device->info.ver >= 8 && 8827ec681f3Smrg !device->info.is_cherryview; 8837ec681f3Smrg assert(device->use_softpin == device->supports_48bit_addresses); 88401e04c3fSmrg 88501e04c3fSmrg device->has_context_isolation = 88601e04c3fSmrg anv_gem_get_param(fd, I915_PARAM_HAS_CONTEXT_ISOLATION); 88701e04c3fSmrg 8887ec681f3Smrg device->has_exec_timeline = 8897ec681f3Smrg anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_TIMELINE_FENCES); 8907ec681f3Smrg if (env_var_as_boolean("ANV_QUEUE_THREAD_DISABLE", false)) 8917ec681f3Smrg device->has_exec_timeline = false; 8927ec681f3Smrg 8937ec681f3Smrg device->has_thread_submit = 8947ec681f3Smrg device->has_syncobj_wait_available && device->has_exec_timeline; 8957ec681f3Smrg 8969f464c52Smaya device->always_use_bindless = 8979f464c52Smaya env_var_as_boolean("ANV_ALWAYS_BINDLESS", false); 8989f464c52Smaya 8997ec681f3Smrg device->use_call_secondary = 9007ec681f3Smrg device->use_softpin && 9017ec681f3Smrg !env_var_as_boolean("ANV_DISABLE_SECONDARY_CMD_BUFFER_CALLS", false); 9027ec681f3Smrg 9039f464c52Smaya /* We first got the A64 messages on broadwell and we can only use them if 9049f464c52Smaya * we can pass addresses directly into the shader which requires softpin. 9059f464c52Smaya */ 9067ec681f3Smrg device->has_a64_buffer_access = device->info.ver >= 8 && 9079f464c52Smaya device->use_softpin; 9089f464c52Smaya 9097ec681f3Smrg /* We first get bindless image access on Skylake. 9109f464c52Smaya */ 9117ec681f3Smrg device->has_bindless_images = device->info.ver >= 9; 9129f464c52Smaya 9139f464c52Smaya /* We've had bindless samplers since Ivy Bridge (forever in Vulkan terms) 9149f464c52Smaya * because it's just a matter of setting the sampler address in the sample 9159f464c52Smaya * message header. However, we've not bothered to wire it up for vec4 so 9167ec681f3Smrg * we leave it disabled on gfx7. 9179f464c52Smaya */ 9187ec681f3Smrg device->has_bindless_samplers = device->info.ver >= 8; 9199f464c52Smaya 9207ec681f3Smrg device->has_implicit_ccs = device->info.has_aux_map; 92101e04c3fSmrg 9227ec681f3Smrg /* Check if we can read the GPU timestamp register from the CPU */ 9237ec681f3Smrg uint64_t u64_ignore; 9247ec681f3Smrg device->has_reg_timestamp = anv_gem_reg_read(fd, TIMESTAMP | I915_REG_READ_8B_WA, 9257ec681f3Smrg &u64_ignore) == 0; 92601e04c3fSmrg 9277ec681f3Smrg device->always_flush_cache = INTEL_DEBUG(DEBUG_SYNC) || 9287ec681f3Smrg driQueryOptionb(&instance->dri_options, "always_flush_cache"); 92901e04c3fSmrg 9307ec681f3Smrg device->has_mmap_offset = 9317ec681f3Smrg anv_gem_get_param(fd, I915_PARAM_MMAP_GTT_VERSION) >= 4; 93201e04c3fSmrg 9337ec681f3Smrg device->has_userptr_probe = 9347ec681f3Smrg anv_gem_get_param(fd, I915_PARAM_HAS_USERPTR_PROBE); 93501e04c3fSmrg 93601e04c3fSmrg device->compiler = brw_compiler_create(NULL, &device->info); 93701e04c3fSmrg if (device->compiler == NULL) { 9387ec681f3Smrg result = vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY); 9397ec681f3Smrg goto fail_base; 94001e04c3fSmrg } 94101e04c3fSmrg device->compiler->shader_debug_log = compiler_debug_log; 94201e04c3fSmrg device->compiler->shader_perf_log = compiler_perf_log; 94301e04c3fSmrg device->compiler->supports_pull_constants = false; 94401e04c3fSmrg device->compiler->constant_buffer_0_is_relative = 9457ec681f3Smrg device->info.ver < 8 || !device->has_context_isolation; 94601e04c3fSmrg device->compiler->supports_shader_constants = true; 9477ec681f3Smrg device->compiler->compact_params = false; 9487ec681f3Smrg device->compiler->indirect_ubos_use_sampler = device->info.ver < 12; 94901e04c3fSmrg 9509f464c52Smaya /* Broadwell PRM says: 9519f464c52Smaya * 9527ec681f3Smrg * "Before Gfx8, there was a historical configuration control field to 9539f464c52Smaya * swizzle address bit[6] for in X/Y tiling modes. This was set in three 9549f464c52Smaya * different places: TILECTL[1:0], ARB_MODE[5:4], and 9559f464c52Smaya * DISP_ARB_CTL[14:13]. 9569f464c52Smaya * 9577ec681f3Smrg * For Gfx8 and subsequent generations, the swizzle fields are all 9589f464c52Smaya * reserved, and the CPU's memory controller performs all address 9599f464c52Smaya * swizzling modifications." 9609f464c52Smaya */ 9619f464c52Smaya bool swizzled = 9627ec681f3Smrg device->info.ver < 8 && anv_gem_get_bit6_swizzle(fd, I915_TILING_X); 9639f464c52Smaya 96401e04c3fSmrg isl_device_init(&device->isl_dev, &device->info, swizzled); 96501e04c3fSmrg 96601e04c3fSmrg result = anv_physical_device_init_uuids(device); 96701e04c3fSmrg if (result != VK_SUCCESS) 9687ec681f3Smrg goto fail_compiler; 96901e04c3fSmrg 97001e04c3fSmrg anv_physical_device_init_disk_cache(device); 97101e04c3fSmrg 9727ec681f3Smrg if (instance->vk.enabled_extensions.KHR_display) { 97301e04c3fSmrg master_fd = open(primary_path, O_RDWR | O_CLOEXEC); 97401e04c3fSmrg if (master_fd >= 0) { 97501e04c3fSmrg /* prod the device with a GETPARAM call which will fail if 97601e04c3fSmrg * we don't have permission to even render on this device 97701e04c3fSmrg */ 97801e04c3fSmrg if (anv_gem_get_param(master_fd, I915_PARAM_CHIPSET_ID) == 0) { 97901e04c3fSmrg close(master_fd); 98001e04c3fSmrg master_fd = -1; 98101e04c3fSmrg } 98201e04c3fSmrg } 98301e04c3fSmrg } 98401e04c3fSmrg device->master_fd = master_fd; 98501e04c3fSmrg 9867ec681f3Smrg device->engine_info = anv_gem_get_engine_info(fd); 9877ec681f3Smrg anv_physical_device_init_queue_families(device); 9887ec681f3Smrg 98901e04c3fSmrg result = anv_init_wsi(device); 9907ec681f3Smrg if (result != VK_SUCCESS) 9917ec681f3Smrg goto fail_engine_info; 99201e04c3fSmrg 9937ec681f3Smrg anv_physical_device_init_perf(device, fd); 99401e04c3fSmrg 9957ec681f3Smrg anv_measure_device_init(device); 9967ec681f3Smrg 9977ec681f3Smrg get_device_extensions(device, &device->vk.supported_extensions); 99801e04c3fSmrg 99901e04c3fSmrg device->local_fd = fd; 100001e04c3fSmrg 10017ec681f3Smrg anv_genX(&device->info, init_physical_device_state)(device); 10027ec681f3Smrg 10037ec681f3Smrg *device_out = device; 10047ec681f3Smrg 10057ec681f3Smrg struct stat st; 10067ec681f3Smrg 10077ec681f3Smrg if (stat(primary_path, &st) == 0) { 10087ec681f3Smrg device->has_master = true; 10097ec681f3Smrg device->master_major = major(st.st_rdev); 10107ec681f3Smrg device->master_minor = minor(st.st_rdev); 10117ec681f3Smrg } else { 10127ec681f3Smrg device->has_master = false; 10137ec681f3Smrg device->master_major = 0; 10147ec681f3Smrg device->master_minor = 0; 10157ec681f3Smrg } 10167ec681f3Smrg 10177ec681f3Smrg if (stat(path, &st) == 0) { 10187ec681f3Smrg device->has_local = true; 10197ec681f3Smrg device->local_major = major(st.st_rdev); 10207ec681f3Smrg device->local_minor = minor(st.st_rdev); 10217ec681f3Smrg } else { 10227ec681f3Smrg device->has_local = false; 10237ec681f3Smrg device->local_major = 0; 10247ec681f3Smrg device->local_minor = 0; 10257ec681f3Smrg } 10267ec681f3Smrg 102701e04c3fSmrg return VK_SUCCESS; 102801e04c3fSmrg 10297ec681f3Smrgfail_engine_info: 10307ec681f3Smrg free(device->engine_info); 10317ec681f3Smrg anv_physical_device_free_disk_cache(device); 10327ec681f3Smrgfail_compiler: 10337ec681f3Smrg ralloc_free(device->compiler); 10347ec681f3Smrgfail_base: 10357ec681f3Smrg vk_physical_device_finish(&device->vk); 10367ec681f3Smrgfail_alloc: 10377ec681f3Smrg vk_free(&instance->vk.alloc, device); 10387ec681f3Smrgfail_fd: 103901e04c3fSmrg close(fd); 104001e04c3fSmrg if (master_fd != -1) 104101e04c3fSmrg close(master_fd); 104201e04c3fSmrg return result; 104301e04c3fSmrg} 104401e04c3fSmrg 104501e04c3fSmrgstatic void 10467ec681f3Smrganv_physical_device_destroy(struct anv_physical_device *device) 104701e04c3fSmrg{ 104801e04c3fSmrg anv_finish_wsi(device); 10497ec681f3Smrg anv_measure_device_destroy(device); 10507ec681f3Smrg free(device->engine_info); 105101e04c3fSmrg anv_physical_device_free_disk_cache(device); 105201e04c3fSmrg ralloc_free(device->compiler); 10537ec681f3Smrg ralloc_free(device->perf); 105401e04c3fSmrg close(device->local_fd); 105501e04c3fSmrg if (device->master_fd >= 0) 105601e04c3fSmrg close(device->master_fd); 10577ec681f3Smrg vk_physical_device_finish(&device->vk); 10587ec681f3Smrg vk_free(&device->instance->vk.alloc, device); 105901e04c3fSmrg} 106001e04c3fSmrg 106101e04c3fSmrgVkResult anv_EnumerateInstanceExtensionProperties( 106201e04c3fSmrg const char* pLayerName, 106301e04c3fSmrg uint32_t* pPropertyCount, 106401e04c3fSmrg VkExtensionProperties* pProperties) 106501e04c3fSmrg{ 10667ec681f3Smrg if (pLayerName) 10677ec681f3Smrg return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT); 106801e04c3fSmrg 10697ec681f3Smrg return vk_enumerate_instance_extension_properties( 10707ec681f3Smrg &instance_extensions, pPropertyCount, pProperties); 10717ec681f3Smrg} 107201e04c3fSmrg 10737ec681f3Smrgstatic void 10747ec681f3Smrganv_init_dri_options(struct anv_instance *instance) 10757ec681f3Smrg{ 10767ec681f3Smrg driParseOptionInfo(&instance->available_dri_options, anv_dri_options, 10777ec681f3Smrg ARRAY_SIZE(anv_dri_options)); 10787ec681f3Smrg driParseConfigFiles(&instance->dri_options, 10797ec681f3Smrg &instance->available_dri_options, 0, "anv", NULL, NULL, 10807ec681f3Smrg instance->vk.app_info.app_name, 10817ec681f3Smrg instance->vk.app_info.app_version, 10827ec681f3Smrg instance->vk.app_info.engine_name, 10837ec681f3Smrg instance->vk.app_info.engine_version); 108401e04c3fSmrg} 108501e04c3fSmrg 108601e04c3fSmrgVkResult anv_CreateInstance( 108701e04c3fSmrg const VkInstanceCreateInfo* pCreateInfo, 108801e04c3fSmrg const VkAllocationCallbacks* pAllocator, 108901e04c3fSmrg VkInstance* pInstance) 109001e04c3fSmrg{ 109101e04c3fSmrg struct anv_instance *instance; 109201e04c3fSmrg VkResult result; 109301e04c3fSmrg 109401e04c3fSmrg assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO); 109501e04c3fSmrg 10967ec681f3Smrg if (pAllocator == NULL) 10977ec681f3Smrg pAllocator = vk_default_allocator(); 109801e04c3fSmrg 10997ec681f3Smrg instance = vk_alloc(pAllocator, sizeof(*instance), 8, 11007ec681f3Smrg VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); 110101e04c3fSmrg if (!instance) 11027ec681f3Smrg return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY); 110301e04c3fSmrg 11047ec681f3Smrg struct vk_instance_dispatch_table dispatch_table; 11057ec681f3Smrg vk_instance_dispatch_table_from_entrypoints( 11067ec681f3Smrg &dispatch_table, &anv_instance_entrypoints, true); 11077ec681f3Smrg vk_instance_dispatch_table_from_entrypoints( 11087ec681f3Smrg &dispatch_table, &wsi_instance_entrypoints, false); 110901e04c3fSmrg 11107ec681f3Smrg result = vk_instance_init(&instance->vk, &instance_extensions, 11117ec681f3Smrg &dispatch_table, pCreateInfo, pAllocator); 111201e04c3fSmrg if (result != VK_SUCCESS) { 11137ec681f3Smrg vk_free(pAllocator, instance); 11147ec681f3Smrg return vk_error(NULL, result); 111501e04c3fSmrg } 111601e04c3fSmrg 11177ec681f3Smrg instance->physical_devices_enumerated = false; 11187ec681f3Smrg list_inithead(&instance->physical_devices); 11197ec681f3Smrg 112001e04c3fSmrg instance->pipeline_cache_enabled = 112101e04c3fSmrg env_var_as_boolean("ANV_ENABLE_PIPELINE_CACHE", true); 112201e04c3fSmrg 112301e04c3fSmrg VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false)); 112401e04c3fSmrg 11257ec681f3Smrg anv_init_dri_options(instance); 11269f464c52Smaya 112701e04c3fSmrg *pInstance = anv_instance_to_handle(instance); 112801e04c3fSmrg 112901e04c3fSmrg return VK_SUCCESS; 113001e04c3fSmrg} 113101e04c3fSmrg 113201e04c3fSmrgvoid anv_DestroyInstance( 113301e04c3fSmrg VkInstance _instance, 113401e04c3fSmrg const VkAllocationCallbacks* pAllocator) 113501e04c3fSmrg{ 113601e04c3fSmrg ANV_FROM_HANDLE(anv_instance, instance, _instance); 113701e04c3fSmrg 113801e04c3fSmrg if (!instance) 113901e04c3fSmrg return; 114001e04c3fSmrg 11417ec681f3Smrg list_for_each_entry_safe(struct anv_physical_device, pdevice, 11427ec681f3Smrg &instance->physical_devices, link) 11437ec681f3Smrg anv_physical_device_destroy(pdevice); 114401e04c3fSmrg 11457ec681f3Smrg VG(VALGRIND_DESTROY_MEMPOOL(instance)); 114601e04c3fSmrg 11479f464c52Smaya driDestroyOptionCache(&instance->dri_options); 11489f464c52Smaya driDestroyOptionInfo(&instance->available_dri_options); 11499f464c52Smaya 11507ec681f3Smrg vk_instance_finish(&instance->vk); 11517ec681f3Smrg vk_free(&instance->vk.alloc, instance); 115201e04c3fSmrg} 115301e04c3fSmrg 115401e04c3fSmrgstatic VkResult 11557ec681f3Smrganv_enumerate_physical_devices(struct anv_instance *instance) 115601e04c3fSmrg{ 11577ec681f3Smrg if (instance->physical_devices_enumerated) 11587ec681f3Smrg return VK_SUCCESS; 11597ec681f3Smrg 11607ec681f3Smrg instance->physical_devices_enumerated = true; 11617ec681f3Smrg 116201e04c3fSmrg /* TODO: Check for more devices ? */ 116301e04c3fSmrg drmDevicePtr devices[8]; 116401e04c3fSmrg int max_devices; 116501e04c3fSmrg 116601e04c3fSmrg max_devices = drmGetDevices2(0, devices, ARRAY_SIZE(devices)); 116701e04c3fSmrg if (max_devices < 1) 11687ec681f3Smrg return VK_SUCCESS; 116901e04c3fSmrg 11707ec681f3Smrg VkResult result = VK_SUCCESS; 117101e04c3fSmrg for (unsigned i = 0; i < (unsigned)max_devices; i++) { 117201e04c3fSmrg if (devices[i]->available_nodes & 1 << DRM_NODE_RENDER && 117301e04c3fSmrg devices[i]->bustype == DRM_BUS_PCI && 117401e04c3fSmrg devices[i]->deviceinfo.pci->vendor_id == 0x8086) { 117501e04c3fSmrg 11767ec681f3Smrg struct anv_physical_device *pdevice; 11777ec681f3Smrg result = anv_physical_device_try_create(instance, devices[i], 11787ec681f3Smrg &pdevice); 11797ec681f3Smrg /* Incompatible DRM device, skip. */ 11807ec681f3Smrg if (result == VK_ERROR_INCOMPATIBLE_DRIVER) { 11817ec681f3Smrg result = VK_SUCCESS; 11827ec681f3Smrg continue; 11837ec681f3Smrg } 11847ec681f3Smrg 11857ec681f3Smrg /* Error creating the physical device, report the error. */ 11867ec681f3Smrg if (result != VK_SUCCESS) 118701e04c3fSmrg break; 11887ec681f3Smrg 11897ec681f3Smrg list_addtail(&pdevice->link, &instance->physical_devices); 119001e04c3fSmrg } 119101e04c3fSmrg } 119201e04c3fSmrg drmFreeDevices(devices, max_devices); 119301e04c3fSmrg 11947ec681f3Smrg /* If we successfully enumerated any devices, call it success */ 119501e04c3fSmrg return result; 119601e04c3fSmrg} 119701e04c3fSmrg 119801e04c3fSmrgVkResult anv_EnumeratePhysicalDevices( 119901e04c3fSmrg VkInstance _instance, 120001e04c3fSmrg uint32_t* pPhysicalDeviceCount, 120101e04c3fSmrg VkPhysicalDevice* pPhysicalDevices) 120201e04c3fSmrg{ 120301e04c3fSmrg ANV_FROM_HANDLE(anv_instance, instance, _instance); 120401e04c3fSmrg VK_OUTARRAY_MAKE(out, pPhysicalDevices, pPhysicalDeviceCount); 120501e04c3fSmrg 12067ec681f3Smrg VkResult result = anv_enumerate_physical_devices(instance); 120701e04c3fSmrg if (result != VK_SUCCESS) 120801e04c3fSmrg return result; 120901e04c3fSmrg 12107ec681f3Smrg list_for_each_entry(struct anv_physical_device, pdevice, 12117ec681f3Smrg &instance->physical_devices, link) { 12127ec681f3Smrg vk_outarray_append(&out, i) { 12137ec681f3Smrg *i = anv_physical_device_to_handle(pdevice); 12147ec681f3Smrg } 121501e04c3fSmrg } 121601e04c3fSmrg 121701e04c3fSmrg return vk_outarray_status(&out); 121801e04c3fSmrg} 121901e04c3fSmrg 122001e04c3fSmrgVkResult anv_EnumeratePhysicalDeviceGroups( 122101e04c3fSmrg VkInstance _instance, 122201e04c3fSmrg uint32_t* pPhysicalDeviceGroupCount, 122301e04c3fSmrg VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties) 122401e04c3fSmrg{ 122501e04c3fSmrg ANV_FROM_HANDLE(anv_instance, instance, _instance); 122601e04c3fSmrg VK_OUTARRAY_MAKE(out, pPhysicalDeviceGroupProperties, 122701e04c3fSmrg pPhysicalDeviceGroupCount); 122801e04c3fSmrg 12297ec681f3Smrg VkResult result = anv_enumerate_physical_devices(instance); 123001e04c3fSmrg if (result != VK_SUCCESS) 123101e04c3fSmrg return result; 123201e04c3fSmrg 12337ec681f3Smrg list_for_each_entry(struct anv_physical_device, pdevice, 12347ec681f3Smrg &instance->physical_devices, link) { 12357ec681f3Smrg vk_outarray_append(&out, p) { 12367ec681f3Smrg p->physicalDeviceCount = 1; 12377ec681f3Smrg memset(p->physicalDevices, 0, sizeof(p->physicalDevices)); 12387ec681f3Smrg p->physicalDevices[0] = anv_physical_device_to_handle(pdevice); 12397ec681f3Smrg p->subsetAllocation = false; 124001e04c3fSmrg 12417ec681f3Smrg vk_foreach_struct(ext, p->pNext) 12427ec681f3Smrg anv_debug_ignored_stype(ext->sType); 12437ec681f3Smrg } 124401e04c3fSmrg } 124501e04c3fSmrg 124601e04c3fSmrg return vk_outarray_status(&out); 124701e04c3fSmrg} 124801e04c3fSmrg 124901e04c3fSmrgvoid anv_GetPhysicalDeviceFeatures( 125001e04c3fSmrg VkPhysicalDevice physicalDevice, 125101e04c3fSmrg VkPhysicalDeviceFeatures* pFeatures) 125201e04c3fSmrg{ 125301e04c3fSmrg ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice); 125401e04c3fSmrg 12557ec681f3Smrg /* Just pick one; they're all the same */ 12567ec681f3Smrg const bool has_astc_ldr = 12577ec681f3Smrg isl_format_supports_sampling(&pdevice->info, 12587ec681f3Smrg ISL_FORMAT_ASTC_LDR_2D_4X4_FLT16); 12597ec681f3Smrg 126001e04c3fSmrg *pFeatures = (VkPhysicalDeviceFeatures) { 126101e04c3fSmrg .robustBufferAccess = true, 126201e04c3fSmrg .fullDrawIndexUint32 = true, 126301e04c3fSmrg .imageCubeArray = true, 126401e04c3fSmrg .independentBlend = true, 126501e04c3fSmrg .geometryShader = true, 126601e04c3fSmrg .tessellationShader = true, 126701e04c3fSmrg .sampleRateShading = true, 126801e04c3fSmrg .dualSrcBlend = true, 126901e04c3fSmrg .logicOp = true, 127001e04c3fSmrg .multiDrawIndirect = true, 127101e04c3fSmrg .drawIndirectFirstInstance = true, 127201e04c3fSmrg .depthClamp = true, 127301e04c3fSmrg .depthBiasClamp = true, 127401e04c3fSmrg .fillModeNonSolid = true, 12757ec681f3Smrg .depthBounds = pdevice->info.ver >= 12, 127601e04c3fSmrg .wideLines = true, 127701e04c3fSmrg .largePoints = true, 127801e04c3fSmrg .alphaToOne = true, 127901e04c3fSmrg .multiViewport = true, 128001e04c3fSmrg .samplerAnisotropy = true, 12817ec681f3Smrg .textureCompressionETC2 = pdevice->info.ver >= 8 || 128201e04c3fSmrg pdevice->info.is_baytrail, 12837ec681f3Smrg .textureCompressionASTC_LDR = has_astc_ldr, 128401e04c3fSmrg .textureCompressionBC = true, 128501e04c3fSmrg .occlusionQueryPrecise = true, 128601e04c3fSmrg .pipelineStatisticsQuery = true, 128701e04c3fSmrg .fragmentStoresAndAtomics = true, 128801e04c3fSmrg .shaderTessellationAndGeometryPointSize = true, 128901e04c3fSmrg .shaderImageGatherExtended = true, 129001e04c3fSmrg .shaderStorageImageExtendedFormats = true, 129101e04c3fSmrg .shaderStorageImageMultisample = false, 129201e04c3fSmrg .shaderStorageImageReadWithoutFormat = false, 129301e04c3fSmrg .shaderStorageImageWriteWithoutFormat = true, 129401e04c3fSmrg .shaderUniformBufferArrayDynamicIndexing = true, 129501e04c3fSmrg .shaderSampledImageArrayDynamicIndexing = true, 129601e04c3fSmrg .shaderStorageBufferArrayDynamicIndexing = true, 129701e04c3fSmrg .shaderStorageImageArrayDynamicIndexing = true, 129801e04c3fSmrg .shaderClipDistance = true, 129901e04c3fSmrg .shaderCullDistance = true, 13007ec681f3Smrg .shaderFloat64 = pdevice->info.ver >= 8 && 13017ec681f3Smrg pdevice->info.has_64bit_float, 13027ec681f3Smrg .shaderInt64 = pdevice->info.ver >= 8, 13037ec681f3Smrg .shaderInt16 = pdevice->info.ver >= 8, 13047ec681f3Smrg .shaderResourceMinLod = pdevice->info.ver >= 9, 130501e04c3fSmrg .variableMultisampleRate = true, 130601e04c3fSmrg .inheritedQueries = true, 130701e04c3fSmrg }; 130801e04c3fSmrg 130901e04c3fSmrg /* We can't do image stores in vec4 shaders */ 131001e04c3fSmrg pFeatures->vertexPipelineStoresAndAtomics = 131101e04c3fSmrg pdevice->compiler->scalar_stage[MESA_SHADER_VERTEX] && 131201e04c3fSmrg pdevice->compiler->scalar_stage[MESA_SHADER_GEOMETRY]; 131301e04c3fSmrg 13147ec681f3Smrg struct vk_app_info *app_info = &pdevice->instance->vk.app_info; 131501e04c3fSmrg 131601e04c3fSmrg /* The new DOOM and Wolfenstein games require depthBounds without 131701e04c3fSmrg * checking for it. They seem to run fine without it so just claim it's 131801e04c3fSmrg * there and accept the consequences. 131901e04c3fSmrg */ 132001e04c3fSmrg if (app_info->engine_name && strcmp(app_info->engine_name, "idTech") == 0) 132101e04c3fSmrg pFeatures->depthBounds = true; 132201e04c3fSmrg} 132301e04c3fSmrg 13247ec681f3Smrgstatic void 13257ec681f3Smrganv_get_physical_device_features_1_1(struct anv_physical_device *pdevice, 13267ec681f3Smrg VkPhysicalDeviceVulkan11Features *f) 13277ec681f3Smrg{ 13287ec681f3Smrg assert(f->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES); 13297ec681f3Smrg 13307ec681f3Smrg f->storageBuffer16BitAccess = pdevice->info.ver >= 8; 13317ec681f3Smrg f->uniformAndStorageBuffer16BitAccess = pdevice->info.ver >= 8; 13327ec681f3Smrg f->storagePushConstant16 = pdevice->info.ver >= 8; 13337ec681f3Smrg f->storageInputOutput16 = false; 13347ec681f3Smrg f->multiview = true; 13357ec681f3Smrg f->multiviewGeometryShader = true; 13367ec681f3Smrg f->multiviewTessellationShader = true; 13377ec681f3Smrg f->variablePointersStorageBuffer = true; 13387ec681f3Smrg f->variablePointers = true; 13397ec681f3Smrg f->protectedMemory = false; 13407ec681f3Smrg f->samplerYcbcrConversion = true; 13417ec681f3Smrg f->shaderDrawParameters = true; 13427ec681f3Smrg} 13437ec681f3Smrg 13447ec681f3Smrgstatic void 13457ec681f3Smrganv_get_physical_device_features_1_2(struct anv_physical_device *pdevice, 13467ec681f3Smrg VkPhysicalDeviceVulkan12Features *f) 13477ec681f3Smrg{ 13487ec681f3Smrg assert(f->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES); 13497ec681f3Smrg 13507ec681f3Smrg f->samplerMirrorClampToEdge = true; 13517ec681f3Smrg f->drawIndirectCount = true; 13527ec681f3Smrg f->storageBuffer8BitAccess = pdevice->info.ver >= 8; 13537ec681f3Smrg f->uniformAndStorageBuffer8BitAccess = pdevice->info.ver >= 8; 13547ec681f3Smrg f->storagePushConstant8 = pdevice->info.ver >= 8; 13557ec681f3Smrg f->shaderBufferInt64Atomics = pdevice->info.ver >= 9 && 13567ec681f3Smrg pdevice->use_softpin; 13577ec681f3Smrg f->shaderSharedInt64Atomics = false; 13587ec681f3Smrg f->shaderFloat16 = pdevice->info.ver >= 8; 13597ec681f3Smrg f->shaderInt8 = pdevice->info.ver >= 8; 13607ec681f3Smrg 13617ec681f3Smrg bool descIndexing = pdevice->has_a64_buffer_access && 13627ec681f3Smrg pdevice->has_bindless_images; 13637ec681f3Smrg f->descriptorIndexing = descIndexing; 13647ec681f3Smrg f->shaderInputAttachmentArrayDynamicIndexing = false; 13657ec681f3Smrg f->shaderUniformTexelBufferArrayDynamicIndexing = descIndexing; 13667ec681f3Smrg f->shaderStorageTexelBufferArrayDynamicIndexing = descIndexing; 13677ec681f3Smrg f->shaderUniformBufferArrayNonUniformIndexing = descIndexing; 13687ec681f3Smrg f->shaderSampledImageArrayNonUniformIndexing = descIndexing; 13697ec681f3Smrg f->shaderStorageBufferArrayNonUniformIndexing = descIndexing; 13707ec681f3Smrg f->shaderStorageImageArrayNonUniformIndexing = descIndexing; 13717ec681f3Smrg f->shaderInputAttachmentArrayNonUniformIndexing = false; 13727ec681f3Smrg f->shaderUniformTexelBufferArrayNonUniformIndexing = descIndexing; 13737ec681f3Smrg f->shaderStorageTexelBufferArrayNonUniformIndexing = descIndexing; 13747ec681f3Smrg f->descriptorBindingUniformBufferUpdateAfterBind = descIndexing; 13757ec681f3Smrg f->descriptorBindingSampledImageUpdateAfterBind = descIndexing; 13767ec681f3Smrg f->descriptorBindingStorageImageUpdateAfterBind = descIndexing; 13777ec681f3Smrg f->descriptorBindingStorageBufferUpdateAfterBind = descIndexing; 13787ec681f3Smrg f->descriptorBindingUniformTexelBufferUpdateAfterBind = descIndexing; 13797ec681f3Smrg f->descriptorBindingStorageTexelBufferUpdateAfterBind = descIndexing; 13807ec681f3Smrg f->descriptorBindingUpdateUnusedWhilePending = descIndexing; 13817ec681f3Smrg f->descriptorBindingPartiallyBound = descIndexing; 13827ec681f3Smrg f->descriptorBindingVariableDescriptorCount = descIndexing; 13837ec681f3Smrg f->runtimeDescriptorArray = descIndexing; 13847ec681f3Smrg 13857ec681f3Smrg f->samplerFilterMinmax = pdevice->info.ver >= 9; 13867ec681f3Smrg f->scalarBlockLayout = true; 13877ec681f3Smrg f->imagelessFramebuffer = true; 13887ec681f3Smrg f->uniformBufferStandardLayout = true; 13897ec681f3Smrg f->shaderSubgroupExtendedTypes = true; 13907ec681f3Smrg f->separateDepthStencilLayouts = true; 13917ec681f3Smrg f->hostQueryReset = true; 13927ec681f3Smrg f->timelineSemaphore = true; 13937ec681f3Smrg f->bufferDeviceAddress = pdevice->has_a64_buffer_access; 13947ec681f3Smrg f->bufferDeviceAddressCaptureReplay = pdevice->has_a64_buffer_access; 13957ec681f3Smrg f->bufferDeviceAddressMultiDevice = false; 13967ec681f3Smrg f->vulkanMemoryModel = true; 13977ec681f3Smrg f->vulkanMemoryModelDeviceScope = true; 13987ec681f3Smrg f->vulkanMemoryModelAvailabilityVisibilityChains = true; 13997ec681f3Smrg f->shaderOutputViewportIndex = true; 14007ec681f3Smrg f->shaderOutputLayer = true; 14017ec681f3Smrg f->subgroupBroadcastDynamicId = true; 14027ec681f3Smrg} 14037ec681f3Smrg 140401e04c3fSmrgvoid anv_GetPhysicalDeviceFeatures2( 140501e04c3fSmrg VkPhysicalDevice physicalDevice, 140601e04c3fSmrg VkPhysicalDeviceFeatures2* pFeatures) 140701e04c3fSmrg{ 14089f464c52Smaya ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice); 140901e04c3fSmrg anv_GetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features); 141001e04c3fSmrg 14117ec681f3Smrg VkPhysicalDeviceVulkan11Features core_1_1 = { 14127ec681f3Smrg .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, 14137ec681f3Smrg }; 14147ec681f3Smrg anv_get_physical_device_features_1_1(pdevice, &core_1_1); 14157ec681f3Smrg 14167ec681f3Smrg VkPhysicalDeviceVulkan12Features core_1_2 = { 14177ec681f3Smrg .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, 14187ec681f3Smrg }; 14197ec681f3Smrg anv_get_physical_device_features_1_2(pdevice, &core_1_2); 14207ec681f3Smrg 142101e04c3fSmrg vk_foreach_struct(ext, pFeatures->pNext) { 14227ec681f3Smrg if (vk_get_physical_device_core_1_1_feature_ext(ext, &core_1_1)) 14237ec681f3Smrg continue; 14247ec681f3Smrg if (vk_get_physical_device_core_1_2_feature_ext(ext, &core_1_2)) 14257ec681f3Smrg continue; 14267ec681f3Smrg 142701e04c3fSmrg switch (ext->sType) { 14287ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT: { 14297ec681f3Smrg VkPhysicalDevice4444FormatsFeaturesEXT *features = 14307ec681f3Smrg (VkPhysicalDevice4444FormatsFeaturesEXT *)ext; 14317ec681f3Smrg features->formatA4R4G4B4 = true; 14327ec681f3Smrg features->formatA4B4G4R4 = false; 14339f464c52Smaya break; 14349f464c52Smaya } 14359f464c52Smaya 14367ec681f3Smrg 14377ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR: { 14387ec681f3Smrg VkPhysicalDeviceAccelerationStructureFeaturesKHR *features = (void *)ext; 14397ec681f3Smrg features->accelerationStructure = false; 14407ec681f3Smrg features->accelerationStructureCaptureReplay = false; 14417ec681f3Smrg features->accelerationStructureIndirectBuild = false; 14427ec681f3Smrg features->accelerationStructureHostCommands = false; 14437ec681f3Smrg features->descriptorBindingAccelerationStructureUpdateAfterBind = true; 14449f464c52Smaya break; 14459f464c52Smaya } 14469f464c52Smaya 14479f464c52Smaya case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT: { 14489f464c52Smaya VkPhysicalDeviceBufferDeviceAddressFeaturesEXT *features = (void *)ext; 14499f464c52Smaya features->bufferDeviceAddress = pdevice->has_a64_buffer_access; 14509f464c52Smaya features->bufferDeviceAddressCaptureReplay = false; 14519f464c52Smaya features->bufferDeviceAddressMultiDevice = false; 14529f464c52Smaya break; 14539f464c52Smaya } 14549f464c52Smaya 14557ec681f3Smrg 14567ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT: { 14577ec681f3Smrg VkPhysicalDeviceColorWriteEnableFeaturesEXT *features = 14587ec681f3Smrg (VkPhysicalDeviceColorWriteEnableFeaturesEXT *)ext; 14597ec681f3Smrg features->colorWriteEnable = true; 14607ec681f3Smrg break; 14617ec681f3Smrg } 14627ec681f3Smrg 14639f464c52Smaya case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV: { 14649f464c52Smaya VkPhysicalDeviceComputeShaderDerivativesFeaturesNV *features = 14659f464c52Smaya (VkPhysicalDeviceComputeShaderDerivativesFeaturesNV *)ext; 14669f464c52Smaya features->computeDerivativeGroupQuads = true; 14679f464c52Smaya features->computeDerivativeGroupLinear = true; 14689f464c52Smaya break; 14699f464c52Smaya } 14709f464c52Smaya 14719f464c52Smaya case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT: { 14729f464c52Smaya VkPhysicalDeviceConditionalRenderingFeaturesEXT *features = 14739f464c52Smaya (VkPhysicalDeviceConditionalRenderingFeaturesEXT*)ext; 14747ec681f3Smrg features->conditionalRendering = pdevice->info.verx10 >= 75; 14757ec681f3Smrg features->inheritedConditionalRendering = pdevice->info.verx10 >= 75; 14767ec681f3Smrg break; 14777ec681f3Smrg } 14787ec681f3Smrg 14797ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT: { 14807ec681f3Smrg VkPhysicalDeviceCustomBorderColorFeaturesEXT *features = 14817ec681f3Smrg (VkPhysicalDeviceCustomBorderColorFeaturesEXT *)ext; 14827ec681f3Smrg features->customBorderColors = pdevice->info.ver >= 8; 14837ec681f3Smrg features->customBorderColorWithoutFormat = pdevice->info.ver >= 8; 14849f464c52Smaya break; 14859f464c52Smaya } 14869f464c52Smaya 14879f464c52Smaya case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: { 14889f464c52Smaya VkPhysicalDeviceDepthClipEnableFeaturesEXT *features = 14899f464c52Smaya (VkPhysicalDeviceDepthClipEnableFeaturesEXT *)ext; 14909f464c52Smaya features->depthClipEnable = true; 14919f464c52Smaya break; 14929f464c52Smaya } 14939f464c52Smaya 14947ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT: { 14957ec681f3Smrg VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT *features = 14967ec681f3Smrg (VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT *)ext; 14977ec681f3Smrg features->fragmentShaderSampleInterlock = pdevice->info.ver >= 9; 14987ec681f3Smrg features->fragmentShaderPixelInterlock = pdevice->info.ver >= 9; 14997ec681f3Smrg features->fragmentShaderShadingRateInterlock = false; 15007ec681f3Smrg break; 15017ec681f3Smrg } 15027ec681f3Smrg 15037ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR: { 15047ec681f3Smrg VkPhysicalDeviceFragmentShadingRateFeaturesKHR *features = 15057ec681f3Smrg (VkPhysicalDeviceFragmentShadingRateFeaturesKHR *)ext; 15067ec681f3Smrg features->attachmentFragmentShadingRate = false; 15077ec681f3Smrg features->pipelineFragmentShadingRate = true; 15087ec681f3Smrg features->primitiveFragmentShadingRate = false; 15099f464c52Smaya break; 15109f464c52Smaya } 15119f464c52Smaya 15127ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT: { 15137ec681f3Smrg VkPhysicalDeviceImageRobustnessFeaturesEXT *features = 15147ec681f3Smrg (VkPhysicalDeviceImageRobustnessFeaturesEXT *)ext; 15157ec681f3Smrg features->robustImageAccess = true; 15169f464c52Smaya break; 15179f464c52Smaya } 15189f464c52Smaya 15197ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT: { 15207ec681f3Smrg VkPhysicalDeviceIndexTypeUint8FeaturesEXT *features = 15217ec681f3Smrg (VkPhysicalDeviceIndexTypeUint8FeaturesEXT *)ext; 15227ec681f3Smrg features->indexTypeUint8 = true; 15239f464c52Smaya break; 15249f464c52Smaya } 15259f464c52Smaya 15269f464c52Smaya case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT: { 15279f464c52Smaya VkPhysicalDeviceInlineUniformBlockFeaturesEXT *features = 15289f464c52Smaya (VkPhysicalDeviceInlineUniformBlockFeaturesEXT *)ext; 15299f464c52Smaya features->inlineUniformBlock = true; 15309f464c52Smaya features->descriptorBindingInlineUniformBlockUpdateAfterBind = true; 153101e04c3fSmrg break; 153201e04c3fSmrg } 153301e04c3fSmrg 15347ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT: { 15357ec681f3Smrg VkPhysicalDeviceLineRasterizationFeaturesEXT *features = 15367ec681f3Smrg (VkPhysicalDeviceLineRasterizationFeaturesEXT *)ext; 15377ec681f3Smrg features->rectangularLines = true; 15387ec681f3Smrg features->bresenhamLines = true; 15397ec681f3Smrg /* Support for Smooth lines with MSAA was removed on gfx11. From the 15407ec681f3Smrg * BSpec section "Multisample ModesState" table for "AA Line Support 15417ec681f3Smrg * Requirements": 15427ec681f3Smrg * 15437ec681f3Smrg * GFX10:BUG:######## NUM_MULTISAMPLES == 1 15447ec681f3Smrg * 15457ec681f3Smrg * Fortunately, this isn't a case most people care about. 15467ec681f3Smrg */ 15477ec681f3Smrg features->smoothLines = pdevice->info.ver < 10; 15487ec681f3Smrg features->stippledRectangularLines = false; 15497ec681f3Smrg features->stippledBresenhamLines = true; 15507ec681f3Smrg features->stippledSmoothLines = false; 15517ec681f3Smrg break; 15527ec681f3Smrg } 15537ec681f3Smrg 15547ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR: { 15557ec681f3Smrg VkPhysicalDeviceMaintenance4FeaturesKHR *features = 15567ec681f3Smrg (VkPhysicalDeviceMaintenance4FeaturesKHR *)ext; 15577ec681f3Smrg features->maintenance4 = true; 15587ec681f3Smrg break; 15597ec681f3Smrg } 15607ec681f3Smrg 15617ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR: { 15627ec681f3Smrg VkPhysicalDevicePerformanceQueryFeaturesKHR *feature = 15637ec681f3Smrg (VkPhysicalDevicePerformanceQueryFeaturesKHR *)ext; 15647ec681f3Smrg feature->performanceCounterQueryPools = true; 15657ec681f3Smrg /* HW only supports a single configuration at a time. */ 15667ec681f3Smrg feature->performanceCounterMultipleQueryPools = false; 15677ec681f3Smrg break; 15687ec681f3Smrg } 15697ec681f3Smrg 15707ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT: { 15717ec681f3Smrg VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT *features = 15727ec681f3Smrg (VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT *)ext; 15737ec681f3Smrg features->pipelineCreationCacheControl = true; 15747ec681f3Smrg break; 15757ec681f3Smrg } 15767ec681f3Smrg 15777ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR: { 15787ec681f3Smrg VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR *features = 15797ec681f3Smrg (VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR *)ext; 15807ec681f3Smrg features->pipelineExecutableInfo = true; 15817ec681f3Smrg break; 15827ec681f3Smrg } 15837ec681f3Smrg 15847ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT: { 15857ec681f3Smrg VkPhysicalDevicePrivateDataFeaturesEXT *features = (void *)ext; 15867ec681f3Smrg features->privateData = true; 15877ec681f3Smrg break; 15887ec681f3Smrg } 15897ec681f3Smrg 15907ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT: { 15917ec681f3Smrg VkPhysicalDeviceProvokingVertexFeaturesEXT *features = 15927ec681f3Smrg (VkPhysicalDeviceProvokingVertexFeaturesEXT *)ext; 15937ec681f3Smrg features->provokingVertexLast = true; 15947ec681f3Smrg features->transformFeedbackPreservesProvokingVertex = true; 15957ec681f3Smrg break; 15967ec681f3Smrg } 15977ec681f3Smrg 15987ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT: { 15997ec681f3Smrg VkPhysicalDeviceRobustness2FeaturesEXT *features = (void *)ext; 16007ec681f3Smrg features->robustBufferAccess2 = true; 16017ec681f3Smrg features->robustImageAccess2 = true; 16027ec681f3Smrg features->nullDescriptor = true; 16037ec681f3Smrg break; 16047ec681f3Smrg } 16057ec681f3Smrg 16067ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT: { 16077ec681f3Smrg VkPhysicalDeviceShaderAtomicFloatFeaturesEXT *features = (void *)ext; 16087ec681f3Smrg features->shaderBufferFloat32Atomics = true; 16097ec681f3Smrg features->shaderBufferFloat32AtomicAdd = pdevice->info.has_lsc; 16107ec681f3Smrg features->shaderBufferFloat64Atomics = pdevice->info.has_lsc; 16117ec681f3Smrg features->shaderBufferFloat64AtomicAdd = false; 16127ec681f3Smrg features->shaderSharedFloat32Atomics = true; 16137ec681f3Smrg features->shaderSharedFloat32AtomicAdd = false; 16147ec681f3Smrg features->shaderSharedFloat64Atomics = false; 16157ec681f3Smrg features->shaderSharedFloat64AtomicAdd = false; 16167ec681f3Smrg features->shaderImageFloat32Atomics = true; 16177ec681f3Smrg features->shaderImageFloat32AtomicAdd = false; 16187ec681f3Smrg features->sparseImageFloat32Atomics = false; 16197ec681f3Smrg features->sparseImageFloat32AtomicAdd = false; 16207ec681f3Smrg break; 16217ec681f3Smrg } 16227ec681f3Smrg 16237ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT: { 16247ec681f3Smrg VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT *features = (void *)ext; 16257ec681f3Smrg features->shaderBufferFloat16Atomics = false; 16267ec681f3Smrg features->shaderBufferFloat16AtomicAdd = false; 16277ec681f3Smrg features->shaderBufferFloat16AtomicMinMax = false; 16287ec681f3Smrg features->shaderBufferFloat32AtomicMinMax = pdevice->info.ver >= 9; 16297ec681f3Smrg features->shaderBufferFloat64AtomicMinMax = pdevice->info.has_lsc; 16307ec681f3Smrg features->shaderSharedFloat16Atomics = false; 16317ec681f3Smrg features->shaderSharedFloat16AtomicAdd = false; 16327ec681f3Smrg features->shaderSharedFloat16AtomicMinMax = false; 16337ec681f3Smrg features->shaderSharedFloat32AtomicMinMax = pdevice->info.ver >= 9; 16347ec681f3Smrg features->shaderSharedFloat64AtomicMinMax = false; 16357ec681f3Smrg features->shaderImageFloat32AtomicMinMax = false; 16367ec681f3Smrg features->sparseImageFloat32AtomicMinMax = false; 16377ec681f3Smrg break; 16387ec681f3Smrg } 16397ec681f3Smrg 16407ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT: { 16417ec681f3Smrg VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT *features = (void *)ext; 16427ec681f3Smrg features->shaderDemoteToHelperInvocation = true; 16437ec681f3Smrg break; 16447ec681f3Smrg } 16457ec681f3Smrg 16467ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR: { 16477ec681f3Smrg VkPhysicalDeviceShaderClockFeaturesKHR *features = 16487ec681f3Smrg (VkPhysicalDeviceShaderClockFeaturesKHR *)ext; 16497ec681f3Smrg features->shaderSubgroupClock = true; 16507ec681f3Smrg features->shaderDeviceClock = false; 165101e04c3fSmrg break; 165201e04c3fSmrg } 165301e04c3fSmrg 16547ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL: { 16557ec681f3Smrg VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL *features = 16567ec681f3Smrg (VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL *)ext; 16577ec681f3Smrg features->shaderIntegerFunctions2 = true; 165801e04c3fSmrg break; 165901e04c3fSmrg } 166001e04c3fSmrg 16617ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR: { 16627ec681f3Smrg VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR *features = 16637ec681f3Smrg (VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR *)ext; 16647ec681f3Smrg features->shaderIntegerDotProduct = true; 16657ec681f3Smrg break; 16667ec681f3Smrg }; 16677ec681f3Smrg 16687ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR: { 16697ec681f3Smrg VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR *features = 16707ec681f3Smrg (VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR *)ext; 16717ec681f3Smrg features->shaderSubgroupUniformControlFlow = true; 167201e04c3fSmrg break; 167301e04c3fSmrg } 167401e04c3fSmrg 16757ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR: { 16767ec681f3Smrg VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR *features = 16777ec681f3Smrg (VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR *)ext; 16787ec681f3Smrg features->shaderTerminateInvocation = true; 167901e04c3fSmrg break; 168001e04c3fSmrg } 168101e04c3fSmrg 16827ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT: { 16837ec681f3Smrg VkPhysicalDeviceSubgroupSizeControlFeaturesEXT *features = 16847ec681f3Smrg (VkPhysicalDeviceSubgroupSizeControlFeaturesEXT *)ext; 16857ec681f3Smrg features->subgroupSizeControl = true; 16867ec681f3Smrg features->computeFullSubgroups = true; 16879f464c52Smaya break; 16889f464c52Smaya } 168901e04c3fSmrg 16907ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR: { 16917ec681f3Smrg VkPhysicalDeviceSynchronization2FeaturesKHR *features = 16927ec681f3Smrg (VkPhysicalDeviceSynchronization2FeaturesKHR *)ext; 16937ec681f3Smrg features->synchronization2 = true; 169401e04c3fSmrg break; 169501e04c3fSmrg } 169601e04c3fSmrg 16977ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT: { 16987ec681f3Smrg VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT *features = 16997ec681f3Smrg (VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT *)ext; 17007ec681f3Smrg features->texelBufferAlignment = true; 17019f464c52Smaya break; 17029f464c52Smaya } 170301e04c3fSmrg 17049f464c52Smaya case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT: { 17059f464c52Smaya VkPhysicalDeviceTransformFeedbackFeaturesEXT *features = 17069f464c52Smaya (VkPhysicalDeviceTransformFeedbackFeaturesEXT *)ext; 17079f464c52Smaya features->transformFeedback = true; 17089f464c52Smaya features->geometryStreams = true; 170901e04c3fSmrg break; 171001e04c3fSmrg } 171101e04c3fSmrg 171201e04c3fSmrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: { 171301e04c3fSmrg VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *features = 171401e04c3fSmrg (VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *)ext; 17159f464c52Smaya features->vertexAttributeInstanceRateDivisor = true; 17169f464c52Smaya features->vertexAttributeInstanceRateZeroDivisor = true; 17179f464c52Smaya break; 17189f464c52Smaya } 17199f464c52Smaya 17207ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR: { 17217ec681f3Smrg VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR *features = 17227ec681f3Smrg (VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR *)ext; 17237ec681f3Smrg features->workgroupMemoryExplicitLayout = true; 17247ec681f3Smrg features->workgroupMemoryExplicitLayoutScalarBlockLayout = true; 17257ec681f3Smrg features->workgroupMemoryExplicitLayout8BitAccess = true; 17267ec681f3Smrg features->workgroupMemoryExplicitLayout16BitAccess = true; 17277ec681f3Smrg break; 17287ec681f3Smrg } 17297ec681f3Smrg 17309f464c52Smaya case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT: { 17319f464c52Smaya VkPhysicalDeviceYcbcrImageArraysFeaturesEXT *features = 17329f464c52Smaya (VkPhysicalDeviceYcbcrImageArraysFeaturesEXT *)ext; 17339f464c52Smaya features->ycbcrImageArrays = true; 173401e04c3fSmrg break; 173501e04c3fSmrg } 173601e04c3fSmrg 17377ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT: { 17387ec681f3Smrg VkPhysicalDeviceExtendedDynamicStateFeaturesEXT *features = 17397ec681f3Smrg (VkPhysicalDeviceExtendedDynamicStateFeaturesEXT *)ext; 17407ec681f3Smrg features->extendedDynamicState = true; 17417ec681f3Smrg break; 17427ec681f3Smrg } 17437ec681f3Smrg 17447ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT: { 17457ec681f3Smrg VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *features = 17467ec681f3Smrg (VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *)ext; 17477ec681f3Smrg features->extendedDynamicState2 = true; 17487ec681f3Smrg features->extendedDynamicState2LogicOp = true; 17497ec681f3Smrg features->extendedDynamicState2PatchControlPoints = false; 17507ec681f3Smrg break; 17517ec681f3Smrg } 17527ec681f3Smrg 17537ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES_KHR: { 17547ec681f3Smrg VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR *features = 17557ec681f3Smrg (VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR *)ext; 17567ec681f3Smrg features->shaderZeroInitializeWorkgroupMemory = true; 17577ec681f3Smrg break; 17587ec681f3Smrg } 17597ec681f3Smrg 17607ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT: { 17617ec681f3Smrg VkPhysicalDeviceMultiDrawFeaturesEXT *features = (VkPhysicalDeviceMultiDrawFeaturesEXT *)ext; 17627ec681f3Smrg features->multiDraw = true; 17637ec681f3Smrg break; 17647ec681f3Smrg } 17657ec681f3Smrg 17667ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT: { 17677ec681f3Smrg VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT *features = 17687ec681f3Smrg (VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT *)ext; 17697ec681f3Smrg features->primitiveTopologyListRestart = true; 17707ec681f3Smrg features->primitiveTopologyPatchListRestart = true; 17717ec681f3Smrg break; 17727ec681f3Smrg } 17737ec681f3Smrg 177401e04c3fSmrg default: 177501e04c3fSmrg anv_debug_ignored_stype(ext->sType); 177601e04c3fSmrg break; 177701e04c3fSmrg } 177801e04c3fSmrg } 17797ec681f3Smrg 178001e04c3fSmrg} 178101e04c3fSmrg 17829f464c52Smaya#define MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BUFFERS 64 17839f464c52Smaya 17849f464c52Smaya#define MAX_PER_STAGE_DESCRIPTOR_INPUT_ATTACHMENTS 64 17859f464c52Smaya#define MAX_DESCRIPTOR_SET_INPUT_ATTACHMENTS 256 17869f464c52Smaya 17877ec681f3Smrg#define MAX_CUSTOM_BORDER_COLORS 4096 17887ec681f3Smrg 178901e04c3fSmrgvoid anv_GetPhysicalDeviceProperties( 179001e04c3fSmrg VkPhysicalDevice physicalDevice, 179101e04c3fSmrg VkPhysicalDeviceProperties* pProperties) 179201e04c3fSmrg{ 179301e04c3fSmrg ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice); 17947ec681f3Smrg const struct intel_device_info *devinfo = &pdevice->info; 179501e04c3fSmrg 17969f464c52Smaya const uint32_t max_ssbos = pdevice->has_a64_buffer_access ? UINT16_MAX : 64; 17979f464c52Smaya const uint32_t max_textures = 17989f464c52Smaya pdevice->has_bindless_images ? UINT16_MAX : 128; 17999f464c52Smaya const uint32_t max_samplers = 18009f464c52Smaya pdevice->has_bindless_samplers ? UINT16_MAX : 18017ec681f3Smrg (devinfo->verx10 >= 75) ? 128 : 16; 18029f464c52Smaya const uint32_t max_images = 18039f464c52Smaya pdevice->has_bindless_images ? UINT16_MAX : MAX_IMAGES; 180401e04c3fSmrg 18057ec681f3Smrg /* If we can use bindless for everything, claim a high per-stage limit, 18067ec681f3Smrg * otherwise use the binding table size, minus the slots reserved for 18077ec681f3Smrg * render targets and one slot for the descriptor buffer. */ 18089f464c52Smaya const uint32_t max_per_stage = 18097ec681f3Smrg pdevice->has_bindless_images && pdevice->has_a64_buffer_access 18107ec681f3Smrg ? UINT32_MAX : MAX_BINDING_TABLE_SIZE - MAX_RTS - 1; 18119f464c52Smaya 18127ec681f3Smrg const uint32_t max_workgroup_size = 32 * devinfo->max_cs_workgroup_threads; 181301e04c3fSmrg 181401e04c3fSmrg VkSampleCountFlags sample_counts = 181501e04c3fSmrg isl_device_get_sample_counts(&pdevice->isl_dev); 181601e04c3fSmrg 181701e04c3fSmrg 181801e04c3fSmrg VkPhysicalDeviceLimits limits = { 181901e04c3fSmrg .maxImageDimension1D = (1 << 14), 182001e04c3fSmrg .maxImageDimension2D = (1 << 14), 182101e04c3fSmrg .maxImageDimension3D = (1 << 11), 182201e04c3fSmrg .maxImageDimensionCube = (1 << 14), 182301e04c3fSmrg .maxImageArrayLayers = (1 << 11), 182401e04c3fSmrg .maxTexelBufferElements = 128 * 1024 * 1024, 182501e04c3fSmrg .maxUniformBufferRange = (1ul << 27), 18267ec681f3Smrg .maxStorageBufferRange = pdevice->isl_dev.max_buffer_size, 182701e04c3fSmrg .maxPushConstantsSize = MAX_PUSH_CONSTANTS_SIZE, 182801e04c3fSmrg .maxMemoryAllocationCount = UINT32_MAX, 182901e04c3fSmrg .maxSamplerAllocationCount = 64 * 1024, 183001e04c3fSmrg .bufferImageGranularity = 64, /* A cache line */ 183101e04c3fSmrg .sparseAddressSpaceSize = 0, 183201e04c3fSmrg .maxBoundDescriptorSets = MAX_SETS, 183301e04c3fSmrg .maxPerStageDescriptorSamplers = max_samplers, 18349f464c52Smaya .maxPerStageDescriptorUniformBuffers = MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BUFFERS, 18359f464c52Smaya .maxPerStageDescriptorStorageBuffers = max_ssbos, 18369f464c52Smaya .maxPerStageDescriptorSampledImages = max_textures, 183701e04c3fSmrg .maxPerStageDescriptorStorageImages = max_images, 18389f464c52Smaya .maxPerStageDescriptorInputAttachments = MAX_PER_STAGE_DESCRIPTOR_INPUT_ATTACHMENTS, 18399f464c52Smaya .maxPerStageResources = max_per_stage, 184001e04c3fSmrg .maxDescriptorSetSamplers = 6 * max_samplers, /* number of stages * maxPerStageDescriptorSamplers */ 18419f464c52Smaya .maxDescriptorSetUniformBuffers = 6 * MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BUFFERS, /* number of stages * maxPerStageDescriptorUniformBuffers */ 184201e04c3fSmrg .maxDescriptorSetUniformBuffersDynamic = MAX_DYNAMIC_BUFFERS / 2, 18439f464c52Smaya .maxDescriptorSetStorageBuffers = 6 * max_ssbos, /* number of stages * maxPerStageDescriptorStorageBuffers */ 184401e04c3fSmrg .maxDescriptorSetStorageBuffersDynamic = MAX_DYNAMIC_BUFFERS / 2, 18459f464c52Smaya .maxDescriptorSetSampledImages = 6 * max_textures, /* number of stages * maxPerStageDescriptorSampledImages */ 184601e04c3fSmrg .maxDescriptorSetStorageImages = 6 * max_images, /* number of stages * maxPerStageDescriptorStorageImages */ 18479f464c52Smaya .maxDescriptorSetInputAttachments = MAX_DESCRIPTOR_SET_INPUT_ATTACHMENTS, 184801e04c3fSmrg .maxVertexInputAttributes = MAX_VBS, 184901e04c3fSmrg .maxVertexInputBindings = MAX_VBS, 185001e04c3fSmrg .maxVertexInputAttributeOffset = 2047, 185101e04c3fSmrg .maxVertexInputBindingStride = 2048, 185201e04c3fSmrg .maxVertexOutputComponents = 128, 185301e04c3fSmrg .maxTessellationGenerationLevel = 64, 185401e04c3fSmrg .maxTessellationPatchSize = 32, 185501e04c3fSmrg .maxTessellationControlPerVertexInputComponents = 128, 185601e04c3fSmrg .maxTessellationControlPerVertexOutputComponents = 128, 185701e04c3fSmrg .maxTessellationControlPerPatchOutputComponents = 128, 185801e04c3fSmrg .maxTessellationControlTotalOutputComponents = 2048, 185901e04c3fSmrg .maxTessellationEvaluationInputComponents = 128, 186001e04c3fSmrg .maxTessellationEvaluationOutputComponents = 128, 186101e04c3fSmrg .maxGeometryShaderInvocations = 32, 18627ec681f3Smrg .maxGeometryInputComponents = devinfo->ver >= 8 ? 128 : 64, 186301e04c3fSmrg .maxGeometryOutputComponents = 128, 186401e04c3fSmrg .maxGeometryOutputVertices = 256, 186501e04c3fSmrg .maxGeometryTotalOutputComponents = 1024, 18669f464c52Smaya .maxFragmentInputComponents = 116, /* 128 components - (PSIZ, CLIP_DIST0, CLIP_DIST1) */ 186701e04c3fSmrg .maxFragmentOutputAttachments = 8, 186801e04c3fSmrg .maxFragmentDualSrcAttachments = 1, 186901e04c3fSmrg .maxFragmentCombinedOutputResources = 8, 18707ec681f3Smrg .maxComputeSharedMemorySize = 64 * 1024, 187101e04c3fSmrg .maxComputeWorkGroupCount = { 65535, 65535, 65535 }, 18729f464c52Smaya .maxComputeWorkGroupInvocations = max_workgroup_size, 187301e04c3fSmrg .maxComputeWorkGroupSize = { 18749f464c52Smaya max_workgroup_size, 18759f464c52Smaya max_workgroup_size, 18769f464c52Smaya max_workgroup_size, 187701e04c3fSmrg }, 1878993e1d59Smrg .subPixelPrecisionBits = 8, 18799f464c52Smaya .subTexelPrecisionBits = 8, 18809f464c52Smaya .mipmapPrecisionBits = 8, 188101e04c3fSmrg .maxDrawIndexedIndexValue = UINT32_MAX, 188201e04c3fSmrg .maxDrawIndirectCount = UINT32_MAX, 188301e04c3fSmrg .maxSamplerLodBias = 16, 188401e04c3fSmrg .maxSamplerAnisotropy = 16, 188501e04c3fSmrg .maxViewports = MAX_VIEWPORTS, 188601e04c3fSmrg .maxViewportDimensions = { (1 << 14), (1 << 14) }, 188701e04c3fSmrg .viewportBoundsRange = { INT16_MIN, INT16_MAX }, 188801e04c3fSmrg .viewportSubPixelBits = 13, /* We take a float? */ 188901e04c3fSmrg .minMemoryMapAlignment = 4096, /* A page */ 18907ec681f3Smrg /* The dataport requires texel alignment so we need to assume a worst 18917ec681f3Smrg * case of R32G32B32A32 which is 16 bytes. 18927ec681f3Smrg */ 18937ec681f3Smrg .minTexelBufferOffsetAlignment = 16, 18947ec681f3Smrg .minUniformBufferOffsetAlignment = ANV_UBO_ALIGNMENT, 18957ec681f3Smrg .minStorageBufferOffsetAlignment = ANV_SSBO_ALIGNMENT, 189601e04c3fSmrg .minTexelOffset = -8, 189701e04c3fSmrg .maxTexelOffset = 7, 189801e04c3fSmrg .minTexelGatherOffset = -32, 189901e04c3fSmrg .maxTexelGatherOffset = 31, 190001e04c3fSmrg .minInterpolationOffset = -0.5, 190101e04c3fSmrg .maxInterpolationOffset = 0.4375, 190201e04c3fSmrg .subPixelInterpolationOffsetBits = 4, 190301e04c3fSmrg .maxFramebufferWidth = (1 << 14), 190401e04c3fSmrg .maxFramebufferHeight = (1 << 14), 190501e04c3fSmrg .maxFramebufferLayers = (1 << 11), 190601e04c3fSmrg .framebufferColorSampleCounts = sample_counts, 190701e04c3fSmrg .framebufferDepthSampleCounts = sample_counts, 190801e04c3fSmrg .framebufferStencilSampleCounts = sample_counts, 190901e04c3fSmrg .framebufferNoAttachmentsSampleCounts = sample_counts, 191001e04c3fSmrg .maxColorAttachments = MAX_RTS, 191101e04c3fSmrg .sampledImageColorSampleCounts = sample_counts, 19127ec681f3Smrg .sampledImageIntegerSampleCounts = sample_counts, 191301e04c3fSmrg .sampledImageDepthSampleCounts = sample_counts, 191401e04c3fSmrg .sampledImageStencilSampleCounts = sample_counts, 191501e04c3fSmrg .storageImageSampleCounts = VK_SAMPLE_COUNT_1_BIT, 191601e04c3fSmrg .maxSampleMaskWords = 1, 19179f464c52Smaya .timestampComputeAndGraphics = true, 191801e04c3fSmrg .timestampPeriod = 1000000000.0 / devinfo->timestamp_frequency, 191901e04c3fSmrg .maxClipDistances = 8, 192001e04c3fSmrg .maxCullDistances = 8, 192101e04c3fSmrg .maxCombinedClipAndCullDistances = 8, 192201e04c3fSmrg .discreteQueuePriorities = 2, 192301e04c3fSmrg .pointSizeRange = { 0.125, 255.875 }, 19247ec681f3Smrg /* While SKL and up support much wider lines than we are setting here, 19257ec681f3Smrg * in practice we run into conformance issues if we go past this limit. 19267ec681f3Smrg * Since the Windows driver does the same, it's probably fair to assume 19277ec681f3Smrg * that no one needs more than this. 19287ec681f3Smrg */ 192901e04c3fSmrg .lineWidthRange = { 0.0, 7.9921875 }, 193001e04c3fSmrg .pointSizeGranularity = (1.0 / 8.0), 193101e04c3fSmrg .lineWidthGranularity = (1.0 / 128.0), 19327ec681f3Smrg .strictLines = false, 193301e04c3fSmrg .standardSampleLocations = true, 193401e04c3fSmrg .optimalBufferCopyOffsetAlignment = 128, 193501e04c3fSmrg .optimalBufferCopyRowPitchAlignment = 128, 193601e04c3fSmrg .nonCoherentAtomSize = 64, 193701e04c3fSmrg }; 193801e04c3fSmrg 193901e04c3fSmrg *pProperties = (VkPhysicalDeviceProperties) { 19407ec681f3Smrg .apiVersion = ANV_API_VERSION, 194101e04c3fSmrg .driverVersion = vk_get_driver_version(), 194201e04c3fSmrg .vendorID = 0x8086, 19437ec681f3Smrg .deviceID = pdevice->info.chipset_id, 19447ec681f3Smrg .deviceType = pdevice->info.has_local_mem ? 19457ec681f3Smrg VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU : 19467ec681f3Smrg VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, 194701e04c3fSmrg .limits = limits, 194801e04c3fSmrg .sparseProperties = {0}, /* Broadwell doesn't do sparse. */ 194901e04c3fSmrg }; 195001e04c3fSmrg 195101e04c3fSmrg snprintf(pProperties->deviceName, sizeof(pProperties->deviceName), 19527ec681f3Smrg "%s", pdevice->info.name); 195301e04c3fSmrg memcpy(pProperties->pipelineCacheUUID, 195401e04c3fSmrg pdevice->pipeline_cache_uuid, VK_UUID_SIZE); 195501e04c3fSmrg} 195601e04c3fSmrg 19577ec681f3Smrgstatic void 19587ec681f3Smrganv_get_physical_device_properties_1_1(struct anv_physical_device *pdevice, 19597ec681f3Smrg VkPhysicalDeviceVulkan11Properties *p) 19607ec681f3Smrg{ 19617ec681f3Smrg assert(p->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES); 19627ec681f3Smrg 19637ec681f3Smrg memcpy(p->deviceUUID, pdevice->device_uuid, VK_UUID_SIZE); 19647ec681f3Smrg memcpy(p->driverUUID, pdevice->driver_uuid, VK_UUID_SIZE); 19657ec681f3Smrg memset(p->deviceLUID, 0, VK_LUID_SIZE); 19667ec681f3Smrg p->deviceNodeMask = 0; 19677ec681f3Smrg p->deviceLUIDValid = false; 19687ec681f3Smrg 19697ec681f3Smrg p->subgroupSize = BRW_SUBGROUP_SIZE; 19707ec681f3Smrg VkShaderStageFlags scalar_stages = 0; 19717ec681f3Smrg for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) { 19727ec681f3Smrg if (pdevice->compiler->scalar_stage[stage]) 19737ec681f3Smrg scalar_stages |= mesa_to_vk_shader_stage(stage); 19747ec681f3Smrg } 19757ec681f3Smrg if (pdevice->vk.supported_extensions.KHR_ray_tracing_pipeline) { 19767ec681f3Smrg scalar_stages |= VK_SHADER_STAGE_RAYGEN_BIT_KHR | 19777ec681f3Smrg VK_SHADER_STAGE_ANY_HIT_BIT_KHR | 19787ec681f3Smrg VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | 19797ec681f3Smrg VK_SHADER_STAGE_MISS_BIT_KHR | 19807ec681f3Smrg VK_SHADER_STAGE_INTERSECTION_BIT_KHR | 19817ec681f3Smrg VK_SHADER_STAGE_CALLABLE_BIT_KHR; 19827ec681f3Smrg } 19837ec681f3Smrg p->subgroupSupportedStages = scalar_stages; 19847ec681f3Smrg p->subgroupSupportedOperations = VK_SUBGROUP_FEATURE_BASIC_BIT | 19857ec681f3Smrg VK_SUBGROUP_FEATURE_VOTE_BIT | 19867ec681f3Smrg VK_SUBGROUP_FEATURE_BALLOT_BIT | 19877ec681f3Smrg VK_SUBGROUP_FEATURE_SHUFFLE_BIT | 19887ec681f3Smrg VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT | 19897ec681f3Smrg VK_SUBGROUP_FEATURE_QUAD_BIT; 19907ec681f3Smrg if (pdevice->info.ver >= 8) { 19917ec681f3Smrg /* TODO: There's no technical reason why these can't be made to 19927ec681f3Smrg * work on gfx7 but they don't at the moment so it's best to leave 19937ec681f3Smrg * the feature disabled than enabled and broken. 19947ec681f3Smrg */ 19957ec681f3Smrg p->subgroupSupportedOperations |= VK_SUBGROUP_FEATURE_ARITHMETIC_BIT | 19967ec681f3Smrg VK_SUBGROUP_FEATURE_CLUSTERED_BIT; 19977ec681f3Smrg } 19987ec681f3Smrg p->subgroupQuadOperationsInAllStages = pdevice->info.ver >= 8; 19997ec681f3Smrg 20007ec681f3Smrg p->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY; 20017ec681f3Smrg p->maxMultiviewViewCount = 16; 20027ec681f3Smrg p->maxMultiviewInstanceIndex = UINT32_MAX / 16; 20037ec681f3Smrg p->protectedNoFault = false; 20047ec681f3Smrg /* This value doesn't matter for us today as our per-stage descriptors are 20057ec681f3Smrg * the real limit. 20067ec681f3Smrg */ 20077ec681f3Smrg p->maxPerSetDescriptors = 1024; 20087ec681f3Smrg p->maxMemoryAllocationSize = MAX_MEMORY_ALLOCATION_SIZE; 20097ec681f3Smrg} 20107ec681f3Smrg 20117ec681f3Smrgstatic void 20127ec681f3Smrganv_get_physical_device_properties_1_2(struct anv_physical_device *pdevice, 20137ec681f3Smrg VkPhysicalDeviceVulkan12Properties *p) 20147ec681f3Smrg{ 20157ec681f3Smrg assert(p->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES); 20167ec681f3Smrg 20177ec681f3Smrg p->driverID = VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR; 20187ec681f3Smrg memset(p->driverName, 0, sizeof(p->driverName)); 20197ec681f3Smrg snprintf(p->driverName, VK_MAX_DRIVER_NAME_SIZE_KHR, 20207ec681f3Smrg "Intel open-source Mesa driver"); 20217ec681f3Smrg memset(p->driverInfo, 0, sizeof(p->driverInfo)); 20227ec681f3Smrg snprintf(p->driverInfo, VK_MAX_DRIVER_INFO_SIZE_KHR, 20237ec681f3Smrg "Mesa " PACKAGE_VERSION MESA_GIT_SHA1); 20247ec681f3Smrg 20257ec681f3Smrg /* Don't advertise conformance with a particular version if the hardware's 20267ec681f3Smrg * support is incomplete/alpha. 20277ec681f3Smrg */ 20287ec681f3Smrg if (pdevice->is_alpha) { 20297ec681f3Smrg p->conformanceVersion = (VkConformanceVersionKHR) { 20307ec681f3Smrg .major = 0, 20317ec681f3Smrg .minor = 0, 20327ec681f3Smrg .subminor = 0, 20337ec681f3Smrg .patch = 0, 20347ec681f3Smrg }; 20357ec681f3Smrg } 20367ec681f3Smrg else { 20377ec681f3Smrg p->conformanceVersion = (VkConformanceVersionKHR) { 20387ec681f3Smrg .major = 1, 20397ec681f3Smrg .minor = 2, 20407ec681f3Smrg .subminor = 0, 20417ec681f3Smrg .patch = 0, 20427ec681f3Smrg }; 20437ec681f3Smrg } 20447ec681f3Smrg 20457ec681f3Smrg p->denormBehaviorIndependence = 20467ec681f3Smrg VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR; 20477ec681f3Smrg p->roundingModeIndependence = 20487ec681f3Smrg VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR; 20497ec681f3Smrg 20507ec681f3Smrg /* Broadwell does not support HF denorms and there are restrictions 20517ec681f3Smrg * other gens. According to Kabylake's PRM: 20527ec681f3Smrg * 20537ec681f3Smrg * "math - Extended Math Function 20547ec681f3Smrg * [...] 20557ec681f3Smrg * Restriction : Half-float denorms are always retained." 20567ec681f3Smrg */ 20577ec681f3Smrg p->shaderDenormFlushToZeroFloat16 = false; 20587ec681f3Smrg p->shaderDenormPreserveFloat16 = pdevice->info.ver > 8; 20597ec681f3Smrg p->shaderRoundingModeRTEFloat16 = true; 20607ec681f3Smrg p->shaderRoundingModeRTZFloat16 = true; 20617ec681f3Smrg p->shaderSignedZeroInfNanPreserveFloat16 = true; 20627ec681f3Smrg 20637ec681f3Smrg p->shaderDenormFlushToZeroFloat32 = true; 20647ec681f3Smrg p->shaderDenormPreserveFloat32 = true; 20657ec681f3Smrg p->shaderRoundingModeRTEFloat32 = true; 20667ec681f3Smrg p->shaderRoundingModeRTZFloat32 = true; 20677ec681f3Smrg p->shaderSignedZeroInfNanPreserveFloat32 = true; 20687ec681f3Smrg 20697ec681f3Smrg p->shaderDenormFlushToZeroFloat64 = true; 20707ec681f3Smrg p->shaderDenormPreserveFloat64 = true; 20717ec681f3Smrg p->shaderRoundingModeRTEFloat64 = true; 20727ec681f3Smrg p->shaderRoundingModeRTZFloat64 = true; 20737ec681f3Smrg p->shaderSignedZeroInfNanPreserveFloat64 = true; 20747ec681f3Smrg 20757ec681f3Smrg /* It's a bit hard to exactly map our implementation to the limits 20767ec681f3Smrg * described by Vulkan. The bindless surface handle in the extended 20777ec681f3Smrg * message descriptors is 20 bits and it's an index into the table of 20787ec681f3Smrg * RENDER_SURFACE_STATE structs that starts at bindless surface base 20797ec681f3Smrg * address. This means that we can have at must 1M surface states 20807ec681f3Smrg * allocated at any given time. Since most image views take two 20817ec681f3Smrg * descriptors, this means we have a limit of about 500K image views. 20827ec681f3Smrg * 20837ec681f3Smrg * However, since we allocate surface states at vkCreateImageView time, 20847ec681f3Smrg * this means our limit is actually something on the order of 500K image 20857ec681f3Smrg * views allocated at any time. The actual limit describe by Vulkan, on 20867ec681f3Smrg * the other hand, is a limit of how many you can have in a descriptor set. 20877ec681f3Smrg * Assuming anyone using 1M descriptors will be using the same image view 20887ec681f3Smrg * twice a bunch of times (or a bunch of null descriptors), we can safely 20897ec681f3Smrg * advertise a larger limit here. 20907ec681f3Smrg */ 20917ec681f3Smrg const unsigned max_bindless_views = 1 << 20; 20927ec681f3Smrg p->maxUpdateAfterBindDescriptorsInAllPools = max_bindless_views; 20937ec681f3Smrg p->shaderUniformBufferArrayNonUniformIndexingNative = false; 20947ec681f3Smrg p->shaderSampledImageArrayNonUniformIndexingNative = false; 20957ec681f3Smrg p->shaderStorageBufferArrayNonUniformIndexingNative = true; 20967ec681f3Smrg p->shaderStorageImageArrayNonUniformIndexingNative = false; 20977ec681f3Smrg p->shaderInputAttachmentArrayNonUniformIndexingNative = false; 20987ec681f3Smrg p->robustBufferAccessUpdateAfterBind = true; 20997ec681f3Smrg p->quadDivergentImplicitLod = false; 21007ec681f3Smrg p->maxPerStageDescriptorUpdateAfterBindSamplers = max_bindless_views; 21017ec681f3Smrg p->maxPerStageDescriptorUpdateAfterBindUniformBuffers = MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BUFFERS; 21027ec681f3Smrg p->maxPerStageDescriptorUpdateAfterBindStorageBuffers = UINT32_MAX; 21037ec681f3Smrg p->maxPerStageDescriptorUpdateAfterBindSampledImages = max_bindless_views; 21047ec681f3Smrg p->maxPerStageDescriptorUpdateAfterBindStorageImages = max_bindless_views; 21057ec681f3Smrg p->maxPerStageDescriptorUpdateAfterBindInputAttachments = MAX_PER_STAGE_DESCRIPTOR_INPUT_ATTACHMENTS; 21067ec681f3Smrg p->maxPerStageUpdateAfterBindResources = UINT32_MAX; 21077ec681f3Smrg p->maxDescriptorSetUpdateAfterBindSamplers = max_bindless_views; 21087ec681f3Smrg p->maxDescriptorSetUpdateAfterBindUniformBuffers = 6 * MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BUFFERS; 21097ec681f3Smrg p->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = MAX_DYNAMIC_BUFFERS / 2; 21107ec681f3Smrg p->maxDescriptorSetUpdateAfterBindStorageBuffers = UINT32_MAX; 21117ec681f3Smrg p->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = MAX_DYNAMIC_BUFFERS / 2; 21127ec681f3Smrg p->maxDescriptorSetUpdateAfterBindSampledImages = max_bindless_views; 21137ec681f3Smrg p->maxDescriptorSetUpdateAfterBindStorageImages = max_bindless_views; 21147ec681f3Smrg p->maxDescriptorSetUpdateAfterBindInputAttachments = MAX_DESCRIPTOR_SET_INPUT_ATTACHMENTS; 21157ec681f3Smrg 21167ec681f3Smrg /* We support all of the depth resolve modes */ 21177ec681f3Smrg p->supportedDepthResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR | 21187ec681f3Smrg VK_RESOLVE_MODE_AVERAGE_BIT_KHR | 21197ec681f3Smrg VK_RESOLVE_MODE_MIN_BIT_KHR | 21207ec681f3Smrg VK_RESOLVE_MODE_MAX_BIT_KHR; 21217ec681f3Smrg /* Average doesn't make sense for stencil so we don't support that */ 21227ec681f3Smrg p->supportedStencilResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR; 21237ec681f3Smrg if (pdevice->info.ver >= 8) { 21247ec681f3Smrg /* The advanced stencil resolve modes currently require stencil 21257ec681f3Smrg * sampling be supported by the hardware. 21267ec681f3Smrg */ 21277ec681f3Smrg p->supportedStencilResolveModes |= VK_RESOLVE_MODE_MIN_BIT_KHR | 21287ec681f3Smrg VK_RESOLVE_MODE_MAX_BIT_KHR; 21297ec681f3Smrg } 21307ec681f3Smrg p->independentResolveNone = true; 21317ec681f3Smrg p->independentResolve = true; 21327ec681f3Smrg 21337ec681f3Smrg p->filterMinmaxSingleComponentFormats = pdevice->info.ver >= 9; 21347ec681f3Smrg p->filterMinmaxImageComponentMapping = pdevice->info.ver >= 9; 21357ec681f3Smrg 21367ec681f3Smrg p->maxTimelineSemaphoreValueDifference = UINT64_MAX; 21377ec681f3Smrg 21387ec681f3Smrg p->framebufferIntegerColorSampleCounts = 21397ec681f3Smrg isl_device_get_sample_counts(&pdevice->isl_dev); 21407ec681f3Smrg} 21417ec681f3Smrg 214201e04c3fSmrgvoid anv_GetPhysicalDeviceProperties2( 214301e04c3fSmrg VkPhysicalDevice physicalDevice, 214401e04c3fSmrg VkPhysicalDeviceProperties2* pProperties) 214501e04c3fSmrg{ 214601e04c3fSmrg ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice); 214701e04c3fSmrg 214801e04c3fSmrg anv_GetPhysicalDeviceProperties(physicalDevice, &pProperties->properties); 214901e04c3fSmrg 21507ec681f3Smrg VkPhysicalDeviceVulkan11Properties core_1_1 = { 21517ec681f3Smrg .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES, 21527ec681f3Smrg }; 21537ec681f3Smrg anv_get_physical_device_properties_1_1(pdevice, &core_1_1); 21547ec681f3Smrg 21557ec681f3Smrg VkPhysicalDeviceVulkan12Properties core_1_2 = { 21567ec681f3Smrg .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES, 21577ec681f3Smrg }; 21587ec681f3Smrg anv_get_physical_device_properties_1_2(pdevice, &core_1_2); 21597ec681f3Smrg 216001e04c3fSmrg vk_foreach_struct(ext, pProperties->pNext) { 21617ec681f3Smrg if (vk_get_physical_device_core_1_1_property_ext(ext, &core_1_1)) 21627ec681f3Smrg continue; 21637ec681f3Smrg if (vk_get_physical_device_core_1_2_property_ext(ext, &core_1_2)) 21647ec681f3Smrg continue; 21657ec681f3Smrg 216601e04c3fSmrg switch (ext->sType) { 21677ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR: { 21687ec681f3Smrg VkPhysicalDeviceAccelerationStructurePropertiesKHR *props = (void *)ext; 21697ec681f3Smrg props->maxGeometryCount = (1u << 24) - 1; 21707ec681f3Smrg props->maxInstanceCount = (1u << 24) - 1; 21717ec681f3Smrg props->maxPrimitiveCount = (1u << 29) - 1; 21727ec681f3Smrg props->maxPerStageDescriptorAccelerationStructures = UINT16_MAX; 21737ec681f3Smrg props->maxPerStageDescriptorUpdateAfterBindAccelerationStructures = UINT16_MAX; 21747ec681f3Smrg props->maxDescriptorSetAccelerationStructures = UINT16_MAX; 21757ec681f3Smrg props->maxDescriptorSetUpdateAfterBindAccelerationStructures = UINT16_MAX; 21767ec681f3Smrg props->minAccelerationStructureScratchOffsetAlignment = 64; 21777ec681f3Smrg break; 21787ec681f3Smrg } 21797ec681f3Smrg 21807ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT: { 21817ec681f3Smrg /* TODO: Real limits */ 21827ec681f3Smrg VkPhysicalDeviceConservativeRasterizationPropertiesEXT *properties = 21837ec681f3Smrg (VkPhysicalDeviceConservativeRasterizationPropertiesEXT *)ext; 21847ec681f3Smrg /* There's nothing in the public docs about this value as far as I 21857ec681f3Smrg * can tell. However, this is the value the Windows driver reports 21867ec681f3Smrg * and there's a comment on a rejected HW feature in the internal 21877ec681f3Smrg * docs that says: 21887ec681f3Smrg * 21897ec681f3Smrg * "This is similar to conservative rasterization, except the 21907ec681f3Smrg * primitive area is not extended by 1/512 and..." 21917ec681f3Smrg * 21927ec681f3Smrg * That's a bit of an obtuse reference but it's the best we've got 21937ec681f3Smrg * for now. 21947ec681f3Smrg */ 21957ec681f3Smrg properties->primitiveOverestimationSize = 1.0f / 512.0f; 21967ec681f3Smrg properties->maxExtraPrimitiveOverestimationSize = 0.0f; 21977ec681f3Smrg properties->extraPrimitiveOverestimationSizeGranularity = 0.0f; 21987ec681f3Smrg properties->primitiveUnderestimation = false; 21997ec681f3Smrg properties->conservativePointAndLineRasterization = false; 22007ec681f3Smrg properties->degenerateTrianglesRasterized = true; 22017ec681f3Smrg properties->degenerateLinesRasterized = false; 22027ec681f3Smrg properties->fullyCoveredFragmentShaderInputVariable = false; 22037ec681f3Smrg properties->conservativeRasterizationPostDepthCoverage = true; 22047ec681f3Smrg break; 22057ec681f3Smrg } 220601e04c3fSmrg 22077ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT: { 22087ec681f3Smrg VkPhysicalDeviceCustomBorderColorPropertiesEXT *properties = 22097ec681f3Smrg (VkPhysicalDeviceCustomBorderColorPropertiesEXT *)ext; 22107ec681f3Smrg properties->maxCustomBorderColorSamplers = MAX_CUSTOM_BORDER_COLORS; 22119f464c52Smaya break; 22129f464c52Smaya } 22139f464c52Smaya 22149f464c52Smaya 22157ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR: { 22167ec681f3Smrg VkPhysicalDeviceFragmentShadingRatePropertiesKHR *props = 22177ec681f3Smrg (VkPhysicalDeviceFragmentShadingRatePropertiesKHR *)ext; 22187ec681f3Smrg /* Those must be 0 if attachmentFragmentShadingRate is not 22197ec681f3Smrg * supported. 22209f464c52Smaya */ 22217ec681f3Smrg props->minFragmentShadingRateAttachmentTexelSize = (VkExtent2D) { 0, 0 }; 22227ec681f3Smrg props->maxFragmentShadingRateAttachmentTexelSize = (VkExtent2D) { 0, 0 }; 22237ec681f3Smrg props->maxFragmentShadingRateAttachmentTexelSizeAspectRatio = 0; 22247ec681f3Smrg 22257ec681f3Smrg props->primitiveFragmentShadingRateWithMultipleViewports = false; 22267ec681f3Smrg props->layeredShadingRateAttachments = false; 22277ec681f3Smrg props->fragmentShadingRateNonTrivialCombinerOps = false; 22287ec681f3Smrg props->maxFragmentSize = (VkExtent2D) { 4, 4 }; 22297ec681f3Smrg props->maxFragmentSizeAspectRatio = 4; 22307ec681f3Smrg props->maxFragmentShadingRateCoverageSamples = 4 * 4 * 16; 22317ec681f3Smrg props->maxFragmentShadingRateRasterizationSamples = VK_SAMPLE_COUNT_16_BIT; 22327ec681f3Smrg props->fragmentShadingRateWithShaderDepthStencilWrites = false; 22337ec681f3Smrg props->fragmentShadingRateWithSampleMask = true; 22347ec681f3Smrg props->fragmentShadingRateWithShaderSampleMask = false; 22357ec681f3Smrg props->fragmentShadingRateWithConservativeRasterization = true; 22367ec681f3Smrg props->fragmentShadingRateWithFragmentShaderInterlock = true; 22377ec681f3Smrg props->fragmentShadingRateWithCustomSampleLocations = true; 22387ec681f3Smrg props->fragmentShadingRateStrictMultiplyCombiner = false; 22397ec681f3Smrg break; 22407ec681f3Smrg } 22417ec681f3Smrg 22427ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT: { 22437ec681f3Smrg VkPhysicalDeviceDrmPropertiesEXT *props = 22447ec681f3Smrg (VkPhysicalDeviceDrmPropertiesEXT *)ext; 22457ec681f3Smrg 22467ec681f3Smrg props->hasPrimary = pdevice->has_master; 22477ec681f3Smrg props->primaryMajor = pdevice->master_major; 22487ec681f3Smrg props->primaryMinor = pdevice->master_minor; 22497ec681f3Smrg 22507ec681f3Smrg props->hasRender = pdevice->has_local; 22517ec681f3Smrg props->renderMajor = pdevice->local_major; 22527ec681f3Smrg props->renderMinor = pdevice->local_minor; 22537ec681f3Smrg 225401e04c3fSmrg break; 225501e04c3fSmrg } 225601e04c3fSmrg 22579f464c52Smaya case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT: { 22589f464c52Smaya VkPhysicalDeviceExternalMemoryHostPropertiesEXT *props = 22599f464c52Smaya (VkPhysicalDeviceExternalMemoryHostPropertiesEXT *) ext; 22609f464c52Smaya /* Userptr needs page aligned memory. */ 22619f464c52Smaya props->minImportedHostPointerAlignment = 4096; 22629f464c52Smaya break; 22639f464c52Smaya } 22649f464c52Smaya 22659f464c52Smaya case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT: { 22669f464c52Smaya VkPhysicalDeviceInlineUniformBlockPropertiesEXT *props = 22679f464c52Smaya (VkPhysicalDeviceInlineUniformBlockPropertiesEXT *)ext; 22689f464c52Smaya props->maxInlineUniformBlockSize = MAX_INLINE_UNIFORM_BLOCK_SIZE; 22699f464c52Smaya props->maxPerStageDescriptorInlineUniformBlocks = 22709f464c52Smaya MAX_INLINE_UNIFORM_BLOCK_DESCRIPTORS; 22719f464c52Smaya props->maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks = 22729f464c52Smaya MAX_INLINE_UNIFORM_BLOCK_DESCRIPTORS; 22739f464c52Smaya props->maxDescriptorSetInlineUniformBlocks = 22749f464c52Smaya MAX_INLINE_UNIFORM_BLOCK_DESCRIPTORS; 22759f464c52Smaya props->maxDescriptorSetUpdateAfterBindInlineUniformBlocks = 22769f464c52Smaya MAX_INLINE_UNIFORM_BLOCK_DESCRIPTORS; 22779f464c52Smaya break; 22789f464c52Smaya } 22799f464c52Smaya 22807ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT: { 22817ec681f3Smrg VkPhysicalDeviceLineRasterizationPropertiesEXT *props = 22827ec681f3Smrg (VkPhysicalDeviceLineRasterizationPropertiesEXT *)ext; 22837ec681f3Smrg /* In the Skylake PRM Vol. 7, subsection titled "GIQ (Diamond) 22847ec681f3Smrg * Sampling Rules - Legacy Mode", it says the following: 22857ec681f3Smrg * 22867ec681f3Smrg * "Note that the device divides a pixel into a 16x16 array of 22877ec681f3Smrg * subpixels, referenced by their upper left corners." 22887ec681f3Smrg * 22897ec681f3Smrg * This is the only known reference in the PRMs to the subpixel 22907ec681f3Smrg * precision of line rasterization and a "16x16 array of subpixels" 22917ec681f3Smrg * implies 4 subpixel precision bits. Empirical testing has shown 22927ec681f3Smrg * that 4 subpixel precision bits applies to all line rasterization 22937ec681f3Smrg * types. 229401e04c3fSmrg */ 22957ec681f3Smrg props->lineSubPixelPrecisionBits = 4; 229601e04c3fSmrg break; 229701e04c3fSmrg } 229801e04c3fSmrg 22997ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR: { 23007ec681f3Smrg VkPhysicalDeviceMaintenance4PropertiesKHR *properties = 23017ec681f3Smrg (VkPhysicalDeviceMaintenance4PropertiesKHR *)ext; 23027ec681f3Smrg properties->maxBufferSize = pdevice->isl_dev.max_buffer_size; 230301e04c3fSmrg break; 230401e04c3fSmrg } 230501e04c3fSmrg 230601e04c3fSmrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT: { 230701e04c3fSmrg VkPhysicalDevicePCIBusInfoPropertiesEXT *properties = 230801e04c3fSmrg (VkPhysicalDevicePCIBusInfoPropertiesEXT *)ext; 230901e04c3fSmrg properties->pciDomain = pdevice->pci_info.domain; 231001e04c3fSmrg properties->pciBus = pdevice->pci_info.bus; 231101e04c3fSmrg properties->pciDevice = pdevice->pci_info.device; 231201e04c3fSmrg properties->pciFunction = pdevice->pci_info.function; 231301e04c3fSmrg break; 231401e04c3fSmrg } 231501e04c3fSmrg 23167ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR: { 23177ec681f3Smrg VkPhysicalDevicePerformanceQueryPropertiesKHR *properties = 23187ec681f3Smrg (VkPhysicalDevicePerformanceQueryPropertiesKHR *)ext; 23197ec681f3Smrg /* We could support this by spawning a shader to do the equation 23207ec681f3Smrg * normalization. 23217ec681f3Smrg */ 23227ec681f3Smrg properties->allowCommandBufferQueryCopies = false; 23237ec681f3Smrg break; 23247ec681f3Smrg } 23257ec681f3Smrg 23267ec681f3Smrg#pragma GCC diagnostic push 23277ec681f3Smrg#pragma GCC diagnostic ignored "-Wswitch" 23287ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID: { 23297ec681f3Smrg VkPhysicalDevicePresentationPropertiesANDROID *props = 23307ec681f3Smrg (VkPhysicalDevicePresentationPropertiesANDROID *)ext; 23317ec681f3Smrg props->sharedImage = VK_FALSE; 233201e04c3fSmrg break; 233301e04c3fSmrg } 23347ec681f3Smrg#pragma GCC diagnostic pop 233501e04c3fSmrg 23367ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT: { 23377ec681f3Smrg VkPhysicalDeviceProvokingVertexPropertiesEXT *properties = 23387ec681f3Smrg (VkPhysicalDeviceProvokingVertexPropertiesEXT *)ext; 23397ec681f3Smrg properties->provokingVertexModePerPipeline = true; 23407ec681f3Smrg properties->transformFeedbackPreservesTriangleFanProvokingVertex = false; 23419f464c52Smaya break; 23429f464c52Smaya } 23439f464c52Smaya 23449f464c52Smaya case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: { 23459f464c52Smaya VkPhysicalDevicePushDescriptorPropertiesKHR *properties = 23469f464c52Smaya (VkPhysicalDevicePushDescriptorPropertiesKHR *) ext; 23479f464c52Smaya properties->maxPushDescriptors = MAX_PUSH_DESCRIPTORS; 23489f464c52Smaya break; 23499f464c52Smaya } 23509f464c52Smaya 23517ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT: { 23527ec681f3Smrg VkPhysicalDeviceRobustness2PropertiesEXT *properties = (void *)ext; 23537ec681f3Smrg properties->robustStorageBufferAccessSizeAlignment = 23547ec681f3Smrg ANV_SSBO_BOUNDS_CHECK_ALIGNMENT; 23557ec681f3Smrg properties->robustUniformBufferAccessSizeAlignment = 23567ec681f3Smrg ANV_UBO_ALIGNMENT; 235701e04c3fSmrg break; 235801e04c3fSmrg } 235901e04c3fSmrg 23607ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR: { 23617ec681f3Smrg VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR *props = 23627ec681f3Smrg (VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR *)ext; 23637ec681f3Smrg 23647ec681f3Smrg props->integerDotProduct8BitUnsignedAccelerated = false; 23657ec681f3Smrg props->integerDotProduct8BitSignedAccelerated = false; 23667ec681f3Smrg props->integerDotProduct8BitMixedSignednessAccelerated = false; 23677ec681f3Smrg props->integerDotProduct4x8BitPackedUnsignedAccelerated = pdevice->info.ver >= 12; 23687ec681f3Smrg props->integerDotProduct4x8BitPackedSignedAccelerated = pdevice->info.ver >= 12; 23697ec681f3Smrg props->integerDotProduct4x8BitPackedMixedSignednessAccelerated = pdevice->info.ver >= 12; 23707ec681f3Smrg props->integerDotProduct16BitUnsignedAccelerated = false; 23717ec681f3Smrg props->integerDotProduct16BitSignedAccelerated = false; 23727ec681f3Smrg props->integerDotProduct16BitMixedSignednessAccelerated = false; 23737ec681f3Smrg props->integerDotProduct32BitUnsignedAccelerated = false; 23747ec681f3Smrg props->integerDotProduct32BitSignedAccelerated = false; 23757ec681f3Smrg props->integerDotProduct32BitMixedSignednessAccelerated = false; 23767ec681f3Smrg props->integerDotProduct64BitUnsignedAccelerated = false; 23777ec681f3Smrg props->integerDotProduct64BitSignedAccelerated = false; 23787ec681f3Smrg props->integerDotProduct64BitMixedSignednessAccelerated = false; 23797ec681f3Smrg props->integerDotProductAccumulatingSaturating8BitUnsignedAccelerated = false; 23807ec681f3Smrg props->integerDotProductAccumulatingSaturating8BitSignedAccelerated = false; 23817ec681f3Smrg props->integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated = false; 23827ec681f3Smrg props->integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated = pdevice->info.ver >= 12; 23837ec681f3Smrg props->integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated = pdevice->info.ver >= 12; 23847ec681f3Smrg props->integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated = pdevice->info.ver >= 12; 23857ec681f3Smrg props->integerDotProductAccumulatingSaturating16BitUnsignedAccelerated = false; 23867ec681f3Smrg props->integerDotProductAccumulatingSaturating16BitSignedAccelerated = false; 23877ec681f3Smrg props->integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated = false; 23887ec681f3Smrg props->integerDotProductAccumulatingSaturating32BitUnsignedAccelerated = false; 23897ec681f3Smrg props->integerDotProductAccumulatingSaturating32BitSignedAccelerated = false; 23907ec681f3Smrg props->integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated = false; 23917ec681f3Smrg props->integerDotProductAccumulatingSaturating64BitUnsignedAccelerated = false; 23927ec681f3Smrg props->integerDotProductAccumulatingSaturating64BitSignedAccelerated = false; 23937ec681f3Smrg props->integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated = false; 239401e04c3fSmrg 23957ec681f3Smrg break; 23967ec681f3Smrg } 239701e04c3fSmrg 23987ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT: { 23997ec681f3Smrg VkPhysicalDeviceSubgroupSizeControlPropertiesEXT *props = 24007ec681f3Smrg (VkPhysicalDeviceSubgroupSizeControlPropertiesEXT *)ext; 24017ec681f3Smrg STATIC_ASSERT(8 <= BRW_SUBGROUP_SIZE && BRW_SUBGROUP_SIZE <= 32); 24027ec681f3Smrg props->minSubgroupSize = 8; 24037ec681f3Smrg props->maxSubgroupSize = 32; 24047ec681f3Smrg props->maxComputeWorkgroupSubgroups = pdevice->info.max_cs_workgroup_threads; 24057ec681f3Smrg props->requiredSubgroupSizeStages = VK_SHADER_STAGE_COMPUTE_BIT; 24067ec681f3Smrg break; 24077ec681f3Smrg } 24087ec681f3Smrg 24097ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT: { 24107ec681f3Smrg VkPhysicalDeviceSampleLocationsPropertiesEXT *props = 24117ec681f3Smrg (VkPhysicalDeviceSampleLocationsPropertiesEXT *)ext; 24127ec681f3Smrg 24137ec681f3Smrg props->sampleLocationSampleCounts = 24147ec681f3Smrg isl_device_get_sample_counts(&pdevice->isl_dev); 24157ec681f3Smrg 24167ec681f3Smrg /* See also anv_GetPhysicalDeviceMultisamplePropertiesEXT */ 24177ec681f3Smrg props->maxSampleLocationGridSize.width = 1; 24187ec681f3Smrg props->maxSampleLocationGridSize.height = 1; 24197ec681f3Smrg 24207ec681f3Smrg props->sampleLocationCoordinateRange[0] = 0; 24217ec681f3Smrg props->sampleLocationCoordinateRange[1] = 0.9375; 24227ec681f3Smrg props->sampleLocationSubPixelBits = 4; 24237ec681f3Smrg 24247ec681f3Smrg props->variableSampleLocations = true; 24257ec681f3Smrg break; 24267ec681f3Smrg } 242701e04c3fSmrg 24287ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT: { 24297ec681f3Smrg VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT *props = 24307ec681f3Smrg (VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT *)ext; 24317ec681f3Smrg 24327ec681f3Smrg /* From the SKL PRM Vol. 2d, docs for RENDER_SURFACE_STATE::Surface 24337ec681f3Smrg * Base Address: 24347ec681f3Smrg * 24357ec681f3Smrg * "For SURFTYPE_BUFFER non-rendertarget surfaces, this field 24367ec681f3Smrg * specifies the base address of the first element of the surface, 24377ec681f3Smrg * computed in software by adding the surface base address to the 24387ec681f3Smrg * byte offset of the element in the buffer. The base address must 24397ec681f3Smrg * be aligned to element size." 24407ec681f3Smrg * 24417ec681f3Smrg * The typed dataport messages require that things be texel aligned. 24427ec681f3Smrg * Otherwise, we may just load/store the wrong data or, in the worst 24437ec681f3Smrg * case, there may be hangs. 24447ec681f3Smrg */ 24457ec681f3Smrg props->storageTexelBufferOffsetAlignmentBytes = 16; 24467ec681f3Smrg props->storageTexelBufferOffsetSingleTexelAlignment = true; 24477ec681f3Smrg 24487ec681f3Smrg /* The sampler, however, is much more forgiving and it can handle 24497ec681f3Smrg * arbitrary byte alignment for linear and buffer surfaces. It's 24507ec681f3Smrg * hard to find a good PRM citation for this but years of empirical 24517ec681f3Smrg * experience demonstrate that this is true. 24527ec681f3Smrg */ 24537ec681f3Smrg props->uniformTexelBufferOffsetAlignmentBytes = 1; 24547ec681f3Smrg props->uniformTexelBufferOffsetSingleTexelAlignment = false; 24559f464c52Smaya break; 24569f464c52Smaya } 24579f464c52Smaya 24589f464c52Smaya case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT: { 24599f464c52Smaya VkPhysicalDeviceTransformFeedbackPropertiesEXT *props = 24609f464c52Smaya (VkPhysicalDeviceTransformFeedbackPropertiesEXT *)ext; 24619f464c52Smaya 24629f464c52Smaya props->maxTransformFeedbackStreams = MAX_XFB_STREAMS; 24639f464c52Smaya props->maxTransformFeedbackBuffers = MAX_XFB_BUFFERS; 24649f464c52Smaya props->maxTransformFeedbackBufferSize = (1ull << 32); 24659f464c52Smaya props->maxTransformFeedbackStreamDataSize = 128 * 4; 24669f464c52Smaya props->maxTransformFeedbackBufferDataSize = 128 * 4; 24679f464c52Smaya props->maxTransformFeedbackBufferDataStride = 2048; 24689f464c52Smaya props->transformFeedbackQueries = true; 24699f464c52Smaya props->transformFeedbackStreamsLinesTriangles = false; 24709f464c52Smaya props->transformFeedbackRasterizationStreamSelect = false; 24717ec681f3Smrg /* This requires MI_MATH */ 24727ec681f3Smrg props->transformFeedbackDraw = pdevice->info.verx10 >= 75; 247301e04c3fSmrg break; 247401e04c3fSmrg } 247501e04c3fSmrg 247601e04c3fSmrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: { 247701e04c3fSmrg VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *props = 247801e04c3fSmrg (VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext; 247901e04c3fSmrg /* We have to restrict this a bit for multiview */ 248001e04c3fSmrg props->maxVertexAttribDivisor = UINT32_MAX / 16; 248101e04c3fSmrg break; 248201e04c3fSmrg } 248301e04c3fSmrg 24847ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT: { 24857ec681f3Smrg VkPhysicalDeviceMultiDrawPropertiesEXT *props = (VkPhysicalDeviceMultiDrawPropertiesEXT *)ext; 24867ec681f3Smrg props->maxMultiDrawCount = 2048; 24877ec681f3Smrg break; 24887ec681f3Smrg } 24897ec681f3Smrg 249001e04c3fSmrg default: 249101e04c3fSmrg anv_debug_ignored_stype(ext->sType); 249201e04c3fSmrg break; 249301e04c3fSmrg } 249401e04c3fSmrg } 249501e04c3fSmrg} 249601e04c3fSmrg 249701e04c3fSmrgstatic const VkQueueFamilyProperties 24987ec681f3Smrganv_queue_family_properties_template = { 249901e04c3fSmrg .timestampValidBits = 36, /* XXX: Real value here */ 250001e04c3fSmrg .minImageTransferGranularity = { 1, 1, 1 }, 250101e04c3fSmrg}; 250201e04c3fSmrg 250301e04c3fSmrgvoid anv_GetPhysicalDeviceQueueFamilyProperties( 250401e04c3fSmrg VkPhysicalDevice physicalDevice, 250501e04c3fSmrg uint32_t* pCount, 250601e04c3fSmrg VkQueueFamilyProperties* pQueueFamilyProperties) 250701e04c3fSmrg{ 25087ec681f3Smrg ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice); 250901e04c3fSmrg VK_OUTARRAY_MAKE(out, pQueueFamilyProperties, pCount); 251001e04c3fSmrg 25117ec681f3Smrg for (uint32_t i = 0; i < pdevice->queue.family_count; i++) { 25127ec681f3Smrg struct anv_queue_family *queue_family = &pdevice->queue.families[i]; 25137ec681f3Smrg vk_outarray_append(&out, p) { 25147ec681f3Smrg *p = anv_queue_family_properties_template; 25157ec681f3Smrg p->queueFlags = queue_family->queueFlags; 25167ec681f3Smrg p->queueCount = queue_family->queueCount; 25177ec681f3Smrg } 251801e04c3fSmrg } 251901e04c3fSmrg} 252001e04c3fSmrg 252101e04c3fSmrgvoid anv_GetPhysicalDeviceQueueFamilyProperties2( 252201e04c3fSmrg VkPhysicalDevice physicalDevice, 252301e04c3fSmrg uint32_t* pQueueFamilyPropertyCount, 252401e04c3fSmrg VkQueueFamilyProperties2* pQueueFamilyProperties) 252501e04c3fSmrg{ 25267ec681f3Smrg ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice); 252701e04c3fSmrg VK_OUTARRAY_MAKE(out, pQueueFamilyProperties, pQueueFamilyPropertyCount); 252801e04c3fSmrg 25297ec681f3Smrg for (uint32_t i = 0; i < pdevice->queue.family_count; i++) { 25307ec681f3Smrg struct anv_queue_family *queue_family = &pdevice->queue.families[i]; 25317ec681f3Smrg vk_outarray_append(&out, p) { 25327ec681f3Smrg p->queueFamilyProperties = anv_queue_family_properties_template; 25337ec681f3Smrg p->queueFamilyProperties.queueFlags = queue_family->queueFlags; 25347ec681f3Smrg p->queueFamilyProperties.queueCount = queue_family->queueCount; 253501e04c3fSmrg 25367ec681f3Smrg vk_foreach_struct(s, p->pNext) { 25377ec681f3Smrg anv_debug_ignored_stype(s->sType); 25387ec681f3Smrg } 253901e04c3fSmrg } 254001e04c3fSmrg } 254101e04c3fSmrg} 254201e04c3fSmrg 254301e04c3fSmrgvoid anv_GetPhysicalDeviceMemoryProperties( 254401e04c3fSmrg VkPhysicalDevice physicalDevice, 254501e04c3fSmrg VkPhysicalDeviceMemoryProperties* pMemoryProperties) 254601e04c3fSmrg{ 254701e04c3fSmrg ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice); 254801e04c3fSmrg 254901e04c3fSmrg pMemoryProperties->memoryTypeCount = physical_device->memory.type_count; 255001e04c3fSmrg for (uint32_t i = 0; i < physical_device->memory.type_count; i++) { 255101e04c3fSmrg pMemoryProperties->memoryTypes[i] = (VkMemoryType) { 255201e04c3fSmrg .propertyFlags = physical_device->memory.types[i].propertyFlags, 255301e04c3fSmrg .heapIndex = physical_device->memory.types[i].heapIndex, 255401e04c3fSmrg }; 255501e04c3fSmrg } 255601e04c3fSmrg 255701e04c3fSmrg pMemoryProperties->memoryHeapCount = physical_device->memory.heap_count; 255801e04c3fSmrg for (uint32_t i = 0; i < physical_device->memory.heap_count; i++) { 255901e04c3fSmrg pMemoryProperties->memoryHeaps[i] = (VkMemoryHeap) { 256001e04c3fSmrg .size = physical_device->memory.heaps[i].size, 256101e04c3fSmrg .flags = physical_device->memory.heaps[i].flags, 256201e04c3fSmrg }; 256301e04c3fSmrg } 256401e04c3fSmrg} 256501e04c3fSmrg 25669f464c52Smayastatic void 25679f464c52Smayaanv_get_memory_budget(VkPhysicalDevice physicalDevice, 25689f464c52Smaya VkPhysicalDeviceMemoryBudgetPropertiesEXT *memoryBudget) 25699f464c52Smaya{ 25709f464c52Smaya ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice); 25719f464c52Smaya 25727ec681f3Smrg anv_update_meminfo(device, device->local_fd); 25737ec681f3Smrg 25747ec681f3Smrg VkDeviceSize total_sys_heaps_size = 0, total_vram_heaps_size = 0; 25757ec681f3Smrg for (size_t i = 0; i < device->memory.heap_count; i++) { 25767ec681f3Smrg if (device->memory.heaps[i].is_local_mem) { 25777ec681f3Smrg total_vram_heaps_size += device->memory.heaps[i].size; 25787ec681f3Smrg } else { 25797ec681f3Smrg total_sys_heaps_size += device->memory.heaps[i].size; 25807ec681f3Smrg } 25817ec681f3Smrg } 25829f464c52Smaya 25839f464c52Smaya for (size_t i = 0; i < device->memory.heap_count; i++) { 25849f464c52Smaya VkDeviceSize heap_size = device->memory.heaps[i].size; 25859f464c52Smaya VkDeviceSize heap_used = device->memory.heaps[i].used; 25867ec681f3Smrg VkDeviceSize heap_budget, total_heaps_size; 25877ec681f3Smrg uint64_t mem_available = 0; 25887ec681f3Smrg 25897ec681f3Smrg if (device->memory.heaps[i].is_local_mem) { 25907ec681f3Smrg total_heaps_size = total_vram_heaps_size; 25917ec681f3Smrg mem_available = device->vram.available; 25927ec681f3Smrg } else { 25937ec681f3Smrg total_heaps_size = total_sys_heaps_size; 25947ec681f3Smrg mem_available = device->sys.available; 25957ec681f3Smrg } 25969f464c52Smaya 25979f464c52Smaya double heap_proportion = (double) heap_size / total_heaps_size; 25987ec681f3Smrg VkDeviceSize available_prop = mem_available * heap_proportion; 25999f464c52Smaya 26009f464c52Smaya /* 26019f464c52Smaya * Let's not incite the app to starve the system: report at most 90% of 26027ec681f3Smrg * the available heap memory. 26039f464c52Smaya */ 26047ec681f3Smrg uint64_t heap_available = available_prop * 9 / 10; 26059f464c52Smaya heap_budget = MIN2(heap_size, heap_used + heap_available); 26069f464c52Smaya 26079f464c52Smaya /* 26089f464c52Smaya * Round down to the nearest MB 26099f464c52Smaya */ 26109f464c52Smaya heap_budget &= ~((1ull << 20) - 1); 26119f464c52Smaya 26129f464c52Smaya /* 26139f464c52Smaya * The heapBudget value must be non-zero for array elements less than 26149f464c52Smaya * VkPhysicalDeviceMemoryProperties::memoryHeapCount. The heapBudget 26159f464c52Smaya * value must be less than or equal to VkMemoryHeap::size for each heap. 26169f464c52Smaya */ 26179f464c52Smaya assert(0 < heap_budget && heap_budget <= heap_size); 26189f464c52Smaya 26199f464c52Smaya memoryBudget->heapUsage[i] = heap_used; 26209f464c52Smaya memoryBudget->heapBudget[i] = heap_budget; 26219f464c52Smaya } 26229f464c52Smaya 26239f464c52Smaya /* The heapBudget and heapUsage values must be zero for array elements 26249f464c52Smaya * greater than or equal to VkPhysicalDeviceMemoryProperties::memoryHeapCount 26259f464c52Smaya */ 26269f464c52Smaya for (uint32_t i = device->memory.heap_count; i < VK_MAX_MEMORY_HEAPS; i++) { 26279f464c52Smaya memoryBudget->heapBudget[i] = 0; 26289f464c52Smaya memoryBudget->heapUsage[i] = 0; 26299f464c52Smaya } 26309f464c52Smaya} 26319f464c52Smaya 263201e04c3fSmrgvoid anv_GetPhysicalDeviceMemoryProperties2( 263301e04c3fSmrg VkPhysicalDevice physicalDevice, 263401e04c3fSmrg VkPhysicalDeviceMemoryProperties2* pMemoryProperties) 263501e04c3fSmrg{ 263601e04c3fSmrg anv_GetPhysicalDeviceMemoryProperties(physicalDevice, 263701e04c3fSmrg &pMemoryProperties->memoryProperties); 263801e04c3fSmrg 263901e04c3fSmrg vk_foreach_struct(ext, pMemoryProperties->pNext) { 264001e04c3fSmrg switch (ext->sType) { 26419f464c52Smaya case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT: 26429f464c52Smaya anv_get_memory_budget(physicalDevice, (void*)ext); 26439f464c52Smaya break; 264401e04c3fSmrg default: 264501e04c3fSmrg anv_debug_ignored_stype(ext->sType); 264601e04c3fSmrg break; 264701e04c3fSmrg } 264801e04c3fSmrg } 264901e04c3fSmrg} 265001e04c3fSmrg 265101e04c3fSmrgvoid 265201e04c3fSmrganv_GetDeviceGroupPeerMemoryFeatures( 265301e04c3fSmrg VkDevice device, 265401e04c3fSmrg uint32_t heapIndex, 265501e04c3fSmrg uint32_t localDeviceIndex, 265601e04c3fSmrg uint32_t remoteDeviceIndex, 265701e04c3fSmrg VkPeerMemoryFeatureFlags* pPeerMemoryFeatures) 265801e04c3fSmrg{ 265901e04c3fSmrg assert(localDeviceIndex == 0 && remoteDeviceIndex == 0); 266001e04c3fSmrg *pPeerMemoryFeatures = VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT | 266101e04c3fSmrg VK_PEER_MEMORY_FEATURE_COPY_DST_BIT | 266201e04c3fSmrg VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT | 266301e04c3fSmrg VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT; 266401e04c3fSmrg} 266501e04c3fSmrg 266601e04c3fSmrgPFN_vkVoidFunction anv_GetInstanceProcAddr( 266701e04c3fSmrg VkInstance _instance, 266801e04c3fSmrg const char* pName) 266901e04c3fSmrg{ 267001e04c3fSmrg ANV_FROM_HANDLE(anv_instance, instance, _instance); 26717ec681f3Smrg return vk_instance_get_proc_addr(&instance->vk, 26727ec681f3Smrg &anv_instance_entrypoints, 26737ec681f3Smrg pName); 267401e04c3fSmrg} 267501e04c3fSmrg 267601e04c3fSmrg/* With version 1+ of the loader interface the ICD should expose 267701e04c3fSmrg * vk_icdGetInstanceProcAddr to work around certain LD_PRELOAD issues seen in apps. 267801e04c3fSmrg */ 267901e04c3fSmrgPUBLIC 268001e04c3fSmrgVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr( 268101e04c3fSmrg VkInstance instance, 268201e04c3fSmrg const char* pName); 268301e04c3fSmrg 268401e04c3fSmrgPUBLIC 268501e04c3fSmrgVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr( 268601e04c3fSmrg VkInstance instance, 268701e04c3fSmrg const char* pName) 268801e04c3fSmrg{ 268901e04c3fSmrg return anv_GetInstanceProcAddr(instance, pName); 269001e04c3fSmrg} 269101e04c3fSmrg 26927ec681f3Smrg/* With version 4+ of the loader interface the ICD should expose 26937ec681f3Smrg * vk_icdGetPhysicalDeviceProcAddr() 26947ec681f3Smrg */ 26957ec681f3SmrgPUBLIC 26967ec681f3SmrgVKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr( 26977ec681f3Smrg VkInstance _instance, 26987ec681f3Smrg const char* pName); 269901e04c3fSmrg 27007ec681f3SmrgPFN_vkVoidFunction vk_icdGetPhysicalDeviceProcAddr( 27017ec681f3Smrg VkInstance _instance, 27027ec681f3Smrg const char* pName) 270301e04c3fSmrg{ 27047ec681f3Smrg ANV_FROM_HANDLE(anv_instance, instance, _instance); 27057ec681f3Smrg return vk_instance_get_physical_device_proc_addr(&instance->vk, pName); 270601e04c3fSmrg} 270701e04c3fSmrg 270801e04c3fSmrgstatic struct anv_state 270901e04c3fSmrganv_state_pool_emit_data(struct anv_state_pool *pool, size_t size, size_t align, const void *p) 271001e04c3fSmrg{ 271101e04c3fSmrg struct anv_state state; 271201e04c3fSmrg 271301e04c3fSmrg state = anv_state_pool_alloc(pool, size, align); 271401e04c3fSmrg memcpy(state.map, p, size); 271501e04c3fSmrg 271601e04c3fSmrg return state; 271701e04c3fSmrg} 271801e04c3fSmrg 271901e04c3fSmrgstatic void 272001e04c3fSmrganv_device_init_border_colors(struct anv_device *device) 272101e04c3fSmrg{ 27227ec681f3Smrg if (device->info.is_haswell) { 27237ec681f3Smrg static const struct hsw_border_color border_colors[] = { 27247ec681f3Smrg [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] = { .float32 = { 0.0, 0.0, 0.0, 0.0 } }, 27257ec681f3Smrg [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] = { .float32 = { 0.0, 0.0, 0.0, 1.0 } }, 27267ec681f3Smrg [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] = { .float32 = { 1.0, 1.0, 1.0, 1.0 } }, 27277ec681f3Smrg [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] = { .uint32 = { 0, 0, 0, 0 } }, 27287ec681f3Smrg [VK_BORDER_COLOR_INT_OPAQUE_BLACK] = { .uint32 = { 0, 0, 0, 1 } }, 27297ec681f3Smrg [VK_BORDER_COLOR_INT_OPAQUE_WHITE] = { .uint32 = { 1, 1, 1, 1 } }, 27307ec681f3Smrg }; 273101e04c3fSmrg 27327ec681f3Smrg device->border_colors = 27337ec681f3Smrg anv_state_pool_emit_data(&device->dynamic_state_pool, 27347ec681f3Smrg sizeof(border_colors), 512, border_colors); 27357ec681f3Smrg } else { 27367ec681f3Smrg static const struct gfx8_border_color border_colors[] = { 27377ec681f3Smrg [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] = { .float32 = { 0.0, 0.0, 0.0, 0.0 } }, 27387ec681f3Smrg [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] = { .float32 = { 0.0, 0.0, 0.0, 1.0 } }, 27397ec681f3Smrg [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] = { .float32 = { 1.0, 1.0, 1.0, 1.0 } }, 27407ec681f3Smrg [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] = { .uint32 = { 0, 0, 0, 0 } }, 27417ec681f3Smrg [VK_BORDER_COLOR_INT_OPAQUE_BLACK] = { .uint32 = { 0, 0, 0, 1 } }, 27427ec681f3Smrg [VK_BORDER_COLOR_INT_OPAQUE_WHITE] = { .uint32 = { 1, 1, 1, 1 } }, 27437ec681f3Smrg }; 27447ec681f3Smrg 27457ec681f3Smrg device->border_colors = 27467ec681f3Smrg anv_state_pool_emit_data(&device->dynamic_state_pool, 27477ec681f3Smrg sizeof(border_colors), 64, border_colors); 27487ec681f3Smrg } 274901e04c3fSmrg} 275001e04c3fSmrg 27517ec681f3Smrgstatic VkResult 275201e04c3fSmrganv_device_init_trivial_batch(struct anv_device *device) 275301e04c3fSmrg{ 27547ec681f3Smrg VkResult result = anv_device_alloc_bo(device, "trivial-batch", 4096, 27557ec681f3Smrg ANV_BO_ALLOC_MAPPED, 27567ec681f3Smrg 0 /* explicit_address */, 27577ec681f3Smrg &device->trivial_batch_bo); 27587ec681f3Smrg if (result != VK_SUCCESS) 27597ec681f3Smrg return result; 276001e04c3fSmrg 276101e04c3fSmrg struct anv_batch batch = { 27627ec681f3Smrg .start = device->trivial_batch_bo->map, 27637ec681f3Smrg .next = device->trivial_batch_bo->map, 27647ec681f3Smrg .end = device->trivial_batch_bo->map + 4096, 276501e04c3fSmrg }; 276601e04c3fSmrg 27677ec681f3Smrg anv_batch_emit(&batch, GFX7_MI_BATCH_BUFFER_END, bbe); 27687ec681f3Smrg anv_batch_emit(&batch, GFX7_MI_NOOP, noop); 276901e04c3fSmrg 277001e04c3fSmrg if (!device->info.has_llc) 27717ec681f3Smrg intel_clflush_range(batch.start, batch.next - batch.start); 277201e04c3fSmrg 27737ec681f3Smrg return VK_SUCCESS; 277401e04c3fSmrg} 277501e04c3fSmrg 277601e04c3fSmrgstatic int 277701e04c3fSmrgvk_priority_to_gen(int priority) 277801e04c3fSmrg{ 277901e04c3fSmrg switch (priority) { 278001e04c3fSmrg case VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT: 27817ec681f3Smrg return INTEL_CONTEXT_LOW_PRIORITY; 278201e04c3fSmrg case VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT: 27837ec681f3Smrg return INTEL_CONTEXT_MEDIUM_PRIORITY; 278401e04c3fSmrg case VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT: 27857ec681f3Smrg return INTEL_CONTEXT_HIGH_PRIORITY; 278601e04c3fSmrg case VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT: 27877ec681f3Smrg return INTEL_CONTEXT_REALTIME_PRIORITY; 278801e04c3fSmrg default: 278901e04c3fSmrg unreachable("Invalid priority"); 279001e04c3fSmrg } 279101e04c3fSmrg} 279201e04c3fSmrg 27939f464c52Smayastatic bool 27947ec681f3Smrgget_bo_from_pool(struct intel_batch_decode_bo *ret, 27959f464c52Smaya struct anv_block_pool *pool, 27969f464c52Smaya uint64_t address) 27979f464c52Smaya{ 27987ec681f3Smrg anv_block_pool_foreach_bo(bo, pool) { 27997ec681f3Smrg uint64_t bo_address = intel_48b_address(bo->offset); 28007ec681f3Smrg if (address >= bo_address && address < (bo_address + bo->size)) { 28017ec681f3Smrg *ret = (struct intel_batch_decode_bo) { 28029f464c52Smaya .addr = bo_address, 28037ec681f3Smrg .size = bo->size, 28047ec681f3Smrg .map = bo->map, 28059f464c52Smaya }; 28069f464c52Smaya return true; 28079f464c52Smaya } 28089f464c52Smaya } 28099f464c52Smaya return false; 28109f464c52Smaya} 28119f464c52Smaya 28129f464c52Smaya/* Finding a buffer for batch decoding */ 28137ec681f3Smrgstatic struct intel_batch_decode_bo 28149f464c52Smayadecode_get_bo(void *v_batch, bool ppgtt, uint64_t address) 28159f464c52Smaya{ 28169f464c52Smaya struct anv_device *device = v_batch; 28177ec681f3Smrg struct intel_batch_decode_bo ret_bo = {}; 28189f464c52Smaya 28199f464c52Smaya assert(ppgtt); 28209f464c52Smaya 28219f464c52Smaya if (get_bo_from_pool(&ret_bo, &device->dynamic_state_pool.block_pool, address)) 28229f464c52Smaya return ret_bo; 28239f464c52Smaya if (get_bo_from_pool(&ret_bo, &device->instruction_state_pool.block_pool, address)) 28249f464c52Smaya return ret_bo; 28259f464c52Smaya if (get_bo_from_pool(&ret_bo, &device->binding_table_pool.block_pool, address)) 28269f464c52Smaya return ret_bo; 28279f464c52Smaya if (get_bo_from_pool(&ret_bo, &device->surface_state_pool.block_pool, address)) 28289f464c52Smaya return ret_bo; 28299f464c52Smaya 28309f464c52Smaya if (!device->cmd_buffer_being_decoded) 28317ec681f3Smrg return (struct intel_batch_decode_bo) { }; 28329f464c52Smaya 28339f464c52Smaya struct anv_batch_bo **bo; 28349f464c52Smaya 28359f464c52Smaya u_vector_foreach(bo, &device->cmd_buffer_being_decoded->seen_bbos) { 28369f464c52Smaya /* The decoder zeroes out the top 16 bits, so we need to as well */ 28377ec681f3Smrg uint64_t bo_address = (*bo)->bo->offset & (~0ull >> 16); 28389f464c52Smaya 28397ec681f3Smrg if (address >= bo_address && address < bo_address + (*bo)->bo->size) { 28407ec681f3Smrg return (struct intel_batch_decode_bo) { 28419f464c52Smaya .addr = bo_address, 28427ec681f3Smrg .size = (*bo)->bo->size, 28437ec681f3Smrg .map = (*bo)->bo->map, 28449f464c52Smaya }; 28459f464c52Smaya } 28469f464c52Smaya } 28479f464c52Smaya 28487ec681f3Smrg return (struct intel_batch_decode_bo) { }; 28497ec681f3Smrg} 28507ec681f3Smrg 28517ec681f3Smrgstruct intel_aux_map_buffer { 28527ec681f3Smrg struct intel_buffer base; 28537ec681f3Smrg struct anv_state state; 28547ec681f3Smrg}; 28557ec681f3Smrg 28567ec681f3Smrgstatic struct intel_buffer * 28577ec681f3Smrgintel_aux_map_buffer_alloc(void *driver_ctx, uint32_t size) 28587ec681f3Smrg{ 28597ec681f3Smrg struct intel_aux_map_buffer *buf = malloc(sizeof(struct intel_aux_map_buffer)); 28607ec681f3Smrg if (!buf) 28617ec681f3Smrg return NULL; 28627ec681f3Smrg 28637ec681f3Smrg struct anv_device *device = (struct anv_device*)driver_ctx; 28647ec681f3Smrg assert(device->physical->supports_48bit_addresses && 28657ec681f3Smrg device->physical->use_softpin); 28667ec681f3Smrg 28677ec681f3Smrg struct anv_state_pool *pool = &device->dynamic_state_pool; 28687ec681f3Smrg buf->state = anv_state_pool_alloc(pool, size, size); 28697ec681f3Smrg 28707ec681f3Smrg buf->base.gpu = pool->block_pool.bo->offset + buf->state.offset; 28717ec681f3Smrg buf->base.gpu_end = buf->base.gpu + buf->state.alloc_size; 28727ec681f3Smrg buf->base.map = buf->state.map; 28737ec681f3Smrg buf->base.driver_bo = &buf->state; 28747ec681f3Smrg return &buf->base; 28757ec681f3Smrg} 28767ec681f3Smrg 28777ec681f3Smrgstatic void 28787ec681f3Smrgintel_aux_map_buffer_free(void *driver_ctx, struct intel_buffer *buffer) 28797ec681f3Smrg{ 28807ec681f3Smrg struct intel_aux_map_buffer *buf = (struct intel_aux_map_buffer*)buffer; 28817ec681f3Smrg struct anv_device *device = (struct anv_device*)driver_ctx; 28827ec681f3Smrg struct anv_state_pool *pool = &device->dynamic_state_pool; 28837ec681f3Smrg anv_state_pool_free(pool, buf->state); 28847ec681f3Smrg free(buf); 28859f464c52Smaya} 28869f464c52Smaya 28877ec681f3Smrgstatic struct intel_mapped_pinned_buffer_alloc aux_map_allocator = { 28887ec681f3Smrg .alloc = intel_aux_map_buffer_alloc, 28897ec681f3Smrg .free = intel_aux_map_buffer_free, 28907ec681f3Smrg}; 28917ec681f3Smrg 289201e04c3fSmrgVkResult anv_CreateDevice( 289301e04c3fSmrg VkPhysicalDevice physicalDevice, 289401e04c3fSmrg const VkDeviceCreateInfo* pCreateInfo, 289501e04c3fSmrg const VkAllocationCallbacks* pAllocator, 289601e04c3fSmrg VkDevice* pDevice) 289701e04c3fSmrg{ 289801e04c3fSmrg ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice); 289901e04c3fSmrg VkResult result; 290001e04c3fSmrg struct anv_device *device; 290101e04c3fSmrg 290201e04c3fSmrg assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO); 290301e04c3fSmrg 290401e04c3fSmrg /* Check enabled features */ 29057ec681f3Smrg bool robust_buffer_access = false; 290601e04c3fSmrg if (pCreateInfo->pEnabledFeatures) { 29077ec681f3Smrg if (pCreateInfo->pEnabledFeatures->robustBufferAccess) 29087ec681f3Smrg robust_buffer_access = true; 29097ec681f3Smrg } 29107ec681f3Smrg 29117ec681f3Smrg vk_foreach_struct_const(ext, pCreateInfo->pNext) { 29127ec681f3Smrg switch (ext->sType) { 29137ec681f3Smrg case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2: { 29147ec681f3Smrg const VkPhysicalDeviceFeatures2 *features = (const void *)ext; 29157ec681f3Smrg if (features->features.robustBufferAccess) 29167ec681f3Smrg robust_buffer_access = true; 29177ec681f3Smrg break; 29187ec681f3Smrg } 29197ec681f3Smrg 29207ec681f3Smrg default: 29217ec681f3Smrg /* Don't warn */ 29227ec681f3Smrg break; 292301e04c3fSmrg } 292401e04c3fSmrg } 292501e04c3fSmrg 292601e04c3fSmrg /* Check requested queues and fail if we are requested to create any 292701e04c3fSmrg * queues with flags we don't support. 292801e04c3fSmrg */ 292901e04c3fSmrg assert(pCreateInfo->queueCreateInfoCount > 0); 293001e04c3fSmrg for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) { 293101e04c3fSmrg if (pCreateInfo->pQueueCreateInfos[i].flags != 0) 29327ec681f3Smrg return vk_error(physical_device, VK_ERROR_INITIALIZATION_FAILED); 293301e04c3fSmrg } 293401e04c3fSmrg 293501e04c3fSmrg /* Check if client specified queue priority. */ 293601e04c3fSmrg const VkDeviceQueueGlobalPriorityCreateInfoEXT *queue_priority = 293701e04c3fSmrg vk_find_struct_const(pCreateInfo->pQueueCreateInfos[0].pNext, 293801e04c3fSmrg DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT); 293901e04c3fSmrg 294001e04c3fSmrg VkQueueGlobalPriorityEXT priority = 294101e04c3fSmrg queue_priority ? queue_priority->globalPriority : 294201e04c3fSmrg VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT; 294301e04c3fSmrg 29447ec681f3Smrg device = vk_zalloc2(&physical_device->instance->vk.alloc, pAllocator, 294501e04c3fSmrg sizeof(*device), 8, 294601e04c3fSmrg VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); 294701e04c3fSmrg if (!device) 29487ec681f3Smrg return vk_error(physical_device, VK_ERROR_OUT_OF_HOST_MEMORY); 29497ec681f3Smrg 29507ec681f3Smrg struct vk_device_dispatch_table dispatch_table; 29517ec681f3Smrg vk_device_dispatch_table_from_entrypoints(&dispatch_table, 29527ec681f3Smrg anv_genX(&physical_device->info, device_entrypoints), true); 29537ec681f3Smrg vk_device_dispatch_table_from_entrypoints(&dispatch_table, 29547ec681f3Smrg &anv_device_entrypoints, false); 29557ec681f3Smrg vk_device_dispatch_table_from_entrypoints(&dispatch_table, 29567ec681f3Smrg &wsi_device_entrypoints, false); 29577ec681f3Smrg 29587ec681f3Smrg result = vk_device_init(&device->vk, &physical_device->vk, 29597ec681f3Smrg &dispatch_table, pCreateInfo, pAllocator); 29607ec681f3Smrg if (result != VK_SUCCESS) 29617ec681f3Smrg goto fail_alloc; 296201e04c3fSmrg 29637ec681f3Smrg if (INTEL_DEBUG(DEBUG_BATCH)) { 29649f464c52Smaya const unsigned decode_flags = 29657ec681f3Smrg INTEL_BATCH_DECODE_FULL | 29667ec681f3Smrg (INTEL_DEBUG(DEBUG_COLOR) ? INTEL_BATCH_DECODE_IN_COLOR : 0) | 29677ec681f3Smrg INTEL_BATCH_DECODE_OFFSETS | 29687ec681f3Smrg INTEL_BATCH_DECODE_FLOATS; 29697ec681f3Smrg 29707ec681f3Smrg intel_batch_decode_ctx_init(&device->decoder_ctx, 29717ec681f3Smrg &physical_device->info, 29727ec681f3Smrg stderr, decode_flags, NULL, 29737ec681f3Smrg decode_get_bo, NULL, device); 29749f464c52Smaya } 29759f464c52Smaya 29767ec681f3Smrg device->physical = physical_device; 297701e04c3fSmrg device->_lost = false; 297801e04c3fSmrg 297901e04c3fSmrg /* XXX(chadv): Can we dup() physicalDevice->fd here? */ 298001e04c3fSmrg device->fd = open(physical_device->path, O_RDWR | O_CLOEXEC); 298101e04c3fSmrg if (device->fd == -1) { 29827ec681f3Smrg result = vk_error(device, VK_ERROR_INITIALIZATION_FAILED); 298301e04c3fSmrg goto fail_device; 298401e04c3fSmrg } 298501e04c3fSmrg 29867ec681f3Smrg uint32_t num_queues = 0; 29877ec681f3Smrg for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) 29887ec681f3Smrg num_queues += pCreateInfo->pQueueCreateInfos[i].queueCount; 29897ec681f3Smrg 29907ec681f3Smrg if (device->physical->engine_info) { 29917ec681f3Smrg /* The kernel API supports at most 64 engines */ 29927ec681f3Smrg assert(num_queues <= 64); 29937ec681f3Smrg uint16_t engine_classes[64]; 29947ec681f3Smrg int engine_count = 0; 29957ec681f3Smrg for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) { 29967ec681f3Smrg const VkDeviceQueueCreateInfo *queueCreateInfo = 29977ec681f3Smrg &pCreateInfo->pQueueCreateInfos[i]; 29987ec681f3Smrg 29997ec681f3Smrg assert(queueCreateInfo->queueFamilyIndex < 30007ec681f3Smrg physical_device->queue.family_count); 30017ec681f3Smrg struct anv_queue_family *queue_family = 30027ec681f3Smrg &physical_device->queue.families[queueCreateInfo->queueFamilyIndex]; 30037ec681f3Smrg 30047ec681f3Smrg for (uint32_t j = 0; j < queueCreateInfo->queueCount; j++) 30057ec681f3Smrg engine_classes[engine_count++] = queue_family->engine_class; 30067ec681f3Smrg } 30077ec681f3Smrg device->context_id = 30087ec681f3Smrg anv_gem_create_context_engines(device, 30097ec681f3Smrg physical_device->engine_info, 30107ec681f3Smrg engine_count, engine_classes); 30117ec681f3Smrg } else { 30127ec681f3Smrg assert(num_queues == 1); 30137ec681f3Smrg device->context_id = anv_gem_create_context(device); 30147ec681f3Smrg } 301501e04c3fSmrg if (device->context_id == -1) { 30167ec681f3Smrg result = vk_error(device, VK_ERROR_INITIALIZATION_FAILED); 301701e04c3fSmrg goto fail_fd; 301801e04c3fSmrg } 301901e04c3fSmrg 30207ec681f3Smrg /* Here we tell the kernel not to attempt to recover our context but 30217ec681f3Smrg * immediately (on the next batchbuffer submission) report that the 30227ec681f3Smrg * context is lost, and we will do the recovery ourselves. In the case 30237ec681f3Smrg * of Vulkan, recovery means throwing VK_ERROR_DEVICE_LOST and letting 30247ec681f3Smrg * the client clean up the pieces. 30257ec681f3Smrg */ 30267ec681f3Smrg anv_gem_set_context_param(device->fd, device->context_id, 30277ec681f3Smrg I915_CONTEXT_PARAM_RECOVERABLE, false); 30287ec681f3Smrg 30297ec681f3Smrg device->has_thread_submit = physical_device->has_thread_submit; 30307ec681f3Smrg 30317ec681f3Smrg device->queues = 30327ec681f3Smrg vk_zalloc(&device->vk.alloc, num_queues * sizeof(*device->queues), 8, 30337ec681f3Smrg VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); 30347ec681f3Smrg if (device->queues == NULL) { 30357ec681f3Smrg result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 30367ec681f3Smrg goto fail_context_id; 30377ec681f3Smrg } 30387ec681f3Smrg 30397ec681f3Smrg device->queue_count = 0; 30407ec681f3Smrg for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) { 30417ec681f3Smrg const VkDeviceQueueCreateInfo *queueCreateInfo = 30427ec681f3Smrg &pCreateInfo->pQueueCreateInfos[i]; 30437ec681f3Smrg 30447ec681f3Smrg for (uint32_t j = 0; j < queueCreateInfo->queueCount; j++) { 30457ec681f3Smrg /* When using legacy contexts, we use I915_EXEC_RENDER but, with 30467ec681f3Smrg * engine-based contexts, the bottom 6 bits of exec_flags are used 30477ec681f3Smrg * for the engine ID. 30487ec681f3Smrg */ 30497ec681f3Smrg uint32_t exec_flags = device->physical->engine_info ? 30507ec681f3Smrg device->queue_count : I915_EXEC_RENDER; 30517ec681f3Smrg 30527ec681f3Smrg result = anv_queue_init(device, &device->queues[device->queue_count], 30537ec681f3Smrg exec_flags, queueCreateInfo, j); 30547ec681f3Smrg if (result != VK_SUCCESS) 30557ec681f3Smrg goto fail_queues; 30567ec681f3Smrg 30577ec681f3Smrg device->queue_count++; 30587ec681f3Smrg } 30597ec681f3Smrg } 30607ec681f3Smrg 306101e04c3fSmrg if (physical_device->use_softpin) { 306201e04c3fSmrg if (pthread_mutex_init(&device->vma_mutex, NULL) != 0) { 30637ec681f3Smrg result = vk_error(device, VK_ERROR_INITIALIZATION_FAILED); 30647ec681f3Smrg goto fail_queues; 306501e04c3fSmrg } 306601e04c3fSmrg 306701e04c3fSmrg /* keep the page with address zero out of the allocator */ 30687ec681f3Smrg util_vma_heap_init(&device->vma_lo, 30697ec681f3Smrg LOW_HEAP_MIN_ADDRESS, LOW_HEAP_SIZE); 30707ec681f3Smrg 30717ec681f3Smrg util_vma_heap_init(&device->vma_cva, CLIENT_VISIBLE_HEAP_MIN_ADDRESS, 30727ec681f3Smrg CLIENT_VISIBLE_HEAP_SIZE); 30739f464c52Smaya 30747ec681f3Smrg /* Leave the last 4GiB out of the high vma range, so that no state 30757ec681f3Smrg * base address + size can overflow 48 bits. For more information see 30767ec681f3Smrg * the comment about Wa32bitGeneralStateOffset in anv_allocator.c 30777ec681f3Smrg */ 30787ec681f3Smrg util_vma_heap_init(&device->vma_hi, HIGH_HEAP_MIN_ADDRESS, 30797ec681f3Smrg physical_device->gtt_size - (1ull << 32) - 30807ec681f3Smrg HIGH_HEAP_MIN_ADDRESS); 308101e04c3fSmrg } 308201e04c3fSmrg 30839f464c52Smaya list_inithead(&device->memory_objects); 30849f464c52Smaya 308501e04c3fSmrg /* As per spec, the driver implementation may deny requests to acquire 308601e04c3fSmrg * a priority above the default priority (MEDIUM) if the caller does not 308701e04c3fSmrg * have sufficient privileges. In this scenario VK_ERROR_NOT_PERMITTED_EXT 308801e04c3fSmrg * is returned. 308901e04c3fSmrg */ 309001e04c3fSmrg if (physical_device->has_context_priority) { 309101e04c3fSmrg int err = anv_gem_set_context_param(device->fd, device->context_id, 309201e04c3fSmrg I915_CONTEXT_PARAM_PRIORITY, 309301e04c3fSmrg vk_priority_to_gen(priority)); 309401e04c3fSmrg if (err != 0 && priority > VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT) { 30957ec681f3Smrg result = vk_error(device, VK_ERROR_NOT_PERMITTED_EXT); 30967ec681f3Smrg goto fail_vmas; 309701e04c3fSmrg } 309801e04c3fSmrg } 309901e04c3fSmrg 310001e04c3fSmrg device->info = physical_device->info; 310101e04c3fSmrg device->isl_dev = physical_device->isl_dev; 310201e04c3fSmrg 310301e04c3fSmrg /* On Broadwell and later, we can use batch chaining to more efficiently 310401e04c3fSmrg * implement growing command buffers. Prior to Haswell, the kernel 310501e04c3fSmrg * command parser gets in the way and we have to fall back to growing 310601e04c3fSmrg * the batch. 310701e04c3fSmrg */ 31087ec681f3Smrg device->can_chain_batches = device->info.ver >= 8; 310901e04c3fSmrg 31107ec681f3Smrg device->robust_buffer_access = robust_buffer_access; 311101e04c3fSmrg 311201e04c3fSmrg if (pthread_mutex_init(&device->mutex, NULL) != 0) { 31137ec681f3Smrg result = vk_error(device, VK_ERROR_INITIALIZATION_FAILED); 31147ec681f3Smrg goto fail_queues; 311501e04c3fSmrg } 311601e04c3fSmrg 311701e04c3fSmrg pthread_condattr_t condattr; 311801e04c3fSmrg if (pthread_condattr_init(&condattr) != 0) { 31197ec681f3Smrg result = vk_error(device, VK_ERROR_INITIALIZATION_FAILED); 312001e04c3fSmrg goto fail_mutex; 312101e04c3fSmrg } 312201e04c3fSmrg if (pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC) != 0) { 312301e04c3fSmrg pthread_condattr_destroy(&condattr); 31247ec681f3Smrg result = vk_error(device, VK_ERROR_INITIALIZATION_FAILED); 312501e04c3fSmrg goto fail_mutex; 312601e04c3fSmrg } 31279f464c52Smaya if (pthread_cond_init(&device->queue_submit, &condattr) != 0) { 312801e04c3fSmrg pthread_condattr_destroy(&condattr); 31297ec681f3Smrg result = vk_error(device, VK_ERROR_INITIALIZATION_FAILED); 313001e04c3fSmrg goto fail_mutex; 313101e04c3fSmrg } 313201e04c3fSmrg pthread_condattr_destroy(&condattr); 313301e04c3fSmrg 31347ec681f3Smrg result = anv_bo_cache_init(&device->bo_cache, device); 31357ec681f3Smrg if (result != VK_SUCCESS) 31367ec681f3Smrg goto fail_queue_cond; 313701e04c3fSmrg 31387ec681f3Smrg anv_bo_pool_init(&device->batch_bo_pool, device, "batch"); 313901e04c3fSmrg 31407ec681f3Smrg /* Because scratch is also relative to General State Base Address, we leave 31417ec681f3Smrg * the base address 0 and start the pool memory at an offset. This way we 31427ec681f3Smrg * get the correct offsets in the anv_states that get allocated from it. 31437ec681f3Smrg */ 31447ec681f3Smrg result = anv_state_pool_init(&device->general_state_pool, device, 31457ec681f3Smrg "general pool", 31467ec681f3Smrg 0, GENERAL_STATE_POOL_MIN_ADDRESS, 16384); 314701e04c3fSmrg if (result != VK_SUCCESS) 314801e04c3fSmrg goto fail_batch_bo_pool; 314901e04c3fSmrg 315001e04c3fSmrg result = anv_state_pool_init(&device->dynamic_state_pool, device, 31517ec681f3Smrg "dynamic pool", 31527ec681f3Smrg DYNAMIC_STATE_POOL_MIN_ADDRESS, 0, 16384); 315301e04c3fSmrg if (result != VK_SUCCESS) 31547ec681f3Smrg goto fail_general_state_pool; 31557ec681f3Smrg 31567ec681f3Smrg if (device->info.ver >= 8) { 31577ec681f3Smrg /* The border color pointer is limited to 24 bits, so we need to make 31587ec681f3Smrg * sure that any such color used at any point in the program doesn't 31597ec681f3Smrg * exceed that limit. 31607ec681f3Smrg * We achieve that by reserving all the custom border colors we support 31617ec681f3Smrg * right off the bat, so they are close to the base address. 31627ec681f3Smrg */ 31637ec681f3Smrg anv_state_reserved_pool_init(&device->custom_border_colors, 31647ec681f3Smrg &device->dynamic_state_pool, 31657ec681f3Smrg MAX_CUSTOM_BORDER_COLORS, 31667ec681f3Smrg sizeof(struct gfx8_border_color), 64); 31677ec681f3Smrg } 316801e04c3fSmrg 316901e04c3fSmrg result = anv_state_pool_init(&device->instruction_state_pool, device, 31707ec681f3Smrg "instruction pool", 31717ec681f3Smrg INSTRUCTION_STATE_POOL_MIN_ADDRESS, 0, 16384); 317201e04c3fSmrg if (result != VK_SUCCESS) 317301e04c3fSmrg goto fail_dynamic_state_pool; 317401e04c3fSmrg 317501e04c3fSmrg result = anv_state_pool_init(&device->surface_state_pool, device, 31767ec681f3Smrg "surface state pool", 31777ec681f3Smrg SURFACE_STATE_POOL_MIN_ADDRESS, 0, 4096); 317801e04c3fSmrg if (result != VK_SUCCESS) 317901e04c3fSmrg goto fail_instruction_state_pool; 318001e04c3fSmrg 318101e04c3fSmrg if (physical_device->use_softpin) { 31827ec681f3Smrg int64_t bt_pool_offset = (int64_t)BINDING_TABLE_POOL_MIN_ADDRESS - 31837ec681f3Smrg (int64_t)SURFACE_STATE_POOL_MIN_ADDRESS; 31847ec681f3Smrg assert(INT32_MIN < bt_pool_offset && bt_pool_offset < 0); 318501e04c3fSmrg result = anv_state_pool_init(&device->binding_table_pool, device, 31867ec681f3Smrg "binding table pool", 31877ec681f3Smrg SURFACE_STATE_POOL_MIN_ADDRESS, 31887ec681f3Smrg bt_pool_offset, 4096); 318901e04c3fSmrg if (result != VK_SUCCESS) 319001e04c3fSmrg goto fail_surface_state_pool; 319101e04c3fSmrg } 319201e04c3fSmrg 31937ec681f3Smrg if (device->info.has_aux_map) { 31947ec681f3Smrg device->aux_map_ctx = intel_aux_map_init(device, &aux_map_allocator, 31957ec681f3Smrg &physical_device->info); 31967ec681f3Smrg if (!device->aux_map_ctx) 31977ec681f3Smrg goto fail_binding_table_pool; 31987ec681f3Smrg } 31997ec681f3Smrg 32007ec681f3Smrg result = anv_device_alloc_bo(device, "workaround", 4096, 32017ec681f3Smrg ANV_BO_ALLOC_CAPTURE | 32027ec681f3Smrg ANV_BO_ALLOC_MAPPED | 32037ec681f3Smrg ANV_BO_ALLOC_LOCAL_MEM, 32047ec681f3Smrg 0 /* explicit_address */, 32057ec681f3Smrg &device->workaround_bo); 320601e04c3fSmrg if (result != VK_SUCCESS) 32077ec681f3Smrg goto fail_surface_aux_map_pool; 32087ec681f3Smrg 32097ec681f3Smrg device->workaround_address = (struct anv_address) { 32107ec681f3Smrg .bo = device->workaround_bo, 32117ec681f3Smrg .offset = align_u32( 32127ec681f3Smrg intel_debug_write_identifiers(device->workaround_bo->map, 32137ec681f3Smrg device->workaround_bo->size, 32147ec681f3Smrg "Anv") + 8, 8), 32157ec681f3Smrg }; 321601e04c3fSmrg 32177ec681f3Smrg device->debug_frame_desc = 32187ec681f3Smrg intel_debug_get_identifier_block(device->workaround_bo->map, 32197ec681f3Smrg device->workaround_bo->size, 32207ec681f3Smrg INTEL_DEBUG_BLOCK_TYPE_FRAME); 322101e04c3fSmrg 32227ec681f3Smrg result = anv_device_init_trivial_batch(device); 32237ec681f3Smrg if (result != VK_SUCCESS) 322401e04c3fSmrg goto fail_workaround_bo; 322501e04c3fSmrg 32267ec681f3Smrg /* Allocate a null surface state at surface state offset 0. This makes 32277ec681f3Smrg * NULL descriptor handling trivial because we can just memset structures 32287ec681f3Smrg * to zero and they have a valid descriptor. 32297ec681f3Smrg */ 32307ec681f3Smrg device->null_surface_state = 32317ec681f3Smrg anv_state_pool_alloc(&device->surface_state_pool, 32327ec681f3Smrg device->isl_dev.ss.size, 32337ec681f3Smrg device->isl_dev.ss.align); 32347ec681f3Smrg isl_null_fill_state(&device->isl_dev, device->null_surface_state.map, 32357ec681f3Smrg .size = isl_extent3d(1, 1, 1) /* This shouldn't matter */); 32367ec681f3Smrg assert(device->null_surface_state.offset == 0); 323701e04c3fSmrg 323801e04c3fSmrg anv_scratch_pool_init(device, &device->scratch_pool); 323901e04c3fSmrg 32407ec681f3Smrg /* TODO(RT): Do we want some sort of data structure for this? */ 32417ec681f3Smrg memset(device->rt_scratch_bos, 0, sizeof(device->rt_scratch_bos)); 32427ec681f3Smrg 32437ec681f3Smrg result = anv_genX(&device->info, init_device_state)(device); 324401e04c3fSmrg if (result != VK_SUCCESS) 32457ec681f3Smrg goto fail_trivial_batch_bo_and_scratch_pool; 32467ec681f3Smrg 32477ec681f3Smrg anv_pipeline_cache_init(&device->default_pipeline_cache, device, 32487ec681f3Smrg true /* cache_enabled */, false /* external_sync */); 324901e04c3fSmrg 32507ec681f3Smrg result = anv_device_init_rt_shaders(device); 32517ec681f3Smrg if (result != VK_SUCCESS) 32527ec681f3Smrg goto fail_rt_trampoline; 325301e04c3fSmrg 325401e04c3fSmrg anv_device_init_blorp(device); 325501e04c3fSmrg 325601e04c3fSmrg anv_device_init_border_colors(device); 325701e04c3fSmrg 32587ec681f3Smrg anv_device_perf_init(device); 32597ec681f3Smrg 326001e04c3fSmrg *pDevice = anv_device_to_handle(device); 326101e04c3fSmrg 326201e04c3fSmrg return VK_SUCCESS; 326301e04c3fSmrg 32647ec681f3Smrg fail_rt_trampoline: 32657ec681f3Smrg anv_pipeline_cache_finish(&device->default_pipeline_cache); 32667ec681f3Smrg fail_trivial_batch_bo_and_scratch_pool: 326701e04c3fSmrg anv_scratch_pool_finish(device, &device->scratch_pool); 32687ec681f3Smrg anv_device_release_bo(device, device->trivial_batch_bo); 32697ec681f3Smrg fail_workaround_bo: 32707ec681f3Smrg anv_device_release_bo(device, device->workaround_bo); 32717ec681f3Smrg fail_surface_aux_map_pool: 32727ec681f3Smrg if (device->info.has_aux_map) { 32737ec681f3Smrg intel_aux_map_finish(device->aux_map_ctx); 32747ec681f3Smrg device->aux_map_ctx = NULL; 32757ec681f3Smrg } 327601e04c3fSmrg fail_binding_table_pool: 327701e04c3fSmrg if (physical_device->use_softpin) 327801e04c3fSmrg anv_state_pool_finish(&device->binding_table_pool); 327901e04c3fSmrg fail_surface_state_pool: 328001e04c3fSmrg anv_state_pool_finish(&device->surface_state_pool); 328101e04c3fSmrg fail_instruction_state_pool: 328201e04c3fSmrg anv_state_pool_finish(&device->instruction_state_pool); 328301e04c3fSmrg fail_dynamic_state_pool: 32847ec681f3Smrg if (device->info.ver >= 8) 32857ec681f3Smrg anv_state_reserved_pool_finish(&device->custom_border_colors); 328601e04c3fSmrg anv_state_pool_finish(&device->dynamic_state_pool); 32877ec681f3Smrg fail_general_state_pool: 32887ec681f3Smrg anv_state_pool_finish(&device->general_state_pool); 328901e04c3fSmrg fail_batch_bo_pool: 329001e04c3fSmrg anv_bo_pool_finish(&device->batch_bo_pool); 32917ec681f3Smrg anv_bo_cache_finish(&device->bo_cache); 32927ec681f3Smrg fail_queue_cond: 329301e04c3fSmrg pthread_cond_destroy(&device->queue_submit); 329401e04c3fSmrg fail_mutex: 329501e04c3fSmrg pthread_mutex_destroy(&device->mutex); 32967ec681f3Smrg fail_vmas: 32977ec681f3Smrg if (physical_device->use_softpin) { 32987ec681f3Smrg util_vma_heap_finish(&device->vma_hi); 32997ec681f3Smrg util_vma_heap_finish(&device->vma_cva); 33007ec681f3Smrg util_vma_heap_finish(&device->vma_lo); 33017ec681f3Smrg } 33027ec681f3Smrg fail_queues: 33037ec681f3Smrg for (uint32_t i = 0; i < device->queue_count; i++) 33047ec681f3Smrg anv_queue_finish(&device->queues[i]); 33057ec681f3Smrg vk_free(&device->vk.alloc, device->queues); 330601e04c3fSmrg fail_context_id: 330701e04c3fSmrg anv_gem_destroy_context(device, device->context_id); 330801e04c3fSmrg fail_fd: 330901e04c3fSmrg close(device->fd); 331001e04c3fSmrg fail_device: 33117ec681f3Smrg vk_device_finish(&device->vk); 33127ec681f3Smrg fail_alloc: 33137ec681f3Smrg vk_free(&device->vk.alloc, device); 331401e04c3fSmrg 331501e04c3fSmrg return result; 331601e04c3fSmrg} 331701e04c3fSmrg 331801e04c3fSmrgvoid anv_DestroyDevice( 331901e04c3fSmrg VkDevice _device, 332001e04c3fSmrg const VkAllocationCallbacks* pAllocator) 332101e04c3fSmrg{ 332201e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 332301e04c3fSmrg 332401e04c3fSmrg if (!device) 332501e04c3fSmrg return; 332601e04c3fSmrg 332701e04c3fSmrg anv_device_finish_blorp(device); 332801e04c3fSmrg 33297ec681f3Smrg anv_device_finish_rt_shaders(device); 333001e04c3fSmrg 33317ec681f3Smrg anv_pipeline_cache_finish(&device->default_pipeline_cache); 333201e04c3fSmrg 333301e04c3fSmrg#ifdef HAVE_VALGRIND 333401e04c3fSmrg /* We only need to free these to prevent valgrind errors. The backing 333501e04c3fSmrg * BO will go away in a couple of lines so we don't actually leak. 333601e04c3fSmrg */ 33377ec681f3Smrg if (device->info.ver >= 8) 33387ec681f3Smrg anv_state_reserved_pool_finish(&device->custom_border_colors); 333901e04c3fSmrg anv_state_pool_free(&device->dynamic_state_pool, device->border_colors); 33407ec681f3Smrg anv_state_pool_free(&device->dynamic_state_pool, device->slice_hash); 334101e04c3fSmrg#endif 334201e04c3fSmrg 33437ec681f3Smrg for (unsigned i = 0; i < ARRAY_SIZE(device->rt_scratch_bos); i++) { 33447ec681f3Smrg if (device->rt_scratch_bos[i] != NULL) 33457ec681f3Smrg anv_device_release_bo(device, device->rt_scratch_bos[i]); 33467ec681f3Smrg } 33477ec681f3Smrg 334801e04c3fSmrg anv_scratch_pool_finish(device, &device->scratch_pool); 334901e04c3fSmrg 33507ec681f3Smrg anv_device_release_bo(device, device->workaround_bo); 33517ec681f3Smrg anv_device_release_bo(device, device->trivial_batch_bo); 335201e04c3fSmrg 33537ec681f3Smrg if (device->info.has_aux_map) { 33547ec681f3Smrg intel_aux_map_finish(device->aux_map_ctx); 33557ec681f3Smrg device->aux_map_ctx = NULL; 33567ec681f3Smrg } 335701e04c3fSmrg 33587ec681f3Smrg if (device->physical->use_softpin) 335901e04c3fSmrg anv_state_pool_finish(&device->binding_table_pool); 336001e04c3fSmrg anv_state_pool_finish(&device->surface_state_pool); 336101e04c3fSmrg anv_state_pool_finish(&device->instruction_state_pool); 336201e04c3fSmrg anv_state_pool_finish(&device->dynamic_state_pool); 33637ec681f3Smrg anv_state_pool_finish(&device->general_state_pool); 33647ec681f3Smrg 33657ec681f3Smrg anv_bo_pool_finish(&device->batch_bo_pool); 336601e04c3fSmrg 336701e04c3fSmrg anv_bo_cache_finish(&device->bo_cache); 336801e04c3fSmrg 33697ec681f3Smrg if (device->physical->use_softpin) { 33707ec681f3Smrg util_vma_heap_finish(&device->vma_hi); 33717ec681f3Smrg util_vma_heap_finish(&device->vma_cva); 33727ec681f3Smrg util_vma_heap_finish(&device->vma_lo); 33737ec681f3Smrg } 337401e04c3fSmrg 337501e04c3fSmrg pthread_cond_destroy(&device->queue_submit); 337601e04c3fSmrg pthread_mutex_destroy(&device->mutex); 337701e04c3fSmrg 33787ec681f3Smrg for (uint32_t i = 0; i < device->queue_count; i++) 33797ec681f3Smrg anv_queue_finish(&device->queues[i]); 33807ec681f3Smrg vk_free(&device->vk.alloc, device->queues); 33817ec681f3Smrg 338201e04c3fSmrg anv_gem_destroy_context(device, device->context_id); 338301e04c3fSmrg 33847ec681f3Smrg if (INTEL_DEBUG(DEBUG_BATCH)) 33857ec681f3Smrg intel_batch_decode_ctx_finish(&device->decoder_ctx); 33869f464c52Smaya 338701e04c3fSmrg close(device->fd); 338801e04c3fSmrg 33897ec681f3Smrg vk_device_finish(&device->vk); 33907ec681f3Smrg vk_free(&device->vk.alloc, device); 339101e04c3fSmrg} 339201e04c3fSmrg 339301e04c3fSmrgVkResult anv_EnumerateInstanceLayerProperties( 339401e04c3fSmrg uint32_t* pPropertyCount, 339501e04c3fSmrg VkLayerProperties* pProperties) 339601e04c3fSmrg{ 339701e04c3fSmrg if (pProperties == NULL) { 339801e04c3fSmrg *pPropertyCount = 0; 339901e04c3fSmrg return VK_SUCCESS; 340001e04c3fSmrg } 340101e04c3fSmrg 340201e04c3fSmrg /* None supported at this time */ 34037ec681f3Smrg return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT); 340401e04c3fSmrg} 340501e04c3fSmrg 34067ec681f3Smrgvoid 34077ec681f3Smrg_anv_device_report_lost(struct anv_device *device) 340801e04c3fSmrg{ 34097ec681f3Smrg assert(p_atomic_read(&device->_lost) > 0); 341001e04c3fSmrg 34117ec681f3Smrg device->lost_reported = true; 34127ec681f3Smrg 34137ec681f3Smrg for (uint32_t i = 0; i < device->queue_count; i++) { 34147ec681f3Smrg struct anv_queue *queue = &device->queues[i]; 34157ec681f3Smrg if (queue->lost) { 34167ec681f3Smrg __vk_errorf(queue, VK_ERROR_DEVICE_LOST, 34177ec681f3Smrg queue->error_file, queue->error_line, 34187ec681f3Smrg "%s", queue->error_msg); 34197ec681f3Smrg } 34207ec681f3Smrg } 342101e04c3fSmrg} 342201e04c3fSmrg 34237ec681f3SmrgVkResult 34247ec681f3Smrg_anv_device_set_lost(struct anv_device *device, 34257ec681f3Smrg const char *file, int line, 34267ec681f3Smrg const char *msg, ...) 342701e04c3fSmrg{ 34287ec681f3Smrg VkResult err; 34297ec681f3Smrg va_list ap; 343001e04c3fSmrg 34317ec681f3Smrg if (p_atomic_read(&device->_lost) > 0) 34327ec681f3Smrg return VK_ERROR_DEVICE_LOST; 343301e04c3fSmrg 34347ec681f3Smrg p_atomic_inc(&device->_lost); 34357ec681f3Smrg device->lost_reported = true; 343601e04c3fSmrg 34377ec681f3Smrg va_start(ap, msg); 34387ec681f3Smrg err = __vk_errorv(device, VK_ERROR_DEVICE_LOST, file, line, msg, ap); 34397ec681f3Smrg va_end(ap); 344001e04c3fSmrg 34417ec681f3Smrg if (env_var_as_boolean("ANV_ABORT_ON_DEVICE_LOSS", false)) 34427ec681f3Smrg abort(); 344301e04c3fSmrg 34447ec681f3Smrg return err; 344501e04c3fSmrg} 344601e04c3fSmrg 344701e04c3fSmrgVkResult 34487ec681f3Smrg_anv_queue_set_lost(struct anv_queue *queue, 344901e04c3fSmrg const char *file, int line, 345001e04c3fSmrg const char *msg, ...) 345101e04c3fSmrg{ 345201e04c3fSmrg va_list ap; 345301e04c3fSmrg 34547ec681f3Smrg if (queue->lost) 34557ec681f3Smrg return VK_ERROR_DEVICE_LOST; 34567ec681f3Smrg 34577ec681f3Smrg queue->lost = true; 345801e04c3fSmrg 34597ec681f3Smrg queue->error_file = file; 34607ec681f3Smrg queue->error_line = line; 346101e04c3fSmrg va_start(ap, msg); 34627ec681f3Smrg vsnprintf(queue->error_msg, sizeof(queue->error_msg), 34637ec681f3Smrg msg, ap); 346401e04c3fSmrg va_end(ap); 346501e04c3fSmrg 34667ec681f3Smrg p_atomic_inc(&queue->device->_lost); 34677ec681f3Smrg 346801e04c3fSmrg if (env_var_as_boolean("ANV_ABORT_ON_DEVICE_LOSS", false)) 346901e04c3fSmrg abort(); 347001e04c3fSmrg 34717ec681f3Smrg return VK_ERROR_DEVICE_LOST; 347201e04c3fSmrg} 347301e04c3fSmrg 347401e04c3fSmrgVkResult 347501e04c3fSmrganv_device_query_status(struct anv_device *device) 347601e04c3fSmrg{ 347701e04c3fSmrg /* This isn't likely as most of the callers of this function already check 347801e04c3fSmrg * for it. However, it doesn't hurt to check and it potentially lets us 347901e04c3fSmrg * avoid an ioctl. 348001e04c3fSmrg */ 348101e04c3fSmrg if (anv_device_is_lost(device)) 348201e04c3fSmrg return VK_ERROR_DEVICE_LOST; 348301e04c3fSmrg 348401e04c3fSmrg uint32_t active, pending; 34857ec681f3Smrg int ret = anv_gem_context_get_reset_stats(device->fd, device->context_id, 34867ec681f3Smrg &active, &pending); 348701e04c3fSmrg if (ret == -1) { 348801e04c3fSmrg /* We don't know the real error. */ 348901e04c3fSmrg return anv_device_set_lost(device, "get_reset_stats failed: %m"); 349001e04c3fSmrg } 349101e04c3fSmrg 349201e04c3fSmrg if (active) { 349301e04c3fSmrg return anv_device_set_lost(device, "GPU hung on one of our command buffers"); 349401e04c3fSmrg } else if (pending) { 349501e04c3fSmrg return anv_device_set_lost(device, "GPU hung with commands in-flight"); 349601e04c3fSmrg } 349701e04c3fSmrg 349801e04c3fSmrg return VK_SUCCESS; 349901e04c3fSmrg} 350001e04c3fSmrg 350101e04c3fSmrgVkResult 350201e04c3fSmrganv_device_bo_busy(struct anv_device *device, struct anv_bo *bo) 350301e04c3fSmrg{ 350401e04c3fSmrg /* Note: This only returns whether or not the BO is in use by an i915 GPU. 350501e04c3fSmrg * Other usages of the BO (such as on different hardware) will not be 350601e04c3fSmrg * flagged as "busy" by this ioctl. Use with care. 350701e04c3fSmrg */ 350801e04c3fSmrg int ret = anv_gem_busy(device, bo->gem_handle); 350901e04c3fSmrg if (ret == 1) { 351001e04c3fSmrg return VK_NOT_READY; 351101e04c3fSmrg } else if (ret == -1) { 351201e04c3fSmrg /* We don't know the real error. */ 351301e04c3fSmrg return anv_device_set_lost(device, "gem wait failed: %m"); 351401e04c3fSmrg } 351501e04c3fSmrg 351601e04c3fSmrg /* Query for device status after the busy call. If the BO we're checking 351701e04c3fSmrg * got caught in a GPU hang we don't want to return VK_SUCCESS to the 351801e04c3fSmrg * client because it clearly doesn't have valid data. Yes, this most 351901e04c3fSmrg * likely means an ioctl, but we just did an ioctl to query the busy status 352001e04c3fSmrg * so it's no great loss. 352101e04c3fSmrg */ 352201e04c3fSmrg return anv_device_query_status(device); 352301e04c3fSmrg} 352401e04c3fSmrg 352501e04c3fSmrgVkResult 352601e04c3fSmrganv_device_wait(struct anv_device *device, struct anv_bo *bo, 352701e04c3fSmrg int64_t timeout) 352801e04c3fSmrg{ 352901e04c3fSmrg int ret = anv_gem_wait(device, bo->gem_handle, &timeout); 353001e04c3fSmrg if (ret == -1 && errno == ETIME) { 353101e04c3fSmrg return VK_TIMEOUT; 353201e04c3fSmrg } else if (ret == -1) { 353301e04c3fSmrg /* We don't know the real error. */ 353401e04c3fSmrg return anv_device_set_lost(device, "gem wait failed: %m"); 353501e04c3fSmrg } 353601e04c3fSmrg 353701e04c3fSmrg /* Query for device status after the wait. If the BO we're waiting on got 353801e04c3fSmrg * caught in a GPU hang we don't want to return VK_SUCCESS to the client 353901e04c3fSmrg * because it clearly doesn't have valid data. Yes, this most likely means 354001e04c3fSmrg * an ioctl, but we just did an ioctl to wait so it's no great loss. 354101e04c3fSmrg */ 354201e04c3fSmrg return anv_device_query_status(device); 354301e04c3fSmrg} 354401e04c3fSmrg 35457ec681f3Smrguint64_t 35467ec681f3Smrganv_vma_alloc(struct anv_device *device, 35477ec681f3Smrg uint64_t size, uint64_t align, 35487ec681f3Smrg enum anv_bo_alloc_flags alloc_flags, 35497ec681f3Smrg uint64_t client_address) 355001e04c3fSmrg{ 355101e04c3fSmrg pthread_mutex_lock(&device->vma_mutex); 355201e04c3fSmrg 35537ec681f3Smrg uint64_t addr = 0; 355401e04c3fSmrg 35557ec681f3Smrg if (alloc_flags & ANV_BO_ALLOC_CLIENT_VISIBLE_ADDRESS) { 35567ec681f3Smrg if (client_address) { 35577ec681f3Smrg if (util_vma_heap_alloc_addr(&device->vma_cva, 35587ec681f3Smrg client_address, size)) { 35597ec681f3Smrg addr = client_address; 35607ec681f3Smrg } 35617ec681f3Smrg } else { 35627ec681f3Smrg addr = util_vma_heap_alloc(&device->vma_cva, size, align); 356301e04c3fSmrg } 35647ec681f3Smrg /* We don't want to fall back to other heaps */ 35657ec681f3Smrg goto done; 356601e04c3fSmrg } 356701e04c3fSmrg 35687ec681f3Smrg assert(client_address == 0); 35697ec681f3Smrg 35707ec681f3Smrg if (!(alloc_flags & ANV_BO_ALLOC_32BIT_ADDRESS)) 35717ec681f3Smrg addr = util_vma_heap_alloc(&device->vma_hi, size, align); 35727ec681f3Smrg 35737ec681f3Smrg if (addr == 0) 35747ec681f3Smrg addr = util_vma_heap_alloc(&device->vma_lo, size, align); 357501e04c3fSmrg 35767ec681f3Smrgdone: 357701e04c3fSmrg pthread_mutex_unlock(&device->vma_mutex); 357801e04c3fSmrg 35797ec681f3Smrg assert(addr == intel_48b_address(addr)); 35807ec681f3Smrg return intel_canonical_address(addr); 358101e04c3fSmrg} 358201e04c3fSmrg 358301e04c3fSmrgvoid 35847ec681f3Smrganv_vma_free(struct anv_device *device, 35857ec681f3Smrg uint64_t address, uint64_t size) 358601e04c3fSmrg{ 35877ec681f3Smrg const uint64_t addr_48b = intel_48b_address(address); 358801e04c3fSmrg 358901e04c3fSmrg pthread_mutex_lock(&device->vma_mutex); 359001e04c3fSmrg 359101e04c3fSmrg if (addr_48b >= LOW_HEAP_MIN_ADDRESS && 359201e04c3fSmrg addr_48b <= LOW_HEAP_MAX_ADDRESS) { 35937ec681f3Smrg util_vma_heap_free(&device->vma_lo, addr_48b, size); 35947ec681f3Smrg } else if (addr_48b >= CLIENT_VISIBLE_HEAP_MIN_ADDRESS && 35957ec681f3Smrg addr_48b <= CLIENT_VISIBLE_HEAP_MAX_ADDRESS) { 35967ec681f3Smrg util_vma_heap_free(&device->vma_cva, addr_48b, size); 359701e04c3fSmrg } else { 35987ec681f3Smrg assert(addr_48b >= HIGH_HEAP_MIN_ADDRESS); 35997ec681f3Smrg util_vma_heap_free(&device->vma_hi, addr_48b, size); 360001e04c3fSmrg } 360101e04c3fSmrg 360201e04c3fSmrg pthread_mutex_unlock(&device->vma_mutex); 360301e04c3fSmrg} 360401e04c3fSmrg 360501e04c3fSmrgVkResult anv_AllocateMemory( 360601e04c3fSmrg VkDevice _device, 360701e04c3fSmrg const VkMemoryAllocateInfo* pAllocateInfo, 360801e04c3fSmrg const VkAllocationCallbacks* pAllocator, 360901e04c3fSmrg VkDeviceMemory* pMem) 361001e04c3fSmrg{ 361101e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 36127ec681f3Smrg struct anv_physical_device *pdevice = device->physical; 361301e04c3fSmrg struct anv_device_memory *mem; 361401e04c3fSmrg VkResult result = VK_SUCCESS; 361501e04c3fSmrg 361601e04c3fSmrg assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO); 361701e04c3fSmrg 361801e04c3fSmrg /* The Vulkan 1.0.33 spec says "allocationSize must be greater than 0". */ 361901e04c3fSmrg assert(pAllocateInfo->allocationSize > 0); 362001e04c3fSmrg 36217ec681f3Smrg VkDeviceSize aligned_alloc_size = 36227ec681f3Smrg align_u64(pAllocateInfo->allocationSize, 4096); 362301e04c3fSmrg 36247ec681f3Smrg if (aligned_alloc_size > MAX_MEMORY_ALLOCATION_SIZE) 36257ec681f3Smrg return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY); 362601e04c3fSmrg 36277ec681f3Smrg assert(pAllocateInfo->memoryTypeIndex < pdevice->memory.type_count); 36287ec681f3Smrg struct anv_memory_type *mem_type = 36297ec681f3Smrg &pdevice->memory.types[pAllocateInfo->memoryTypeIndex]; 36307ec681f3Smrg assert(mem_type->heapIndex < pdevice->memory.heap_count); 36317ec681f3Smrg struct anv_memory_heap *mem_heap = 36327ec681f3Smrg &pdevice->memory.heaps[mem_type->heapIndex]; 36337ec681f3Smrg 36347ec681f3Smrg uint64_t mem_heap_used = p_atomic_read(&mem_heap->used); 36357ec681f3Smrg if (mem_heap_used + aligned_alloc_size > mem_heap->size) 36367ec681f3Smrg return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY); 36377ec681f3Smrg 36387ec681f3Smrg mem = vk_object_alloc(&device->vk, pAllocator, sizeof(*mem), 36397ec681f3Smrg VK_OBJECT_TYPE_DEVICE_MEMORY); 364001e04c3fSmrg if (mem == NULL) 36417ec681f3Smrg return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 364201e04c3fSmrg 36437ec681f3Smrg mem->type = mem_type; 364401e04c3fSmrg mem->map = NULL; 364501e04c3fSmrg mem->map_size = 0; 36469f464c52Smaya mem->ahw = NULL; 36479f464c52Smaya mem->host_ptr = NULL; 364801e04c3fSmrg 36497ec681f3Smrg enum anv_bo_alloc_flags alloc_flags = 0; 365001e04c3fSmrg 36517ec681f3Smrg const VkExportMemoryAllocateInfo *export_info = NULL; 36527ec681f3Smrg const VkImportAndroidHardwareBufferInfoANDROID *ahw_import_info = NULL; 36537ec681f3Smrg const VkImportMemoryFdInfoKHR *fd_info = NULL; 36547ec681f3Smrg const VkImportMemoryHostPointerInfoEXT *host_ptr_info = NULL; 36557ec681f3Smrg const VkMemoryDedicatedAllocateInfo *dedicated_info = NULL; 36567ec681f3Smrg VkMemoryAllocateFlags vk_flags = 0; 36577ec681f3Smrg uint64_t client_address = 0; 365801e04c3fSmrg 36597ec681f3Smrg vk_foreach_struct_const(ext, pAllocateInfo->pNext) { 36607ec681f3Smrg switch (ext->sType) { 36617ec681f3Smrg case VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO: 36627ec681f3Smrg export_info = (void *)ext; 36637ec681f3Smrg break; 36647ec681f3Smrg 36657ec681f3Smrg case VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID: 36667ec681f3Smrg ahw_import_info = (void *)ext; 36677ec681f3Smrg break; 36687ec681f3Smrg 36697ec681f3Smrg case VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR: 36707ec681f3Smrg fd_info = (void *)ext; 36717ec681f3Smrg break; 36727ec681f3Smrg 36737ec681f3Smrg case VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT: 36747ec681f3Smrg host_ptr_info = (void *)ext; 36757ec681f3Smrg break; 36767ec681f3Smrg 36777ec681f3Smrg case VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO: { 36787ec681f3Smrg const VkMemoryAllocateFlagsInfo *flags_info = (void *)ext; 36797ec681f3Smrg vk_flags = flags_info->flags; 36807ec681f3Smrg break; 36817ec681f3Smrg } 36827ec681f3Smrg 36837ec681f3Smrg case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO: 36847ec681f3Smrg dedicated_info = (void *)ext; 36857ec681f3Smrg break; 36867ec681f3Smrg 36877ec681f3Smrg case VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR: { 36887ec681f3Smrg const VkMemoryOpaqueCaptureAddressAllocateInfoKHR *addr_info = 36897ec681f3Smrg (const VkMemoryOpaqueCaptureAddressAllocateInfoKHR *)ext; 36907ec681f3Smrg client_address = addr_info->opaqueCaptureAddress; 36917ec681f3Smrg break; 36927ec681f3Smrg } 36937ec681f3Smrg 36947ec681f3Smrg default: 36957ec681f3Smrg anv_debug_ignored_stype(ext->sType); 36967ec681f3Smrg break; 36977ec681f3Smrg } 369801e04c3fSmrg } 369901e04c3fSmrg 37007ec681f3Smrg /* By default, we want all VkDeviceMemory objects to support CCS */ 37017ec681f3Smrg if (device->physical->has_implicit_ccs) 37027ec681f3Smrg alloc_flags |= ANV_BO_ALLOC_IMPLICIT_CCS; 37037ec681f3Smrg 37047ec681f3Smrg if (vk_flags & VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR) 37057ec681f3Smrg alloc_flags |= ANV_BO_ALLOC_CLIENT_VISIBLE_ADDRESS; 37067ec681f3Smrg 37077ec681f3Smrg if ((export_info && export_info->handleTypes) || 37087ec681f3Smrg (fd_info && fd_info->handleType) || 37097ec681f3Smrg (host_ptr_info && host_ptr_info->handleType)) { 37107ec681f3Smrg /* Anything imported or exported is EXTERNAL */ 37117ec681f3Smrg alloc_flags |= ANV_BO_ALLOC_EXTERNAL; 371201e04c3fSmrg 37137ec681f3Smrg /* We can't have implicit CCS on external memory with an AUX-table. 37147ec681f3Smrg * Doing so would require us to sync the aux tables across processes 37157ec681f3Smrg * which is impractical. 37167ec681f3Smrg */ 37177ec681f3Smrg if (device->info.has_aux_map) 37187ec681f3Smrg alloc_flags &= ~ANV_BO_ALLOC_IMPLICIT_CCS; 37197ec681f3Smrg } 37209f464c52Smaya 37219f464c52Smaya /* Check if we need to support Android HW buffer export. If so, 37229f464c52Smaya * create AHardwareBuffer and import memory from it. 37239f464c52Smaya */ 37249f464c52Smaya bool android_export = false; 37259f464c52Smaya if (export_info && export_info->handleTypes & 37269f464c52Smaya VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) 37279f464c52Smaya android_export = true; 37289f464c52Smaya 37299f464c52Smaya if (ahw_import_info) { 37309f464c52Smaya result = anv_import_ahw_memory(_device, mem, ahw_import_info); 37319f464c52Smaya if (result != VK_SUCCESS) 37329f464c52Smaya goto fail; 37339f464c52Smaya 37349f464c52Smaya goto success; 37359f464c52Smaya } else if (android_export) { 37369f464c52Smaya result = anv_create_ahw_memory(_device, mem, pAllocateInfo); 37379f464c52Smaya if (result != VK_SUCCESS) 37389f464c52Smaya goto fail; 37399f464c52Smaya 37409f464c52Smaya goto success; 37419f464c52Smaya } 37429f464c52Smaya 374301e04c3fSmrg /* The Vulkan spec permits handleType to be 0, in which case the struct is 374401e04c3fSmrg * ignored. 374501e04c3fSmrg */ 374601e04c3fSmrg if (fd_info && fd_info->handleType) { 374701e04c3fSmrg /* At the moment, we support only the below handle types. */ 374801e04c3fSmrg assert(fd_info->handleType == 374901e04c3fSmrg VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT || 375001e04c3fSmrg fd_info->handleType == 375101e04c3fSmrg VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT); 375201e04c3fSmrg 37537ec681f3Smrg result = anv_device_import_bo(device, fd_info->fd, alloc_flags, 37547ec681f3Smrg client_address, &mem->bo); 375501e04c3fSmrg if (result != VK_SUCCESS) 375601e04c3fSmrg goto fail; 375701e04c3fSmrg 375801e04c3fSmrg /* For security purposes, we reject importing the bo if it's smaller 375901e04c3fSmrg * than the requested allocation size. This prevents a malicious client 376001e04c3fSmrg * from passing a buffer to a trusted client, lying about the size, and 376101e04c3fSmrg * telling the trusted client to try and texture from an image that goes 376201e04c3fSmrg * out-of-bounds. This sort of thing could lead to GPU hangs or worse 376301e04c3fSmrg * in the trusted client. The trusted client can protect itself against 376401e04c3fSmrg * this sort of attack but only if it can trust the buffer size. 376501e04c3fSmrg */ 376601e04c3fSmrg if (mem->bo->size < aligned_alloc_size) { 37677ec681f3Smrg result = vk_errorf(device, VK_ERROR_INVALID_EXTERNAL_HANDLE, 376801e04c3fSmrg "aligned allocationSize too large for " 37699f464c52Smaya "VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT: " 377001e04c3fSmrg "%"PRIu64"B > %"PRIu64"B", 377101e04c3fSmrg aligned_alloc_size, mem->bo->size); 37727ec681f3Smrg anv_device_release_bo(device, mem->bo); 377301e04c3fSmrg goto fail; 377401e04c3fSmrg } 377501e04c3fSmrg 377601e04c3fSmrg /* From the Vulkan spec: 377701e04c3fSmrg * 377801e04c3fSmrg * "Importing memory from a file descriptor transfers ownership of 377901e04c3fSmrg * the file descriptor from the application to the Vulkan 378001e04c3fSmrg * implementation. The application must not perform any operations on 378101e04c3fSmrg * the file descriptor after a successful import." 378201e04c3fSmrg * 378301e04c3fSmrg * If the import fails, we leave the file descriptor open. 378401e04c3fSmrg */ 378501e04c3fSmrg close(fd_info->fd); 37869f464c52Smaya goto success; 37879f464c52Smaya } 37889f464c52Smaya 37899f464c52Smaya if (host_ptr_info && host_ptr_info->handleType) { 37909f464c52Smaya if (host_ptr_info->handleType == 37919f464c52Smaya VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT) { 37927ec681f3Smrg result = vk_error(device, VK_ERROR_INVALID_EXTERNAL_HANDLE); 37939f464c52Smaya goto fail; 37949f464c52Smaya } 37959f464c52Smaya 37969f464c52Smaya assert(host_ptr_info->handleType == 37979f464c52Smaya VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT); 37989f464c52Smaya 37997ec681f3Smrg result = anv_device_import_bo_from_host_ptr(device, 38007ec681f3Smrg host_ptr_info->pHostPointer, 38017ec681f3Smrg pAllocateInfo->allocationSize, 38027ec681f3Smrg alloc_flags, 38037ec681f3Smrg client_address, 38047ec681f3Smrg &mem->bo); 380501e04c3fSmrg if (result != VK_SUCCESS) 380601e04c3fSmrg goto fail; 380701e04c3fSmrg 38089f464c52Smaya mem->host_ptr = host_ptr_info->pHostPointer; 38099f464c52Smaya goto success; 38109f464c52Smaya } 38119f464c52Smaya 38127ec681f3Smrg /* Set ALLOC_LOCAL_MEM flag if heap has device local bit set and requested 38137ec681f3Smrg * memory property flag has DEVICE_LOCAL_BIT set. 38147ec681f3Smrg */ 38157ec681f3Smrg if (mem_type->propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) 38167ec681f3Smrg alloc_flags |= ANV_BO_ALLOC_LOCAL_MEM; 381701e04c3fSmrg 38187ec681f3Smrg /* Regular allocate (not importing memory). */ 38199f464c52Smaya 38207ec681f3Smrg result = anv_device_alloc_bo(device, "user", pAllocateInfo->allocationSize, 38217ec681f3Smrg alloc_flags, client_address, &mem->bo); 38229f464c52Smaya if (result != VK_SUCCESS) 38239f464c52Smaya goto fail; 38249f464c52Smaya 38259f464c52Smaya if (dedicated_info && dedicated_info->image != VK_NULL_HANDLE) { 38269f464c52Smaya ANV_FROM_HANDLE(anv_image, image, dedicated_info->image); 38279f464c52Smaya 38289f464c52Smaya /* Some legacy (non-modifiers) consumers need the tiling to be set on 38299f464c52Smaya * the BO. In this case, we have a dedicated allocation. 38309f464c52Smaya */ 38317ec681f3Smrg if (image->vk.wsi_legacy_scanout) { 38329f464c52Smaya const uint32_t i915_tiling = 38337ec681f3Smrg isl_tiling_to_i915_tiling(image->planes[0].primary_surface.isl.tiling); 38349f464c52Smaya int ret = anv_gem_set_tiling(device, mem->bo->gem_handle, 38357ec681f3Smrg image->planes[0].primary_surface.isl.row_pitch_B, 38369f464c52Smaya i915_tiling); 38379f464c52Smaya if (ret) { 38387ec681f3Smrg anv_device_release_bo(device, mem->bo); 38397ec681f3Smrg result = vk_errorf(device, VK_ERROR_OUT_OF_DEVICE_MEMORY, 38407ec681f3Smrg "failed to set BO tiling: %m"); 38417ec681f3Smrg goto fail; 384201e04c3fSmrg } 384301e04c3fSmrg } 384401e04c3fSmrg } 384501e04c3fSmrg 38467ec681f3Smrg success: 38477ec681f3Smrg mem_heap_used = p_atomic_add_return(&mem_heap->used, mem->bo->size); 38487ec681f3Smrg if (mem_heap_used > mem_heap->size) { 38497ec681f3Smrg p_atomic_add(&mem_heap->used, -mem->bo->size); 38507ec681f3Smrg anv_device_release_bo(device, mem->bo); 38517ec681f3Smrg result = vk_errorf(device, VK_ERROR_OUT_OF_DEVICE_MEMORY, 38527ec681f3Smrg "Out of heap memory"); 38537ec681f3Smrg goto fail; 38547ec681f3Smrg } 38557ec681f3Smrg 38569f464c52Smaya pthread_mutex_lock(&device->mutex); 38579f464c52Smaya list_addtail(&mem->link, &device->memory_objects); 38589f464c52Smaya pthread_mutex_unlock(&device->mutex); 38599f464c52Smaya 386001e04c3fSmrg *pMem = anv_device_memory_to_handle(mem); 386101e04c3fSmrg 386201e04c3fSmrg return VK_SUCCESS; 386301e04c3fSmrg 386401e04c3fSmrg fail: 38657ec681f3Smrg vk_object_free(&device->vk, pAllocator, mem); 386601e04c3fSmrg 386701e04c3fSmrg return result; 386801e04c3fSmrg} 386901e04c3fSmrg 387001e04c3fSmrgVkResult anv_GetMemoryFdKHR( 387101e04c3fSmrg VkDevice device_h, 387201e04c3fSmrg const VkMemoryGetFdInfoKHR* pGetFdInfo, 387301e04c3fSmrg int* pFd) 387401e04c3fSmrg{ 387501e04c3fSmrg ANV_FROM_HANDLE(anv_device, dev, device_h); 387601e04c3fSmrg ANV_FROM_HANDLE(anv_device_memory, mem, pGetFdInfo->memory); 387701e04c3fSmrg 387801e04c3fSmrg assert(pGetFdInfo->sType == VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR); 387901e04c3fSmrg 388001e04c3fSmrg assert(pGetFdInfo->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT || 388101e04c3fSmrg pGetFdInfo->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT); 388201e04c3fSmrg 38837ec681f3Smrg return anv_device_export_bo(dev, mem->bo, pFd); 388401e04c3fSmrg} 388501e04c3fSmrg 388601e04c3fSmrgVkResult anv_GetMemoryFdPropertiesKHR( 388701e04c3fSmrg VkDevice _device, 38889f464c52Smaya VkExternalMemoryHandleTypeFlagBits handleType, 388901e04c3fSmrg int fd, 389001e04c3fSmrg VkMemoryFdPropertiesKHR* pMemoryFdProperties) 389101e04c3fSmrg{ 389201e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 389301e04c3fSmrg 389401e04c3fSmrg switch (handleType) { 389501e04c3fSmrg case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: 389601e04c3fSmrg /* dma-buf can be imported as any memory type */ 389701e04c3fSmrg pMemoryFdProperties->memoryTypeBits = 38987ec681f3Smrg (1 << device->physical->memory.type_count) - 1; 389901e04c3fSmrg return VK_SUCCESS; 390001e04c3fSmrg 390101e04c3fSmrg default: 390201e04c3fSmrg /* The valid usage section for this function says: 390301e04c3fSmrg * 390401e04c3fSmrg * "handleType must not be one of the handle types defined as 390501e04c3fSmrg * opaque." 390601e04c3fSmrg * 390701e04c3fSmrg * So opaque handle types fall into the default "unsupported" case. 390801e04c3fSmrg */ 39097ec681f3Smrg return vk_error(device, VK_ERROR_INVALID_EXTERNAL_HANDLE); 391001e04c3fSmrg } 391101e04c3fSmrg} 391201e04c3fSmrg 39139f464c52SmayaVkResult anv_GetMemoryHostPointerPropertiesEXT( 39149f464c52Smaya VkDevice _device, 39159f464c52Smaya VkExternalMemoryHandleTypeFlagBits handleType, 39169f464c52Smaya const void* pHostPointer, 39179f464c52Smaya VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties) 39189f464c52Smaya{ 39199f464c52Smaya ANV_FROM_HANDLE(anv_device, device, _device); 39209f464c52Smaya 39219f464c52Smaya assert(pMemoryHostPointerProperties->sType == 39229f464c52Smaya VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT); 39239f464c52Smaya 39249f464c52Smaya switch (handleType) { 39257ec681f3Smrg case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: 39269f464c52Smaya /* Host memory can be imported as any memory type. */ 39279f464c52Smaya pMemoryHostPointerProperties->memoryTypeBits = 39287ec681f3Smrg (1ull << device->physical->memory.type_count) - 1; 39299f464c52Smaya 39309f464c52Smaya return VK_SUCCESS; 39317ec681f3Smrg 39329f464c52Smaya default: 39339f464c52Smaya return VK_ERROR_INVALID_EXTERNAL_HANDLE; 39349f464c52Smaya } 39359f464c52Smaya} 39369f464c52Smaya 393701e04c3fSmrgvoid anv_FreeMemory( 393801e04c3fSmrg VkDevice _device, 393901e04c3fSmrg VkDeviceMemory _mem, 394001e04c3fSmrg const VkAllocationCallbacks* pAllocator) 394101e04c3fSmrg{ 394201e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 394301e04c3fSmrg ANV_FROM_HANDLE(anv_device_memory, mem, _mem); 394401e04c3fSmrg 394501e04c3fSmrg if (mem == NULL) 394601e04c3fSmrg return; 394701e04c3fSmrg 39489f464c52Smaya pthread_mutex_lock(&device->mutex); 39499f464c52Smaya list_del(&mem->link); 39509f464c52Smaya pthread_mutex_unlock(&device->mutex); 39519f464c52Smaya 395201e04c3fSmrg if (mem->map) 395301e04c3fSmrg anv_UnmapMemory(_device, _mem); 395401e04c3fSmrg 39557ec681f3Smrg p_atomic_add(&device->physical->memory.heaps[mem->type->heapIndex].used, 39569f464c52Smaya -mem->bo->size); 39579f464c52Smaya 39587ec681f3Smrg anv_device_release_bo(device, mem->bo); 395901e04c3fSmrg 39609f464c52Smaya#if defined(ANDROID) && ANDROID_API_LEVEL >= 26 39619f464c52Smaya if (mem->ahw) 39629f464c52Smaya AHardwareBuffer_release(mem->ahw); 39639f464c52Smaya#endif 39649f464c52Smaya 39657ec681f3Smrg vk_object_free(&device->vk, pAllocator, mem); 396601e04c3fSmrg} 396701e04c3fSmrg 396801e04c3fSmrgVkResult anv_MapMemory( 396901e04c3fSmrg VkDevice _device, 397001e04c3fSmrg VkDeviceMemory _memory, 397101e04c3fSmrg VkDeviceSize offset, 397201e04c3fSmrg VkDeviceSize size, 397301e04c3fSmrg VkMemoryMapFlags flags, 397401e04c3fSmrg void** ppData) 397501e04c3fSmrg{ 397601e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 397701e04c3fSmrg ANV_FROM_HANDLE(anv_device_memory, mem, _memory); 397801e04c3fSmrg 397901e04c3fSmrg if (mem == NULL) { 398001e04c3fSmrg *ppData = NULL; 398101e04c3fSmrg return VK_SUCCESS; 398201e04c3fSmrg } 398301e04c3fSmrg 39849f464c52Smaya if (mem->host_ptr) { 39859f464c52Smaya *ppData = mem->host_ptr + offset; 39869f464c52Smaya return VK_SUCCESS; 39879f464c52Smaya } 39889f464c52Smaya 398901e04c3fSmrg if (size == VK_WHOLE_SIZE) 399001e04c3fSmrg size = mem->bo->size - offset; 399101e04c3fSmrg 399201e04c3fSmrg /* From the Vulkan spec version 1.0.32 docs for MapMemory: 399301e04c3fSmrg * 399401e04c3fSmrg * * If size is not equal to VK_WHOLE_SIZE, size must be greater than 0 399501e04c3fSmrg * assert(size != 0); 399601e04c3fSmrg * * If size is not equal to VK_WHOLE_SIZE, size must be less than or 399701e04c3fSmrg * equal to the size of the memory minus offset 399801e04c3fSmrg */ 399901e04c3fSmrg assert(size > 0); 400001e04c3fSmrg assert(offset + size <= mem->bo->size); 400101e04c3fSmrg 400201e04c3fSmrg /* FIXME: Is this supposed to be thread safe? Since vkUnmapMemory() only 400301e04c3fSmrg * takes a VkDeviceMemory pointer, it seems like only one map of the memory 400401e04c3fSmrg * at a time is valid. We could just mmap up front and return an offset 400501e04c3fSmrg * pointer here, but that may exhaust virtual memory on 32 bit 400601e04c3fSmrg * userspace. */ 400701e04c3fSmrg 400801e04c3fSmrg uint32_t gem_flags = 0; 400901e04c3fSmrg 401001e04c3fSmrg if (!device->info.has_llc && 401101e04c3fSmrg (mem->type->propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) 401201e04c3fSmrg gem_flags |= I915_MMAP_WC; 401301e04c3fSmrg 401401e04c3fSmrg /* GEM will fail to map if the offset isn't 4k-aligned. Round down. */ 40157ec681f3Smrg uint64_t map_offset; 40167ec681f3Smrg if (!device->physical->has_mmap_offset) 40177ec681f3Smrg map_offset = offset & ~4095ull; 40187ec681f3Smrg else 40197ec681f3Smrg map_offset = 0; 402001e04c3fSmrg assert(offset >= map_offset); 402101e04c3fSmrg uint64_t map_size = (offset + size) - map_offset; 402201e04c3fSmrg 402301e04c3fSmrg /* Let's map whole pages */ 402401e04c3fSmrg map_size = align_u64(map_size, 4096); 402501e04c3fSmrg 402601e04c3fSmrg void *map = anv_gem_mmap(device, mem->bo->gem_handle, 402701e04c3fSmrg map_offset, map_size, gem_flags); 402801e04c3fSmrg if (map == MAP_FAILED) 40297ec681f3Smrg return vk_error(device, VK_ERROR_MEMORY_MAP_FAILED); 403001e04c3fSmrg 403101e04c3fSmrg mem->map = map; 403201e04c3fSmrg mem->map_size = map_size; 40337ec681f3Smrg mem->map_delta = (offset - map_offset); 403401e04c3fSmrg 40357ec681f3Smrg *ppData = mem->map + mem->map_delta; 403601e04c3fSmrg 403701e04c3fSmrg return VK_SUCCESS; 403801e04c3fSmrg} 403901e04c3fSmrg 404001e04c3fSmrgvoid anv_UnmapMemory( 404101e04c3fSmrg VkDevice _device, 404201e04c3fSmrg VkDeviceMemory _memory) 404301e04c3fSmrg{ 40447ec681f3Smrg ANV_FROM_HANDLE(anv_device, device, _device); 404501e04c3fSmrg ANV_FROM_HANDLE(anv_device_memory, mem, _memory); 404601e04c3fSmrg 40479f464c52Smaya if (mem == NULL || mem->host_ptr) 404801e04c3fSmrg return; 404901e04c3fSmrg 40507ec681f3Smrg anv_gem_munmap(device, mem->map, mem->map_size); 405101e04c3fSmrg 405201e04c3fSmrg mem->map = NULL; 405301e04c3fSmrg mem->map_size = 0; 40547ec681f3Smrg mem->map_delta = 0; 405501e04c3fSmrg} 405601e04c3fSmrg 405701e04c3fSmrgstatic void 405801e04c3fSmrgclflush_mapped_ranges(struct anv_device *device, 405901e04c3fSmrg uint32_t count, 406001e04c3fSmrg const VkMappedMemoryRange *ranges) 406101e04c3fSmrg{ 406201e04c3fSmrg for (uint32_t i = 0; i < count; i++) { 406301e04c3fSmrg ANV_FROM_HANDLE(anv_device_memory, mem, ranges[i].memory); 40647ec681f3Smrg uint64_t map_offset = ranges[i].offset + mem->map_delta; 40657ec681f3Smrg if (map_offset >= mem->map_size) 406601e04c3fSmrg continue; 406701e04c3fSmrg 40687ec681f3Smrg if (mem->type->propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) 40697ec681f3Smrg continue; 40707ec681f3Smrg 40717ec681f3Smrg intel_clflush_range(mem->map + map_offset, 40727ec681f3Smrg MIN2(ranges[i].size, mem->map_size - map_offset)); 407301e04c3fSmrg } 407401e04c3fSmrg} 407501e04c3fSmrg 407601e04c3fSmrgVkResult anv_FlushMappedMemoryRanges( 407701e04c3fSmrg VkDevice _device, 407801e04c3fSmrg uint32_t memoryRangeCount, 407901e04c3fSmrg const VkMappedMemoryRange* pMemoryRanges) 408001e04c3fSmrg{ 408101e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 408201e04c3fSmrg 40837ec681f3Smrg if (!device->physical->memory.need_clflush) 408401e04c3fSmrg return VK_SUCCESS; 408501e04c3fSmrg 408601e04c3fSmrg /* Make sure the writes we're flushing have landed. */ 408701e04c3fSmrg __builtin_ia32_mfence(); 408801e04c3fSmrg 408901e04c3fSmrg clflush_mapped_ranges(device, memoryRangeCount, pMemoryRanges); 409001e04c3fSmrg 409101e04c3fSmrg return VK_SUCCESS; 409201e04c3fSmrg} 409301e04c3fSmrg 409401e04c3fSmrgVkResult anv_InvalidateMappedMemoryRanges( 409501e04c3fSmrg VkDevice _device, 409601e04c3fSmrg uint32_t memoryRangeCount, 409701e04c3fSmrg const VkMappedMemoryRange* pMemoryRanges) 409801e04c3fSmrg{ 409901e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 410001e04c3fSmrg 41017ec681f3Smrg if (!device->physical->memory.need_clflush) 410201e04c3fSmrg return VK_SUCCESS; 410301e04c3fSmrg 410401e04c3fSmrg clflush_mapped_ranges(device, memoryRangeCount, pMemoryRanges); 410501e04c3fSmrg 410601e04c3fSmrg /* Make sure no reads get moved up above the invalidate. */ 410701e04c3fSmrg __builtin_ia32_mfence(); 410801e04c3fSmrg 410901e04c3fSmrg return VK_SUCCESS; 411001e04c3fSmrg} 411101e04c3fSmrg 411201e04c3fSmrgvoid anv_GetDeviceMemoryCommitment( 411301e04c3fSmrg VkDevice device, 411401e04c3fSmrg VkDeviceMemory memory, 411501e04c3fSmrg VkDeviceSize* pCommittedMemoryInBytes) 411601e04c3fSmrg{ 411701e04c3fSmrg *pCommittedMemoryInBytes = 0; 411801e04c3fSmrg} 411901e04c3fSmrg 412001e04c3fSmrgstatic void 412101e04c3fSmrganv_bind_buffer_memory(const VkBindBufferMemoryInfo *pBindInfo) 412201e04c3fSmrg{ 412301e04c3fSmrg ANV_FROM_HANDLE(anv_device_memory, mem, pBindInfo->memory); 412401e04c3fSmrg ANV_FROM_HANDLE(anv_buffer, buffer, pBindInfo->buffer); 412501e04c3fSmrg 412601e04c3fSmrg assert(pBindInfo->sType == VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO); 412701e04c3fSmrg 412801e04c3fSmrg if (mem) { 41297ec681f3Smrg assert(pBindInfo->memoryOffset < mem->bo->size); 41307ec681f3Smrg assert(mem->bo->size - pBindInfo->memoryOffset >= buffer->size); 413101e04c3fSmrg buffer->address = (struct anv_address) { 413201e04c3fSmrg .bo = mem->bo, 413301e04c3fSmrg .offset = pBindInfo->memoryOffset, 413401e04c3fSmrg }; 413501e04c3fSmrg } else { 413601e04c3fSmrg buffer->address = ANV_NULL_ADDRESS; 413701e04c3fSmrg } 413801e04c3fSmrg} 413901e04c3fSmrg 414001e04c3fSmrgVkResult anv_BindBufferMemory2( 414101e04c3fSmrg VkDevice device, 414201e04c3fSmrg uint32_t bindInfoCount, 414301e04c3fSmrg const VkBindBufferMemoryInfo* pBindInfos) 414401e04c3fSmrg{ 414501e04c3fSmrg for (uint32_t i = 0; i < bindInfoCount; i++) 414601e04c3fSmrg anv_bind_buffer_memory(&pBindInfos[i]); 414701e04c3fSmrg 414801e04c3fSmrg return VK_SUCCESS; 414901e04c3fSmrg} 415001e04c3fSmrg 415101e04c3fSmrgVkResult anv_QueueBindSparse( 415201e04c3fSmrg VkQueue _queue, 415301e04c3fSmrg uint32_t bindInfoCount, 415401e04c3fSmrg const VkBindSparseInfo* pBindInfo, 415501e04c3fSmrg VkFence fence) 415601e04c3fSmrg{ 415701e04c3fSmrg ANV_FROM_HANDLE(anv_queue, queue, _queue); 415801e04c3fSmrg if (anv_device_is_lost(queue->device)) 415901e04c3fSmrg return VK_ERROR_DEVICE_LOST; 416001e04c3fSmrg 41617ec681f3Smrg return vk_error(queue, VK_ERROR_FEATURE_NOT_PRESENT); 416201e04c3fSmrg} 416301e04c3fSmrg 416401e04c3fSmrg// Event functions 416501e04c3fSmrg 416601e04c3fSmrgVkResult anv_CreateEvent( 416701e04c3fSmrg VkDevice _device, 416801e04c3fSmrg const VkEventCreateInfo* pCreateInfo, 416901e04c3fSmrg const VkAllocationCallbacks* pAllocator, 417001e04c3fSmrg VkEvent* pEvent) 417101e04c3fSmrg{ 417201e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 417301e04c3fSmrg struct anv_event *event; 417401e04c3fSmrg 417501e04c3fSmrg assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_EVENT_CREATE_INFO); 417601e04c3fSmrg 41777ec681f3Smrg event = vk_object_alloc(&device->vk, pAllocator, sizeof(*event), 41787ec681f3Smrg VK_OBJECT_TYPE_EVENT); 41797ec681f3Smrg if (event == NULL) 41807ec681f3Smrg return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 418101e04c3fSmrg 41827ec681f3Smrg event->state = anv_state_pool_alloc(&device->dynamic_state_pool, 41837ec681f3Smrg sizeof(uint64_t), 8); 41847ec681f3Smrg *(uint64_t *)event->state.map = VK_EVENT_RESET; 418501e04c3fSmrg 418601e04c3fSmrg *pEvent = anv_event_to_handle(event); 418701e04c3fSmrg 418801e04c3fSmrg return VK_SUCCESS; 418901e04c3fSmrg} 419001e04c3fSmrg 419101e04c3fSmrgvoid anv_DestroyEvent( 419201e04c3fSmrg VkDevice _device, 419301e04c3fSmrg VkEvent _event, 419401e04c3fSmrg const VkAllocationCallbacks* pAllocator) 419501e04c3fSmrg{ 419601e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 419701e04c3fSmrg ANV_FROM_HANDLE(anv_event, event, _event); 419801e04c3fSmrg 419901e04c3fSmrg if (!event) 420001e04c3fSmrg return; 420101e04c3fSmrg 420201e04c3fSmrg anv_state_pool_free(&device->dynamic_state_pool, event->state); 42037ec681f3Smrg 42047ec681f3Smrg vk_object_free(&device->vk, pAllocator, event); 420501e04c3fSmrg} 420601e04c3fSmrg 420701e04c3fSmrgVkResult anv_GetEventStatus( 420801e04c3fSmrg VkDevice _device, 420901e04c3fSmrg VkEvent _event) 421001e04c3fSmrg{ 421101e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 421201e04c3fSmrg ANV_FROM_HANDLE(anv_event, event, _event); 421301e04c3fSmrg 421401e04c3fSmrg if (anv_device_is_lost(device)) 421501e04c3fSmrg return VK_ERROR_DEVICE_LOST; 421601e04c3fSmrg 42177ec681f3Smrg return *(uint64_t *)event->state.map; 421801e04c3fSmrg} 421901e04c3fSmrg 422001e04c3fSmrgVkResult anv_SetEvent( 422101e04c3fSmrg VkDevice _device, 422201e04c3fSmrg VkEvent _event) 422301e04c3fSmrg{ 422401e04c3fSmrg ANV_FROM_HANDLE(anv_event, event, _event); 422501e04c3fSmrg 42267ec681f3Smrg *(uint64_t *)event->state.map = VK_EVENT_SET; 422701e04c3fSmrg 422801e04c3fSmrg return VK_SUCCESS; 422901e04c3fSmrg} 423001e04c3fSmrg 423101e04c3fSmrgVkResult anv_ResetEvent( 423201e04c3fSmrg VkDevice _device, 423301e04c3fSmrg VkEvent _event) 423401e04c3fSmrg{ 423501e04c3fSmrg ANV_FROM_HANDLE(anv_event, event, _event); 423601e04c3fSmrg 42377ec681f3Smrg *(uint64_t *)event->state.map = VK_EVENT_RESET; 423801e04c3fSmrg 423901e04c3fSmrg return VK_SUCCESS; 424001e04c3fSmrg} 424101e04c3fSmrg 424201e04c3fSmrg// Buffer functions 424301e04c3fSmrg 42447ec681f3Smrgstatic void 42457ec681f3Smrganv_get_buffer_memory_requirements(struct anv_device *device, 42467ec681f3Smrg VkDeviceSize size, 42477ec681f3Smrg VkBufferUsageFlags usage, 42487ec681f3Smrg VkMemoryRequirements2* pMemoryRequirements) 42497ec681f3Smrg{ 42507ec681f3Smrg /* The Vulkan spec (git aaed022) says: 42517ec681f3Smrg * 42527ec681f3Smrg * memoryTypeBits is a bitfield and contains one bit set for every 42537ec681f3Smrg * supported memory type for the resource. The bit `1<<i` is set if and 42547ec681f3Smrg * only if the memory type `i` in the VkPhysicalDeviceMemoryProperties 42557ec681f3Smrg * structure for the physical device is supported. 42567ec681f3Smrg */ 42577ec681f3Smrg uint32_t memory_types = (1ull << device->physical->memory.type_count) - 1; 42587ec681f3Smrg 42597ec681f3Smrg /* Base alignment requirement of a cache line */ 42607ec681f3Smrg uint32_t alignment = 16; 42617ec681f3Smrg 42627ec681f3Smrg if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) 42637ec681f3Smrg alignment = MAX2(alignment, ANV_UBO_ALIGNMENT); 42647ec681f3Smrg 42657ec681f3Smrg pMemoryRequirements->memoryRequirements.size = size; 42667ec681f3Smrg pMemoryRequirements->memoryRequirements.alignment = alignment; 42677ec681f3Smrg 42687ec681f3Smrg /* Storage and Uniform buffers should have their size aligned to 42697ec681f3Smrg * 32-bits to avoid boundary checks when last DWord is not complete. 42707ec681f3Smrg * This would ensure that not internal padding would be needed for 42717ec681f3Smrg * 16-bit types. 42727ec681f3Smrg */ 42737ec681f3Smrg if (device->robust_buffer_access && 42747ec681f3Smrg (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT || 42757ec681f3Smrg usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) 42767ec681f3Smrg pMemoryRequirements->memoryRequirements.size = align_u64(size, 4); 42777ec681f3Smrg 42787ec681f3Smrg pMemoryRequirements->memoryRequirements.memoryTypeBits = memory_types; 42797ec681f3Smrg 42807ec681f3Smrg vk_foreach_struct(ext, pMemoryRequirements->pNext) { 42817ec681f3Smrg switch (ext->sType) { 42827ec681f3Smrg case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: { 42837ec681f3Smrg VkMemoryDedicatedRequirements *requirements = (void *)ext; 42847ec681f3Smrg requirements->prefersDedicatedAllocation = false; 42857ec681f3Smrg requirements->requiresDedicatedAllocation = false; 42867ec681f3Smrg break; 42877ec681f3Smrg } 42887ec681f3Smrg 42897ec681f3Smrg default: 42907ec681f3Smrg anv_debug_ignored_stype(ext->sType); 42917ec681f3Smrg break; 42927ec681f3Smrg } 42937ec681f3Smrg } 42947ec681f3Smrg} 42957ec681f3Smrg 42967ec681f3Smrgvoid anv_GetBufferMemoryRequirements2( 42977ec681f3Smrg VkDevice _device, 42987ec681f3Smrg const VkBufferMemoryRequirementsInfo2* pInfo, 42997ec681f3Smrg VkMemoryRequirements2* pMemoryRequirements) 43007ec681f3Smrg{ 43017ec681f3Smrg ANV_FROM_HANDLE(anv_device, device, _device); 43027ec681f3Smrg ANV_FROM_HANDLE(anv_buffer, buffer, pInfo->buffer); 43037ec681f3Smrg 43047ec681f3Smrg anv_get_buffer_memory_requirements(device, 43057ec681f3Smrg buffer->size, 43067ec681f3Smrg buffer->usage, 43077ec681f3Smrg pMemoryRequirements); 43087ec681f3Smrg} 43097ec681f3Smrg 43107ec681f3Smrgvoid anv_GetDeviceBufferMemoryRequirementsKHR( 43117ec681f3Smrg VkDevice _device, 43127ec681f3Smrg const VkDeviceBufferMemoryRequirementsKHR* pInfo, 43137ec681f3Smrg VkMemoryRequirements2* pMemoryRequirements) 43147ec681f3Smrg{ 43157ec681f3Smrg ANV_FROM_HANDLE(anv_device, device, _device); 43167ec681f3Smrg 43177ec681f3Smrg anv_get_buffer_memory_requirements(device, 43187ec681f3Smrg pInfo->pCreateInfo->size, 43197ec681f3Smrg pInfo->pCreateInfo->usage, 43207ec681f3Smrg pMemoryRequirements); 43217ec681f3Smrg} 43227ec681f3Smrg 432301e04c3fSmrgVkResult anv_CreateBuffer( 432401e04c3fSmrg VkDevice _device, 432501e04c3fSmrg const VkBufferCreateInfo* pCreateInfo, 432601e04c3fSmrg const VkAllocationCallbacks* pAllocator, 432701e04c3fSmrg VkBuffer* pBuffer) 432801e04c3fSmrg{ 432901e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 433001e04c3fSmrg struct anv_buffer *buffer; 433101e04c3fSmrg 43327ec681f3Smrg /* Don't allow creating buffers bigger than our address space. The real 43337ec681f3Smrg * issue here is that we may align up the buffer size and we don't want 43347ec681f3Smrg * doing so to cause roll-over. However, no one has any business 43357ec681f3Smrg * allocating a buffer larger than our GTT size. 43367ec681f3Smrg */ 43377ec681f3Smrg if (pCreateInfo->size > device->physical->gtt_size) 43387ec681f3Smrg return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY); 43397ec681f3Smrg 434001e04c3fSmrg assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO); 434101e04c3fSmrg 43427ec681f3Smrg buffer = vk_object_alloc(&device->vk, pAllocator, sizeof(*buffer), 43437ec681f3Smrg VK_OBJECT_TYPE_BUFFER); 434401e04c3fSmrg if (buffer == NULL) 43457ec681f3Smrg return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 434601e04c3fSmrg 43477ec681f3Smrg buffer->create_flags = pCreateInfo->flags; 434801e04c3fSmrg buffer->size = pCreateInfo->size; 434901e04c3fSmrg buffer->usage = pCreateInfo->usage; 435001e04c3fSmrg buffer->address = ANV_NULL_ADDRESS; 435101e04c3fSmrg 435201e04c3fSmrg *pBuffer = anv_buffer_to_handle(buffer); 435301e04c3fSmrg 435401e04c3fSmrg return VK_SUCCESS; 435501e04c3fSmrg} 435601e04c3fSmrg 435701e04c3fSmrgvoid anv_DestroyBuffer( 435801e04c3fSmrg VkDevice _device, 435901e04c3fSmrg VkBuffer _buffer, 436001e04c3fSmrg const VkAllocationCallbacks* pAllocator) 436101e04c3fSmrg{ 436201e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 436301e04c3fSmrg ANV_FROM_HANDLE(anv_buffer, buffer, _buffer); 436401e04c3fSmrg 436501e04c3fSmrg if (!buffer) 436601e04c3fSmrg return; 436701e04c3fSmrg 43687ec681f3Smrg vk_object_free(&device->vk, pAllocator, buffer); 436901e04c3fSmrg} 437001e04c3fSmrg 43717ec681f3SmrgVkDeviceAddress anv_GetBufferDeviceAddress( 43729f464c52Smaya VkDevice device, 43737ec681f3Smrg const VkBufferDeviceAddressInfoKHR* pInfo) 43749f464c52Smaya{ 43759f464c52Smaya ANV_FROM_HANDLE(anv_buffer, buffer, pInfo->buffer); 43769f464c52Smaya 43777ec681f3Smrg assert(!anv_address_is_null(buffer->address)); 43789f464c52Smaya assert(buffer->address.bo->flags & EXEC_OBJECT_PINNED); 43799f464c52Smaya 43809f464c52Smaya return anv_address_physical(buffer->address); 43819f464c52Smaya} 43829f464c52Smaya 43837ec681f3Smrguint64_t anv_GetBufferOpaqueCaptureAddress( 43847ec681f3Smrg VkDevice device, 43857ec681f3Smrg const VkBufferDeviceAddressInfoKHR* pInfo) 43867ec681f3Smrg{ 43877ec681f3Smrg return 0; 43887ec681f3Smrg} 43897ec681f3Smrg 43907ec681f3Smrguint64_t anv_GetDeviceMemoryOpaqueCaptureAddress( 43917ec681f3Smrg VkDevice device, 43927ec681f3Smrg const VkDeviceMemoryOpaqueCaptureAddressInfoKHR* pInfo) 43937ec681f3Smrg{ 43947ec681f3Smrg ANV_FROM_HANDLE(anv_device_memory, memory, pInfo->memory); 43957ec681f3Smrg 43967ec681f3Smrg assert(memory->bo->flags & EXEC_OBJECT_PINNED); 43977ec681f3Smrg assert(memory->bo->has_client_visible_address); 43987ec681f3Smrg 43997ec681f3Smrg return intel_48b_address(memory->bo->offset); 44007ec681f3Smrg} 44017ec681f3Smrg 440201e04c3fSmrgvoid 440301e04c3fSmrganv_fill_buffer_surface_state(struct anv_device *device, struct anv_state state, 440401e04c3fSmrg enum isl_format format, 44057ec681f3Smrg isl_surf_usage_flags_t usage, 440601e04c3fSmrg struct anv_address address, 440701e04c3fSmrg uint32_t range, uint32_t stride) 440801e04c3fSmrg{ 440901e04c3fSmrg isl_buffer_fill_state(&device->isl_dev, state.map, 441001e04c3fSmrg .address = anv_address_physical(address), 44117ec681f3Smrg .mocs = isl_mocs(&device->isl_dev, usage, 44127ec681f3Smrg address.bo && address.bo->is_external), 441301e04c3fSmrg .size_B = range, 441401e04c3fSmrg .format = format, 44159f464c52Smaya .swizzle = ISL_SWIZZLE_IDENTITY, 441601e04c3fSmrg .stride_B = stride); 441701e04c3fSmrg} 441801e04c3fSmrg 441901e04c3fSmrgvoid anv_DestroySampler( 442001e04c3fSmrg VkDevice _device, 442101e04c3fSmrg VkSampler _sampler, 442201e04c3fSmrg const VkAllocationCallbacks* pAllocator) 442301e04c3fSmrg{ 442401e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 442501e04c3fSmrg ANV_FROM_HANDLE(anv_sampler, sampler, _sampler); 442601e04c3fSmrg 442701e04c3fSmrg if (!sampler) 442801e04c3fSmrg return; 442901e04c3fSmrg 44309f464c52Smaya if (sampler->bindless_state.map) { 44319f464c52Smaya anv_state_pool_free(&device->dynamic_state_pool, 44329f464c52Smaya sampler->bindless_state); 44339f464c52Smaya } 44349f464c52Smaya 44357ec681f3Smrg if (sampler->custom_border_color.map) { 44367ec681f3Smrg anv_state_reserved_pool_free(&device->custom_border_colors, 44377ec681f3Smrg sampler->custom_border_color); 44387ec681f3Smrg } 44397ec681f3Smrg 44407ec681f3Smrg vk_object_free(&device->vk, pAllocator, sampler); 444101e04c3fSmrg} 444201e04c3fSmrg 444301e04c3fSmrgVkResult anv_CreateFramebuffer( 444401e04c3fSmrg VkDevice _device, 444501e04c3fSmrg const VkFramebufferCreateInfo* pCreateInfo, 444601e04c3fSmrg const VkAllocationCallbacks* pAllocator, 444701e04c3fSmrg VkFramebuffer* pFramebuffer) 444801e04c3fSmrg{ 444901e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 445001e04c3fSmrg struct anv_framebuffer *framebuffer; 445101e04c3fSmrg 445201e04c3fSmrg assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO); 445301e04c3fSmrg 44547ec681f3Smrg size_t size = sizeof(*framebuffer); 445501e04c3fSmrg 44567ec681f3Smrg /* VK_KHR_imageless_framebuffer extension says: 44577ec681f3Smrg * 44587ec681f3Smrg * If flags includes VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR, 44597ec681f3Smrg * parameter pAttachments is ignored. 44607ec681f3Smrg */ 44617ec681f3Smrg if (!(pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR)) 44627ec681f3Smrg size += sizeof(struct anv_image_view *) * pCreateInfo->attachmentCount; 44637ec681f3Smrg 44647ec681f3Smrg framebuffer = vk_object_alloc(&device->vk, pAllocator, size, 44657ec681f3Smrg VK_OBJECT_TYPE_FRAMEBUFFER); 44667ec681f3Smrg if (framebuffer == NULL) 44677ec681f3Smrg return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 446801e04c3fSmrg 446901e04c3fSmrg framebuffer->width = pCreateInfo->width; 447001e04c3fSmrg framebuffer->height = pCreateInfo->height; 447101e04c3fSmrg framebuffer->layers = pCreateInfo->layers; 447201e04c3fSmrg 44737ec681f3Smrg if (!(pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR)) { 44747ec681f3Smrg for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) { 44757ec681f3Smrg ANV_FROM_HANDLE(anv_image_view, iview, pCreateInfo->pAttachments[i]); 44767ec681f3Smrg framebuffer->attachments[i] = iview; 44777ec681f3Smrg } 44787ec681f3Smrg framebuffer->attachment_count = pCreateInfo->attachmentCount; 44797ec681f3Smrg } 44807ec681f3Smrg 448101e04c3fSmrg *pFramebuffer = anv_framebuffer_to_handle(framebuffer); 448201e04c3fSmrg 448301e04c3fSmrg return VK_SUCCESS; 448401e04c3fSmrg} 448501e04c3fSmrg 448601e04c3fSmrgvoid anv_DestroyFramebuffer( 448701e04c3fSmrg VkDevice _device, 448801e04c3fSmrg VkFramebuffer _fb, 448901e04c3fSmrg const VkAllocationCallbacks* pAllocator) 449001e04c3fSmrg{ 449101e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 449201e04c3fSmrg ANV_FROM_HANDLE(anv_framebuffer, fb, _fb); 449301e04c3fSmrg 449401e04c3fSmrg if (!fb) 449501e04c3fSmrg return; 449601e04c3fSmrg 44977ec681f3Smrg vk_object_free(&device->vk, pAllocator, fb); 449801e04c3fSmrg} 449901e04c3fSmrg 450001e04c3fSmrgstatic const VkTimeDomainEXT anv_time_domains[] = { 450101e04c3fSmrg VK_TIME_DOMAIN_DEVICE_EXT, 450201e04c3fSmrg VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT, 45037ec681f3Smrg#ifdef CLOCK_MONOTONIC_RAW 450401e04c3fSmrg VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT, 45057ec681f3Smrg#endif 450601e04c3fSmrg}; 450701e04c3fSmrg 450801e04c3fSmrgVkResult anv_GetPhysicalDeviceCalibrateableTimeDomainsEXT( 450901e04c3fSmrg VkPhysicalDevice physicalDevice, 451001e04c3fSmrg uint32_t *pTimeDomainCount, 451101e04c3fSmrg VkTimeDomainEXT *pTimeDomains) 451201e04c3fSmrg{ 451301e04c3fSmrg int d; 451401e04c3fSmrg VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount); 451501e04c3fSmrg 451601e04c3fSmrg for (d = 0; d < ARRAY_SIZE(anv_time_domains); d++) { 451701e04c3fSmrg vk_outarray_append(&out, i) { 451801e04c3fSmrg *i = anv_time_domains[d]; 451901e04c3fSmrg } 452001e04c3fSmrg } 452101e04c3fSmrg 452201e04c3fSmrg return vk_outarray_status(&out); 452301e04c3fSmrg} 452401e04c3fSmrg 452501e04c3fSmrgstatic uint64_t 452601e04c3fSmrganv_clock_gettime(clockid_t clock_id) 452701e04c3fSmrg{ 452801e04c3fSmrg struct timespec current; 452901e04c3fSmrg int ret; 453001e04c3fSmrg 453101e04c3fSmrg ret = clock_gettime(clock_id, ¤t); 45327ec681f3Smrg#ifdef CLOCK_MONOTONIC_RAW 453301e04c3fSmrg if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW) 453401e04c3fSmrg ret = clock_gettime(CLOCK_MONOTONIC, ¤t); 45357ec681f3Smrg#endif 453601e04c3fSmrg if (ret < 0) 453701e04c3fSmrg return 0; 453801e04c3fSmrg 453901e04c3fSmrg return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec; 454001e04c3fSmrg} 454101e04c3fSmrg 454201e04c3fSmrgVkResult anv_GetCalibratedTimestampsEXT( 454301e04c3fSmrg VkDevice _device, 454401e04c3fSmrg uint32_t timestampCount, 454501e04c3fSmrg const VkCalibratedTimestampInfoEXT *pTimestampInfos, 454601e04c3fSmrg uint64_t *pTimestamps, 454701e04c3fSmrg uint64_t *pMaxDeviation) 454801e04c3fSmrg{ 454901e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 455001e04c3fSmrg uint64_t timestamp_frequency = device->info.timestamp_frequency; 455101e04c3fSmrg int ret; 455201e04c3fSmrg int d; 455301e04c3fSmrg uint64_t begin, end; 455401e04c3fSmrg uint64_t max_clock_period = 0; 455501e04c3fSmrg 45567ec681f3Smrg#ifdef CLOCK_MONOTONIC_RAW 455701e04c3fSmrg begin = anv_clock_gettime(CLOCK_MONOTONIC_RAW); 45587ec681f3Smrg#else 45597ec681f3Smrg begin = anv_clock_gettime(CLOCK_MONOTONIC); 45607ec681f3Smrg#endif 456101e04c3fSmrg 456201e04c3fSmrg for (d = 0; d < timestampCount; d++) { 456301e04c3fSmrg switch (pTimestampInfos[d].timeDomain) { 456401e04c3fSmrg case VK_TIME_DOMAIN_DEVICE_EXT: 45657ec681f3Smrg ret = anv_gem_reg_read(device->fd, TIMESTAMP | I915_REG_READ_8B_WA, 456601e04c3fSmrg &pTimestamps[d]); 456701e04c3fSmrg 456801e04c3fSmrg if (ret != 0) { 456901e04c3fSmrg return anv_device_set_lost(device, "Failed to read the TIMESTAMP " 457001e04c3fSmrg "register: %m"); 457101e04c3fSmrg } 457201e04c3fSmrg uint64_t device_period = DIV_ROUND_UP(1000000000, timestamp_frequency); 457301e04c3fSmrg max_clock_period = MAX2(max_clock_period, device_period); 457401e04c3fSmrg break; 457501e04c3fSmrg case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT: 457601e04c3fSmrg pTimestamps[d] = anv_clock_gettime(CLOCK_MONOTONIC); 457701e04c3fSmrg max_clock_period = MAX2(max_clock_period, 1); 457801e04c3fSmrg break; 457901e04c3fSmrg 45807ec681f3Smrg#ifdef CLOCK_MONOTONIC_RAW 458101e04c3fSmrg case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT: 458201e04c3fSmrg pTimestamps[d] = begin; 458301e04c3fSmrg break; 45847ec681f3Smrg#endif 458501e04c3fSmrg default: 458601e04c3fSmrg pTimestamps[d] = 0; 458701e04c3fSmrg break; 458801e04c3fSmrg } 458901e04c3fSmrg } 459001e04c3fSmrg 45917ec681f3Smrg#ifdef CLOCK_MONOTONIC_RAW 459201e04c3fSmrg end = anv_clock_gettime(CLOCK_MONOTONIC_RAW); 45937ec681f3Smrg#else 45947ec681f3Smrg end = anv_clock_gettime(CLOCK_MONOTONIC); 45957ec681f3Smrg#endif 459601e04c3fSmrg 459701e04c3fSmrg /* 459801e04c3fSmrg * The maximum deviation is the sum of the interval over which we 459901e04c3fSmrg * perform the sampling and the maximum period of any sampled 460001e04c3fSmrg * clock. That's because the maximum skew between any two sampled 460101e04c3fSmrg * clock edges is when the sampled clock with the largest period is 460201e04c3fSmrg * sampled at the end of that period but right at the beginning of the 460301e04c3fSmrg * sampling interval and some other clock is sampled right at the 460401e04c3fSmrg * begining of its sampling period and right at the end of the 460501e04c3fSmrg * sampling interval. Let's assume the GPU has the longest clock 460601e04c3fSmrg * period and that the application is sampling GPU and monotonic: 460701e04c3fSmrg * 460801e04c3fSmrg * s e 460901e04c3fSmrg * w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e f 461001e04c3fSmrg * Raw -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_- 461101e04c3fSmrg * 461201e04c3fSmrg * g 461301e04c3fSmrg * 0 1 2 3 461401e04c3fSmrg * GPU -----_____-----_____-----_____-----_____ 461501e04c3fSmrg * 461601e04c3fSmrg * m 461701e04c3fSmrg * x y z 0 1 2 3 4 5 6 7 8 9 a b c 461801e04c3fSmrg * Monotonic -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_- 461901e04c3fSmrg * 462001e04c3fSmrg * Interval <-----------------> 462101e04c3fSmrg * Deviation <--------------------------> 462201e04c3fSmrg * 462301e04c3fSmrg * s = read(raw) 2 462401e04c3fSmrg * g = read(GPU) 1 462501e04c3fSmrg * m = read(monotonic) 2 462601e04c3fSmrg * e = read(raw) b 462701e04c3fSmrg * 462801e04c3fSmrg * We round the sample interval up by one tick to cover sampling error 462901e04c3fSmrg * in the interval clock 463001e04c3fSmrg */ 463101e04c3fSmrg 463201e04c3fSmrg uint64_t sample_interval = end - begin + 1; 463301e04c3fSmrg 463401e04c3fSmrg *pMaxDeviation = sample_interval + max_clock_period; 463501e04c3fSmrg 463601e04c3fSmrg return VK_SUCCESS; 463701e04c3fSmrg} 463801e04c3fSmrg 46397ec681f3Smrgvoid anv_GetPhysicalDeviceMultisamplePropertiesEXT( 46407ec681f3Smrg VkPhysicalDevice physicalDevice, 46417ec681f3Smrg VkSampleCountFlagBits samples, 46427ec681f3Smrg VkMultisamplePropertiesEXT* pMultisampleProperties) 46437ec681f3Smrg{ 46447ec681f3Smrg ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice); 46457ec681f3Smrg 46467ec681f3Smrg assert(pMultisampleProperties->sType == 46477ec681f3Smrg VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT); 46487ec681f3Smrg 46497ec681f3Smrg VkExtent2D grid_size; 46507ec681f3Smrg if (samples & isl_device_get_sample_counts(&physical_device->isl_dev)) { 46517ec681f3Smrg grid_size.width = 1; 46527ec681f3Smrg grid_size.height = 1; 46537ec681f3Smrg } else { 46547ec681f3Smrg grid_size.width = 0; 46557ec681f3Smrg grid_size.height = 0; 46567ec681f3Smrg } 46577ec681f3Smrg pMultisampleProperties->maxSampleLocationGridSize = grid_size; 46587ec681f3Smrg 46597ec681f3Smrg vk_foreach_struct(ext, pMultisampleProperties->pNext) 46607ec681f3Smrg anv_debug_ignored_stype(ext->sType); 46617ec681f3Smrg} 46627ec681f3Smrg 466301e04c3fSmrg/* vk_icd.h does not declare this function, so we declare it here to 466401e04c3fSmrg * suppress Wmissing-prototypes. 466501e04c3fSmrg */ 466601e04c3fSmrgPUBLIC VKAPI_ATTR VkResult VKAPI_CALL 466701e04c3fSmrgvk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion); 466801e04c3fSmrg 466901e04c3fSmrgPUBLIC VKAPI_ATTR VkResult VKAPI_CALL 467001e04c3fSmrgvk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion) 467101e04c3fSmrg{ 467201e04c3fSmrg /* For the full details on loader interface versioning, see 467301e04c3fSmrg * <https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/loader/LoaderAndLayerInterface.md>. 467401e04c3fSmrg * What follows is a condensed summary, to help you navigate the large and 467501e04c3fSmrg * confusing official doc. 467601e04c3fSmrg * 467701e04c3fSmrg * - Loader interface v0 is incompatible with later versions. We don't 467801e04c3fSmrg * support it. 467901e04c3fSmrg * 468001e04c3fSmrg * - In loader interface v1: 468101e04c3fSmrg * - The first ICD entrypoint called by the loader is 468201e04c3fSmrg * vk_icdGetInstanceProcAddr(). The ICD must statically expose this 468301e04c3fSmrg * entrypoint. 468401e04c3fSmrg * - The ICD must statically expose no other Vulkan symbol unless it is 468501e04c3fSmrg * linked with -Bsymbolic. 468601e04c3fSmrg * - Each dispatchable Vulkan handle created by the ICD must be 468701e04c3fSmrg * a pointer to a struct whose first member is VK_LOADER_DATA. The 468801e04c3fSmrg * ICD must initialize VK_LOADER_DATA.loadMagic to ICD_LOADER_MAGIC. 468901e04c3fSmrg * - The loader implements vkCreate{PLATFORM}SurfaceKHR() and 469001e04c3fSmrg * vkDestroySurfaceKHR(). The ICD must be capable of working with 469101e04c3fSmrg * such loader-managed surfaces. 469201e04c3fSmrg * 469301e04c3fSmrg * - Loader interface v2 differs from v1 in: 469401e04c3fSmrg * - The first ICD entrypoint called by the loader is 469501e04c3fSmrg * vk_icdNegotiateLoaderICDInterfaceVersion(). The ICD must 469601e04c3fSmrg * statically expose this entrypoint. 469701e04c3fSmrg * 469801e04c3fSmrg * - Loader interface v3 differs from v2 in: 469901e04c3fSmrg * - The ICD must implement vkCreate{PLATFORM}SurfaceKHR(), 470001e04c3fSmrg * vkDestroySurfaceKHR(), and other API which uses VKSurfaceKHR, 470101e04c3fSmrg * because the loader no longer does so. 47027ec681f3Smrg * 47037ec681f3Smrg * - Loader interface v4 differs from v3 in: 47047ec681f3Smrg * - The ICD must implement vk_icdGetPhysicalDeviceProcAddr(). 470501e04c3fSmrg */ 47067ec681f3Smrg *pSupportedVersion = MIN2(*pSupportedVersion, 4u); 470701e04c3fSmrg return VK_SUCCESS; 470801e04c3fSmrg} 47097ec681f3Smrg 47107ec681f3SmrgVkResult anv_GetPhysicalDeviceFragmentShadingRatesKHR( 47117ec681f3Smrg VkPhysicalDevice physicalDevice, 47127ec681f3Smrg uint32_t* pFragmentShadingRateCount, 47137ec681f3Smrg VkPhysicalDeviceFragmentShadingRateKHR* pFragmentShadingRates) 47147ec681f3Smrg{ 47157ec681f3Smrg ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice); 47167ec681f3Smrg VK_OUTARRAY_MAKE(out, pFragmentShadingRates, pFragmentShadingRateCount); 47177ec681f3Smrg 47187ec681f3Smrg#define append_rate(_samples, _width, _height) \ 47197ec681f3Smrg do { \ 47207ec681f3Smrg vk_outarray_append(&out, __r) { \ 47217ec681f3Smrg __r->sampleCounts = _samples; \ 47227ec681f3Smrg __r->fragmentSize = (VkExtent2D) { \ 47237ec681f3Smrg .width = _width, \ 47247ec681f3Smrg .height = _height, \ 47257ec681f3Smrg }; \ 47267ec681f3Smrg } \ 47277ec681f3Smrg } while (0) 47287ec681f3Smrg 47297ec681f3Smrg VkSampleCountFlags sample_counts = 47307ec681f3Smrg isl_device_get_sample_counts(&physical_device->isl_dev); 47317ec681f3Smrg 47327ec681f3Smrg for (uint32_t x = 4; x >= 1; x /= 2) { 47337ec681f3Smrg for (uint32_t y = 4; y >= 1; y /= 2) { 47347ec681f3Smrg /* For size {1, 1}, the sample count must be ~0 */ 47357ec681f3Smrg if (x == 1 && y == 1) 47367ec681f3Smrg append_rate(~0, x, y); 47377ec681f3Smrg else 47387ec681f3Smrg append_rate(sample_counts, x, y); 47397ec681f3Smrg } 47407ec681f3Smrg } 47417ec681f3Smrg 47427ec681f3Smrg#undef append_rate 47437ec681f3Smrg 47447ec681f3Smrg return vk_outarray_status(&out); 47457ec681f3Smrg} 4746