1/* 2 * Copyright 2018 Collabora Ltd. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. 22 */ 23 24#ifndef ZINK_SCREEN_H 25#define ZINK_SCREEN_H 26 27#include "zink_device_info.h" 28#include "zink_instance.h" 29#include "vk_dispatch_table.h" 30 31#include "util/u_idalloc.h" 32#include "pipe/p_screen.h" 33#include "util/slab.h" 34#include "compiler/nir/nir.h" 35#include "util/disk_cache.h" 36#include "util/log.h" 37#include "util/simple_mtx.h" 38#include "util/u_queue.h" 39#include "util/u_live_shader_cache.h" 40#include "util/u_vertex_state_cache.h" 41#include "pipebuffer/pb_cache.h" 42#include "pipebuffer/pb_slab.h" 43 44#include <vulkan/vulkan.h> 45 46 47#ifdef __cplusplus 48extern "C" { 49#endif 50 51extern uint32_t zink_debug; 52struct hash_table; 53struct util_dl_library; 54 55struct zink_batch_state; 56struct zink_context; 57struct zink_descriptor_layout_key; 58struct zink_program; 59struct zink_shader; 60enum zink_descriptor_type; 61 62/* this is the spec minimum */ 63#define ZINK_SPARSE_BUFFER_PAGE_SIZE (64 * 1024) 64 65enum zink_debug { 66 ZINK_DEBUG_NIR = (1<<0), 67 ZINK_DEBUG_SPIRV = (1<<1), 68 ZINK_DEBUG_TGSI = (1<<2), 69 ZINK_DEBUG_VALIDATION = (1<<3), 70 ZINK_DEBUG_SYNC = (1<<4), 71 ZINK_DEBUG_COMPACT = (1<<5), 72 ZINK_DEBUG_NOREORDER = (1<<6), 73}; 74 75#define NUM_SLAB_ALLOCATORS 3 76#define MIN_SLAB_ORDER 8 77 78#define ZINK_CONTEXT_COPY_ONLY (1<<30) 79 80enum zink_descriptor_mode { 81 ZINK_DESCRIPTOR_MODE_AUTO, 82 ZINK_DESCRIPTOR_MODE_LAZY, 83 ZINK_DESCRIPTOR_MODE_CACHED, 84 ZINK_DESCRIPTOR_MODE_NOTEMPLATES, 85 ZINK_DESCRIPTOR_MODE_COMPACT, 86}; 87 88extern enum zink_descriptor_mode zink_descriptor_mode; 89 90//keep in sync with zink_descriptor_type since headers can't be cross-included 91#define ZINK_MAX_DESCRIPTOR_SETS 6 92 93struct zink_modifier_prop { 94 uint32_t drmFormatModifierCount; 95 VkDrmFormatModifierPropertiesEXT* pDrmFormatModifierProperties; 96}; 97 98struct zink_screen { 99 struct pipe_screen base; 100 101 struct util_dl_library *loader_lib; 102 PFN_vkGetInstanceProcAddr vk_GetInstanceProcAddr; 103 PFN_vkGetDeviceProcAddr vk_GetDeviceProcAddr; 104 105 bool threaded; 106 bool is_cpu; 107 bool abort_on_hang; 108 uint64_t curr_batch; //the current batch id 109 uint32_t last_finished; 110 VkSemaphore sem; 111 VkFence fence; 112 struct util_queue flush_queue; 113 struct zink_context *copy_context; 114 115 unsigned buffer_rebind_counter; 116 unsigned image_rebind_counter; 117 unsigned robust_ctx_count; 118 119 struct hash_table dts; 120 simple_mtx_t dt_lock; 121 122 bool device_lost; 123 int drm_fd; 124 125 struct hash_table framebuffer_cache; 126 127 struct slab_parent_pool transfer_pool; 128 struct disk_cache *disk_cache; 129 struct util_queue cache_put_thread; 130 struct util_queue cache_get_thread; 131 132 struct util_live_shader_cache shaders; 133 134 struct { 135 struct pb_cache bo_cache; 136 struct pb_slabs bo_slabs[NUM_SLAB_ALLOCATORS]; 137 unsigned min_alloc_size; 138 uint32_t next_bo_unique_id; 139 } pb; 140 uint8_t heap_map[VK_MAX_MEMORY_TYPES]; 141 VkMemoryPropertyFlags heap_flags[VK_MAX_MEMORY_TYPES]; 142 bool resizable_bar; 143 144 uint64_t total_video_mem; 145 uint64_t clamp_video_mem; 146 uint64_t total_mem; 147 148 VkInstance instance; 149 struct zink_instance_info instance_info; 150 151 VkPhysicalDevice pdev; 152 uint32_t vk_version, spirv_version; 153 struct util_idalloc_mt buffer_ids; 154 struct util_vertex_state_cache vertex_state_cache; 155 156 struct zink_device_info info; 157 struct nir_shader_compiler_options nir_options; 158 159 bool have_X8_D24_UNORM_PACK32; 160 bool have_D24_UNORM_S8_UINT; 161 bool have_D32_SFLOAT_S8_UINT; 162 bool have_triangle_fans; 163 bool need_2D_zs; 164 bool need_2D_sparse; 165 bool faked_e5sparse; //drivers may not expose R9G9B9E5 but cts requires it 166 167 uint32_t gfx_queue; 168 uint32_t sparse_queue; 169 uint32_t max_queues; 170 uint32_t timestamp_valid_bits; 171 VkDevice dev; 172 VkQueue queue; //gfx+compute 173 VkQueue queue_sparse; 174 simple_mtx_t queue_lock; 175 VkDebugUtilsMessengerEXT debugUtilsCallbackHandle; 176 177 uint32_t cur_custom_border_color_samplers; 178 179 struct vk_dispatch_table vk; 180 181 bool compact_descriptors; 182 uint8_t desc_set_id[ZINK_MAX_DESCRIPTOR_SETS]; 183 bool (*descriptor_program_init)(struct zink_context *ctx, struct zink_program *pg); 184 void (*descriptor_program_deinit)(struct zink_context *ctx, struct zink_program *pg); 185 void (*descriptors_update)(struct zink_context *ctx, bool is_compute); 186 void (*context_update_descriptor_states)(struct zink_context *ctx, bool is_compute); 187 void (*context_invalidate_descriptor_state)(struct zink_context *ctx, enum pipe_shader_type shader, 188 enum zink_descriptor_type type, 189 unsigned start, unsigned count); 190 bool (*batch_descriptor_init)(struct zink_screen *screen, struct zink_batch_state *bs); 191 void (*batch_descriptor_reset)(struct zink_screen *screen, struct zink_batch_state *bs); 192 void (*batch_descriptor_deinit)(struct zink_screen *screen, struct zink_batch_state *bs); 193 bool (*descriptors_init)(struct zink_context *ctx); 194 void (*descriptors_deinit)(struct zink_context *ctx); 195 196 struct { 197 bool dual_color_blend_by_location; 198 bool inline_uniforms; 199 } driconf; 200 201 VkFormatProperties format_props[PIPE_FORMAT_COUNT]; 202 struct zink_modifier_prop modifier_props[PIPE_FORMAT_COUNT]; 203 struct { 204 uint32_t image_view; 205 uint32_t buffer_view; 206 } null_descriptor_hashes; 207 208 VkExtent2D maxSampleLocationGridSize[5]; 209 210 struct { 211 bool color_write_missing; 212 bool depth_clip_control_missing; 213 bool implicit_sync; 214 unsigned z16_unscaled_bias; 215 unsigned z24_unscaled_bias; 216 } driver_workarounds; 217}; 218 219/* update last_finished to account for batch_id wrapping */ 220static inline void 221zink_screen_update_last_finished(struct zink_screen *screen, uint64_t batch_id) 222{ 223 const uint32_t check_id = (uint32_t)batch_id; 224 /* last_finished may have wrapped */ 225 if (screen->last_finished < UINT_MAX / 2) { 226 /* last_finished has wrapped, batch_id has not */ 227 if (check_id > UINT_MAX / 2) 228 return; 229 } else if (check_id < UINT_MAX / 2) { 230 /* batch_id has wrapped, last_finished has not */ 231 screen->last_finished = check_id; 232 return; 233 } 234 /* neither have wrapped */ 235 screen->last_finished = MAX2(check_id, screen->last_finished); 236} 237 238/* check a batch_id against last_finished while accounting for wrapping */ 239static inline bool 240zink_screen_check_last_finished(struct zink_screen *screen, uint32_t batch_id) 241{ 242 const uint32_t check_id = (uint32_t)batch_id; 243 /* last_finished may have wrapped */ 244 if (screen->last_finished < UINT_MAX / 2) { 245 /* last_finished has wrapped, batch_id has not */ 246 if (check_id > UINT_MAX / 2) 247 return true; 248 } else if (check_id < UINT_MAX / 2) { 249 /* batch_id has wrapped, last_finished has not */ 250 return false; 251 } 252 return screen->last_finished >= check_id; 253} 254 255bool 256zink_screen_init_semaphore(struct zink_screen *screen); 257 258static inline bool 259zink_screen_handle_vkresult(struct zink_screen *screen, VkResult ret) 260{ 261 bool success = false; 262 switch (ret) { 263 case VK_SUCCESS: 264 success = true; 265 break; 266 case VK_ERROR_DEVICE_LOST: 267 screen->device_lost = true; 268 mesa_loge("zink: DEVICE LOST!\n"); 269 /* if nothing can save us, abort */ 270 if (screen->abort_on_hang && !screen->robust_ctx_count) 271 abort(); 272 FALLTHROUGH; 273 default: 274 success = false; 275 break; 276 } 277 return success; 278} 279 280static inline struct zink_screen * 281zink_screen(struct pipe_screen *pipe) 282{ 283 return (struct zink_screen *)pipe; 284} 285 286 287struct mem_cache_entry { 288 VkDeviceMemory mem; 289 void *map; 290}; 291 292#define VKCTX(fn) zink_screen(ctx->base.screen)->vk.fn 293#define VKSCR(fn) screen->vk.fn 294 295VkFormat 296zink_get_format(struct zink_screen *screen, enum pipe_format format); 297 298bool 299zink_screen_timeline_wait(struct zink_screen *screen, uint64_t batch_id, uint64_t timeout); 300 301bool 302zink_is_depth_format_supported(struct zink_screen *screen, VkFormat format); 303 304#define GET_PROC_ADDR_INSTANCE_LOCAL(screen, instance, x) PFN_vk##x vk_##x = (PFN_vk##x)(screen)->vk_GetInstanceProcAddr(instance, "vk"#x) 305 306void 307zink_screen_update_pipeline_cache(struct zink_screen *screen, struct zink_program *pg); 308 309void 310zink_screen_get_pipeline_cache(struct zink_screen *screen, struct zink_program *pg); 311 312void 313zink_screen_init_descriptor_funcs(struct zink_screen *screen, bool fallback); 314 315void 316zink_stub_function_not_loaded(void); 317 318#define warn_missing_feature(warned, feat) \ 319 do { \ 320 if (!warned) { \ 321 mesa_logw("WARNING: Incorrect rendering will happen " \ 322 "because the Vulkan device doesn't support " \ 323 "the '%s' feature\n", feat); \ 324 warned = true; \ 325 } \ 326 } while (0) 327 328#ifdef __cplusplus 329} 330#endif 331 332#endif 333