zink_context.h revision 7ec681f3
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_CONTEXT_H
25#define ZINK_CONTEXT_H
26
27#define ZINK_FBFETCH_BINDING 6 //COMPUTE+1
28#define ZINK_SHADER_COUNT (PIPE_SHADER_TYPES - 1)
29
30#define ZINK_DEFAULT_MAX_DESCS 5000
31#define ZINK_DEFAULT_DESC_CLAMP (ZINK_DEFAULT_MAX_DESCS * 0.9)
32
33#define ZINK_MAX_BINDLESS_HANDLES 1024
34
35#include "zink_clear.h"
36#include "zink_pipeline.h"
37#include "zink_batch.h"
38#include "zink_compiler.h"
39#include "zink_descriptors.h"
40#include "zink_surface.h"
41
42#include "pipe/p_context.h"
43#include "pipe/p_state.h"
44#include "util/u_rect.h"
45#include "util/u_threaded_context.h"
46#include "util/u_idalloc.h"
47#include "util/slab.h"
48#include "util/list.h"
49#include "util/u_dynarray.h"
50
51#include <vulkan/vulkan.h>
52
53#ifdef __cplusplus
54extern "C" {
55#endif
56
57struct blitter_context;
58struct list_head;
59
60struct zink_blend_state;
61struct zink_depth_stencil_alpha_state;
62struct zink_gfx_program;
63struct zink_rasterizer_state;
64struct zink_resource;
65struct zink_vertex_elements_state;
66
67enum zink_blit_flags {
68   ZINK_BLIT_NORMAL = 1 << 0,
69   ZINK_BLIT_SAVE_FS = 1 << 1,
70   ZINK_BLIT_SAVE_FB = 1 << 2,
71   ZINK_BLIT_SAVE_TEXTURES = 1 << 3,
72   ZINK_BLIT_NO_COND_RENDER = 1 << 4,
73};
74
75struct zink_sampler_state {
76   VkSampler sampler;
77   uint32_t hash;
78   struct zink_descriptor_refs desc_set_refs;
79   struct zink_batch_usage *batch_uses;
80   bool custom_border_color;
81};
82
83struct zink_buffer_view {
84   struct pipe_reference reference;
85   struct pipe_resource *pres;
86   VkBufferViewCreateInfo bvci;
87   VkBufferView buffer_view;
88   uint32_t hash;
89   struct zink_batch_usage *batch_uses;
90   struct zink_descriptor_refs desc_set_refs;
91};
92
93struct zink_sampler_view {
94   struct pipe_sampler_view base;
95   union {
96      struct zink_surface *image_view;
97      struct zink_buffer_view *buffer_view;
98   };
99};
100
101struct zink_image_view {
102   struct pipe_image_view base;
103   union {
104      struct zink_surface *surface;
105      struct zink_buffer_view *buffer_view;
106   };
107};
108
109static inline struct zink_sampler_view *
110zink_sampler_view(struct pipe_sampler_view *pview)
111{
112   return (struct zink_sampler_view *)pview;
113}
114
115struct zink_so_target {
116   struct pipe_stream_output_target base;
117   struct pipe_resource *counter_buffer;
118   VkDeviceSize counter_buffer_offset;
119   uint32_t stride;
120   bool counter_buffer_valid;
121};
122
123static inline struct zink_so_target *
124zink_so_target(struct pipe_stream_output_target *so_target)
125{
126   return (struct zink_so_target *)so_target;
127}
128
129struct zink_viewport_state {
130   struct pipe_viewport_state viewport_states[PIPE_MAX_VIEWPORTS];
131   struct pipe_scissor_state scissor_states[PIPE_MAX_VIEWPORTS];
132   uint8_t num_viewports;
133};
134
135
136struct zink_descriptor_surface {
137   union {
138      struct zink_surface *surface;
139      struct zink_buffer_view *bufferview;
140   };
141   bool is_buffer;
142};
143
144struct zink_bindless_descriptor {
145   struct zink_descriptor_surface ds;
146   struct zink_sampler_state *sampler;
147   uint32_t handle;
148   uint32_t access; //PIPE_ACCESS_...
149};
150
151static inline struct zink_resource *
152zink_descriptor_surface_resource(struct zink_descriptor_surface *ds)
153{
154   return ds->is_buffer ? (struct zink_resource*)ds->bufferview->pres : (struct zink_resource*)ds->surface->base.texture;
155}
156
157typedef void (*pipe_draw_vbo_func)(struct pipe_context *pipe,
158                                   const struct pipe_draw_info *info,
159                                   unsigned drawid_offset,
160                                   const struct pipe_draw_indirect_info *indirect,
161                                   const struct pipe_draw_start_count_bias *draws,
162                                   unsigned num_draws);
163
164typedef void (*pipe_launch_grid_func)(struct pipe_context *pipe, const struct pipe_grid_info *info);
165
166typedef enum {
167   ZINK_NO_MULTIDRAW,
168   ZINK_MULTIDRAW,
169} zink_multidraw;
170
171typedef enum {
172   ZINK_NO_DYNAMIC_STATE,
173   ZINK_DYNAMIC_STATE,
174} zink_dynamic_state;
175
176typedef enum {
177   ZINK_NO_DYNAMIC_STATE2,
178   ZINK_DYNAMIC_STATE2,
179} zink_dynamic_state2;
180
181typedef enum {
182   ZINK_NO_DYNAMIC_VERTEX_INPUT,
183   ZINK_DYNAMIC_VERTEX_INPUT,
184} zink_dynamic_vertex_input;
185
186struct zink_context {
187   struct pipe_context base;
188   struct threaded_context *tc;
189   struct slab_child_pool transfer_pool;
190   struct slab_child_pool transfer_pool_unsync;
191   struct blitter_context *blitter;
192
193   pipe_draw_vbo_func draw_vbo[2]; //batch changed
194   pipe_launch_grid_func launch_grid[2]; //batch changed
195
196   struct pipe_device_reset_callback reset;
197
198   simple_mtx_t batch_mtx;
199   struct zink_fence *deferred_fence;
200   struct zink_fence *last_fence; //the last command buffer submitted
201   struct zink_batch_state *batch_states; //list of submitted batch states: ordered by increasing timeline id
202   unsigned batch_states_count; //number of states in `batch_states`
203   struct util_dynarray free_batch_states; //unused batch states
204   bool oom_flush;
205   bool oom_stall;
206   struct zink_batch batch;
207
208   unsigned shader_has_inlinable_uniforms_mask;
209   unsigned inlinable_uniforms_valid_mask;
210   uint32_t compute_inlinable_uniforms[MAX_INLINABLE_UNIFORMS];
211
212   struct pipe_constant_buffer ubos[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
213   struct pipe_shader_buffer ssbos[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS];
214   uint32_t writable_ssbos[PIPE_SHADER_TYPES];
215   struct zink_image_view image_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
216
217   struct pipe_framebuffer_state fb_state;
218   struct zink_framebuffer *(*get_framebuffer)(struct zink_context*);
219   void (*init_framebuffer)(struct zink_screen *screen, struct zink_framebuffer *fb, struct zink_render_pass *rp);
220   struct hash_table framebuffer_cache;
221
222   struct zink_vertex_elements_state *element_state;
223   struct zink_rasterizer_state *rast_state;
224   struct zink_depth_stencil_alpha_state *dsa_state;
225
226   struct hash_table desc_set_layouts[ZINK_DESCRIPTOR_TYPES];
227   bool pipeline_changed[2]; //gfx, compute
228
229   struct zink_shader *gfx_stages[ZINK_SHADER_COUNT];
230   struct zink_shader *last_vertex_stage;
231   bool shader_reads_drawid;
232   bool shader_reads_basevertex;
233   struct zink_gfx_pipeline_state gfx_pipeline_state;
234   /* there are 5 gfx stages, but VS and FS are assumed to be always present,
235    * thus only 3 stages need to be considered, giving 2^3 = 8 program caches.
236    */
237   struct hash_table program_cache[8];
238   uint32_t gfx_hash;
239   struct zink_gfx_program *curr_program;
240
241   struct zink_descriptor_data *dd;
242
243   struct zink_shader *compute_stage;
244   struct zink_compute_pipeline_state compute_pipeline_state;
245   struct hash_table compute_program_cache;
246   struct zink_compute_program *curr_compute;
247
248   unsigned shader_stages : ZINK_SHADER_COUNT; /* mask of bound gfx shader stages */
249   unsigned dirty_shader_stages : 6; /* mask of changed shader stages */
250   bool last_vertex_stage_dirty;
251
252   struct set render_pass_state_cache;
253   struct hash_table *render_pass_cache;
254   bool new_swapchain;
255   bool fb_changed;
256   bool rp_changed;
257
258   struct zink_framebuffer *framebuffer;
259   struct zink_framebuffer_clear fb_clears[PIPE_MAX_COLOR_BUFS + 1];
260   uint16_t clears_enabled;
261   uint16_t rp_clears_enabled;
262   uint16_t fbfetch_outputs;
263
264   struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
265   bool vertex_buffers_dirty;
266
267   void *sampler_states[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
268   struct pipe_sampler_view *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
269
270   struct zink_viewport_state vp_state;
271   bool vp_state_changed;
272   bool scissor_changed;
273
274   float blend_constants[4];
275
276   bool sample_locations_changed;
277   VkSampleLocationEXT vk_sample_locations[PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE * PIPE_MAX_SAMPLE_LOCATION_GRID_SIZE];
278   uint8_t sample_locations[2 * 4 * 8 * 16];
279
280   struct pipe_stencil_ref stencil_ref;
281
282   union {
283      struct {
284         float default_inner_level[2];
285         float default_outer_level[4];
286      };
287      float tess_levels[6];
288   };
289
290   struct list_head suspended_queries;
291   struct list_head primitives_generated_queries;
292   bool queries_disabled, render_condition_active;
293   struct {
294      struct zink_query *query;
295      bool inverted;
296   } render_condition;
297
298   struct pipe_resource *dummy_vertex_buffer;
299   struct pipe_resource *dummy_xfb_buffer;
300   struct pipe_surface *dummy_surface[7];
301   struct zink_buffer_view *dummy_bufferview;
302
303   unsigned buffer_rebind_counter;
304
305   struct {
306      /* descriptor info */
307      VkDescriptorBufferInfo ubos[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
308      uint32_t push_valid;
309      uint8_t num_ubos[PIPE_SHADER_TYPES];
310
311      VkDescriptorBufferInfo ssbos[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS];
312      uint8_t num_ssbos[PIPE_SHADER_TYPES];
313
314      VkDescriptorImageInfo textures[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
315      VkBufferView tbos[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
316      uint8_t num_samplers[PIPE_SHADER_TYPES];
317      uint8_t num_sampler_views[PIPE_SHADER_TYPES];
318
319      VkDescriptorImageInfo images[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
320      VkBufferView texel_images[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
321      uint8_t num_images[PIPE_SHADER_TYPES];
322
323      VkDescriptorImageInfo fbfetch;
324
325      struct zink_resource *descriptor_res[ZINK_DESCRIPTOR_TYPES][PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
326      struct zink_descriptor_surface sampler_surfaces[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
327      struct zink_descriptor_surface image_surfaces[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
328
329      struct {
330         struct util_idalloc tex_slots;
331         struct util_idalloc img_slots;
332         struct hash_table tex_handles;
333         struct hash_table img_handles;
334         VkBufferView *buffer_infos; //tex, img
335         VkDescriptorImageInfo *img_infos; //tex, img
336         struct util_dynarray updates;
337         struct util_dynarray resident;
338      } bindless[2];  //img, buffer
339      union {
340         bool bindless_dirty[2]; //tex, img
341         uint16_t any_bindless_dirty;
342      };
343      bool bindless_refs_dirty;
344   } di;
345   struct set *need_barriers[2]; //gfx, compute
346   struct set update_barriers[2][2]; //[gfx, compute][current, next]
347   uint8_t barrier_set_idx[2];
348   unsigned memory_barrier;
349
350   uint32_t num_so_targets;
351   struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_OUTPUTS];
352   bool dirty_so_targets;
353   bool xfb_barrier;
354   bool first_frame_done;
355   bool have_timelines;
356
357   bool gfx_dirty;
358
359   bool is_device_lost;
360   bool primitive_restart;
361   bool vertex_state_changed : 1;
362   bool blend_state_changed : 1;
363   bool rast_state_changed : 1;
364   bool dsa_state_changed : 1;
365   bool stencil_ref_changed : 1;
366};
367
368static inline struct zink_context *
369zink_context(struct pipe_context *context)
370{
371   return (struct zink_context *)context;
372}
373
374static inline bool
375zink_fb_clear_enabled(const struct zink_context *ctx, unsigned idx)
376{
377   if (idx == PIPE_MAX_COLOR_BUFS)
378      return ctx->clears_enabled & PIPE_CLEAR_DEPTHSTENCIL;
379   return ctx->clears_enabled & (PIPE_CLEAR_COLOR0 << idx);
380}
381
382void
383zink_fence_wait(struct pipe_context *ctx);
384
385void
386zink_wait_on_batch(struct zink_context *ctx, uint32_t batch_id);
387
388bool
389zink_check_batch_completion(struct zink_context *ctx, uint32_t batch_id, bool have_lock);
390
391void
392zink_flush_queue(struct zink_context *ctx);
393void
394zink_update_fbfetch(struct zink_context *ctx);
395bool
396zink_resource_access_is_write(VkAccessFlags flags);
397
398void
399zink_resource_buffer_barrier(struct zink_context *ctx, struct zink_resource *res, VkAccessFlags flags, VkPipelineStageFlags pipeline);
400bool
401zink_resource_image_needs_barrier(struct zink_resource *res, VkImageLayout new_layout, VkAccessFlags flags, VkPipelineStageFlags pipeline);
402bool
403zink_resource_image_barrier_init(VkImageMemoryBarrier *imb, struct zink_resource *res, VkImageLayout new_layout, VkAccessFlags flags, VkPipelineStageFlags pipeline);
404void
405zink_resource_image_barrier(struct zink_context *ctx, struct zink_resource *res,
406                      VkImageLayout new_layout, VkAccessFlags flags, VkPipelineStageFlags pipeline);
407
408bool
409zink_resource_needs_barrier(struct zink_resource *res, VkImageLayout layout, VkAccessFlags flags, VkPipelineStageFlags pipeline);
410void
411zink_update_descriptor_refs(struct zink_context *ctx, bool compute);
412void
413zink_init_vk_sample_locations(struct zink_context *ctx, VkSampleLocationsInfoEXT *loc);
414
415void
416zink_begin_render_pass(struct zink_context *ctx);
417void
418zink_end_render_pass(struct zink_context *ctx);
419
420static inline void
421zink_batch_rp(struct zink_context *ctx)
422{
423   if (!ctx->batch.in_rp)
424      zink_begin_render_pass(ctx);
425}
426
427static inline void
428zink_batch_no_rp(struct zink_context *ctx)
429{
430   zink_end_render_pass(ctx);
431   assert(!ctx->batch.in_rp);
432}
433
434static inline VkPipelineStageFlags
435zink_pipeline_flags_from_pipe_stage(enum pipe_shader_type pstage)
436{
437   switch (pstage) {
438   case PIPE_SHADER_VERTEX:
439      return VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
440   case PIPE_SHADER_FRAGMENT:
441      return VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
442   case PIPE_SHADER_GEOMETRY:
443      return VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
444   case PIPE_SHADER_TESS_CTRL:
445      return VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT;
446   case PIPE_SHADER_TESS_EVAL:
447      return VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT;
448   case PIPE_SHADER_COMPUTE:
449      return VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
450   default:
451      unreachable("unknown shader stage");
452   }
453}
454
455void
456zink_rebind_all_buffers(struct zink_context *ctx);
457
458void
459zink_flush_memory_barrier(struct zink_context *ctx, bool is_compute);
460void
461zink_init_draw_functions(struct zink_context *ctx, struct zink_screen *screen);
462void
463zink_init_grid_functions(struct zink_context *ctx);
464
465#ifdef __cplusplus
466}
467#endif
468
469#ifndef __cplusplus
470VkPipelineStageFlags
471zink_pipeline_flags_from_stage(VkShaderStageFlagBits stage);
472
473VkShaderStageFlagBits
474zink_shader_stage(enum pipe_shader_type type);
475
476struct pipe_context *
477zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags);
478
479void
480zink_context_query_init(struct pipe_context *ctx);
481
482void
483zink_blit_begin(struct zink_context *ctx, enum zink_blit_flags flags);
484
485void
486zink_blit(struct pipe_context *pctx,
487          const struct pipe_blit_info *info);
488
489bool
490zink_blit_region_fills(struct u_rect region, unsigned width, unsigned height);
491
492bool
493zink_blit_region_covers(struct u_rect region, struct u_rect covers);
494
495static inline struct u_rect
496zink_rect_from_box(const struct pipe_box *box)
497{
498   return (struct u_rect){box->x, box->x + box->width, box->y, box->y + box->height};
499}
500
501static inline VkComponentSwizzle
502zink_component_mapping(enum pipe_swizzle swizzle)
503{
504   switch (swizzle) {
505   case PIPE_SWIZZLE_X: return VK_COMPONENT_SWIZZLE_R;
506   case PIPE_SWIZZLE_Y: return VK_COMPONENT_SWIZZLE_G;
507   case PIPE_SWIZZLE_Z: return VK_COMPONENT_SWIZZLE_B;
508   case PIPE_SWIZZLE_W: return VK_COMPONENT_SWIZZLE_A;
509   case PIPE_SWIZZLE_0: return VK_COMPONENT_SWIZZLE_ZERO;
510   case PIPE_SWIZZLE_1: return VK_COMPONENT_SWIZZLE_ONE;
511   case PIPE_SWIZZLE_NONE: return VK_COMPONENT_SWIZZLE_IDENTITY; // ???
512   default:
513      unreachable("unexpected swizzle");
514   }
515}
516
517enum pipe_swizzle
518zink_clamp_void_swizzle(const struct util_format_description *desc, enum pipe_swizzle swizzle);
519
520bool
521zink_resource_rebind(struct zink_context *ctx, struct zink_resource *res);
522
523void
524zink_rebind_framebuffer(struct zink_context *ctx, struct zink_resource *res);
525
526void
527zink_copy_buffer(struct zink_context *ctx, struct zink_resource *dst, struct zink_resource *src,
528                 unsigned dst_offset, unsigned src_offset, unsigned size);
529
530void
531zink_copy_image_buffer(struct zink_context *ctx, struct zink_resource *dst, struct zink_resource *src,
532                       unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz,
533                       unsigned src_level, const struct pipe_box *src_box, enum pipe_map_flags map_flags);
534
535void
536zink_destroy_buffer_view(struct zink_screen *screen, struct zink_buffer_view *buffer_view);
537
538void
539debug_describe_zink_buffer_view(char *buf, const struct zink_buffer_view *ptr);
540
541static inline void
542zink_buffer_view_reference(struct zink_screen *screen,
543                           struct zink_buffer_view **dst,
544                           struct zink_buffer_view *src)
545{
546   struct zink_buffer_view *old_dst = dst ? *dst : NULL;
547
548   if (pipe_reference_described(old_dst ? &old_dst->reference : NULL, &src->reference,
549                                (debug_reference_descriptor)debug_describe_zink_buffer_view))
550      zink_destroy_buffer_view(screen, old_dst);
551   if (dst) *dst = src;
552}
553#endif
554
555#endif
556