X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fintel%2Fvulkan%2Fanv_private.h;h=d6b0f1057998bfe88d5f8194457342d8d45ec1e6;hb=65de778e0b592f76964631b1e9f87f2cb55a7861;hp=67049cc37fe584a042c334b87af39dfe1f2decee;hpb=246261f0addfc24f69ae412b9ef7e40e2c667a4a;p=mesa.git diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 67049cc37fe..d6b0f105799 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -46,6 +46,7 @@ #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" @@ -61,6 +62,7 @@ #include "util/xmlconfig.h" #include "vk_alloc.h" #include "vk_debug_report.h" +#include "vk_object.h" /* Pre-declarations needed for WSI entrypoints */ struct wl_surface; @@ -76,8 +78,9 @@ struct anv_image_view; struct anv_instance; struct gen_aux_map_context; -struct gen_l3_config; struct gen_perf_config; +struct gen_perf_counter_pass; +struct gen_perf_query_result; #include #include @@ -127,7 +130,9 @@ struct gen_perf_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) @@ -139,6 +144,8 @@ struct gen_perf_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 @@ -168,6 +175,14 @@ struct gen_perf_config; #define MAX_PUSH_DESCRIPTORS 32 /* Minimum requirement */ #define MAX_INLINE_UNIFORM_BLOCK_SIZE 4096 #define MAX_INLINE_UNIFORM_BLOCK_DESCRIPTORS 32 +/* We need 16 for UBO block reads to work and 32 for push UBOs. However, we + * use 64 here to avoid cache issues. This could most likely bring it back to + * 32 if we had different virtual addresses for the different views on a given + * GEM object. + */ +#define ANV_UBO_ALIGNMENT 64 +#define ANV_SSBO_BOUNDS_CHECK_ALIGNMENT 4 +#define MAX_VIEWS_FOR_PRIMITIVE_REPLICATION 16 /* From the Skylake PRM Vol. 7 "Binding Table Surface State Model": * @@ -208,6 +223,12 @@ struct gen_perf_config; */ #define ANV_PREDICATE_RESULT_REG 0x2678 /* MI_ALU_REG15 */ +/* We reserve this MI ALU register to pass around an offset computed from + * VkPerformanceQuerySubmitInfoKHR::counterPassIndex VK_KHR_performance_query. + * Other code which uses the MI ALU should leave it alone. + */ +#define ANV_PERF_QUERY_OFFSET_REG 0x2670 /* MI_ALU_REG14 */ + /* 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 @@ -225,18 +246,31 @@ align_down_npot_u32(uint32_t v, uint32_t a) return v - (v % a); } +static inline uint32_t +align_down_u32(uint32_t v, uint32_t a) +{ + assert(a != 0 && a == (a & -a)); + return v & ~(a - 1); +} + static inline uint32_t align_u32(uint32_t v, uint32_t a) { assert(a != 0 && a == (a & -a)); - return (v + a - 1) & ~(a - 1); + return align_down_u32(v + a - 1, 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 @@ -444,15 +478,16 @@ VkResult __vk_errorf(struct anv_instance *instance, const void *object, #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 /** @@ -473,7 +508,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); @@ -634,6 +669,7 @@ struct anv_bo { */ uint64_t offset; + /** Size of the buffer not including implicit aux */ uint64_t size; /* Map for internally mapped BOs. @@ -642,6 +678,30 @@ struct anv_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; @@ -662,8 +722,21 @@ struct anv_bo { /** 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 struct anv_bo * +anv_bo_ref(struct anv_bo *bo) +{ + p_atomic_inc(&bo->refcount); + return bo; +} + static inline struct anv_bo * anv_bo_unwrap(struct anv_bo *bo) { @@ -816,6 +889,11 @@ struct anv_state_table { struct anv_state_pool { struct anv_block_pool block_pool; + /* Offset into the relevant state base address where the state pool starts + * allocating memory. + */ + int32_t start_offset; + struct anv_state_table table; /* The size of blocks which will be allocated from the block pool */ @@ -827,7 +905,11 @@ struct anv_state_pool { struct anv_fixed_size_state_pool buckets[ANV_STATE_BUCKETS]; }; -struct anv_state_stream_block; +struct anv_state_reserved_pool { + struct anv_state_pool *pool; + union anv_free_list reserved_blocks; + uint32_t count; +}; struct anv_state_stream { struct anv_state_pool *state_pool; @@ -842,7 +924,7 @@ struct anv_state_stream { uint32_t next; /* List of all blocks allocated from this pool */ - struct anv_state_stream_block *block_list; + struct util_dynarray all_blocks; }; /* The block_pool functions exported for testing only. The block pool should @@ -857,11 +939,13 @@ 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, + uint64_t base_address, + int32_t start_offset, 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, @@ -875,6 +959,15 @@ void anv_state_stream_finish(struct anv_state_stream *stream); struct anv_state anv_state_stream_alloc(struct anv_state_stream *stream, uint32_t size, uint32_t alignment); +void anv_state_reserved_pool_init(struct anv_state_reserved_pool *pool, + struct anv_state_pool *parent, + uint32_t count, uint32_t size, + uint32_t alignment); +void anv_state_reserved_pool_finish(struct anv_state_reserved_pool *pool); +struct anv_state anv_state_reserved_pool_alloc(struct anv_state_reserved_pool *pool); +void anv_state_reserved_pool_free(struct anv_state_reserved_pool *pool, + struct anv_state state); + VkResult anv_state_table_init(struct anv_state_table *table, struct anv_device *device, uint32_t initial_entries); @@ -900,13 +993,10 @@ anv_state_table_get(struct anv_state_table *table, uint32_t idx) struct anv_bo_pool { struct anv_device *device; - uint64_t bo_flags; - 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, uint32_t size, struct anv_bo **bo_out); @@ -939,9 +1029,6 @@ 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 { @@ -949,18 +1036,20 @@ struct anv_memory_heap { VkDeviceSize size; VkMemoryHeapFlags flags; - /* Driver-internal book-keeping */ - uint64_t vma_start; - uint64_t vma_size; - bool supports_48bit_addresses; - VkDeviceSize used; + /** Driver-internal book-keeping. + * + * Align it to 64 bits to make atomic operations faster on 32 bit platforms. + */ + VkDeviceSize used __attribute__ ((aligned (8))); }; struct anv_physical_device { - VK_LOADER_DATA _loader_data; + struct vk_object_base base; + + /* 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; @@ -984,16 +1073,21 @@ struct anv_physical_device { 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; + bool has_mmap_offset; + uint64_t gtt_size; + + bool use_softpin; bool always_use_bindless; + bool use_call_secondary; /** True if we can access buffers using A64 messages */ bool has_a64_buffer_access; @@ -1002,8 +1096,23 @@ struct anv_physical_device { /** True if we can use bindless access for samplers */ bool has_bindless_samplers; + /** True if we can read the GPU timestamp register + * + * When running in a virtual context, the timestamp register is unreadable + * on Gen12+. + */ + bool has_reg_timestamp; + + /** 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; - struct anv_physical_device_dispatch_table dispatch; uint32_t eu_total; uint32_t subslice_total; @@ -1036,7 +1145,7 @@ struct anv_app_info { }; struct anv_instance { - VK_LOADER_DATA _loader_data; + struct vk_object_base base; VkAllocationCallbacks alloc; @@ -1044,10 +1153,11 @@ 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; @@ -1080,6 +1190,17 @@ struct anv_queue_submit { 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; @@ -1091,6 +1212,8 @@ struct anv_queue_submit { */ uintptr_t * fence_bos; + int perf_query_pass; + const VkAllocationCallbacks * alloc; VkSystemAllocationScope alloc_scope; @@ -1101,20 +1224,28 @@ struct anv_queue_submit { }; struct anv_queue { - VK_LOADER_DATA _loader_data; + struct vk_object_base base; struct anv_device * device; + /* + * A list of struct anv_queue_submit to be submitted to i915. + */ + struct list_head queued_submits; + VkDeviceQueueCreateFlags flags; }; struct anv_pipeline_cache { + struct vk_object_base base; struct anv_device * device; pthread_mutex_t mutex; struct hash_table * nir_cache; struct hash_table * cache; + + bool external_sync; }; struct nir_xfb_info; @@ -1122,7 +1253,8 @@ struct anv_pipeline_bind_map; void anv_pipeline_cache_init(struct anv_pipeline_cache *cache, struct anv_device *device, - bool cache_enabled); + bool cache_enabled, + bool external_sync); void anv_pipeline_cache_finish(struct anv_pipeline_cache *cache); struct anv_shader_bin * @@ -1130,6 +1262,7 @@ anv_pipeline_cache_search(struct anv_pipeline_cache *cache, const void *key, uint32_t key_size); struct anv_shader_bin * anv_pipeline_cache_upload_kernel(struct anv_pipeline_cache *cache, + gl_shader_stage stage, const void *key_data, uint32_t key_size, const void *kernel_data, uint32_t kernel_size, const void *constant_data, @@ -1150,6 +1283,7 @@ anv_device_search_for_kernel(struct anv_device *device, struct anv_shader_bin * anv_device_upload_kernel(struct anv_device *device, struct anv_pipeline_cache *cache, + gl_shader_stage stage, const void *key_data, uint32_t key_size, const void *kernel_data, uint32_t kernel_size, const void *constant_data, @@ -1177,13 +1311,15 @@ anv_device_upload_nir(struct anv_device *device, const struct nir_shader *nir, unsigned char sha1_key[20]); -struct anv_device { - VK_LOADER_DATA _loader_data; +struct anv_address { + struct anv_bo *bo; + uint32_t offset; +}; - VkAllocationCallbacks alloc; +struct anv_device { + struct vk_device vk; - 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; @@ -1196,9 +1332,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; @@ -1212,9 +1347,23 @@ struct anv_device { struct anv_state_pool binding_table_pool; struct anv_state_pool surface_state_pool; + struct anv_state_reserved_pool custom_border_colors; + + /** BO used for various workarounds + * + * There are a number of workarounds on our hardware which require writing + * data somewhere and it doesn't really matter where. For that, we use + * this BO and just write to the first dword or so. + * + * We also need to be able to handle NULL buffers bound as pushed UBOs. + * For that, we use the high bytes (>= 1024) of the workaround BO. + */ struct anv_bo * workaround_bo; + struct anv_address workaround_address; + struct anv_bo * trivial_batch_bo; struct anv_bo * hiz_clear_bo; + struct anv_state null_surface_state; struct anv_pipeline_cache default_pipeline_cache; struct blorp_context blorp; @@ -1227,9 +1376,6 @@ struct anv_device { struct anv_scratch_pool scratch_pool; - uint32_t default_mocs; - uint32_t external_mocs; - pthread_mutex_t mutex; pthread_cond_t queue_submit; int _lost; @@ -1247,10 +1393,16 @@ struct anv_device { 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; @@ -1258,7 +1410,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 @@ -1274,9 +1426,9 @@ static inline uint32_t anv_mocs_for_bo(const struct anv_device *device, const struct anv_bo *bo) { if (bo->is_external) - return device->external_mocs; + 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); @@ -1324,7 +1476,10 @@ enum anv_bo_alloc_flags { /** 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 */ + /** 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 @@ -1338,17 +1493,26 @@ enum anv_bo_alloc_flags { * 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); @@ -1368,7 +1532,7 @@ VkResult anv_device_wait(struct anv_device *device, struct anv_bo *bo, VkResult anv_queue_init(struct anv_device *device, struct anv_queue *queue); void anv_queue_finish(struct anv_queue *queue); -VkResult anv_queue_execbuf(struct anv_queue *queue, struct anv_queue_submit *submit); +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); @@ -1377,7 +1541,7 @@ 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); +void anv_gem_munmap(struct anv_device *device, void *p, uint64_t size); uint32_t anv_gem_create(struct anv_device *device, uint64_t size); void anv_gem_close(struct anv_device *device, uint32_t gem_handle); uint32_t anv_gem_userptr(struct anv_device *device, void *mem, size_t size); @@ -1397,12 +1561,10 @@ int anv_gem_get_context_param(int fd, int context, uint32_t param, int anv_gem_get_param(int fd, uint32_t param); int anv_gem_get_tiling(struct anv_device *device, uint32_t gem_handle); bool anv_gem_get_bit6_swizzle(int fd, uint32_t tiling); -int anv_gem_get_aperture(int fd, uint64_t *size); int anv_gem_gpu_get_reset_stats(struct anv_device *device, uint32_t *active, uint32_t *pending); int anv_gem_handle_to_fd(struct anv_device *device, uint32_t gem_handle); -int anv_gem_reg_read(struct anv_device *device, - uint32_t offset, uint64_t *result); +int anv_gem_reg_read(int fd, uint32_t offset, uint64_t *result); uint32_t anv_gem_fd_to_handle(struct anv_device *device, int fd); int anv_gem_set_caching(struct anv_device *device, uint32_t gem_handle, uint32_t caching); int anv_gem_set_domain(struct anv_device *device, uint32_t gem_handle, @@ -1422,8 +1584,12 @@ 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); +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; @@ -1459,6 +1625,8 @@ struct anv_batch_bo { struct anv_batch { const VkAllocationCallbacks * alloc; + struct anv_address start_addr; + void * start; void * end; void * next; @@ -1485,6 +1653,16 @@ 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); +struct anv_address anv_batch_address(struct anv_batch *batch, void *batch_location); + +static inline void +anv_batch_set_storage(struct anv_batch *batch, struct anv_address addr, + void *map, size_t size) +{ + batch->start_addr = addr; + batch->next = batch->start = map; + batch->end = map + size; +} static inline VkResult anv_batch_set_error(struct anv_batch *batch, VkResult error) @@ -1501,11 +1679,6 @@ anv_batch_has_error(struct anv_batch *batch) return batch->status != VK_SUCCESS; } -struct anv_address { - struct anv_bo *bo; - uint32_t offset; -}; - #define ANV_NULL_ADDRESS ((struct anv_address) { NULL, 0 }) static inline bool @@ -1618,57 +1791,14 @@ _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 - -/* TigerLake MOCS */ -#define GEN12_MOCS GEN9_MOCS -/* TC=1/LLC Only, LeCC=1/Uncacheable, LRUM=0, L3CC=1/Uncacheable */ -#define GEN12_EXTERNAL_MOCS (3 << 1) +/* #define __gen_get_batch_dwords anv_batch_emit_dwords */ +/* #define __gen_get_batch_address anv_batch_address */ +/* #define __gen_address_value anv_address_physical */ +/* #define __gen_address_offset anv_address_add */ struct anv_device_memory { + struct vk_object_base base; + struct list_head link; struct anv_bo * bo; @@ -1822,6 +1952,8 @@ bool anv_descriptor_requires_bindless(const struct anv_physical_device *pdevice, bool sampler); struct anv_descriptor_set_layout { + struct vk_object_base base; + /* Descriptor set layouts can be destroyed at almost any time */ uint32_t ref_cnt; @@ -1840,6 +1972,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; @@ -1847,6 +1982,9 @@ struct anv_descriptor_set_layout { struct anv_descriptor_set_binding_layout binding[0]; }; +void anv_descriptor_set_layout_destroy(struct anv_device *device, + struct anv_descriptor_set_layout *layout); + static inline void anv_descriptor_set_layout_ref(struct anv_descriptor_set_layout *layout) { @@ -1860,7 +1998,7 @@ anv_descriptor_set_layout_unref(struct anv_device *device, { assert(layout && layout->ref_cnt >= 1); if (p_atomic_dec_zero(&layout->ref_cnt)) - vk_free(&device->alloc, layout); + anv_descriptor_set_layout_destroy(device, layout); } struct anv_descriptor { @@ -1884,8 +2022,14 @@ struct anv_descriptor { }; struct anv_descriptor_set { + struct vk_object_base base; + struct anv_descriptor_pool *pool; struct anv_descriptor_set_layout *layout; + + /* Amount of space occupied in the the pool by this descriptor set. It can + * be larger than the size of the descriptor set. + */ uint32_t size; /* State relative to anv_descriptor_pool::bo */ @@ -1903,6 +2047,8 @@ struct anv_descriptor_set { }; struct anv_buffer_view { + struct vk_object_base base; + enum isl_format format; /**< VkBufferViewCreateInfo::format */ uint64_t range; /**< VkBufferViewCreateInfo::range */ @@ -1931,6 +2077,8 @@ struct anv_push_descriptor_set { }; struct anv_descriptor_pool { + struct vk_object_base base; + uint32_t size; uint32_t next; uint32_t free_list; @@ -1973,6 +2121,8 @@ struct anv_descriptor_template_entry { }; struct anv_descriptor_update_template { + struct vk_object_base base; + VkPipelineBindPoint bind_point; /* The descriptor set this template corresponds to. This value is only @@ -2043,35 +2193,68 @@ 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; + + /** 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; +}; - /* Index in the binding */ +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; + + /** Dynamic offset index (for dynamic UBOs) */ + uint8_t dynamic_offset_index; - /* Input attachment index (relative to the subpass) */ - uint8_t input_attachment_index; + /** Start offset in units of 32B */ + uint8_t start; - /* For a storage image, whether it is write-only */ - bool write_only; + /** Range in units of 32B */ + uint8_t length; }; struct anv_pipeline_layout { + struct vk_object_base base; + struct { struct anv_descriptor_set_layout *layout; uint32_t dynamic_offset_start; @@ -2083,6 +2266,8 @@ struct anv_pipeline_layout { }; struct anv_buffer { + struct vk_object_base base; + struct anv_device * device; VkDeviceSize size; @@ -2106,42 +2291,64 @@ anv_buffer_get_range(struct anv_buffer *buffer, uint64_t offset, uint64_t range) } enum anv_cmd_dirty_bits { - ANV_CMD_DIRTY_DYNAMIC_VIEWPORT = 1 << 0, /* VK_DYNAMIC_STATE_VIEWPORT */ - ANV_CMD_DIRTY_DYNAMIC_SCISSOR = 1 << 1, /* VK_DYNAMIC_STATE_SCISSOR */ - ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH = 1 << 2, /* VK_DYNAMIC_STATE_LINE_WIDTH */ - ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS = 1 << 3, /* VK_DYNAMIC_STATE_DEPTH_BIAS */ - ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS = 1 << 4, /* VK_DYNAMIC_STATE_BLEND_CONSTANTS */ - ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS = 1 << 5, /* VK_DYNAMIC_STATE_DEPTH_BOUNDS */ - 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_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 */ + ANV_CMD_DIRTY_DYNAMIC_VIEWPORT = 1 << 0, /* VK_DYNAMIC_STATE_VIEWPORT */ + ANV_CMD_DIRTY_DYNAMIC_SCISSOR = 1 << 1, /* VK_DYNAMIC_STATE_SCISSOR */ + ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH = 1 << 2, /* VK_DYNAMIC_STATE_LINE_WIDTH */ + ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS = 1 << 3, /* VK_DYNAMIC_STATE_DEPTH_BIAS */ + ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS = 1 << 4, /* VK_DYNAMIC_STATE_BLEND_CONSTANTS */ + ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS = 1 << 5, /* VK_DYNAMIC_STATE_DEPTH_BOUNDS */ + 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_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 */ + ANV_CMD_DIRTY_DYNAMIC_CULL_MODE = 1 << 14, /* VK_DYNAMIC_STATE_CULL_MODE_EXT */ + ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE = 1 << 15, /* VK_DYNAMIC_STATE_FRONT_FACE_EXT */ + ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY = 1 << 16, /* VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT */ + ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE = 1 << 17, /* VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT */ + ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE = 1 << 18, /* VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT */ + ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE = 1 << 19, /* VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT */ + ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP = 1 << 20, /* VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT */ + ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE = 1 << 21, /* VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT */ + ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE = 1 << 22, /* VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT */ + ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP = 1 << 23, /* VK_DYNAMIC_STATE_STENCIL_OP_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) +#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 | \ + ANV_CMD_DIRTY_DYNAMIC_CULL_MODE | \ + ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE | \ + ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY | \ + ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE | \ + ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE | \ + ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE | \ + ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP | \ + ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE | \ + ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE | \ + ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP) 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: + case VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT: return ANV_CMD_DIRTY_DYNAMIC_VIEWPORT; case VK_DYNAMIC_STATE_SCISSOR: + case VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT: return ANV_CMD_DIRTY_DYNAMIC_SCISSOR; case VK_DYNAMIC_STATE_LINE_WIDTH: return ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH; @@ -2159,6 +2366,26 @@ anv_cmd_dirty_bit_for_vk_dynamic_state(VkDynamicState vk_state) return ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE; case VK_DYNAMIC_STATE_LINE_STIPPLE_EXT: return ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE; + case VK_DYNAMIC_STATE_CULL_MODE_EXT: + return ANV_CMD_DIRTY_DYNAMIC_CULL_MODE; + case VK_DYNAMIC_STATE_FRONT_FACE_EXT: + return ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE; + case VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT: + return ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY; + case VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT: + return ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE; + case VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT: + return ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE; + case VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT: + return ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE; + case VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT: + return ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP; + case VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT: + return ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE; + case VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT: + return ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE; + case VK_DYNAMIC_STATE_STENCIL_OP_EXT: + return ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP; default: assert(!"Unsupported dynamic state"); return 0; @@ -2179,13 +2406,14 @@ enum anv_pipe_bits { ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT = (1 << 12), ANV_PIPE_DEPTH_STALL_BIT = (1 << 13), ANV_PIPE_CS_STALL_BIT = (1 << 20), + ANV_PIPE_END_OF_PIPE_SYNC_BIT = (1 << 21), /* This bit does not exist directly in PIPE_CONTROL. Instead it means that * a flush has happened but not a CS stall. The next time we do any sort * of invalidation we need to insert a CS stall at that time. Otherwise, * we would have to CS stall on every flush which could be bad. */ - ANV_PIPE_NEEDS_CS_STALL_BIT = (1 << 21), + ANV_PIPE_NEEDS_END_OF_PIPE_SYNC_BIT = (1 << 22), /* This bit does not exist directly in PIPE_CONTROL. It means that render * target operations related to transfer commands with VkBuffer as @@ -2193,7 +2421,19 @@ enum anv_pipe_bits { * streamer might need to be aware of this to trigger the appropriate stall * before they can proceed with the copy. */ - ANV_PIPE_RENDER_TARGET_BUFFER_WRITES = (1 << 22), + ANV_PIPE_RENDER_TARGET_BUFFER_WRITES = (1 << 23), + + /* 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 << 24), + + /* 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 << 25), }; #define ANV_PIPE_FLUSH_BITS ( \ @@ -2213,7 +2453,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) @@ -2374,20 +2615,32 @@ 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]; + + uint64_t push_reg_mask; + + /** Pad out to a multiple of 32 bytes */ + uint32_t pad[2]; + + 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; + } cs; }; struct anv_dynamic_state { @@ -2472,7 +2725,6 @@ struct anv_surface_state { */ struct anv_attachment_state { enum isl_aux_usage aux_usage; - enum isl_aux_usage input_aux_usage; struct anv_surface_state color; struct anv_surface_state input; @@ -2482,8 +2734,6 @@ struct anv_attachment_state { VkImageAspectFlags pending_load_aspects; bool fast_clear; VkClearValue clear_value; - bool clear_color_is_zero_one; - bool clear_color_is_zero; /* When multiview is active, attachments with a renderpass clear * operation have their respective layers cleared on the first @@ -2495,6 +2745,27 @@ struct anv_attachment_state { 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 * * This struct is the base struct for anv_cmd_graphics_state and @@ -2504,12 +2775,7 @@ struct anv_attachment_state { * per-stage array in anv_cmd_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]; }; @@ -2523,9 +2789,16 @@ struct anv_cmd_pipeline_state { struct anv_cmd_graphics_state { struct anv_cmd_pipeline_state base; + struct anv_graphics_pipeline *pipeline; + 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 { @@ -2545,6 +2818,8 @@ struct anv_cmd_graphics_state { struct anv_cmd_compute_state { struct anv_cmd_pipeline_state base; + struct anv_compute_pipeline *pipeline; + bool pipeline_dirty; struct anv_address num_workgroups; @@ -2577,6 +2852,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 @@ -2610,16 +2889,17 @@ struct anv_cmd_state { * flat array. For depth-stencil attachments, the surface state is simply * left blank. */ - struct anv_state render_pass_states; + struct anv_state attachment_states; /** * A null surface state of the right size to match the framebuffer. This - * is one of the states in render_pass_states. + * is one of the states in attachment_states. */ struct anv_state null_surface_state; }; struct anv_cmd_pool { + struct vk_object_base base; VkAllocationCallbacks alloc; struct list_head cmd_buffers; }; @@ -2632,10 +2912,11 @@ enum anv_cmd_buffer_exec_mode { ANV_CMD_BUFFER_EXEC_MODE_GROW_AND_EMIT, ANV_CMD_BUFFER_EXEC_MODE_CHAIN, ANV_CMD_BUFFER_EXEC_MODE_COPY_AND_CHAIN, + ANV_CMD_BUFFER_EXEC_MODE_CALL_AND_RETURN, }; struct anv_cmd_buffer { - VK_LOADER_DATA _loader_data; + struct vk_object_base base; struct anv_device * device; @@ -2663,7 +2944,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 */ @@ -2679,8 +2960,12 @@ struct anv_cmd_buffer { VkCommandBufferUsageFlags usage_flags; VkCommandBufferLevel level; + struct anv_query_pool *perf_query_pool; + struct anv_cmd_state state; + struct anv_address return_addr; + /* Set by SetPerformanceMarkerINTEL, written into queries by CmdBeginQuery */ uint64_t intel_perf_marker; }; @@ -2695,10 +2980,13 @@ void anv_cmd_buffer_prepare_execbuf(struct anv_cmd_buffer *cmd_buffer); 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); + VkFence fence, + int perf_query_pass); VkResult anv_cmd_buffer_reset(struct anv_cmd_buffer *cmd_buffer); @@ -2756,6 +3044,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, }; @@ -2799,6 +3088,8 @@ struct anv_fence_impl { }; struct anv_fence { + struct vk_object_base base; + /* Permanent fence state. Every fence has some form of permanent state * (type != ANV_SEMAPHORE_TYPE_NONE). This may be a BO to fence on (for * cross-process fences) or it could just be a dummy for use internally. @@ -2815,7 +3106,11 @@ struct anv_fence { struct anv_fence_impl temporary; }; +void anv_fence_reset_temporary(struct anv_device *device, + struct anv_fence *fence); + struct anv_event { + struct vk_object_base base; uint64_t semaphore; struct anv_state state; }; @@ -2824,18 +3119,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; @@ -2850,10 +3173,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 { + struct vk_object_base base; + uint32_t refcount; /* Permanent semaphore state. Every semaphore has some form of permanent @@ -2877,6 +3208,8 @@ void anv_semaphore_reset_temporary(struct anv_device *device, struct anv_semaphore *semaphore); struct anv_shader_module { + struct vk_object_base base; + unsigned char sha1[20]; uint32_t size; char data[0]; @@ -2904,11 +3237,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 { @@ -2919,6 +3258,8 @@ struct anv_shader_bin_key { struct anv_shader_bin { uint32_t ref_cnt; + gl_shader_stage stage; + const struct anv_shader_bin_key *key; struct anv_state kernel; @@ -2940,11 +3281,12 @@ struct anv_shader_bin { struct anv_shader_bin * anv_shader_bin_create(struct anv_device *device, + gl_shader_stage stage, const void *key, uint32_t key_size, const void *kernel, uint32_t kernel_size, 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, + 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); @@ -2967,9 +3309,6 @@ 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; @@ -2979,48 +3318,46 @@ struct anv_pipeline_executable { char *disasm; }; +enum anv_pipeline_type { + ANV_PIPELINE_GRAPHICS, + ANV_PIPELINE_COMPUTE, +}; + struct anv_pipeline { + struct vk_object_base base; + struct anv_device * device; + struct anv_batch batch; - uint32_t batch_data[512]; struct anv_reloc_list batch_relocs; - anv_cmd_dirty_mask_t dynamic_state_mask; - struct anv_dynamic_state dynamic_state; void * mem_ctx; + enum anv_pipeline_type type; VkPipelineCreateFlags flags; - struct anv_subpass * subpass; - bool needs_data_cache; + struct util_dynarray executables; - struct anv_shader_bin * shaders[MESA_SHADER_STAGES]; + const struct gen_l3_config * l3_config; +}; - uint32_t num_executables; - struct anv_pipeline_executable executables[MAX_PIPELINE_EXECUTABLES]; +struct anv_graphics_pipeline { + struct anv_pipeline base; - struct { - const struct gen_l3_config * l3_config; - uint32_t total_size; - } urb; + uint32_t batch_data[512]; - VkShaderStageFlags active_stages; - struct anv_state blend_state; + anv_cmd_dirty_mask_t dynamic_state_mask; + struct anv_dynamic_state dynamic_state; - uint32_t vb_used; - struct anv_pipeline_vertex_binding { - uint32_t stride; - bool instanced; - uint32_t instance_divisor; - } vb[MAX_VBS]; + uint32_t topology; - uint8_t xfb_used; + struct anv_subpass * subpass; - bool primitive_restart; - uint32_t topology; + struct anv_shader_bin * shaders[MESA_SHADER_STAGES]; - uint32_t cs_right_mask; + VkShaderStageFlags active_stages; + bool primitive_restart; bool writes_depth; bool depth_test_enable; bool writes_stencil; @@ -3031,6 +3368,20 @@ struct anv_pipeline { bool kill_pixel; bool depth_bounds_test_enable; + /* When primitive replication is used, subpass->view_mask will describe what + * views to replicate. + */ + bool use_primitive_replication; + + struct anv_state blend_state; + + uint32_t vb_used; + struct anv_pipeline_vertex_binding { + uint32_t stride; + bool instanced; + uint32_t instance_divisor; + } vb[MAX_VBS]; + struct { uint32_t sf[7]; uint32_t depth_stencil_state[3]; @@ -3045,38 +3396,62 @@ struct anv_pipeline { struct { uint32_t wm_depth_stencil[4]; } gen9; +}; + +struct anv_compute_pipeline { + struct anv_pipeline base; + struct anv_shader_bin * cs; + uint32_t cs_right_mask; + uint32_t batch_data[9]; uint32_t interface_descriptor_data[8]; }; +#define ANV_DECL_PIPELINE_DOWNCAST(pipe_type, pipe_enum) \ + static inline struct anv_##pipe_type##_pipeline * \ + anv_pipeline_to_##pipe_type(struct anv_pipeline *pipeline) \ + { \ + assert(pipeline->type == pipe_enum); \ + return (struct anv_##pipe_type##_pipeline *) pipeline; \ + } + +ANV_DECL_PIPELINE_DOWNCAST(graphics, ANV_PIPELINE_GRAPHICS) +ANV_DECL_PIPELINE_DOWNCAST(compute, ANV_PIPELINE_COMPUTE) + static inline bool -anv_pipeline_has_stage(const struct anv_pipeline *pipeline, +anv_pipeline_has_stage(const struct anv_graphics_pipeline *pipeline, gl_shader_stage stage) { return (pipeline->active_stages & mesa_to_vk_shader_stage(stage)) != 0; } -#define ANV_DECL_GET_PROG_DATA_FUNC(prefix, stage) \ -static inline const struct brw_##prefix##_prog_data * \ -get_##prefix##_prog_data(const struct anv_pipeline *pipeline) \ -{ \ - if (anv_pipeline_has_stage(pipeline, stage)) { \ - return (const struct brw_##prefix##_prog_data *) \ - pipeline->shaders[stage]->prog_data; \ - } else { \ - return NULL; \ - } \ +#define ANV_DECL_GET_GRAPHICS_PROG_DATA_FUNC(prefix, stage) \ +static inline const struct brw_##prefix##_prog_data * \ +get_##prefix##_prog_data(const struct anv_graphics_pipeline *pipeline) \ +{ \ + if (anv_pipeline_has_stage(pipeline, stage)) { \ + return (const struct brw_##prefix##_prog_data *) \ + pipeline->shaders[stage]->prog_data; \ + } else { \ + return NULL; \ + } \ } -ANV_DECL_GET_PROG_DATA_FUNC(vs, MESA_SHADER_VERTEX) -ANV_DECL_GET_PROG_DATA_FUNC(tcs, MESA_SHADER_TESS_CTRL) -ANV_DECL_GET_PROG_DATA_FUNC(tes, MESA_SHADER_TESS_EVAL) -ANV_DECL_GET_PROG_DATA_FUNC(gs, MESA_SHADER_GEOMETRY) -ANV_DECL_GET_PROG_DATA_FUNC(wm, MESA_SHADER_FRAGMENT) -ANV_DECL_GET_PROG_DATA_FUNC(cs, MESA_SHADER_COMPUTE) +ANV_DECL_GET_GRAPHICS_PROG_DATA_FUNC(vs, MESA_SHADER_VERTEX) +ANV_DECL_GET_GRAPHICS_PROG_DATA_FUNC(tcs, MESA_SHADER_TESS_CTRL) +ANV_DECL_GET_GRAPHICS_PROG_DATA_FUNC(tes, MESA_SHADER_TESS_EVAL) +ANV_DECL_GET_GRAPHICS_PROG_DATA_FUNC(gs, MESA_SHADER_GEOMETRY) +ANV_DECL_GET_GRAPHICS_PROG_DATA_FUNC(wm, MESA_SHADER_FRAGMENT) + +static inline const struct brw_cs_prog_data * +get_cs_prog_data(const struct anv_compute_pipeline *pipeline) +{ + assert(pipeline->cs); + return (const struct brw_cs_prog_data *) pipeline->cs->prog_data; +} static inline const struct brw_vue_prog_data * -anv_pipeline_get_last_vue_prog_data(const struct anv_pipeline *pipeline) +anv_pipeline_get_last_vue_prog_data(const struct anv_graphics_pipeline *pipeline) { if (anv_pipeline_has_stage(pipeline, MESA_SHADER_GEOMETRY)) return &get_gs_prog_data(pipeline)->base; @@ -3087,19 +3462,40 @@ anv_pipeline_get_last_vue_prog_data(const struct anv_pipeline *pipeline) } VkResult -anv_pipeline_init(struct anv_pipeline *pipeline, struct anv_device *device, - struct anv_pipeline_cache *cache, - const VkGraphicsPipelineCreateInfo *pCreateInfo, - const VkAllocationCallbacks *alloc); +anv_pipeline_init(struct anv_pipeline *pipeline, + struct anv_device *device, + enum anv_pipeline_type type, + VkPipelineCreateFlags flags, + const VkAllocationCallbacks *pAllocator); + +void +anv_pipeline_finish(struct anv_pipeline *pipeline, + struct anv_device *device, + const VkAllocationCallbacks *pAllocator); VkResult -anv_pipeline_compile_cs(struct anv_pipeline *pipeline, +anv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline, struct anv_device *device, + struct anv_pipeline_cache *cache, + const VkGraphicsPipelineCreateInfo *pCreateInfo, + const VkAllocationCallbacks *alloc); + +VkResult +anv_pipeline_compile_cs(struct anv_compute_pipeline *pipeline, struct anv_pipeline_cache *cache, const VkComputePipelineCreateInfo *info, const struct anv_shader_module *module, const char *entrypoint, const VkSpecializationInfo *spec_info); +struct anv_cs_parameters { + uint32_t group_size; + uint32_t simd_size; + uint32_t threads; +}; + +struct anv_cs_parameters +anv_cs_parameters(const struct anv_compute_pipeline *pipeline); + struct anv_format_plane { enum isl_format isl_format:16; struct isl_swizzle swizzle; @@ -3125,6 +3521,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) @@ -3188,6 +3590,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) { @@ -3220,6 +3628,8 @@ struct anv_surface { }; struct anv_image { + struct vk_object_base base; + VkImageType type; /**< VkImageCreateInfo::imageType */ /* The original VkFormat provided by the client. This may not match any * of the actual surface formats. @@ -3261,11 +3671,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; @@ -3325,11 +3730,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; @@ -3346,13 +3749,6 @@ struct anv_image { */ struct anv_address address; - /** - * Address of the main surface used to fill the aux map table. This is - * used at destruction of the image since the Vulkan spec does not - * guarantee that the address.bo field we still be valid at destruction. - */ - uint64_t aux_map_surface_address; - /** * When destroying the image, also free the bo. * */ @@ -3376,15 +3772,13 @@ anv_image_aux_levels(const struct anv_image * const image, VkImageAspectFlagBits aspect) { uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect); + if (image->planes[plane].aux_usage == ISL_AUX_USAGE_NONE) + return 0; /* The Gen12 CCS aux surface is represented with only one level. */ - const uint8_t aux_logical_levels = - image->planes[plane].aux_surface.isl.tiling == ISL_TILING_GEN12_CCS ? - image->planes[plane].surface.isl.levels : - image->planes[plane].aux_surface.isl.levels; - - return image->planes[plane].aux_surface.isl.size_B > 0 ? - aux_logical_levels : 0; + 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. */ @@ -3418,7 +3812,7 @@ anv_image_aux_layers(const struct anv_image * const image, } static inline struct anv_address -anv_image_get_clear_color_addr(const struct anv_device *device, +anv_image_get_clear_color_addr(UNUSED const struct anv_device *device, const struct anv_image *image, VkImageAspectFlagBits aspect) { @@ -3479,6 +3873,16 @@ anv_can_sample_with_hiz(const struct gen_device_info * const devinfo, if (!(image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) return false; + /* For Gen8-11, there are some restrictions around sampling from HiZ. + * The Skylake PRM docs for RENDER_SURFACE_STATE::AuxiliarySurfaceMode + * say: + * + * "If this field is set to AUX_HIZ, Number of Multisamples must + * be MULTISAMPLECOUNT_1, and Surface Type cannot be SURFTYPE_3D." + */ + if (image->type == VK_IMAGE_TYPE_3D) + return false; + /* Allow this feature on BDW even though it is disabled in the BDW devinfo * struct. There's documentation which suggests that this feature actually * reduces performance on BDW, but it has only been observed to help so @@ -3556,7 +3960,7 @@ anv_image_hiz_clear(struct anv_cmd_buffer *cmd_buffer, void anv_image_mcs_op(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *image, - enum isl_format format, + enum isl_format format, struct isl_swizzle swizzle, VkImageAspectFlagBits aspect, uint32_t base_layer, uint32_t layer_count, enum isl_aux_op mcs_op, union isl_color_value *clear_value, @@ -3564,7 +3968,7 @@ anv_image_mcs_op(struct anv_cmd_buffer *cmd_buffer, void anv_image_ccs_op(struct anv_cmd_buffer *cmd_buffer, const struct anv_image *image, - enum isl_format format, + enum isl_format format, struct isl_swizzle swizzle, VkImageAspectFlagBits aspect, uint32_t level, uint32_t base_layer, uint32_t layer_count, enum isl_aux_op ccs_op, union isl_color_value *clear_value, @@ -3577,10 +3981,17 @@ anv_image_copy_to_shadow(struct anv_cmd_buffer *cmd_buffer, 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 @@ -3635,6 +4046,8 @@ anv_image_aspects_compatible(VkImageAspectFlags aspects1, } struct anv_image_view { + struct vk_object_base base; + const struct anv_image *image; /**< VkImageViewCreateInfo::image */ VkImageAspectFlags aspect_mask; @@ -3706,16 +4119,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: @@ -3729,9 +4138,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: @@ -3778,7 +4187,37 @@ anv_clear_color_from_att_state(union isl_color_value *clear_color, } +/* Haswell border color is a bit of a disaster. Float and unorm formats use a + * straightforward 32-bit float color in the first 64 bytes. Instead of using + * a nice float/integer union like Gen8+, Haswell specifies the integer border + * color as a separate entry /after/ the float color. The layout of this entry + * also depends on the format's bpp (with extra hacks for RG32), and overlaps. + * + * Since we don't know the format/bpp, we can't make any of the border colors + * containing '1' work for all formats, as it would be in the wrong place for + * some of them. We opt to make 32-bit integers work as this seems like the + * most common option. Fortunately, transparent black works regardless, as + * all zeroes is the same in every bit-size. + */ +struct hsw_border_color { + float float32[4]; + uint32_t _pad0[12]; + uint32_t uint32[4]; + uint32_t _pad1[108]; +}; + +struct gen8_border_color { + union { + float float32[4]; + uint32_t uint32[4]; + }; + /* Pad out to 64 bytes */ + uint32_t _pad[12]; +}; + struct anv_ycbcr_conversion { + struct vk_object_base base; + const struct anv_format * format; VkSamplerYcbcrModelConversion ycbcr_model; VkSamplerYcbcrRange ycbcr_range; @@ -3789,6 +4228,8 @@ struct anv_ycbcr_conversion { }; struct anv_sampler { + struct vk_object_base base; + uint32_t state[3][4]; uint32_t n_planes; struct anv_ycbcr_conversion *conversion; @@ -3797,9 +4238,13 @@ struct anv_sampler { * and with a 32-byte stride for use as bindless samplers. */ struct anv_state bindless_state; + + struct anv_state custom_border_color; }; struct anv_framebuffer { + struct vk_object_base base; + uint32_t width; uint32_t height; uint32_t layers; @@ -3873,6 +4318,8 @@ struct anv_render_pass_attachment { }; struct anv_render_pass { + struct vk_object_base base; + uint32_t attachment_count; uint32_t subpass_count; /* An array of subpass_count+1 flushes, one per subpass boundary */ @@ -3883,7 +4330,12 @@ struct anv_render_pass { #define ANV_PIPELINE_STATISTICS_MASK 0x000007ff +#define OA_SNAPSHOT_SIZE (256) +#define ANV_KHR_PERF_QUERY_SIZE (ALIGN(sizeof(uint64_t), 64) + 2 * OA_SNAPSHOT_SIZE) + struct anv_query_pool { + struct vk_object_base base; + VkQueryType type; VkQueryPipelineStatisticFlags pipeline_statistics; /** Stride between slots, in bytes */ @@ -3891,8 +4343,21 @@ struct anv_query_pool { /** Number of slots in this query pool */ uint32_t slots; struct anv_bo * bo; + + /* Perf queries : */ + struct anv_bo reset_bo; + uint32_t n_counters; + struct gen_perf_counter_pass *counter_pass; + uint32_t n_passes; + struct gen_perf_query_info **pass_query; }; +static inline uint32_t khr_perf_query_preamble_offset(struct anv_query_pool *pool, + uint32_t pass) +{ + return pass * ANV_KHR_PERF_QUERY_SIZE + 8; +} + 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); @@ -3912,6 +4377,8 @@ anv_device_entrypoint_is_enabled(int index, uint32_t core_version, const struct anv_instance_extension_table *instance, const struct anv_device_extension_table *device); +void *anv_resolve_device_entrypoint(const struct gen_device_info *devinfo, + uint32_t index); void *anv_lookup_entrypoint(const struct gen_device_info *devinfo, const char *name); @@ -3946,67 +4413,66 @@ anv_get_subpass_id(const struct anv_cmd_state * const cmd_state) 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 * \ - __anv_type ## _from_handle(__VkType _handle) \ - { \ - return (struct __anv_type *) _handle; \ - } \ - \ - static inline __VkType \ - __anv_type ## _to_handle(struct __anv_type *_obj) \ - { \ - return (__VkType) _obj; \ - } - -#define ANV_DEFINE_NONDISP_HANDLE_CASTS(__anv_type, __VkType) \ - \ - static inline struct __anv_type * \ - __anv_type ## _from_handle(__VkType _handle) \ - { \ - return (struct __anv_type *)(uintptr_t) _handle; \ - } \ - \ - static inline __VkType \ - __anv_type ## _to_handle(struct __anv_type *_obj) \ - { \ - return (__VkType)(uintptr_t) _obj; \ - } +void anv_perf_write_pass_results(struct gen_perf_config *perf, + struct anv_query_pool *pool, uint32_t pass, + const struct gen_perf_query_result *accumulated_results, + union VkPerformanceCounterResultKHR *results); #define ANV_FROM_HANDLE(__anv_type, __name, __handle) \ - struct __anv_type *__name = __anv_type ## _from_handle(__handle) - -ANV_DEFINE_HANDLE_CASTS(anv_cmd_buffer, VkCommandBuffer) -ANV_DEFINE_HANDLE_CASTS(anv_device, VkDevice) -ANV_DEFINE_HANDLE_CASTS(anv_instance, VkInstance) -ANV_DEFINE_HANDLE_CASTS(anv_physical_device, VkPhysicalDevice) -ANV_DEFINE_HANDLE_CASTS(anv_queue, VkQueue) - -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_cmd_pool, VkCommandPool) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_buffer, VkBuffer) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_buffer_view, VkBufferView) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_pool, VkDescriptorPool) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_set, VkDescriptorSet) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_set_layout, VkDescriptorSetLayout) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_update_template, VkDescriptorUpdateTemplate) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_device_memory, VkDeviceMemory) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_fence, VkFence) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_event, VkEvent) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_framebuffer, VkFramebuffer) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_image, VkImage) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_image_view, VkImageView); -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_pipeline_cache, VkPipelineCache) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_pipeline, VkPipeline) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_pipeline_layout, VkPipelineLayout) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_query_pool, VkQueryPool) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_render_pass, VkRenderPass) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_sampler, VkSampler) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_semaphore, VkSemaphore) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_shader_module, VkShaderModule) -ANV_DEFINE_NONDISP_HANDLE_CASTS(vk_debug_report_callback, VkDebugReportCallbackEXT) -ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_ycbcr_conversion, VkSamplerYcbcrConversion) + VK_FROM_HANDLE(__anv_type, __name, __handle) + +VK_DEFINE_HANDLE_CASTS(anv_cmd_buffer, base, VkCommandBuffer, + VK_OBJECT_TYPE_COMMAND_BUFFER) +VK_DEFINE_HANDLE_CASTS(anv_device, vk.base, VkDevice, VK_OBJECT_TYPE_DEVICE) +VK_DEFINE_HANDLE_CASTS(anv_instance, base, VkInstance, VK_OBJECT_TYPE_INSTANCE) +VK_DEFINE_HANDLE_CASTS(anv_physical_device, base, VkPhysicalDevice, + VK_OBJECT_TYPE_PHYSICAL_DEVICE) +VK_DEFINE_HANDLE_CASTS(anv_queue, base, VkQueue, VK_OBJECT_TYPE_QUEUE) + +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_cmd_pool, base, VkCommandPool, + VK_OBJECT_TYPE_COMMAND_POOL) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_buffer, base, VkBuffer, + VK_OBJECT_TYPE_BUFFER) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_buffer_view, base, VkBufferView, + VK_OBJECT_TYPE_BUFFER_VIEW) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_pool, base, VkDescriptorPool, + VK_OBJECT_TYPE_DESCRIPTOR_POOL) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_set, base, VkDescriptorSet, + VK_OBJECT_TYPE_DESCRIPTOR_SET) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_set_layout, base, + VkDescriptorSetLayout, + VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_update_template, base, + VkDescriptorUpdateTemplate, + VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_device_memory, base, VkDeviceMemory, + VK_OBJECT_TYPE_DEVICE_MEMORY) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_fence, base, VkFence, VK_OBJECT_TYPE_FENCE) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_event, base, VkEvent, VK_OBJECT_TYPE_EVENT) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_framebuffer, base, VkFramebuffer, + VK_OBJECT_TYPE_FRAMEBUFFER) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_image, base, VkImage, VK_OBJECT_TYPE_IMAGE) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_image_view, base, VkImageView, + VK_OBJECT_TYPE_IMAGE_VIEW); +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_pipeline_cache, base, VkPipelineCache, + VK_OBJECT_TYPE_PIPELINE_CACHE) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_pipeline, base, VkPipeline, + VK_OBJECT_TYPE_PIPELINE) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_pipeline_layout, base, VkPipelineLayout, + VK_OBJECT_TYPE_PIPELINE_LAYOUT) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_query_pool, base, VkQueryPool, + VK_OBJECT_TYPE_QUERY_POOL) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_render_pass, base, VkRenderPass, + VK_OBJECT_TYPE_RENDER_PASS) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_sampler, base, VkSampler, + VK_OBJECT_TYPE_SAMPLER) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_semaphore, base, VkSemaphore, + VK_OBJECT_TYPE_SEMAPHORE) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_shader_module, base, VkShaderModule, + VK_OBJECT_TYPE_SHADER_MODULE) +VK_DEFINE_NONDISP_HANDLE_CASTS(anv_ycbcr_conversion, base, + VkSamplerYcbcrConversion, + VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION) /* Gen-specific function declarations */ #ifdef genX