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