X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fintel%2Fvulkan%2Fanv_private.h;h=e30a49a72a02b5b490335b0469ef1d610d2023df;hb=811990dc1c5ee1c02956041ae6f98a770b2c9f8b;hp=2bc4d4a05b6d633c83fee35db51d355dcd380e03;hpb=629806b55bccd7f3e5b7b753820c4442fdb30bbe;p=mesa.git diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 2bc4d4a05b6..e30a49a72a0 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -40,23 +40,26 @@ #define __gen_validate_value(x) VALGRIND_CHECK_MEM_IS_DEFINED(&(x), sizeof(x)) #endif #else -#define VG(x) +#define VG(x) ((void)0) #endif #include "common/gen_clflush.h" #include "common/gen_decoder.h" #include "common/gen_gem.h" +#include "common/gen_l3_config.h" #include "dev/gen_device_info.h" #include "blorp/blorp.h" #include "compiler/brw_compiler.h" +#include "util/bitset.h" #include "util/macros.h" #include "util/hash_table.h" #include "util/list.h" -#include "util/set.h" +#include "util/sparse_array.h" #include "util/u_atomic.h" #include "util/u_vector.h" #include "util/u_math.h" #include "util/vma.h" +#include "util/xmlconfig.h" #include "vk_alloc.h" #include "vk_debug_report.h" @@ -67,12 +70,14 @@ typedef struct xcb_connection_t xcb_connection_t; typedef uint32_t xcb_visualid_t; typedef uint32_t xcb_window_t; +struct anv_batch; struct anv_buffer; struct anv_buffer_view; struct anv_image_view; struct anv_instance; -struct gen_l3_config; +struct gen_aux_map_context; +struct gen_perf_config; #include #include @@ -87,6 +92,8 @@ struct gen_l3_config; #include "common/intel_log.h" #include "wsi_common.h" +#define NSEC_PER_SEC 1000000000ull + /* anv Virtual Memory Layout * ========================= * @@ -120,7 +127,9 @@ struct gen_l3_config; #define SURFACE_STATE_POOL_MAX_ADDRESS 0x00017fffffffULL #define INSTRUCTION_STATE_POOL_MIN_ADDRESS 0x000180000000ULL /* 6 GiB */ #define INSTRUCTION_STATE_POOL_MAX_ADDRESS 0x0001bfffffffULL -#define HIGH_HEAP_MIN_ADDRESS 0x0001c0000000ULL /* 7 GiB */ +#define CLIENT_VISIBLE_HEAP_MIN_ADDRESS 0x0001c0000000ULL /* 7 GiB */ +#define CLIENT_VISIBLE_HEAP_MAX_ADDRESS 0x0002bfffffffULL +#define HIGH_HEAP_MIN_ADDRESS 0x0002c0000000ULL /* 11 GiB */ #define LOW_HEAP_SIZE \ (LOW_HEAP_MAX_ADDRESS - LOW_HEAP_MIN_ADDRESS + 1) @@ -132,6 +141,8 @@ struct gen_l3_config; (SURFACE_STATE_POOL_MAX_ADDRESS - SURFACE_STATE_POOL_MIN_ADDRESS + 1) #define INSTRUCTION_STATE_POOL_SIZE \ (INSTRUCTION_STATE_POOL_MAX_ADDRESS - INSTRUCTION_STATE_POOL_MIN_ADDRESS + 1) +#define CLIENT_VISIBLE_HEAP_SIZE \ + (CLIENT_VISIBLE_HEAP_MAX_ADDRESS - CLIENT_VISIBLE_HEAP_MIN_ADDRESS + 1) /* Allowing different clear colors requires us to perform a depth resolve at * the end of certain render passes. This is because while slow clears store @@ -201,6 +212,15 @@ struct gen_l3_config; */ #define ANV_PREDICATE_RESULT_REG 0x2678 /* MI_ALU_REG15 */ +/* For gen12 we set the streamout buffers using 4 separate commands + * (3DSTATE_SO_BUFFER_INDEX_*) instead of 3DSTATE_SO_BUFFER. However the layout + * of the 3DSTATE_SO_BUFFER_INDEX_* commands is identical to that of + * 3DSTATE_SO_BUFFER apart from the SOBufferIndex field, so for now we use the + * 3DSTATE_SO_BUFFER command, but change the 3DCommandSubOpcode. + * SO_BUFFER_INDEX_0_CMD is actually the 3DCommandSubOpcode for + * 3DSTATE_SO_BUFFER_INDEX_0. + */ +#define SO_BUFFER_INDEX_0_CMD 0x60 #define anv_printflike(a, b) __attribute__((__format__(__printf__, a, b))) static inline uint32_t @@ -217,10 +237,16 @@ align_u32(uint32_t v, uint32_t a) } static inline uint64_t -align_u64(uint64_t v, uint64_t a) +align_down_u64(uint64_t v, uint64_t a) { assert(a != 0 && a == (a & -a)); - return (v + a - 1) & ~(a - 1); + return v & ~(a - 1); +} + +static inline uint64_t +align_u64(uint64_t v, uint64_t a) +{ + return align_down_u64(v + a - 1, a); } static inline int32_t @@ -284,6 +310,20 @@ vk_to_isl_color(VkClearColorValue color) }; } +static inline void *anv_unpack_ptr(uintptr_t ptr, int bits, int *flags) +{ + uintptr_t mask = (1ull << bits) - 1; + *flags = ptr & mask; + return (void *) (ptr & ~mask); +} + +static inline uintptr_t anv_pack_ptr(void *ptr, int bits, int flags) +{ + uintptr_t value = (uintptr_t) ptr; + uintptr_t mask = (1ull << bits) - 1; + return value | (mask & flags); +} + #define for_each_bit(b, dword) \ for (uint32_t __dword = (dword); \ (b) = __builtin_ffs(__dword) - 1, __dword; \ @@ -407,21 +447,23 @@ VkResult __vk_errorv(struct anv_instance *instance, const void *object, VkResult __vk_errorf(struct anv_instance *instance, const void *object, VkDebugReportObjectTypeEXT type, VkResult error, - const char *file, int line, const char *format, ...); + const char *file, int line, const char *format, ...) + anv_printflike(7, 8); #ifdef DEBUG #define vk_error(error) __vk_errorf(NULL, NULL,\ VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,\ error, __FILE__, __LINE__, NULL) -#define vk_errorv(instance, obj, error, format, args)\ - __vk_errorv(instance, obj, REPORT_OBJECT_TYPE(obj), error,\ - __FILE__, __LINE__, format, args) -#define vk_errorf(instance, obj, error, format, ...)\ +#define vk_errorfi(instance, obj, error, format, ...)\ __vk_errorf(instance, obj, REPORT_OBJECT_TYPE(obj), error,\ __FILE__, __LINE__, format, ## __VA_ARGS__) +#define vk_errorf(device, obj, error, format, ...)\ + vk_errorfi(anv_device_instance_or_null(device),\ + obj, error, format, ## __VA_ARGS__) #else #define vk_error(error) error -#define vk_errorf(instance, obj, error, format, ...) error +#define vk_errorfi(instance, obj, error, format, ...) error +#define vk_errorf(device, obj, error, format, ...) error #endif /** @@ -442,7 +484,7 @@ VkResult __vk_errorf(struct anv_instance *instance, const void *object, #define anv_debug_ignored_stype(sType) \ intel_logd("%s: ignored VkStructureType %u\n", __func__, (sType)) -void __anv_perf_warn(struct anv_instance *instance, const void *object, +void __anv_perf_warn(struct anv_device *device, const void *object, VkDebugReportObjectTypeEXT type, const char *file, int line, const char *format, ...) anv_printflike(6, 7); @@ -583,41 +625,100 @@ anv_multialloc_alloc2(struct anv_multialloc *ma, return anv_multialloc_alloc(ma, alloc ? alloc : parent_alloc, scope); } -/* Extra ANV-defined BO flags which won't be passed to the kernel */ -#define ANV_BO_EXTERNAL (1ull << 31) -#define ANV_BO_FLAG_MASK (1ull << 31) - struct anv_bo { uint32_t gem_handle; + uint32_t refcount; + /* Index into the current validation list. This is used by the * validation list building alrogithm to track which buffers are already * in the validation list so that we can ensure uniqueness. */ uint32_t index; + /* Index for use with util_sparse_array_free_list */ + uint32_t free_index; + /* Last known offset. This value is provided by the kernel when we * execbuf and is used as the presumed offset for the next bunch of * relocations. */ uint64_t offset; + /** Size of the buffer not including implicit aux */ uint64_t size; + + /* Map for internally mapped BOs. + * + * If ANV_BO_WRAPPER is set in flags, map points to the wrapped BO. + */ void *map; + /** Size of the implicit CCS range at the end of the buffer + * + * On Gen12, CCS data is always a direct 1/256 scale-down. A single 64K + * page of main surface data maps to a 256B chunk of CCS data and that + * mapping is provided on TGL-LP by the AUX table which maps virtual memory + * addresses in the main surface to virtual memory addresses for CCS data. + * + * Because we can't change these maps around easily and because Vulkan + * allows two VkImages to be bound to overlapping memory regions (as long + * as the app is careful), it's not feasible to make this mapping part of + * the image. (On Gen11 and earlier, the mapping was provided via + * RENDER_SURFACE_STATE so each image had its own main -> CCS mapping.) + * Instead, we attach the CCS data directly to the buffer object and setup + * the AUX table mapping at BO creation time. + * + * This field is for internal tracking use by the BO allocator only and + * should not be touched by other parts of the code. If something wants to + * know if a BO has implicit CCS data, it should instead look at the + * has_implicit_ccs boolean below. + * + * This data is not included in maps of this buffer. + */ + uint32_t _ccs_size; + /** Flags to pass to the kernel through drm_i915_exec_object2::flags */ uint32_t flags; + + /** True if this BO may be shared with other processes */ + bool is_external:1; + + /** True if this BO is a wrapper + * + * When set to true, none of the fields in this BO are meaningful except + * for anv_bo::is_wrapper and anv_bo::map which points to the actual BO. + * See also anv_bo_unwrap(). Wrapper BOs are not allowed when use_softpin + * is set in the physical device. + */ + bool is_wrapper:1; + + /** See also ANV_BO_ALLOC_FIXED_ADDRESS */ + bool has_fixed_address:1; + + /** True if this BO wraps a host pointer */ + bool from_host_ptr:1; + + /** See also ANV_BO_ALLOC_CLIENT_VISIBLE_ADDRESS */ + bool has_client_visible_address:1; + + /** True if this BO has implicit CCS data attached to it */ + bool has_implicit_ccs:1; }; -static inline void -anv_bo_init(struct anv_bo *bo, uint32_t gem_handle, uint64_t size) +static inline struct anv_bo * +anv_bo_ref(struct anv_bo *bo) { - bo->gem_handle = gem_handle; - bo->index = 0; - bo->offset = -1; - bo->size = size; - bo->map = NULL; - bo->flags = 0; + p_atomic_inc(&bo->refcount); + return bo; +} + +static inline struct anv_bo * +anv_bo_unwrap(struct anv_bo *bo) +{ + while (bo->is_wrapper) + bo = bo->map; + return bo; } /* Represents a lock-free linked list of "free" things. This is used by @@ -631,7 +732,10 @@ union anv_free_list { /* A simple count that is incremented every time the head changes. */ uint32_t count; }; - uint64_t u64; + /* Make sure it's aligned to 64 bits. This will make atomic operations + * faster on 32 bit platforms. + */ + uint64_t u64 __attribute__ ((aligned (8))); }; #define ANV_FREE_LIST_EMPTY ((union anv_free_list) { { UINT32_MAX, 0 } }) @@ -642,21 +746,32 @@ struct anv_block_state { uint32_t next; uint32_t end; }; - uint64_t u64; + /* Make sure it's aligned to 64 bits. This will make atomic operations + * faster on 32 bit platforms. + */ + uint64_t u64 __attribute__ ((aligned (8))); }; }; #define anv_block_pool_foreach_bo(bo, pool) \ - for (bo = (pool)->bos; bo != &(pool)->bos[(pool)->nbos]; bo++) + for (struct anv_bo **_pp_bo = (pool)->bos, *bo; \ + _pp_bo != &(pool)->bos[(pool)->nbos] && (bo = *_pp_bo, true); \ + _pp_bo++) #define ANV_MAX_BLOCK_POOL_BOS 20 struct anv_block_pool { struct anv_device *device; + bool use_softpin; - uint64_t bo_flags; + /* Wrapper BO for use in relocation lists. This BO is simply a wrapper + * around the actual BO so that we grow the pool after the wrapper BO has + * been put in a relocation list. This is only used in the non-softpin + * case. + */ + struct anv_bo wrapper_bo; - struct anv_bo bos[ANV_MAX_BLOCK_POOL_BOS]; + struct anv_bo *bos[ANV_MAX_BLOCK_POOL_BOS]; struct anv_bo *bo; uint32_t nbos; @@ -729,7 +844,7 @@ struct anv_fixed_size_state_pool { }; #define ANV_MIN_STATE_SIZE_LOG2 6 -#define ANV_MAX_STATE_SIZE_LOG2 20 +#define ANV_MAX_STATE_SIZE_LOG2 21 #define ANV_STATE_BUCKETS (ANV_MAX_STATE_SIZE_LOG2 - ANV_MIN_STATE_SIZE_LOG2 + 1) @@ -785,20 +900,19 @@ struct anv_state_stream { VkResult anv_block_pool_init(struct anv_block_pool *pool, struct anv_device *device, uint64_t start_address, - uint32_t initial_size, - uint64_t bo_flags); + uint32_t initial_size); void anv_block_pool_finish(struct anv_block_pool *pool); int32_t anv_block_pool_alloc(struct anv_block_pool *pool, uint32_t block_size, uint32_t *padding); int32_t anv_block_pool_alloc_back(struct anv_block_pool *pool, uint32_t block_size); -void* anv_block_pool_map(struct anv_block_pool *pool, int32_t offset); +void* anv_block_pool_map(struct anv_block_pool *pool, int32_t offset, uint32_t +size); VkResult anv_state_pool_init(struct anv_state_pool *pool, struct anv_device *device, uint64_t start_address, - uint32_t block_size, - uint64_t bo_flags); + uint32_t block_size); void anv_state_pool_finish(struct anv_state_pool *pool); struct anv_state anv_state_pool_alloc(struct anv_state_pool *pool, uint32_t state_size, uint32_t alignment); @@ -836,26 +950,18 @@ anv_state_table_get(struct anv_state_table *table, uint32_t idx) struct anv_bo_pool { struct anv_device *device; - uint64_t bo_flags; - - void *free_list[16]; + struct util_sparse_array_free_list free_list[16]; }; -void anv_bo_pool_init(struct anv_bo_pool *pool, struct anv_device *device, - uint64_t bo_flags); +void anv_bo_pool_init(struct anv_bo_pool *pool, struct anv_device *device); void anv_bo_pool_finish(struct anv_bo_pool *pool); -VkResult anv_bo_pool_alloc(struct anv_bo_pool *pool, struct anv_bo *bo, - uint32_t size); -void anv_bo_pool_free(struct anv_bo_pool *pool, const struct anv_bo *bo); - -struct anv_scratch_bo { - bool exists; - struct anv_bo bo; -}; +VkResult anv_bo_pool_alloc(struct anv_bo_pool *pool, uint32_t size, + struct anv_bo **bo_out); +void anv_bo_pool_free(struct anv_bo_pool *pool, struct anv_bo *bo); struct anv_scratch_pool { /* Indexed by Per-Thread Scratch Space number (the hardware value) and stage */ - struct anv_scratch_bo bos[16][MESA_SHADER_STAGES]; + struct anv_bo *bos[16][MESA_SHADER_STAGES]; }; void anv_scratch_pool_init(struct anv_device *device, @@ -869,38 +975,17 @@ struct anv_bo *anv_scratch_pool_alloc(struct anv_device *device, /** Implements a BO cache that ensures a 1-1 mapping of GEM BOs to anv_bos */ struct anv_bo_cache { - struct hash_table *bo_map; + struct util_sparse_array bo_map; pthread_mutex_t mutex; }; VkResult anv_bo_cache_init(struct anv_bo_cache *cache); void anv_bo_cache_finish(struct anv_bo_cache *cache); -VkResult anv_bo_cache_alloc(struct anv_device *device, - struct anv_bo_cache *cache, - uint64_t size, uint64_t bo_flags, - struct anv_bo **bo); -VkResult anv_bo_cache_import_host_ptr(struct anv_device *device, - struct anv_bo_cache *cache, - void *host_ptr, uint32_t size, - uint64_t bo_flags, struct anv_bo **bo_out); -VkResult anv_bo_cache_import(struct anv_device *device, - struct anv_bo_cache *cache, - int fd, uint64_t bo_flags, - struct anv_bo **bo); -VkResult anv_bo_cache_export(struct anv_device *device, - struct anv_bo_cache *cache, - struct anv_bo *bo_in, int *fd_out); -void anv_bo_cache_release(struct anv_device *device, - struct anv_bo_cache *cache, - struct anv_bo *bo); struct anv_memory_type { /* Standard bits passed on to the client */ VkMemoryPropertyFlags propertyFlags; uint32_t heapIndex; - - /* Driver-internal book-keeping */ - VkBufferUsageFlags valid_buffer_usage; }; struct anv_memory_heap { @@ -909,17 +994,16 @@ struct anv_memory_heap { VkMemoryHeapFlags flags; /* Driver-internal book-keeping */ - uint64_t vma_start; - uint64_t vma_size; - bool supports_48bit_addresses; VkDeviceSize used; }; struct anv_physical_device { VK_LOADER_DATA _loader_data; + /* Link in anv_instance::physical_devices */ + struct list_head link; + struct anv_instance * instance; - uint32_t chipset_id; bool no_hw; char path[20]; const char * name; @@ -941,16 +1025,20 @@ struct anv_physical_device { bool supports_48bit_addresses; struct brw_compiler * compiler; struct isl_device isl_dev; + struct gen_perf_config * perf; int cmd_parser_version; + bool has_softpin; bool has_exec_async; bool has_exec_capture; bool has_exec_fence; bool has_syncobj; bool has_syncobj_wait; bool has_context_priority; - bool use_softpin; bool has_context_isolation; bool has_mem_available; + uint64_t gtt_size; + + bool use_softpin; bool always_use_bindless; /** True if we can access buffers using A64 messages */ @@ -960,6 +1048,15 @@ struct anv_physical_device { /** True if we can use bindless access for samplers */ bool has_bindless_samplers; + /** True if this device has implicit AUX + * + * If true, CCS is handled as an implicit attachment to the BO rather than + * as an explicitly bound surface. + */ + bool has_implicit_ccs; + + bool always_flush_cache; + struct anv_device_extension_table supported_extensions; uint32_t eu_total; @@ -1001,14 +1098,18 @@ struct anv_instance { struct anv_instance_extension_table enabled_extensions; struct anv_instance_dispatch_table dispatch; + struct anv_physical_device_dispatch_table physical_device_dispatch; struct anv_device_dispatch_table device_dispatch; - int physicalDeviceCount; - struct anv_physical_device physicalDevice; + bool physical_devices_enumerated; + struct list_head physical_devices; bool pipeline_cache_enabled; struct vk_debug_report_instance debug_report_callbacks; + + struct driOptionCache dri_options; + struct driOptionCache available_dri_options; }; VkResult anv_init_wsi(struct anv_physical_device *physical_device); @@ -1018,11 +1119,63 @@ uint32_t anv_physical_device_api_version(struct anv_physical_device *dev); bool anv_physical_device_extension_supported(struct anv_physical_device *dev, const char *name); +struct anv_queue_submit { + struct anv_cmd_buffer * cmd_buffer; + + uint32_t fence_count; + uint32_t fence_array_length; + struct drm_i915_gem_exec_fence * fences; + + uint32_t temporary_semaphore_count; + uint32_t temporary_semaphore_array_length; + struct anv_semaphore_impl * temporary_semaphores; + + /* Semaphores to be signaled with a SYNC_FD. */ + struct anv_semaphore ** sync_fd_semaphores; + uint32_t sync_fd_semaphore_count; + uint32_t sync_fd_semaphore_array_length; + + /* Allocated only with non shareable timelines. */ + struct anv_timeline ** wait_timelines; + uint32_t wait_timeline_count; + uint32_t wait_timeline_array_length; + uint64_t * wait_timeline_values; + + struct anv_timeline ** signal_timelines; + uint32_t signal_timeline_count; + uint32_t signal_timeline_array_length; + uint64_t * signal_timeline_values; + + int in_fence; + bool need_out_fence; + int out_fence; + + uint32_t fence_bo_count; + uint32_t fence_bo_array_length; + /* An array of struct anv_bo pointers with lower bit used as a flag to + * signal we will wait on that BO (see anv_(un)pack_ptr). + */ + uintptr_t * fence_bos; + + const VkAllocationCallbacks * alloc; + VkSystemAllocationScope alloc_scope; + + struct anv_bo * simple_bo; + uint32_t simple_bo_size; + + struct list_head link; +}; + struct anv_queue { VK_LOADER_DATA _loader_data; struct anv_device * device; + /* + * A list of struct anv_queue_submit to be submitted to i915. + */ + struct list_head queued_submits; + VkDeviceQueueCreateFlags flags; }; @@ -1054,6 +1207,8 @@ anv_pipeline_cache_upload_kernel(struct anv_pipeline_cache *cache, uint32_t constant_data_size, const struct brw_stage_prog_data *prog_data, uint32_t prog_data_size, + const struct brw_compile_stats *stats, + uint32_t num_stats, const struct nir_xfb_info *xfb_info, const struct anv_pipeline_bind_map *bind_map); @@ -1072,6 +1227,8 @@ anv_device_upload_kernel(struct anv_device *device, uint32_t constant_data_size, const struct brw_stage_prog_data *prog_data, uint32_t prog_data_size, + const struct brw_compile_stats *stats, + uint32_t num_stats, const struct nir_xfb_info *xfb_info, const struct anv_pipeline_bind_map *bind_map); @@ -1096,8 +1253,7 @@ struct anv_device { VkAllocationCallbacks alloc; - struct anv_instance * instance; - uint32_t chipset_id; + struct anv_physical_device * physical; bool no_hw; struct gen_device_info info; struct isl_device isl_dev; @@ -1110,9 +1266,8 @@ struct anv_device { pthread_mutex_t vma_mutex; struct util_vma_heap vma_lo; + struct util_vma_heap vma_cva; struct util_vma_heap vma_hi; - uint64_t vma_lo_available; - uint64_t vma_hi_available; /** List of all anv_device_memory objects */ struct list_head memory_objects; @@ -1126,25 +1281,24 @@ struct anv_device { struct anv_state_pool binding_table_pool; struct anv_state_pool surface_state_pool; - struct anv_bo workaround_bo; - struct anv_bo trivial_batch_bo; - struct anv_bo hiz_clear_bo; + struct anv_bo * workaround_bo; + struct anv_bo * trivial_batch_bo; + struct anv_bo * hiz_clear_bo; struct anv_pipeline_cache default_pipeline_cache; struct blorp_context blorp; struct anv_state border_colors; + struct anv_state slice_hash; + struct anv_queue queue; struct anv_scratch_pool scratch_pool; - uint32_t default_mocs; - uint32_t external_mocs; - pthread_mutex_t mutex; pthread_cond_t queue_submit; - bool _lost; + int _lost; struct gen_batch_decode_ctx decoder_ctx; /* @@ -1152,12 +1306,23 @@ struct anv_device { * the cmd_buffer's list. */ struct anv_cmd_buffer *cmd_buffer_being_decoded; + + int perf_fd; /* -1 if no opened */ + uint64_t perf_metric; /* 0 if unset */ + + struct gen_aux_map_context *aux_map_ctx; }; +static inline struct anv_instance * +anv_device_instance_or_null(const struct anv_device *device) +{ + return device ? device->physical->instance : NULL; +} + static inline struct anv_state_pool * anv_binding_table_pool(struct anv_device *device) { - if (device->instance->physicalDevice.use_softpin) + if (device->physical->use_softpin) return &device->binding_table_pool; else return &device->surface_state_pool; @@ -1165,7 +1330,7 @@ anv_binding_table_pool(struct anv_device *device) static inline struct anv_state anv_binding_table_pool_alloc(struct anv_device *device) { - if (device->instance->physicalDevice.use_softpin) + if (device->physical->use_softpin) return anv_state_pool_alloc(&device->binding_table_pool, device->binding_table_pool.block_size, 0); else @@ -1180,35 +1345,120 @@ anv_binding_table_pool_free(struct anv_device *device, struct anv_state state) { static inline uint32_t anv_mocs_for_bo(const struct anv_device *device, const struct anv_bo *bo) { - if (bo->flags & ANV_BO_EXTERNAL) - return device->external_mocs; + if (bo->is_external) + return device->isl_dev.mocs.external; else - return device->default_mocs; + return device->isl_dev.mocs.internal; } void anv_device_init_blorp(struct anv_device *device); void anv_device_finish_blorp(struct anv_device *device); +void _anv_device_set_all_queue_lost(struct anv_device *device); VkResult _anv_device_set_lost(struct anv_device *device, const char *file, int line, - const char *msg, ...); + const char *msg, ...) + anv_printflike(4, 5); +VkResult _anv_queue_set_lost(struct anv_queue *queue, + const char *file, int line, + const char *msg, ...) + anv_printflike(4, 5); #define anv_device_set_lost(dev, ...) \ _anv_device_set_lost(dev, __FILE__, __LINE__, __VA_ARGS__) +#define anv_queue_set_lost(queue, ...) \ + _anv_queue_set_lost(queue, __FILE__, __LINE__, __VA_ARGS__) static inline bool anv_device_is_lost(struct anv_device *device) { - return unlikely(device->_lost); + return unlikely(p_atomic_read(&device->_lost)); } -VkResult anv_device_execbuf(struct anv_device *device, - struct drm_i915_gem_execbuffer2 *execbuf, - struct anv_bo **execbuf_bos); VkResult anv_device_query_status(struct anv_device *device); + + +enum anv_bo_alloc_flags { + /** Specifies that the BO must have a 32-bit address + * + * This is the opposite of EXEC_OBJECT_SUPPORTS_48B_ADDRESS. + */ + ANV_BO_ALLOC_32BIT_ADDRESS = (1 << 0), + + /** Specifies that the BO may be shared externally */ + ANV_BO_ALLOC_EXTERNAL = (1 << 1), + + /** Specifies that the BO should be mapped */ + ANV_BO_ALLOC_MAPPED = (1 << 2), + + /** Specifies that the BO should be snooped so we get coherency */ + ANV_BO_ALLOC_SNOOPED = (1 << 3), + + /** Specifies that the BO should be captured in error states */ + ANV_BO_ALLOC_CAPTURE = (1 << 4), + + /** Specifies that the BO will have an address assigned by the caller + * + * Such BOs do not exist in any VMA heap. + */ + ANV_BO_ALLOC_FIXED_ADDRESS = (1 << 5), + + /** Enables implicit synchronization on the BO + * + * This is the opposite of EXEC_OBJECT_ASYNC. + */ + ANV_BO_ALLOC_IMPLICIT_SYNC = (1 << 6), + + /** Enables implicit synchronization on the BO + * + * This is equivalent to EXEC_OBJECT_WRITE. + */ + ANV_BO_ALLOC_IMPLICIT_WRITE = (1 << 7), + + /** Has an address which is visible to the client */ + ANV_BO_ALLOC_CLIENT_VISIBLE_ADDRESS = (1 << 8), + + /** This buffer has implicit CCS data attached to it */ + ANV_BO_ALLOC_IMPLICIT_CCS = (1 << 9), +}; + +VkResult anv_device_alloc_bo(struct anv_device *device, uint64_t size, + enum anv_bo_alloc_flags alloc_flags, + uint64_t explicit_address, + struct anv_bo **bo); +VkResult anv_device_import_bo_from_host_ptr(struct anv_device *device, + void *host_ptr, uint32_t size, + enum anv_bo_alloc_flags alloc_flags, + uint64_t client_address, + struct anv_bo **bo_out); +VkResult anv_device_import_bo(struct anv_device *device, int fd, + enum anv_bo_alloc_flags alloc_flags, + uint64_t client_address, + struct anv_bo **bo); +VkResult anv_device_export_bo(struct anv_device *device, + struct anv_bo *bo, int *fd_out); +void anv_device_release_bo(struct anv_device *device, + struct anv_bo *bo); + +static inline struct anv_bo * +anv_device_lookup_bo(struct anv_device *device, uint32_t gem_handle) +{ + return util_sparse_array_get(&device->bo_cache.bo_map, gem_handle); +} + VkResult anv_device_bo_busy(struct anv_device *device, struct anv_bo *bo); VkResult anv_device_wait(struct anv_device *device, struct anv_bo *bo, int64_t timeout); +VkResult anv_queue_init(struct anv_device *device, struct anv_queue *queue); +void anv_queue_finish(struct anv_queue *queue); + +VkResult anv_queue_execbuf_locked(struct anv_queue *queue, struct anv_queue_submit *submit); +VkResult anv_queue_submit_simple_batch(struct anv_queue *queue, + struct anv_batch *batch); + +uint64_t anv_gettime_ns(void); +uint64_t anv_get_absolute_timeout(uint64_t timeout); + void* anv_gem_mmap(struct anv_device *device, uint32_t gem_handle, uint64_t offset, uint64_t size, uint32_t flags); void anv_gem_munmap(void *p, uint64_t size); @@ -1256,17 +1506,20 @@ int anv_gem_syncobj_wait(struct anv_device *device, uint32_t *handles, uint32_t num_handles, int64_t abs_timeout_ns, bool wait_all); -bool anv_vma_alloc(struct anv_device *device, struct anv_bo *bo); -void anv_vma_free(struct anv_device *device, struct anv_bo *bo); - -VkResult anv_bo_init_new(struct anv_bo *bo, struct anv_device *device, uint64_t size); +uint64_t anv_vma_alloc(struct anv_device *device, + uint64_t size, uint64_t align, + enum anv_bo_alloc_flags alloc_flags, + uint64_t client_address); +void anv_vma_free(struct anv_device *device, + uint64_t address, uint64_t size); struct anv_reloc_list { uint32_t num_relocs; uint32_t array_length; struct drm_i915_gem_relocation_entry * relocs; struct anv_bo ** reloc_bos; - struct set * deps; + uint32_t dep_words; + BITSET_WORD * deps; }; VkResult anv_reloc_list_init(struct anv_reloc_list *list, @@ -1277,13 +1530,13 @@ void anv_reloc_list_finish(struct anv_reloc_list *list, VkResult anv_reloc_list_add(struct anv_reloc_list *list, const VkAllocationCallbacks *alloc, uint32_t offset, struct anv_bo *target_bo, - uint32_t delta); + uint32_t delta, uint64_t *address_u64_out); struct anv_batch_bo { /* Link in the anv_cmd_buffer.owned_batch_bos list */ struct list_head link; - struct anv_bo bo; + struct anv_bo * bo; /* Bytes actually consumed in this batch BO */ uint32_t length; @@ -1320,8 +1573,6 @@ void *anv_batch_emit_dwords(struct anv_batch *batch, int num_dwords); void anv_batch_emit_batch(struct anv_batch *batch, struct anv_batch *other); uint64_t anv_batch_emit_reloc(struct anv_batch *batch, void *location, struct anv_bo *bo, uint32_t offset); -VkResult anv_device_submit_simple_batch(struct anv_device *device, - struct anv_batch *batch); static inline VkResult anv_batch_set_error(struct anv_batch *batch, VkResult error) @@ -1455,51 +1706,6 @@ _anv_combine_address(struct anv_batch *batch, void *location, _dst = NULL; \ })) -/* MEMORY_OBJECT_CONTROL_STATE: - * .GraphicsDataTypeGFDT = 0, - * .LLCCacheabilityControlLLCCC = 0, - * .L3CacheabilityControlL3CC = 1, - */ -#define GEN7_MOCS 1 - -/* MEMORY_OBJECT_CONTROL_STATE: - * .LLCeLLCCacheabilityControlLLCCC = 0, - * .L3CacheabilityControlL3CC = 1, - */ -#define GEN75_MOCS 1 - -/* MEMORY_OBJECT_CONTROL_STATE: - * .MemoryTypeLLCeLLCCacheabilityControl = WB, - * .TargetCache = L3DefertoPATforLLCeLLCselection, - * .AgeforQUADLRU = 0 - */ -#define GEN8_MOCS 0x78 - -/* MEMORY_OBJECT_CONTROL_STATE: - * .MemoryTypeLLCeLLCCacheabilityControl = UCwithFenceifcoherentcycle, - * .TargetCache = L3DefertoPATforLLCeLLCselection, - * .AgeforQUADLRU = 0 - */ -#define GEN8_EXTERNAL_MOCS 0x18 - -/* Skylake: MOCS is now an index into an array of 62 different caching - * configurations programmed by the kernel. - */ - -/* TC=LLC/eLLC, LeCC=WB, LRUM=3, L3CC=WB */ -#define GEN9_MOCS (2 << 1) - -/* TC=LLC/eLLC, LeCC=WB, LRUM=3, L3CC=WB */ -#define GEN9_EXTERNAL_MOCS (1 << 1) - -/* Cannonlake MOCS defines are duplicates of Skylake MOCS defines. */ -#define GEN10_MOCS GEN9_MOCS -#define GEN10_EXTERNAL_MOCS GEN9_EXTERNAL_MOCS - -/* Ice Lake MOCS defines are duplicates of Skylake MOCS defines. */ -#define GEN11_MOCS GEN9_MOCS -#define GEN11_EXTERNAL_MOCS GEN9_EXTERNAL_MOCS - struct anv_device_memory { struct list_head link; @@ -1548,6 +1754,17 @@ struct anv_sampled_image_descriptor { uint32_t sampler; }; +struct anv_texture_swizzle_descriptor { + /** Texture swizzle + * + * See also nir_intrinsic_channel_select_intel + */ + uint8_t swizzle[4]; + + /** Unused padding to ensure the struct is a multiple of 64 bits */ + uint32_t _pad; +}; + /** Struct representing a storage image descriptor */ struct anv_storage_image_descriptor { /** Bindless image handles @@ -1589,6 +1806,8 @@ enum anv_descriptor_data { ANV_DESCRIPTOR_SAMPLED_IMAGE = (1 << 6), /** Storage image handles */ ANV_DESCRIPTOR_STORAGE_IMAGE = (1 << 7), + /** Storage image handles */ + ANV_DESCRIPTOR_TEXTURE_SWIZZLE = (1 << 8), }; struct anv_descriptor_set_binding_layout { @@ -1659,6 +1878,9 @@ struct anv_descriptor_set_layout { /* Number of dynamic offsets used by this descriptor set */ uint16_t dynamic_offset_count; + /* For each shader stage, which offsets apply to that stage */ + uint16_t stage_dynamic_offsets[MESA_SHADER_STAGES]; + /* Size of the descriptor buffer for this descriptor set */ uint32_t descriptor_buffer_size; @@ -1754,7 +1976,7 @@ struct anv_descriptor_pool { uint32_t next; uint32_t free_list; - struct anv_bo bo; + struct anv_bo *bo; struct util_vma_heap bo_heap; struct anv_state_stream surface_state_stream; @@ -1862,32 +2084,63 @@ anv_descriptor_set_destroy(struct anv_device *device, struct anv_descriptor_pool *pool, struct anv_descriptor_set *set); +#define ANV_DESCRIPTOR_SET_NULL (UINT8_MAX - 5) +#define ANV_DESCRIPTOR_SET_PUSH_CONSTANTS (UINT8_MAX - 4) #define ANV_DESCRIPTOR_SET_DESCRIPTORS (UINT8_MAX - 3) #define ANV_DESCRIPTOR_SET_NUM_WORK_GROUPS (UINT8_MAX - 2) #define ANV_DESCRIPTOR_SET_SHADER_CONSTANTS (UINT8_MAX - 1) #define ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS UINT8_MAX struct anv_pipeline_binding { - /* The descriptor set this surface corresponds to. The special value of - * ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS indicates that the offset refers - * to a color attachment and not a regular descriptor. + /** Index in the descriptor set + * + * This is a flattened index; the descriptor set layout is already taken + * into account. + */ + uint32_t index; + + /** The descriptor set this surface corresponds to. + * + * The special ANV_DESCRIPTOR_SET_* values above indicates that this + * binding is not a normal descriptor set but something else. */ uint8_t set; - /* Binding in the descriptor set */ - uint32_t binding; + union { + /** Plane in the binding index for images */ + uint8_t plane; - /* Index in the binding */ + /** Input attachment index (relative to the subpass) */ + uint8_t input_attachment_index; + + /** Dynamic offset index (for dynamic UBOs and SSBOs) */ + uint8_t dynamic_offset_index; + }; + + /** For a storage image, whether it is write-only */ + uint8_t write_only; + + /** Pad to 64 bits so that there are no holes and we can safely memcmp + * assuming POD zero-initialization. + */ + uint8_t pad; +}; + +struct anv_push_range { + /** Index in the descriptor set */ uint32_t index; - /* Plane in the binding index */ - uint8_t plane; + /** Descriptor set index */ + uint8_t set; - /* Input attachment index (relative to the subpass) */ - uint8_t input_attachment_index; + /** Dynamic offset index (for dynamic UBOs) */ + uint8_t dynamic_offset_index; - /* For a storage image, whether it is write-only */ - bool write_only; + /** Start offset in units of 32B */ + uint8_t start; + + /** Range in units of 32B */ + uint8_t length; }; struct anv_pipeline_layout { @@ -1934,14 +2187,57 @@ enum anv_cmd_dirty_bits { ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK = 1 << 6, /* VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK */ ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK = 1 << 7, /* VK_DYNAMIC_STATE_STENCIL_WRITE_MASK */ ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE = 1 << 8, /* VK_DYNAMIC_STATE_STENCIL_REFERENCE */ - ANV_CMD_DIRTY_DYNAMIC_ALL = (1 << 9) - 1, ANV_CMD_DIRTY_PIPELINE = 1 << 9, ANV_CMD_DIRTY_INDEX_BUFFER = 1 << 10, ANV_CMD_DIRTY_RENDER_TARGETS = 1 << 11, ANV_CMD_DIRTY_XFB_ENABLE = 1 << 12, + ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE = 1 << 13, /* VK_DYNAMIC_STATE_LINE_STIPPLE_EXT */ }; typedef uint32_t anv_cmd_dirty_mask_t; +#define ANV_CMD_DIRTY_DYNAMIC_ALL \ + (ANV_CMD_DIRTY_DYNAMIC_VIEWPORT | \ + ANV_CMD_DIRTY_DYNAMIC_SCISSOR | \ + ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH | \ + ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS | \ + ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS | \ + ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS | \ + ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK | \ + ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK | \ + ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE | \ + ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE) + +static inline enum anv_cmd_dirty_bits +anv_cmd_dirty_bit_for_vk_dynamic_state(VkDynamicState vk_state) +{ + switch (vk_state) { + case VK_DYNAMIC_STATE_VIEWPORT: + return ANV_CMD_DIRTY_DYNAMIC_VIEWPORT; + case VK_DYNAMIC_STATE_SCISSOR: + return ANV_CMD_DIRTY_DYNAMIC_SCISSOR; + case VK_DYNAMIC_STATE_LINE_WIDTH: + return ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH; + case VK_DYNAMIC_STATE_DEPTH_BIAS: + return ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS; + case VK_DYNAMIC_STATE_BLEND_CONSTANTS: + return ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS; + case VK_DYNAMIC_STATE_DEPTH_BOUNDS: + return ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS; + case VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK: + return ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK; + case VK_DYNAMIC_STATE_STENCIL_WRITE_MASK: + return ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK; + case VK_DYNAMIC_STATE_STENCIL_REFERENCE: + return ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE; + case VK_DYNAMIC_STATE_LINE_STIPPLE_EXT: + return ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE; + default: + assert(!"Unsupported dynamic state"); + return 0; + } +} + + enum anv_pipe_bits { ANV_PIPE_DEPTH_CACHE_FLUSH_BIT = (1 << 0), ANV_PIPE_STALL_AT_SCOREBOARD_BIT = (1 << 1), @@ -1949,6 +2245,7 @@ enum anv_pipe_bits { ANV_PIPE_CONSTANT_CACHE_INVALIDATE_BIT = (1 << 3), ANV_PIPE_VF_CACHE_INVALIDATE_BIT = (1 << 4), ANV_PIPE_DATA_CACHE_FLUSH_BIT = (1 << 5), + ANV_PIPE_TILE_CACHE_FLUSH_BIT = (1 << 6), ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT = (1 << 10), ANV_PIPE_INSTRUCTION_CACHE_INVALIDATE_BIT = (1 << 11), ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT = (1 << 12), @@ -1969,12 +2266,25 @@ enum anv_pipe_bits { * before they can proceed with the copy. */ ANV_PIPE_RENDER_TARGET_BUFFER_WRITES = (1 << 22), + + /* This bit does not exist directly in PIPE_CONTROL. It means that Gen12 + * AUX-TT data has changed and we need to invalidate AUX-TT data. This is + * done by writing the AUX-TT register. + */ + ANV_PIPE_AUX_TABLE_INVALIDATE_BIT = (1 << 23), + + /* This bit does not exist directly in PIPE_CONTROL. It means that a + * PIPE_CONTROL with a post-sync operation will follow. This is used to + * implement a workaround for Gen9. + */ + ANV_PIPE_POST_SYNC_BIT = (1 << 24), }; #define ANV_PIPE_FLUSH_BITS ( \ ANV_PIPE_DEPTH_CACHE_FLUSH_BIT | \ ANV_PIPE_DATA_CACHE_FLUSH_BIT | \ - ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT) + ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | \ + ANV_PIPE_TILE_CACHE_FLUSH_BIT) #define ANV_PIPE_STALL_BITS ( \ ANV_PIPE_STALL_AT_SCOREBOARD_BIT | \ @@ -1987,7 +2297,8 @@ enum anv_pipe_bits { ANV_PIPE_VF_CACHE_INVALIDATE_BIT | \ ANV_PIPE_DATA_CACHE_FLUSH_BIT | \ ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT | \ - ANV_PIPE_INSTRUCTION_CACHE_INVALIDATE_BIT) + ANV_PIPE_INSTRUCTION_CACHE_INVALIDATE_BIT | \ + ANV_PIPE_AUX_TABLE_INVALIDATE_BIT) static inline enum anv_pipe_bits anv_pipe_flush_bits_for_access_flags(VkAccessFlags flags) @@ -2148,20 +2459,30 @@ struct anv_xfb_binding { VkDeviceSize size; }; -#define ANV_PARAM_PUSH(offset) ((1 << 16) | (uint32_t)(offset)) -#define ANV_PARAM_IS_PUSH(param) ((uint32_t)(param) >> 16 == 1) -#define ANV_PARAM_PUSH_OFFSET(param) ((param) & 0xffff) - -#define ANV_PARAM_DYN_OFFSET(offset) ((2 << 16) | (uint32_t)(offset)) -#define ANV_PARAM_IS_DYN_OFFSET(param) ((uint32_t)(param) >> 16 == 2) -#define ANV_PARAM_DYN_OFFSET_IDX(param) ((param) & 0xffff) - struct anv_push_constants { - /* Push constant data provided by the client through vkPushConstants */ + /** Push constant data provided by the client through vkPushConstants */ uint8_t client_data[MAX_PUSH_CONSTANTS_SIZE]; - /* Used for vkCmdDispatchBase */ - uint32_t base_work_group_id[3]; + /** Dynamic offsets for dynamic UBOs and SSBOs */ + uint32_t dynamic_offsets[MAX_DYNAMIC_BUFFERS]; + + struct { + /** Base workgroup ID + * + * Used for vkCmdDispatchBase. + */ + uint32_t base_work_group_id[3]; + + /** Subgroup ID + * + * This is never set by software but is implicitly filled out when + * uploading the push constants for compute shaders. + */ + uint32_t subgroup_id; + + /** Pad out to a multiple of 32 bytes */ + uint32_t pad[4]; + } cs; }; struct anv_dynamic_state { @@ -2204,13 +2525,18 @@ struct anv_dynamic_state { uint32_t front; uint32_t back; } stencil_reference; + + struct { + uint32_t factor; + uint16_t pattern; + } line_stipple; }; extern const struct anv_dynamic_state default_dynamic_state; -void anv_dynamic_state_copy(struct anv_dynamic_state *dest, - const struct anv_dynamic_state *src, - uint32_t copy_mask); +uint32_t anv_dynamic_state_copy(struct anv_dynamic_state *dest, + const struct anv_dynamic_state *src, + uint32_t copy_mask); struct anv_surface_state { struct anv_state state; @@ -2246,6 +2572,7 @@ struct anv_attachment_state { struct anv_surface_state input; VkImageLayout current_layout; + VkImageLayout current_stencil_layout; VkImageAspectFlags pending_clear_aspects; VkImageAspectFlags pending_load_aspects; bool fast_clear; @@ -2260,6 +2587,28 @@ struct anv_attachment_state { * have not been cleared yet when multiview is active. */ uint32_t pending_clear_views; + struct anv_image_view * image_view; +}; + +/** State tracking for vertex buffer flushes + * + * On Gen8-9, the VF cache only considers the bottom 32 bits of memory + * addresses. If you happen to have two vertex buffers which get placed + * exactly 4 GiB apart and use them in back-to-back draw calls, you can get + * collisions. In order to solve this problem, we track vertex address ranges + * which are live in the cache and invalidate the cache if one ever exceeds 32 + * bits. + */ +struct anv_vb_cache_range { + /* Virtual address at which the live vertex buffer cache range starts for + * this vertex buffer index. + */ + uint64_t start; + + /* Virtual address of the byte after where vertex buffer cache range ends. + * This is exclusive such that end - start is the size of the range. + */ + uint64_t end; }; /** State tracking for particular pipeline bind point @@ -2272,11 +2621,8 @@ struct anv_attachment_state { */ struct anv_cmd_pipeline_state { struct anv_pipeline *pipeline; - struct anv_pipeline_layout *layout; struct anv_descriptor_set *descriptors[MAX_SETS]; - uint32_t dynamic_offsets[MAX_DYNAMIC_BUFFERS]; - struct anv_push_descriptor_set *push_descriptors[MAX_SETS]; }; @@ -2293,6 +2639,11 @@ struct anv_cmd_graphics_state { anv_cmd_dirty_mask_t dirty; uint32_t vb_dirty; + struct anv_vb_cache_range ib_bound_range; + struct anv_vb_cache_range ib_dirty_range; + struct anv_vb_cache_range vb_bound_ranges[33]; + struct anv_vb_cache_range vb_dirty_ranges[33]; + struct anv_dynamic_state dynamic; struct { @@ -2322,6 +2673,7 @@ struct anv_cmd_state { /* PIPELINE_SELECT.PipelineSelection */ uint32_t current_pipeline; const struct gen_l3_config * current_l3_config; + uint32_t last_aux_map_state; struct anv_cmd_graphics_state gfx; struct anv_cmd_compute_state compute; @@ -2343,6 +2695,10 @@ struct anv_cmd_state { struct anv_state binding_tables[MESA_SHADER_STAGES]; struct anv_state samplers[MESA_SHADER_STAGES]; + unsigned char sampler_sha1s[MESA_SHADER_STAGES][20]; + unsigned char surface_sha1s[MESA_SHADER_STAGES][20]; + unsigned char push_sha1s[MESA_SHADER_STAGES][20]; + /** * Whether or not the gen8 PMA fix is enabled. We ensure that, at the top * of any command buffer it is disabled by disabling it in EndCommandBuffer @@ -2359,6 +2715,12 @@ struct anv_cmd_state { bool conditional_render_enabled; + /** + * Last rendering scale argument provided to + * genX(cmd_buffer_emit_hashing_mode)(). + */ + unsigned current_hash_scale; + /** * Array length is anv_cmd_state::pass::attachment_count. Array content is * valid only when recording a render pass instance. @@ -2423,7 +2785,7 @@ struct anv_cmd_buffer { * initialized by anv_cmd_buffer_init_batch_bo_chain() */ struct u_vector bt_block_states; - uint32_t bt_next; + struct anv_state bt_next; struct anv_reloc_list surface_relocs; /** Last seen surface state block pool center bo offset */ @@ -2440,6 +2802,9 @@ struct anv_cmd_buffer { VkCommandBufferLevel level; struct anv_cmd_state state; + + /* Set by SetPerformanceMarkerINTEL, written into queries by CmdBeginQuery */ + uint64_t intel_perf_marker; }; VkResult anv_cmd_buffer_init_batch_bo_chain(struct anv_cmd_buffer *cmd_buffer); @@ -2449,11 +2814,13 @@ void anv_cmd_buffer_end_batch_buffer(struct anv_cmd_buffer *cmd_buffer); void anv_cmd_buffer_add_secondary(struct anv_cmd_buffer *primary, struct anv_cmd_buffer *secondary); void anv_cmd_buffer_prepare_execbuf(struct anv_cmd_buffer *cmd_buffer); -VkResult anv_cmd_buffer_execbuf(struct anv_device *device, +VkResult anv_cmd_buffer_execbuf(struct anv_queue *queue, struct anv_cmd_buffer *cmd_buffer, const VkSemaphore *in_semaphores, + const uint64_t *in_wait_values, uint32_t num_in_semaphores, const VkSemaphore *out_semaphores, + const uint64_t *out_signal_values, uint32_t num_out_semaphores, VkFence fence); @@ -2513,6 +2880,7 @@ void anv_cmd_emit_conditional_render_predicate(struct anv_cmd_buffer *cmd_buffer enum anv_fence_type { ANV_FENCE_TYPE_NONE = 0, ANV_FENCE_TYPE_BO, + ANV_FENCE_TYPE_WSI_BO, ANV_FENCE_TYPE_SYNCOBJ, ANV_FENCE_TYPE_WSI, }; @@ -2543,7 +2911,7 @@ struct anv_fence_impl { * will say it's idle in this case. */ struct { - struct anv_bo bo; + struct anv_bo *bo; enum anv_bo_fence_state state; } bo; @@ -2572,6 +2940,9 @@ struct anv_fence { struct anv_fence_impl temporary; }; +void anv_fence_reset_temporary(struct anv_device *device, + struct anv_fence *fence); + struct anv_event { uint64_t semaphore; struct anv_state state; @@ -2581,18 +2952,46 @@ enum anv_semaphore_type { ANV_SEMAPHORE_TYPE_NONE = 0, ANV_SEMAPHORE_TYPE_DUMMY, ANV_SEMAPHORE_TYPE_BO, + ANV_SEMAPHORE_TYPE_WSI_BO, ANV_SEMAPHORE_TYPE_SYNC_FILE, ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ, + ANV_SEMAPHORE_TYPE_TIMELINE, +}; + +struct anv_timeline_point { + struct list_head link; + + uint64_t serial; + + /* Number of waiter on this point, when > 0 the point should not be garbage + * collected. + */ + int waiting; + + /* BO used for synchronization. */ + struct anv_bo *bo; +}; + +struct anv_timeline { + pthread_mutex_t mutex; + pthread_cond_t cond; + + uint64_t highest_past; + uint64_t highest_pending; + + struct list_head points; + struct list_head free_points; }; struct anv_semaphore_impl { enum anv_semaphore_type type; union { - /* A BO representing this semaphore when type == ANV_SEMAPHORE_TYPE_BO. - * This BO will be added to the object list on any execbuf2 calls for - * which this semaphore is used as a wait or signal fence. When used as - * a signal fence, the EXEC_OBJECT_WRITE flag will be set. + /* A BO representing this semaphore when type == ANV_SEMAPHORE_TYPE_BO + * or type == ANV_SEMAPHORE_TYPE_WSI_BO. This BO will be added to the + * object list on any execbuf2 calls for which this semaphore is used as + * a wait or signal fence. When used as a signal fence or when type == + * ANV_SEMAPHORE_TYPE_WSI_BO, the EXEC_OBJECT_WRITE flag will be set. */ struct anv_bo *bo; @@ -2607,10 +3006,18 @@ struct anv_semaphore_impl { * import so we don't need to bother with a userspace cache. */ uint32_t syncobj; + + /* Non shareable timeline semaphore + * + * Used when kernel don't have support for timeline semaphores. + */ + struct anv_timeline timeline; }; }; struct anv_semaphore { + uint32_t refcount; + /* Permanent semaphore state. Every semaphore has some form of permanent * state (type != ANV_SEMAPHORE_TYPE_NONE). This may be a BO to fence on * (for cross-process semaphores0 or it could just be a dummy for use @@ -2659,11 +3066,17 @@ mesa_to_vk_shader_stage(gl_shader_stage mesa_stage) __tmp &= ~(1 << (stage))) struct anv_pipeline_bind_map { + unsigned char surface_sha1[20]; + unsigned char sampler_sha1[20]; + unsigned char push_sha1[20]; + uint32_t surface_count; uint32_t sampler_count; struct anv_pipeline_binding * surface_to_descriptor; struct anv_pipeline_binding * sampler_to_descriptor; + + struct anv_push_range push_ranges[4]; }; struct anv_shader_bin_key { @@ -2685,6 +3098,9 @@ struct anv_shader_bin { const struct brw_stage_prog_data *prog_data; uint32_t prog_data_size; + struct brw_compile_stats stats[3]; + uint32_t num_stats; + struct nir_xfb_info *xfb_info; struct anv_pipeline_bind_map bind_map; @@ -2697,6 +3113,7 @@ anv_shader_bin_create(struct anv_device *device, const void *constant_data, uint32_t constant_data_size, const struct brw_stage_prog_data *prog_data, uint32_t prog_data_size, const void *prog_data_param, + const struct brw_compile_stats *stats, uint32_t num_stats, const struct nir_xfb_info *xfb_info, const struct anv_pipeline_bind_map *bind_map); @@ -2718,20 +3135,36 @@ anv_shader_bin_unref(struct anv_device *device, struct anv_shader_bin *shader) anv_shader_bin_destroy(device, shader); } +/* 5 possible simultaneous shader stages and FS may have up to 3 binaries */ +#define MAX_PIPELINE_EXECUTABLES 7 + +struct anv_pipeline_executable { + gl_shader_stage stage; + + struct brw_compile_stats stats; + + char *nir; + char *disasm; +}; + struct anv_pipeline { struct anv_device * device; struct anv_batch batch; uint32_t batch_data[512]; struct anv_reloc_list batch_relocs; - uint32_t dynamic_state_mask; + anv_cmd_dirty_mask_t dynamic_state_mask; struct anv_dynamic_state dynamic_state; - struct anv_subpass * subpass; + void * mem_ctx; - bool needs_data_cache; + VkPipelineCreateFlags flags; + struct anv_subpass * subpass; struct anv_shader_bin * shaders[MESA_SHADER_STAGES]; + uint32_t num_executables; + struct anv_pipeline_executable executables[MAX_PIPELINE_EXECUTABLES]; + struct { const struct gen_l3_config * l3_config; uint32_t total_size; @@ -2747,8 +3180,6 @@ struct anv_pipeline { uint32_t instance_divisor; } vb[MAX_VBS]; - uint8_t xfb_used; - bool primitive_restart; uint32_t topology; @@ -2762,6 +3193,7 @@ struct anv_pipeline { bool depth_clip_enable; bool sample_shading_enable; bool kill_pixel; + bool depth_bounds_test_enable; struct { uint32_t sf[7]; @@ -2857,6 +3289,12 @@ struct anv_format { bool can_ycbcr; }; +/** + * Return the aspect's _format_ plane, not its _memory_ plane (using the + * vocabulary of VK_EXT_image_drm_format_modifier). As a consequence, \a + * aspect_mask may contain VK_IMAGE_ASPECT_PLANE_*, but must not contain + * VK_IMAGE_ASPECT_MEMORY_PLANE_* . + */ static inline uint32_t anv_image_aspect_to_plane(VkImageAspectFlags image_aspects, VkImageAspectFlags aspect_mask) @@ -2920,6 +3358,12 @@ anv_get_isl_format(const struct gen_device_info *devinfo, VkFormat vk_format, return anv_get_format_plane(devinfo, vk_format, aspect, tiling).isl_format; } +bool anv_formats_ccs_e_compatible(const struct gen_device_info *devinfo, + VkImageCreateFlags create_flags, + VkFormat vk_format, + VkImageTiling vk_tiling, + const VkImageFormatListCreateInfoKHR *fmt_list); + static inline struct isl_swizzle anv_swizzle_for_render(struct isl_swizzle swizzle) { @@ -2965,7 +3409,8 @@ struct anv_image { uint32_t array_size; uint32_t samples; /**< VkImageCreateInfo::samples */ uint32_t n_planes; - VkImageUsageFlags usage; /**< Superset of VkImageCreateInfo::usage. */ + VkImageUsageFlags usage; /**< VkImageCreateInfo::usage. */ + VkImageUsageFlags stencil_usage; VkImageCreateFlags create_flags; /* Flags used when creating image. */ VkImageTiling tiling; /** VkImageCreateInfo::tiling */ @@ -2992,11 +3437,6 @@ struct anv_image { */ bool disjoint; - /* All the formats that can be used when creating views of this image - * are CCS_E compatible. - */ - bool ccs_e_compatible; - /* Image was created with external format. */ bool external_format; @@ -3056,11 +3496,9 @@ struct anv_image { struct anv_surface shadow_surface; /** - * For color images, this is the aux usage for this image when not used - * as a color attachment. - * - * For depth/stencil images, this is set to ISL_AUX_USAGE_HIZ if the - * image has a HiZ buffer. + * The base aux usage for this image. For color images, this can be + * either CCS_E or CCS_D depending on whether or not we can reliably + * leave CCS on all the time. */ enum isl_aux_usage aux_usage; @@ -3100,8 +3538,13 @@ anv_image_aux_levels(const struct anv_image * const image, VkImageAspectFlagBits aspect) { uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect); - return image->planes[plane].aux_surface.isl.size_B > 0 ? - image->planes[plane].aux_surface.isl.levels : 0; + if (image->planes[plane].aux_usage == ISL_AUX_USAGE_NONE) + return 0; + + /* The Gen12 CCS aux surface is represented with only one level. */ + return image->planes[plane].aux_surface.isl.tiling == ISL_TILING_GEN12_CCS ? + image->planes[plane].surface.isl.levels : + image->planes[plane].aux_surface.isl.levels; } /* Returns the number of auxiliary buffer layers attached to an image. */ @@ -3122,8 +3565,15 @@ anv_image_aux_layers(const struct anv_image * const image, return 0; } else { uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect); - return MAX2(image->planes[plane].aux_surface.isl.logical_level0_px.array_len, - image->planes[plane].aux_surface.isl.logical_level0_px.depth >> miplevel); + + /* The Gen12 CCS aux surface is represented with only one layer. */ + const struct isl_extent4d *aux_logical_level0_px = + image->planes[plane].aux_surface.isl.tiling == ISL_TILING_GEN12_CCS ? + &image->planes[plane].surface.isl.logical_level0_px : + &image->planes[plane].aux_surface.isl.logical_level0_px; + + return MAX2(aux_logical_level0_px->array_len, + aux_logical_level0_px->depth >> miplevel); } } @@ -3176,6 +3626,8 @@ anv_image_get_compression_state_addr(const struct anv_device *device, } addr.offset += array_layer * 4; + assert(addr.offset < + image->planes[plane].address.offset + image->planes[plane].size); return addr; } @@ -3199,6 +3651,15 @@ anv_can_sample_with_hiz(const struct gen_device_info * const devinfo, return image->samples == 1; } +static inline bool +anv_image_plane_uses_aux_map(const struct anv_device *device, + const struct anv_image *image, + uint32_t plane) +{ + return device->info.has_aux_map && + isl_aux_usage_has_ccs(image->planes[plane].aux_usage); +} + void anv_cmd_buffer_mark_image_written(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *image, @@ -3272,13 +3733,21 @@ anv_image_ccs_op(struct anv_cmd_buffer *cmd_buffer, void anv_image_copy_to_shadow(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *image, + VkImageAspectFlagBits aspect, uint32_t base_level, uint32_t level_count, uint32_t base_layer, uint32_t layer_count); +enum isl_aux_state +anv_layout_to_aux_state(const struct gen_device_info * const devinfo, + const struct anv_image *image, + const VkImageAspectFlagBits aspect, + const VkImageLayout layout); + enum isl_aux_usage anv_layout_to_aux_usage(const struct gen_device_info * const devinfo, const struct anv_image *image, const VkImageAspectFlagBits aspect, + const VkImageUsageFlagBits usage, const VkImageLayout layout); enum anv_fast_clear_type @@ -3404,16 +3873,12 @@ VkResult anv_image_create(VkDevice _device, const VkAllocationCallbacks* alloc, VkImage *pImage); -const struct anv_surface * -anv_image_get_surface_for_aspect_mask(const struct anv_image *image, - VkImageAspectFlags aspect_mask); - enum isl_format anv_isl_format_for_descriptor_type(VkDescriptorType type); -static inline struct VkExtent3D +static inline VkExtent3D anv_sanitize_image_extent(const VkImageType imageType, - const struct VkExtent3D imageExtent) + const VkExtent3D imageExtent) { switch (imageType) { case VK_IMAGE_TYPE_1D: @@ -3427,9 +3892,9 @@ anv_sanitize_image_extent(const VkImageType imageType, } } -static inline struct VkOffset3D +static inline VkOffset3D anv_sanitize_image_offset(const VkImageType imageType, - const struct VkOffset3D imageOffset) + const VkOffset3D imageOffset) { switch (imageType) { case VK_IMAGE_TYPE_1D: @@ -3510,6 +3975,9 @@ struct anv_subpass_attachment { VkImageUsageFlagBits usage; uint32_t attachment; VkImageLayout layout; + + /* Used only with attachment containing stencil data. */ + VkImageLayout stencil_layout; }; struct anv_subpass { @@ -3560,6 +4028,9 @@ struct anv_render_pass_attachment { VkImageLayout final_layout; VkImageLayout first_subpass_layout; + VkImageLayout stencil_initial_layout; + VkImageLayout stencil_final_layout; + /* The subpass id in which the attachment will be used last. */ uint32_t last_subpass_idx; }; @@ -3582,16 +4053,23 @@ struct anv_query_pool { uint32_t stride; /** Number of slots in this query pool */ uint32_t slots; - struct anv_bo bo; + struct anv_bo * bo; }; int anv_get_instance_entrypoint_index(const char *name); int anv_get_device_entrypoint_index(const char *name); +int anv_get_physical_device_entrypoint_index(const char *name); + +const char *anv_get_instance_entry_name(int index); +const char *anv_get_physical_device_entry_name(int index); +const char *anv_get_device_entry_name(int index); bool anv_instance_entrypoint_is_enabled(int index, uint32_t core_version, const struct anv_instance_extension_table *instance); - +bool +anv_physical_device_entrypoint_is_enabled(int index, uint32_t core_version, + const struct anv_instance_extension_table *instance); bool anv_device_entrypoint_is_enabled(int index, uint32_t core_version, const struct anv_instance_extension_table *instance, @@ -3612,8 +4090,7 @@ enum anv_dump_action { void anv_dump_start(struct anv_device *device, enum anv_dump_action actions); void anv_dump_finish(void); -void anv_dump_add_framebuffer(struct anv_cmd_buffer *cmd_buffer, - struct anv_framebuffer *fb); +void anv_dump_add_attachments(struct anv_cmd_buffer *cmd_buffer); static inline uint32_t anv_get_subpass_id(const struct anv_cmd_state * const cmd_state) @@ -3630,6 +4107,9 @@ anv_get_subpass_id(const struct anv_cmd_state * const cmd_state) return subpass_id; } +struct gen_perf_config *anv_get_perf(const struct gen_device_info *devinfo, int fd); +void anv_device_perf_init(struct anv_device *device); + #define ANV_DEFINE_HANDLE_CASTS(__anv_type, __VkType) \ \ static inline struct __anv_type * \ @@ -3713,6 +4193,9 @@ ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_ycbcr_conversion, VkSamplerYcbcrConversion) # define genX(x) gen11_##x # include "anv_genX.h" # undef genX +# define genX(x) gen12_##x +# include "anv_genX.h" +# undef genX #endif #endif /* ANV_PRIVATE_H */