17ec681f3Smrg/* 27ec681f3Smrg * Copyright 2018 Collabora Ltd. 37ec681f3Smrg * 47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 57ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 67ec681f3Smrg * to deal in the Software without restriction, including without limitation 77ec681f3Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub 87ec681f3Smrg * license, and/or sell copies of the Software, and to permit persons to whom 97ec681f3Smrg * the Software is furnished to do so, subject to the following conditions: 107ec681f3Smrg * 117ec681f3Smrg * The above copyright notice and this permission notice (including the next 127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 137ec681f3Smrg * Software. 147ec681f3Smrg * 157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 187ec681f3Smrg * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 197ec681f3Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 207ec681f3Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 217ec681f3Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE. 227ec681f3Smrg */ 237ec681f3Smrg 247ec681f3Smrg#ifndef ZINK_SCREEN_H 257ec681f3Smrg#define ZINK_SCREEN_H 267ec681f3Smrg 277ec681f3Smrg#include "zink_device_info.h" 287ec681f3Smrg#include "zink_instance.h" 297ec681f3Smrg#include "vk_dispatch_table.h" 307ec681f3Smrg 317ec681f3Smrg#include "util/u_idalloc.h" 327ec681f3Smrg#include "pipe/p_screen.h" 337ec681f3Smrg#include "util/slab.h" 347ec681f3Smrg#include "compiler/nir/nir.h" 357ec681f3Smrg#include "util/disk_cache.h" 367ec681f3Smrg#include "util/log.h" 377ec681f3Smrg#include "util/simple_mtx.h" 387ec681f3Smrg#include "util/u_queue.h" 397ec681f3Smrg#include "util/u_live_shader_cache.h" 407ec681f3Smrg#include "pipebuffer/pb_cache.h" 417ec681f3Smrg#include "pipebuffer/pb_slab.h" 427ec681f3Smrg#include <vulkan/vulkan.h> 437ec681f3Smrg 447ec681f3Smrgextern uint32_t zink_debug; 457ec681f3Smrgstruct hash_table; 467ec681f3Smrg 477ec681f3Smrgstruct zink_batch_state; 487ec681f3Smrgstruct zink_context; 497ec681f3Smrgstruct zink_descriptor_layout_key; 507ec681f3Smrgstruct zink_program; 517ec681f3Smrgstruct zink_shader; 527ec681f3Smrgenum zink_descriptor_type; 537ec681f3Smrg 547ec681f3Smrg/* this is the spec minimum */ 557ec681f3Smrg#define ZINK_SPARSE_BUFFER_PAGE_SIZE (64 * 1024) 567ec681f3Smrg 577ec681f3Smrg#define ZINK_DEBUG_NIR 0x1 587ec681f3Smrg#define ZINK_DEBUG_SPIRV 0x2 597ec681f3Smrg#define ZINK_DEBUG_TGSI 0x4 607ec681f3Smrg#define ZINK_DEBUG_VALIDATION 0x8 617ec681f3Smrg 627ec681f3Smrg#define NUM_SLAB_ALLOCATORS 3 637ec681f3Smrg 647ec681f3Smrgenum zink_descriptor_mode { 657ec681f3Smrg ZINK_DESCRIPTOR_MODE_AUTO, 667ec681f3Smrg ZINK_DESCRIPTOR_MODE_LAZY, 677ec681f3Smrg ZINK_DESCRIPTOR_MODE_NOFALLBACK, 687ec681f3Smrg ZINK_DESCRIPTOR_MODE_NOTEMPLATES, 697ec681f3Smrg}; 707ec681f3Smrg 717ec681f3Smrgstruct zink_modifier_prop { 727ec681f3Smrg uint32_t drmFormatModifierCount; 737ec681f3Smrg VkDrmFormatModifierPropertiesEXT* pDrmFormatModifierProperties; 747ec681f3Smrg}; 757ec681f3Smrg 767ec681f3Smrgstruct zink_screen { 777ec681f3Smrg struct pipe_screen base; 787ec681f3Smrg bool threaded; 797ec681f3Smrg uint32_t curr_batch; //the current batch id 807ec681f3Smrg uint32_t last_finished; //this is racy but ultimately doesn't matter 817ec681f3Smrg VkSemaphore sem; 827ec681f3Smrg VkSemaphore prev_sem; 837ec681f3Smrg struct util_queue flush_queue; 847ec681f3Smrg 857ec681f3Smrg unsigned buffer_rebind_counter; 867ec681f3Smrg 877ec681f3Smrg bool device_lost; 887ec681f3Smrg struct sw_winsys *winsys; 897ec681f3Smrg int drm_fd; 907ec681f3Smrg 917ec681f3Smrg struct hash_table framebuffer_cache; 927ec681f3Smrg simple_mtx_t framebuffer_mtx; 937ec681f3Smrg 947ec681f3Smrg struct slab_parent_pool transfer_pool; 957ec681f3Smrg struct disk_cache *disk_cache; 967ec681f3Smrg struct util_queue cache_put_thread; 977ec681f3Smrg struct util_queue cache_get_thread; 987ec681f3Smrg 997ec681f3Smrg struct util_live_shader_cache shaders; 1007ec681f3Smrg 1017ec681f3Smrg struct { 1027ec681f3Smrg struct pb_cache bo_cache; 1037ec681f3Smrg struct pb_slabs bo_slabs[NUM_SLAB_ALLOCATORS]; 1047ec681f3Smrg unsigned min_alloc_size; 1057ec681f3Smrg struct hash_table *bo_export_table; 1067ec681f3Smrg simple_mtx_t bo_export_table_lock; 1077ec681f3Smrg uint32_t next_bo_unique_id; 1087ec681f3Smrg } pb; 1097ec681f3Smrg uint8_t heap_map[VK_MAX_MEMORY_TYPES]; 1107ec681f3Smrg bool resizable_bar; 1117ec681f3Smrg 1127ec681f3Smrg uint64_t total_video_mem; 1137ec681f3Smrg uint64_t clamp_video_mem; 1147ec681f3Smrg uint64_t total_mem; 1157ec681f3Smrg 1167ec681f3Smrg VkInstance instance; 1177ec681f3Smrg struct zink_instance_info instance_info; 1187ec681f3Smrg 1197ec681f3Smrg VkPhysicalDevice pdev; 1207ec681f3Smrg uint32_t vk_version, spirv_version; 1217ec681f3Smrg struct util_idalloc_mt buffer_ids; 1227ec681f3Smrg 1237ec681f3Smrg struct zink_device_info info; 1247ec681f3Smrg struct nir_shader_compiler_options nir_options; 1257ec681f3Smrg 1267ec681f3Smrg bool have_X8_D24_UNORM_PACK32; 1277ec681f3Smrg bool have_D24_UNORM_S8_UINT; 1287ec681f3Smrg bool have_triangle_fans; 1297ec681f3Smrg 1307ec681f3Smrg uint32_t gfx_queue; 1317ec681f3Smrg uint32_t max_queues; 1327ec681f3Smrg uint32_t timestamp_valid_bits; 1337ec681f3Smrg VkDevice dev; 1347ec681f3Smrg VkQueue queue; //gfx+compute 1357ec681f3Smrg VkQueue thread_queue; //gfx+compute 1367ec681f3Smrg simple_mtx_t queue_lock; 1377ec681f3Smrg VkDebugUtilsMessengerEXT debugUtilsCallbackHandle; 1387ec681f3Smrg 1397ec681f3Smrg uint32_t cur_custom_border_color_samplers; 1407ec681f3Smrg 1417ec681f3Smrg bool needs_mesa_wsi; 1427ec681f3Smrg bool needs_mesa_flush_wsi; 1437ec681f3Smrg 1447ec681f3Smrg struct vk_dispatch_table vk; 1457ec681f3Smrg 1467ec681f3Smrg bool (*descriptor_program_init)(struct zink_context *ctx, struct zink_program *pg); 1477ec681f3Smrg void (*descriptor_program_deinit)(struct zink_screen *screen, struct zink_program *pg); 1487ec681f3Smrg void (*descriptors_update)(struct zink_context *ctx, bool is_compute); 1497ec681f3Smrg void (*context_update_descriptor_states)(struct zink_context *ctx, bool is_compute); 1507ec681f3Smrg void (*context_invalidate_descriptor_state)(struct zink_context *ctx, enum pipe_shader_type shader, 1517ec681f3Smrg enum zink_descriptor_type type, 1527ec681f3Smrg unsigned start, unsigned count); 1537ec681f3Smrg bool (*batch_descriptor_init)(struct zink_screen *screen, struct zink_batch_state *bs); 1547ec681f3Smrg void (*batch_descriptor_reset)(struct zink_screen *screen, struct zink_batch_state *bs); 1557ec681f3Smrg void (*batch_descriptor_deinit)(struct zink_screen *screen, struct zink_batch_state *bs); 1567ec681f3Smrg bool (*descriptors_init)(struct zink_context *ctx); 1577ec681f3Smrg void (*descriptors_deinit)(struct zink_context *ctx); 1587ec681f3Smrg enum zink_descriptor_mode descriptor_mode; 1597ec681f3Smrg 1607ec681f3Smrg struct { 1617ec681f3Smrg bool dual_color_blend_by_location; 1627ec681f3Smrg bool inline_uniforms; 1637ec681f3Smrg } driconf; 1647ec681f3Smrg 1657ec681f3Smrg VkFormatProperties format_props[PIPE_FORMAT_COUNT]; 1667ec681f3Smrg struct zink_modifier_prop modifier_props[PIPE_FORMAT_COUNT]; 1677ec681f3Smrg struct { 1687ec681f3Smrg uint32_t image_view; 1697ec681f3Smrg uint32_t buffer_view; 1707ec681f3Smrg } null_descriptor_hashes; 1717ec681f3Smrg 1727ec681f3Smrg VkExtent2D maxSampleLocationGridSize[5]; 1737ec681f3Smrg}; 1747ec681f3Smrg 1757ec681f3Smrg 1767ec681f3Smrg/* update last_finished to account for batch_id wrapping */ 1777ec681f3Smrgstatic inline void 1787ec681f3Smrgzink_screen_update_last_finished(struct zink_screen *screen, uint32_t batch_id) 1797ec681f3Smrg{ 1807ec681f3Smrg /* last_finished may have wrapped */ 1817ec681f3Smrg if (screen->last_finished < UINT_MAX / 2) { 1827ec681f3Smrg /* last_finished has wrapped, batch_id has not */ 1837ec681f3Smrg if (batch_id > UINT_MAX / 2) 1847ec681f3Smrg return; 1857ec681f3Smrg } else if (batch_id < UINT_MAX / 2) { 1867ec681f3Smrg /* batch_id has wrapped, last_finished has not */ 1877ec681f3Smrg screen->last_finished = batch_id; 1887ec681f3Smrg return; 1897ec681f3Smrg } 1907ec681f3Smrg /* neither have wrapped */ 1917ec681f3Smrg screen->last_finished = MAX2(batch_id, screen->last_finished); 1927ec681f3Smrg} 1937ec681f3Smrg 1947ec681f3Smrg/* check a batch_id against last_finished while accounting for wrapping */ 1957ec681f3Smrgstatic inline bool 1967ec681f3Smrgzink_screen_check_last_finished(struct zink_screen *screen, uint32_t batch_id) 1977ec681f3Smrg{ 1987ec681f3Smrg /* last_finished may have wrapped */ 1997ec681f3Smrg if (screen->last_finished < UINT_MAX / 2) { 2007ec681f3Smrg /* last_finished has wrapped, batch_id has not */ 2017ec681f3Smrg if (batch_id > UINT_MAX / 2) 2027ec681f3Smrg return true; 2037ec681f3Smrg } else if (batch_id < UINT_MAX / 2) { 2047ec681f3Smrg /* batch_id has wrapped, last_finished has not */ 2057ec681f3Smrg return false; 2067ec681f3Smrg } 2077ec681f3Smrg return screen->last_finished >= batch_id; 2087ec681f3Smrg} 2097ec681f3Smrg 2107ec681f3Smrgbool 2117ec681f3Smrgzink_screen_init_semaphore(struct zink_screen *screen); 2127ec681f3Smrg 2137ec681f3Smrgstatic inline bool 2147ec681f3Smrgzink_screen_handle_vkresult(struct zink_screen *screen, VkResult ret) 2157ec681f3Smrg{ 2167ec681f3Smrg bool success = false; 2177ec681f3Smrg switch (ret) { 2187ec681f3Smrg case VK_SUCCESS: 2197ec681f3Smrg success = true; 2207ec681f3Smrg break; 2217ec681f3Smrg case VK_ERROR_DEVICE_LOST: 2227ec681f3Smrg screen->device_lost = true; 2237ec681f3Smrg FALLTHROUGH; 2247ec681f3Smrg default: 2257ec681f3Smrg success = false; 2267ec681f3Smrg break; 2277ec681f3Smrg } 2287ec681f3Smrg return success; 2297ec681f3Smrg} 2307ec681f3Smrg 2317ec681f3Smrgstatic inline struct zink_screen * 2327ec681f3Smrgzink_screen(struct pipe_screen *pipe) 2337ec681f3Smrg{ 2347ec681f3Smrg return (struct zink_screen *)pipe; 2357ec681f3Smrg} 2367ec681f3Smrg 2377ec681f3Smrg 2387ec681f3Smrgstruct mem_cache_entry { 2397ec681f3Smrg VkDeviceMemory mem; 2407ec681f3Smrg void *map; 2417ec681f3Smrg}; 2427ec681f3Smrg 2437ec681f3Smrg#define VKCTX(fn) zink_screen(ctx->base.screen)->vk.fn 2447ec681f3Smrg#define VKSCR(fn) screen->vk.fn 2457ec681f3Smrg 2467ec681f3SmrgVkFormat 2477ec681f3Smrgzink_get_format(struct zink_screen *screen, enum pipe_format format); 2487ec681f3Smrg 2497ec681f3Smrgbool 2507ec681f3Smrgzink_screen_batch_id_wait(struct zink_screen *screen, uint32_t batch_id, uint64_t timeout); 2517ec681f3Smrg 2527ec681f3Smrgbool 2537ec681f3Smrgzink_screen_timeline_wait(struct zink_screen *screen, uint32_t batch_id, uint64_t timeout); 2547ec681f3Smrg 2557ec681f3Smrgbool 2567ec681f3Smrgzink_is_depth_format_supported(struct zink_screen *screen, VkFormat format); 2577ec681f3Smrg 2587ec681f3Smrg#define GET_PROC_ADDR_INSTANCE_LOCAL(instance, x) PFN_vk##x vk_##x = (PFN_vk##x)vkGetInstanceProcAddr(instance, "vk"#x) 2597ec681f3Smrg 2607ec681f3Smrgvoid 2617ec681f3Smrgzink_screen_update_pipeline_cache(struct zink_screen *screen, struct zink_program *pg); 2627ec681f3Smrg 2637ec681f3Smrgvoid 2647ec681f3Smrgzink_screen_get_pipeline_cache(struct zink_screen *screen, struct zink_program *pg); 2657ec681f3Smrg 2667ec681f3Smrgvoid 2677ec681f3Smrgzink_screen_init_descriptor_funcs(struct zink_screen *screen, bool fallback); 2687ec681f3Smrg 2697ec681f3Smrgvoid 2707ec681f3Smrgzink_stub_function_not_loaded(void); 2717ec681f3Smrg 2727ec681f3Smrg#define warn_missing_feature(feat) \ 2737ec681f3Smrg do { \ 2747ec681f3Smrg static bool warned = false; \ 2757ec681f3Smrg if (!warned) { \ 2767ec681f3Smrg fprintf(stderr, "WARNING: Incorrect rendering will happen, " \ 2777ec681f3Smrg "because the Vulkan device doesn't support " \ 2787ec681f3Smrg "the %s feature\n", feat); \ 2797ec681f3Smrg warned = true; \ 2807ec681f3Smrg } \ 2817ec681f3Smrg } while (0) 2827ec681f3Smrg 2837ec681f3Smrg#endif 284