2
* Copyright 2018 Collabora Ltd.
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:
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
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.
27
#include "zink_device_info.h"
28
#include "zink_instance.h"
29
#include "vk_dispatch_table.h"
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"
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"
44
#include <vulkan/vulkan.h>
46
extern uint32_t zink_debug;
49
struct zink_batch_state;
51
struct zink_descriptor_layout_key;
54
enum zink_descriptor_type;
56
/* this is the spec minimum */
57
#define ZINK_SPARSE_BUFFER_PAGE_SIZE (64 * 1024)
59
#define ZINK_DEBUG_NIR 0x1
60
#define ZINK_DEBUG_SPIRV 0x2
61
#define ZINK_DEBUG_TGSI 0x4
62
#define ZINK_DEBUG_VALIDATION 0x8
64
#define NUM_SLAB_ALLOCATORS 3
65
#define MIN_SLAB_ORDER 8
67
#define ZINK_CONTEXT_COPY_ONLY (1<<30)
69
enum zink_descriptor_mode {
70
ZINK_DESCRIPTOR_MODE_AUTO,
71
ZINK_DESCRIPTOR_MODE_LAZY,
72
ZINK_DESCRIPTOR_MODE_NOFALLBACK,
73
ZINK_DESCRIPTOR_MODE_NOTEMPLATES,
76
struct zink_modifier_prop {
77
uint32_t drmFormatModifierCount;
78
VkDrmFormatModifierPropertiesEXT* pDrmFormatModifierProperties;
82
struct pipe_screen base;
85
uint32_t curr_batch; //the current batch id
86
uint32_t last_finished; //this is racy but ultimately doesn't matter
90
struct util_queue flush_queue;
91
struct zink_context *copy_context;
93
unsigned buffer_rebind_counter;
95
struct hash_table dts;
100
struct hash_table framebuffer_cache;
101
simple_mtx_t framebuffer_mtx;
103
struct slab_parent_pool transfer_pool;
104
struct disk_cache *disk_cache;
105
struct util_queue cache_put_thread;
106
struct util_queue cache_get_thread;
108
struct util_live_shader_cache shaders;
111
struct pb_cache bo_cache;
112
struct pb_slabs bo_slabs[NUM_SLAB_ALLOCATORS];
113
unsigned min_alloc_size;
114
struct hash_table *bo_export_table;
115
simple_mtx_t bo_export_table_lock;
116
uint32_t next_bo_unique_id;
118
uint8_t heap_map[VK_MAX_MEMORY_TYPES];
119
VkMemoryPropertyFlags heap_flags[VK_MAX_MEMORY_TYPES];
122
uint64_t total_video_mem;
123
uint64_t clamp_video_mem;
127
struct zink_instance_info instance_info;
129
VkPhysicalDevice pdev;
130
uint32_t vk_version, spirv_version;
131
struct util_idalloc_mt buffer_ids;
132
struct util_vertex_state_cache vertex_state_cache;
134
struct zink_device_info info;
135
struct nir_shader_compiler_options nir_options;
137
bool have_X8_D24_UNORM_PACK32;
138
bool have_D24_UNORM_S8_UINT;
139
bool have_triangle_fans;
142
bool faked_e5sparse; //drivers may not expose R9G9B9E5 but cts requires it
146
uint32_t timestamp_valid_bits;
149
VkQueue queue; //gfx+compute
150
VkQueue thread_queue; //gfx+compute
151
simple_mtx_t queue_lock;
152
VkDebugUtilsMessengerEXT debugUtilsCallbackHandle;
154
uint32_t cur_custom_border_color_samplers;
156
struct vk_dispatch_table vk;
158
bool (*descriptor_program_init)(struct zink_context *ctx, struct zink_program *pg);
159
void (*descriptor_program_deinit)(struct zink_context *ctx, struct zink_program *pg);
160
void (*descriptors_update)(struct zink_context *ctx, bool is_compute);
161
void (*context_update_descriptor_states)(struct zink_context *ctx, bool is_compute);
162
void (*context_invalidate_descriptor_state)(struct zink_context *ctx, enum pipe_shader_type shader,
163
enum zink_descriptor_type type,
164
unsigned start, unsigned count);
165
bool (*batch_descriptor_init)(struct zink_screen *screen, struct zink_batch_state *bs);
166
void (*batch_descriptor_reset)(struct zink_screen *screen, struct zink_batch_state *bs);
167
void (*batch_descriptor_deinit)(struct zink_screen *screen, struct zink_batch_state *bs);
168
bool (*descriptors_init)(struct zink_context *ctx);
169
void (*descriptors_deinit)(struct zink_context *ctx);
170
enum zink_descriptor_mode descriptor_mode;
173
bool dual_color_blend_by_location;
174
bool inline_uniforms;
177
VkFormatProperties format_props[PIPE_FORMAT_COUNT];
178
struct zink_modifier_prop modifier_props[PIPE_FORMAT_COUNT];
181
uint32_t buffer_view;
182
} null_descriptor_hashes;
184
VkExtent2D maxSampleLocationGridSize[5];
187
bool color_write_missing;
188
bool depth_clip_control_missing;
190
} driver_workarounds;
193
/* update last_finished to account for batch_id wrapping */
195
zink_screen_update_last_finished(struct zink_screen *screen, uint32_t batch_id)
197
/* last_finished may have wrapped */
198
if (screen->last_finished < UINT_MAX / 2) {
199
/* last_finished has wrapped, batch_id has not */
200
if (batch_id > UINT_MAX / 2)
202
} else if (batch_id < UINT_MAX / 2) {
203
/* batch_id has wrapped, last_finished has not */
204
screen->last_finished = batch_id;
207
/* neither have wrapped */
208
screen->last_finished = MAX2(batch_id, screen->last_finished);
211
/* check a batch_id against last_finished while accounting for wrapping */
213
zink_screen_check_last_finished(struct zink_screen *screen, uint32_t batch_id)
215
/* last_finished may have wrapped */
216
if (screen->last_finished < UINT_MAX / 2) {
217
/* last_finished has wrapped, batch_id has not */
218
if (batch_id > UINT_MAX / 2)
220
} else if (batch_id < UINT_MAX / 2) {
221
/* batch_id has wrapped, last_finished has not */
224
return screen->last_finished >= batch_id;
228
zink_screen_init_semaphore(struct zink_screen *screen);
231
zink_screen_handle_vkresult(struct zink_screen *screen, VkResult ret)
233
bool success = false;
238
case VK_ERROR_DEVICE_LOST:
239
screen->device_lost = true;
240
mesa_loge("zink: DEVICE LOST!\n");
249
static inline struct zink_screen *
250
zink_screen(struct pipe_screen *pipe)
252
return (struct zink_screen *)pipe;
256
struct mem_cache_entry {
261
#define VKCTX(fn) zink_screen(ctx->base.screen)->vk.fn
262
#define VKSCR(fn) screen->vk.fn
265
zink_get_format(struct zink_screen *screen, enum pipe_format format);
268
zink_screen_batch_id_wait(struct zink_screen *screen, uint32_t batch_id, uint64_t timeout);
271
zink_screen_timeline_wait(struct zink_screen *screen, uint32_t batch_id, uint64_t timeout);
274
zink_is_depth_format_supported(struct zink_screen *screen, VkFormat format);
276
#define GET_PROC_ADDR_INSTANCE_LOCAL(instance, x) PFN_vk##x vk_##x = (PFN_vk##x)vkGetInstanceProcAddr(instance, "vk"#x)
279
zink_screen_update_pipeline_cache(struct zink_screen *screen, struct zink_program *pg);
282
zink_screen_get_pipeline_cache(struct zink_screen *screen, struct zink_program *pg);
285
zink_screen_init_descriptor_funcs(struct zink_screen *screen, bool fallback);
288
zink_stub_function_not_loaded(void);
290
#define warn_missing_feature(warned, feat) \
293
mesa_logw("WARNING: Incorrect rendering will happen " \
294
"because the Vulkan device doesn't support " \
295
"the '%s' feature\n", feat); \