• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "zink_clear.h"
25 #include "zink_context.h"
26 #include "zink_descriptors.h"
27 #include "zink_fence.h"
28 #include "zink_format.h"
29 #include "zink_framebuffer.h"
30 #include "zink_helpers.h"
31 #include "zink_inlines.h"
32 #include "zink_kopper.h"
33 #include "zink_pipeline.h"
34 #include "zink_program.h"
35 #include "zink_query.h"
36 #include "zink_render_pass.h"
37 #include "zink_resource.h"
38 #include "zink_screen.h"
39 #include "zink_state.h"
40 #include "zink_surface.h"
41 
42 
43 #include "nir/pipe_nir.h"
44 #include "util/u_blitter.h"
45 #include "util/u_debug.h"
46 #include "util/format_srgb.h"
47 #include "util/format/u_format.h"
48 #include "util/u_helpers.h"
49 #include "util/u_inlines.h"
50 #include "util/u_sample_positions.h"
51 #include "util/u_string.h"
52 #include "util/u_thread.h"
53 #include "util/perf/u_trace.h"
54 #include "util/u_cpu_detect.h"
55 #include "util/thread_sched.h"
56 #include "util/strndup.h"
57 #include "nir.h"
58 #include "nir_builder.h"
59 
60 #include "vk_format.h"
61 
62 #include "driver_trace/tr_context.h"
63 
64 #include "util/u_memory.h"
65 #include "util/u_upload_mgr.h"
66 
67 #define XXH_INLINE_ALL
68 #include "util/xxhash.h"
69 
70 static void
update_tc_info(struct zink_context * ctx)71 update_tc_info(struct zink_context *ctx)
72 {
73    if (ctx->track_renderpasses) {
74       const struct tc_renderpass_info *info = threaded_context_get_renderpass_info(ctx->tc);
75       ctx->rp_changed |= ctx->dynamic_fb.tc_info.data != info->data;
76       ctx->dynamic_fb.tc_info.data = info->data;
77    } else {
78       struct tc_renderpass_info info = ctx->dynamic_fb.tc_info;
79       bool zsbuf_used = !ctx->zsbuf_unused;
80       bool zsbuf_write = zink_is_zsbuf_write(ctx);
81       ctx->dynamic_fb.tc_info.data32[0] = 0;
82       if (ctx->clears_enabled & PIPE_CLEAR_DEPTHSTENCIL)
83          ctx->dynamic_fb.tc_info.zsbuf_clear_partial = true;
84       if (ctx->rp_clears_enabled & PIPE_CLEAR_DEPTHSTENCIL)
85          ctx->dynamic_fb.tc_info.zsbuf_clear = true;
86       if (ctx->dynamic_fb.tc_info.zsbuf_clear != info.zsbuf_clear)
87          ctx->rp_loadop_changed = true;
88       if (zink_is_zsbuf_write(ctx) != zsbuf_write)
89          ctx->rp_layout_changed = true;
90       ctx->rp_changed |= zink_is_zsbuf_used(ctx) != zsbuf_used;
91    }
92 }
93 
94 void
debug_describe_zink_buffer_view(char * buf,const struct zink_buffer_view * ptr)95 debug_describe_zink_buffer_view(char *buf, const struct zink_buffer_view *ptr)
96 {
97    sprintf(buf, "zink_buffer_view");
98 }
99 
100 ALWAYS_INLINE static void
check_resource_for_batch_ref(struct zink_context * ctx,struct zink_resource * res)101 check_resource_for_batch_ref(struct zink_context *ctx, struct zink_resource *res)
102 {
103    if (!zink_resource_has_binds(res)) {
104       /* avoid desync between usage and tracking:
105        * - if usage exists, it must be removed before the context is destroyed
106        * - having usage does not imply having tracking
107        * - if tracking will be added here, also reapply usage to avoid dangling usage once tracking is removed
108        * TODO: somehow fix this for perf because it's an extra hash lookup
109        */
110       if (!res->obj->dt && zink_resource_has_usage(res))
111          zink_batch_reference_resource_rw(&ctx->batch, res, !!res->obj->bo->writes.u);
112       else
113          zink_batch_reference_resource(&ctx->batch, res);
114    }
115 }
116 
117 static void
zink_context_destroy(struct pipe_context * pctx)118 zink_context_destroy(struct pipe_context *pctx)
119 {
120    struct zink_context *ctx = zink_context(pctx);
121    struct zink_screen *screen = zink_screen(pctx->screen);
122 
123    struct pipe_framebuffer_state fb = {0};
124    pctx->set_framebuffer_state(pctx, &fb);
125 
126    if (util_queue_is_initialized(&screen->flush_queue))
127       util_queue_finish(&screen->flush_queue);
128    if (ctx->batch.state && !screen->device_lost) {
129       simple_mtx_lock(&screen->queue_lock);
130       VkResult result = VKSCR(QueueWaitIdle)(screen->queue);
131       simple_mtx_unlock(&screen->queue_lock);
132 
133       if (result != VK_SUCCESS)
134          mesa_loge("ZINK: vkQueueWaitIdle failed (%s)", vk_Result_to_str(result));
135    }
136 
137    for (unsigned i = 0; i < ARRAY_SIZE(ctx->program_cache); i++) {
138       simple_mtx_lock((&ctx->program_lock[i]));
139       hash_table_foreach(&ctx->program_cache[i], entry) {
140          struct zink_program *pg = entry->data;
141          util_queue_fence_wait(&pg->cache_fence);
142          pg->removed = true;
143       }
144       simple_mtx_unlock((&ctx->program_lock[i]));
145    }
146 
147    if (ctx->blitter)
148       util_blitter_destroy(ctx->blitter);
149    for (unsigned i = 0; i < ctx->fb_state.nr_cbufs; i++)
150       pipe_surface_release(&ctx->base, &ctx->fb_state.cbufs[i]);
151    pipe_surface_release(&ctx->base, &ctx->fb_state.zsbuf);
152 
153    pipe_resource_reference(&ctx->dummy_vertex_buffer, NULL);
154    pipe_resource_reference(&ctx->dummy_xfb_buffer, NULL);
155 
156    for (unsigned i = 0; i < ARRAY_SIZE(ctx->dummy_surface); i++)
157       pipe_surface_release(&ctx->base, &ctx->dummy_surface[i]);
158    zink_buffer_view_reference(screen, &ctx->dummy_bufferview, NULL);
159 
160    zink_descriptors_deinit_bindless(ctx);
161 
162    struct zink_batch_state *bs = ctx->batch_states;
163    while (bs) {
164       struct zink_batch_state *bs_next = bs->next;
165       zink_clear_batch_state(ctx, bs);
166       /* restore link as we insert them into the screens free_batch_states
167        * list below
168        */
169       bs->next = bs_next;
170       bs = bs_next;
171    }
172    bs = ctx->free_batch_states;
173    while (bs) {
174       struct zink_batch_state *bs_next = bs->next;
175       zink_clear_batch_state(ctx, bs);
176       bs->ctx = NULL;
177       /* restore link as we insert them into the screens free_batch_states
178        * list below
179        */
180       bs->next = bs_next;
181       bs = bs_next;
182    }
183    simple_mtx_lock(&screen->free_batch_states_lock);
184    if (ctx->batch_states) {
185       if (screen->free_batch_states)
186          screen->last_free_batch_state->next = ctx->batch_states;
187       else {
188          screen->free_batch_states = ctx->batch_states;
189          screen->last_free_batch_state = screen->free_batch_states;
190       }
191    }
192    while (screen->last_free_batch_state && screen->last_free_batch_state->next)
193       screen->last_free_batch_state = screen->last_free_batch_state->next;
194    if (ctx->free_batch_states) {
195       if (screen->free_batch_states)
196          screen->last_free_batch_state->next = ctx->free_batch_states;
197       else {
198          screen->free_batch_states = ctx->free_batch_states;
199          screen->last_free_batch_state = ctx->last_free_batch_state;
200       }
201    }
202    while (screen->last_free_batch_state && screen->last_free_batch_state->next)
203       screen->last_free_batch_state = screen->last_free_batch_state->next;
204    if (ctx->batch.state) {
205       zink_clear_batch_state(ctx, ctx->batch.state);
206       if (screen->free_batch_states)
207          screen->last_free_batch_state->next = ctx->batch.state;
208       else {
209          screen->free_batch_states = ctx->batch.state;
210          screen->last_free_batch_state = screen->free_batch_states;
211       }
212    }
213    while (screen->last_free_batch_state && screen->last_free_batch_state->next)
214       screen->last_free_batch_state = screen->last_free_batch_state->next;
215    simple_mtx_unlock(&screen->free_batch_states_lock);
216 
217    for (unsigned i = 0; i < 2; i++) {
218       util_idalloc_fini(&ctx->di.bindless[i].tex_slots);
219       util_idalloc_fini(&ctx->di.bindless[i].img_slots);
220       if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB)
221          free(ctx->di.bindless[i].db.buffer_infos);
222       else
223          free(ctx->di.bindless[i].t.buffer_infos);
224       free(ctx->di.bindless[i].img_infos);
225       util_dynarray_fini(&ctx->di.bindless[i].updates);
226       util_dynarray_fini(&ctx->di.bindless[i].resident);
227    }
228 
229    if (ctx->null_fs)
230       pctx->delete_fs_state(pctx, ctx->null_fs);
231 
232    hash_table_foreach(&ctx->framebuffer_cache, he)
233       zink_destroy_framebuffer(screen, he->data);
234 
235    hash_table_foreach(ctx->render_pass_cache, he)
236       zink_destroy_render_pass(screen, he->data);
237 
238    zink_context_destroy_query_pools(ctx);
239    set_foreach(&ctx->gfx_inputs, he) {
240       struct zink_gfx_input_key *ikey = (void*)he->key;
241       VKSCR(DestroyPipeline)(screen->dev, ikey->pipeline, NULL);
242    }
243    set_foreach(&ctx->gfx_outputs, he) {
244       struct zink_gfx_output_key *okey = (void*)he->key;
245       VKSCR(DestroyPipeline)(screen->dev, okey->pipeline, NULL);
246    }
247    u_upload_destroy(pctx->stream_uploader);
248    u_upload_destroy(pctx->const_uploader);
249    slab_destroy_child(&ctx->transfer_pool);
250    for (unsigned i = 0; i < ARRAY_SIZE(ctx->program_cache); i++)
251       _mesa_hash_table_clear(&ctx->program_cache[i], NULL);
252    for (unsigned i = 0; i < ARRAY_SIZE(ctx->program_lock); i++)
253       simple_mtx_destroy(&ctx->program_lock[i]);
254    _mesa_hash_table_destroy(ctx->render_pass_cache, NULL);
255    slab_destroy_child(&ctx->transfer_pool_unsync);
256 
257    if (zink_debug & ZINK_DEBUG_DGC) {
258       for (unsigned i = 0; i < ARRAY_SIZE(ctx->dgc.upload); i++)
259          u_upload_destroy(ctx->dgc.upload[i]);
260       for (unsigned i = 0; i < ARRAY_SIZE(ctx->dgc.buffers); i++) {
261          if (!ctx->dgc.buffers[i])
262             continue;
263          struct pipe_resource *pres = &ctx->dgc.buffers[i]->base.b;
264          pipe_resource_reference(&pres, NULL);
265       }
266       util_dynarray_fini(&ctx->dgc.pipelines);
267    }
268 
269    zink_descriptors_deinit(ctx);
270 
271    if (!(ctx->flags & ZINK_CONTEXT_COPY_ONLY))
272       p_atomic_dec(&screen->base.num_contexts);
273 
274    util_dynarray_foreach(&ctx->di.global_bindings, struct pipe_resource *, res) {
275       pipe_resource_reference(res, NULL);
276    }
277    util_dynarray_fini(&ctx->di.global_bindings);
278 
279    ralloc_free(ctx);
280 }
281 
282 static void
check_device_lost(struct zink_context * ctx)283 check_device_lost(struct zink_context *ctx)
284 {
285    if (!zink_screen(ctx->base.screen)->device_lost || ctx->is_device_lost)
286       return;
287    debug_printf("ZINK: device lost detected!\n");
288    if (ctx->reset.reset)
289       ctx->reset.reset(ctx->reset.data, PIPE_GUILTY_CONTEXT_RESET);
290    ctx->is_device_lost = true;
291 }
292 
293 static enum pipe_reset_status
zink_get_device_reset_status(struct pipe_context * pctx)294 zink_get_device_reset_status(struct pipe_context *pctx)
295 {
296    struct zink_context *ctx = zink_context(pctx);
297 
298    enum pipe_reset_status status = PIPE_NO_RESET;
299 
300    if (ctx->is_device_lost) {
301       // Since we don't know what really happened to the hardware, just
302       // assume that we are in the wrong
303       status = PIPE_GUILTY_CONTEXT_RESET;
304 
305       debug_printf("ZINK: device lost detected!\n");
306 
307       if (ctx->reset.reset)
308          ctx->reset.reset(ctx->reset.data, status);
309    }
310 
311    return status;
312 }
313 
314 static void
zink_set_device_reset_callback(struct pipe_context * pctx,const struct pipe_device_reset_callback * cb)315 zink_set_device_reset_callback(struct pipe_context *pctx,
316                                const struct pipe_device_reset_callback *cb)
317 {
318    struct zink_context *ctx = zink_context(pctx);
319    bool had_reset = !!ctx->reset.reset;
320 
321    if (cb)
322       ctx->reset = *cb;
323    else
324       memset(&ctx->reset, 0, sizeof(ctx->reset));
325 
326    bool have_reset = !!ctx->reset.reset;
327    if (had_reset != have_reset) {
328       if (have_reset)
329          p_atomic_inc(&zink_screen(pctx->screen)->robust_ctx_count);
330       else
331          p_atomic_dec(&zink_screen(pctx->screen)->robust_ctx_count);
332    }
333 }
334 
335 static void
zink_set_context_param(struct pipe_context * pctx,enum pipe_context_param param,unsigned value)336 zink_set_context_param(struct pipe_context *pctx, enum pipe_context_param param,
337                        unsigned value)
338 {
339    struct zink_context *ctx = zink_context(pctx);
340    struct zink_screen *screen = zink_screen(ctx->base.screen);
341 
342    switch (param) {
343    case PIPE_CONTEXT_PARAM_UPDATE_THREAD_SCHEDULING:
344       if (screen->threaded_submit)
345          util_thread_sched_apply_policy(screen->flush_queue.threads[0],
346                                         UTIL_THREAD_DRIVER_SUBMIT, value, NULL);
347       break;
348    default:
349       break;
350    }
351 }
352 
353 static void
zink_set_debug_callback(struct pipe_context * pctx,const struct util_debug_callback * cb)354 zink_set_debug_callback(struct pipe_context *pctx, const struct util_debug_callback *cb)
355 {
356    struct zink_context *ctx = zink_context(pctx);
357 
358    if (cb)
359       ctx->dbg = *cb;
360    else
361       memset(&ctx->dbg, 0, sizeof(ctx->dbg));
362 }
363 
364 static VkSamplerMipmapMode
sampler_mipmap_mode(enum pipe_tex_mipfilter filter)365 sampler_mipmap_mode(enum pipe_tex_mipfilter filter)
366 {
367    switch (filter) {
368    case PIPE_TEX_MIPFILTER_NEAREST: return VK_SAMPLER_MIPMAP_MODE_NEAREST;
369    case PIPE_TEX_MIPFILTER_LINEAR: return VK_SAMPLER_MIPMAP_MODE_LINEAR;
370    case PIPE_TEX_MIPFILTER_NONE:
371       unreachable("PIPE_TEX_MIPFILTER_NONE should be dealt with earlier");
372    }
373    unreachable("unexpected filter");
374 }
375 
376 static VkSamplerAddressMode
sampler_address_mode(enum pipe_tex_wrap filter)377 sampler_address_mode(enum pipe_tex_wrap filter)
378 {
379    switch (filter) {
380    case PIPE_TEX_WRAP_REPEAT: return VK_SAMPLER_ADDRESS_MODE_REPEAT;
381    case PIPE_TEX_WRAP_CLAMP_TO_EDGE: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
382    case PIPE_TEX_WRAP_CLAMP_TO_BORDER: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
383    case PIPE_TEX_WRAP_MIRROR_REPEAT: return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
384    case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
385    case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; /* not technically correct, but kinda works */
386    default: break;
387    }
388    unreachable("unexpected wrap");
389 }
390 
391 /* unnormalizedCoordinates only support CLAMP_TO_EDGE or CLAMP_TO_BORDER */
392 static VkSamplerAddressMode
sampler_address_mode_unnormalized(enum pipe_tex_wrap filter)393 sampler_address_mode_unnormalized(enum pipe_tex_wrap filter)
394 {
395    switch (filter) {
396    case PIPE_TEX_WRAP_CLAMP_TO_EDGE: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
397    case PIPE_TEX_WRAP_CLAMP_TO_BORDER: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
398    default: break;
399    }
400    unreachable("unexpected wrap");
401 }
402 
403 static VkCompareOp
compare_op(enum pipe_compare_func op)404 compare_op(enum pipe_compare_func op)
405 {
406    switch (op) {
407       case PIPE_FUNC_NEVER: return VK_COMPARE_OP_NEVER;
408       case PIPE_FUNC_LESS: return VK_COMPARE_OP_LESS;
409       case PIPE_FUNC_EQUAL: return VK_COMPARE_OP_EQUAL;
410       case PIPE_FUNC_LEQUAL: return VK_COMPARE_OP_LESS_OR_EQUAL;
411       case PIPE_FUNC_GREATER: return VK_COMPARE_OP_GREATER;
412       case PIPE_FUNC_NOTEQUAL: return VK_COMPARE_OP_NOT_EQUAL;
413       case PIPE_FUNC_GEQUAL: return VK_COMPARE_OP_GREATER_OR_EQUAL;
414       case PIPE_FUNC_ALWAYS: return VK_COMPARE_OP_ALWAYS;
415    }
416    unreachable("unexpected compare");
417 }
418 
419 static inline bool
wrap_needs_border_color(unsigned wrap)420 wrap_needs_border_color(unsigned wrap)
421 {
422    return wrap == PIPE_TEX_WRAP_CLAMP || wrap == PIPE_TEX_WRAP_CLAMP_TO_BORDER ||
423           wrap == PIPE_TEX_WRAP_MIRROR_CLAMP || wrap == PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER;
424 }
425 
426 static VkBorderColor
get_border_color(const union pipe_color_union * color,bool is_integer,bool need_custom)427 get_border_color(const union pipe_color_union *color, bool is_integer, bool need_custom)
428 {
429    if (is_integer) {
430       if (color->ui[0] == 0 && color->ui[1] == 0 && color->ui[2] == 0 && color->ui[3] == 0)
431          return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
432       if (color->ui[0] == 0 && color->ui[1] == 0 && color->ui[2] == 0 && color->ui[3] == 1)
433          return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
434       if (color->ui[0] == 1 && color->ui[1] == 1 && color->ui[2] == 1 && color->ui[3] == 1)
435          return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
436       return need_custom ? VK_BORDER_COLOR_INT_CUSTOM_EXT : VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
437    }
438 
439    if (color->f[0] == 0 && color->f[1] == 0 && color->f[2] == 0 && color->f[3] == 0)
440       return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
441    if (color->f[0] == 0 && color->f[1] == 0 && color->f[2] == 0 && color->f[3] == 1)
442       return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
443    if (color->f[0] == 1 && color->f[1] == 1 && color->f[2] == 1 && color->f[3] == 1)
444       return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
445    return need_custom ? VK_BORDER_COLOR_FLOAT_CUSTOM_EXT : VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
446 }
447 
448 static void *
zink_create_sampler_state(struct pipe_context * pctx,const struct pipe_sampler_state * state)449 zink_create_sampler_state(struct pipe_context *pctx,
450                           const struct pipe_sampler_state *state)
451 {
452    struct zink_screen *screen = zink_screen(pctx->screen);
453    ASSERTED struct zink_context *zink = zink_context(pctx);
454    bool need_custom = false;
455    bool need_clamped_border_color = false;
456    VkSamplerCreateInfo sci = {0};
457    VkSamplerCustomBorderColorCreateInfoEXT cbci = {0};
458    VkSamplerCustomBorderColorCreateInfoEXT cbci_clamped = {0};
459    sci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
460    if (screen->info.have_EXT_non_seamless_cube_map && !state->seamless_cube_map)
461       sci.flags |= VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT;
462    if (state->unnormalized_coords) {
463       assert(zink->flags & PIPE_CONTEXT_COMPUTE_ONLY);
464       sci.unnormalizedCoordinates = state->unnormalized_coords;
465    }
466    sci.magFilter = zink_filter(state->mag_img_filter);
467    if (sci.unnormalizedCoordinates)
468       sci.minFilter = sci.magFilter;
469    else
470       sci.minFilter = zink_filter(state->min_img_filter);
471 
472    VkSamplerReductionModeCreateInfo rci;
473    rci.sType = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO;
474    rci.pNext = NULL;
475    switch (state->reduction_mode) {
476    case PIPE_TEX_REDUCTION_MIN:
477       rci.reductionMode = VK_SAMPLER_REDUCTION_MODE_MIN;
478       break;
479    case PIPE_TEX_REDUCTION_MAX:
480       rci.reductionMode = VK_SAMPLER_REDUCTION_MODE_MAX;
481       break;
482    default:
483       rci.reductionMode = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE;
484       break;
485    }
486    if (state->reduction_mode)
487       sci.pNext = &rci;
488 
489    if (sci.unnormalizedCoordinates) {
490       sci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
491    } else if (state->min_mip_filter != PIPE_TEX_MIPFILTER_NONE) {
492       sci.mipmapMode = sampler_mipmap_mode(state->min_mip_filter);
493       sci.minLod = state->min_lod;
494       sci.maxLod = MAX2(state->max_lod, state->min_lod);
495    } else {
496       sci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
497       sci.minLod = 0;
498       sci.maxLod = 0.25f;
499    }
500 
501    if (!sci.unnormalizedCoordinates) {
502       sci.addressModeU = sampler_address_mode(state->wrap_s);
503       sci.addressModeV = sampler_address_mode(state->wrap_t);
504       sci.addressModeW = sampler_address_mode(state->wrap_r);
505    } else {
506       sci.addressModeU = sampler_address_mode_unnormalized(state->wrap_s);
507       sci.addressModeV = sampler_address_mode_unnormalized(state->wrap_t);
508       sci.addressModeW = sampler_address_mode_unnormalized(state->wrap_r);
509    }
510 
511    sci.mipLodBias = CLAMP(state->lod_bias,
512                           -screen->info.props.limits.maxSamplerLodBias,
513                           screen->info.props.limits.maxSamplerLodBias);
514 
515    need_custom |= wrap_needs_border_color(state->wrap_s);
516    need_custom |= wrap_needs_border_color(state->wrap_t);
517    need_custom |= wrap_needs_border_color(state->wrap_r);
518 
519    if (state->compare_mode == PIPE_TEX_COMPARE_NONE)
520       sci.compareOp = VK_COMPARE_OP_NEVER;
521    else {
522       sci.compareOp = compare_op(state->compare_func);
523       sci.compareEnable = VK_TRUE;
524    }
525 
526    bool is_integer = state->border_color_is_integer;
527 
528    sci.borderColor = get_border_color(&state->border_color, is_integer, need_custom);
529    if (sci.borderColor > VK_BORDER_COLOR_INT_OPAQUE_WHITE && need_custom) {
530       if (!screen->info.border_color_feats.customBorderColorWithoutFormat &&
531           screen->info.driver_props.driverID != VK_DRIVER_ID_MESA_TURNIP) {
532          static bool warned = false;
533          warn_missing_feature(warned, "customBorderColorWithoutFormat");
534       }
535       if (screen->info.have_EXT_custom_border_color &&
536           (screen->info.border_color_feats.customBorderColorWithoutFormat || state->border_color_format)) {
537          if (!screen->info.have_EXT_border_color_swizzle) {
538             static bool warned = false;
539             warn_missing_feature(warned, "VK_EXT_border_color_swizzle");
540          }
541 
542          if (!is_integer && !screen->have_D24_UNORM_S8_UINT) {
543             union pipe_color_union clamped_border_color;
544             for (unsigned i = 0; i < 4; ++i) {
545                /* Use channel 0 on purpose, so that we can use OPAQUE_WHITE
546                 * when the border color is 1.0. */
547                clamped_border_color.f[i] = CLAMP(state->border_color.f[0], 0, 1);
548             }
549             if (memcmp(&state->border_color, &clamped_border_color, sizeof(clamped_border_color)) != 0) {
550                need_clamped_border_color = true;
551                cbci_clamped.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT;
552                cbci_clamped.format = VK_FORMAT_UNDEFINED;
553                /* these are identical unions */
554                memcpy(&cbci_clamped.customBorderColor, &clamped_border_color, sizeof(union pipe_color_union));
555             }
556          }
557          cbci.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT;
558          if (screen->info.border_color_feats.customBorderColorWithoutFormat) {
559             cbci.format = VK_FORMAT_UNDEFINED;
560             /* these are identical unions */
561             memcpy(&cbci.customBorderColor, &state->border_color, sizeof(union pipe_color_union));
562          } else {
563             if (util_format_is_depth_or_stencil(state->border_color_format)) {
564                if (is_integer) {
565                   cbci.format = VK_FORMAT_S8_UINT;
566                   for (unsigned i = 0; i < 4; i++)
567                      cbci.customBorderColor.uint32[i] = CLAMP(state->border_color.ui[i], 0, 255);
568                } else {
569                   cbci.format = zink_get_format(screen, util_format_get_depth_only(state->border_color_format));
570                   /* these are identical unions */
571                   memcpy(&cbci.customBorderColor, &state->border_color, sizeof(union pipe_color_union));
572                }
573             } else {
574                cbci.format = zink_get_format(screen, state->border_color_format);
575                union pipe_color_union color;
576                for (unsigned i = 0; i < 4; i++) {
577                   zink_format_clamp_channel_srgb(util_format_description(state->border_color_format), &color, &state->border_color, i);
578                }
579                zink_convert_color(screen, state->border_color_format, (void*)&cbci.customBorderColor, &color);
580             }
581          }
582          cbci.pNext = sci.pNext;
583          sci.pNext = &cbci;
584          UNUSED uint32_t check = p_atomic_inc_return(&screen->cur_custom_border_color_samplers);
585          assert(check <= screen->info.border_color_props.maxCustomBorderColorSamplers);
586       } else
587          sci.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; // TODO with custom shader if we're super interested?
588    }
589 
590    if (state->max_anisotropy > 1) {
591       sci.maxAnisotropy = state->max_anisotropy;
592       sci.anisotropyEnable = VK_TRUE;
593    }
594 
595    struct zink_sampler_state *sampler = CALLOC_STRUCT(zink_sampler_state);
596    if (!sampler)
597       return NULL;
598 
599    VkResult result = VKSCR(CreateSampler)(screen->dev, &sci, NULL, &sampler->sampler);
600    if (result != VK_SUCCESS) {
601       mesa_loge("ZINK: vkCreateSampler failed (%s)", vk_Result_to_str(result));
602       FREE(sampler);
603       return NULL;
604    }
605    if (need_clamped_border_color) {
606       sci.pNext = &cbci_clamped;
607       result = VKSCR(CreateSampler)(screen->dev, &sci, NULL, &sampler->sampler_clamped);
608       if (result != VK_SUCCESS) {
609          mesa_loge("ZINK: vkCreateSampler failed (%s)", vk_Result_to_str(result));
610          VKSCR(DestroySampler)(screen->dev, sampler->sampler, NULL);
611          FREE(sampler);
612          return NULL;
613       }
614    }
615    sampler->custom_border_color = need_custom;
616    if (!screen->info.have_EXT_non_seamless_cube_map)
617       sampler->emulate_nonseamless = !state->seamless_cube_map;
618 
619    return sampler;
620 }
621 
622 ALWAYS_INLINE static VkImageLayout
get_layout_for_binding(const struct zink_context * ctx,struct zink_resource * res,enum zink_descriptor_type type,bool is_compute)623 get_layout_for_binding(const struct zink_context *ctx, struct zink_resource *res, enum zink_descriptor_type type, bool is_compute)
624 {
625    if (res->obj->is_buffer)
626       return 0;
627    switch (type) {
628    case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
629       return zink_descriptor_util_image_layout_eval(ctx, res, is_compute);
630    case ZINK_DESCRIPTOR_TYPE_IMAGE:
631       return VK_IMAGE_LAYOUT_GENERAL;
632    default:
633       break;
634    }
635    return 0;
636 }
637 
638 ALWAYS_INLINE static struct zink_surface *
get_imageview_for_binding(struct zink_context * ctx,gl_shader_stage stage,enum zink_descriptor_type type,unsigned idx)639 get_imageview_for_binding(struct zink_context *ctx, gl_shader_stage stage, enum zink_descriptor_type type, unsigned idx)
640 {
641    switch (type) {
642    case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW: {
643       struct zink_sampler_view *sampler_view = zink_sampler_view(ctx->sampler_views[stage][idx]);
644       if (!sampler_view || !sampler_view->base.texture)
645          return NULL;
646       /* if this is a non-seamless cube sampler, return the cube array view */
647       if (ctx->di.emulate_nonseamless[stage] & ctx->di.cubes[stage] & BITFIELD_BIT(idx))
648          return sampler_view->cube_array;
649       bool needs_zs_shader_swizzle = (ctx->di.zs_swizzle[stage].mask & BITFIELD_BIT(idx)) &&
650                                      zink_screen(ctx->base.screen)->driver_workarounds.needs_zs_shader_swizzle;
651       bool needs_shadow_shader_swizzle = (stage == MESA_SHADER_FRAGMENT) && ctx->gfx_stages[MESA_SHADER_FRAGMENT] &&
652                                          (ctx->di.zs_swizzle[MESA_SHADER_FRAGMENT].mask & ctx->gfx_stages[MESA_SHADER_FRAGMENT]->fs.legacy_shadow_mask & BITFIELD_BIT(idx));
653       if (sampler_view->zs_view && (needs_zs_shader_swizzle || needs_shadow_shader_swizzle))
654          return sampler_view->zs_view;
655       return sampler_view->image_view;
656    }
657    case ZINK_DESCRIPTOR_TYPE_IMAGE: {
658       struct zink_image_view *image_view = &ctx->image_views[stage][idx];
659       return image_view->base.resource ? image_view->surface : NULL;
660    }
661    default:
662       break;
663    }
664    unreachable("ACK");
665    return VK_NULL_HANDLE;
666 }
667 
668 ALWAYS_INLINE static struct zink_buffer_view *
get_bufferview_for_binding(struct zink_context * ctx,gl_shader_stage stage,enum zink_descriptor_type type,unsigned idx)669 get_bufferview_for_binding(struct zink_context *ctx, gl_shader_stage stage, enum zink_descriptor_type type, unsigned idx)
670 {
671    switch (type) {
672    case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW: {
673       struct zink_sampler_view *sampler_view = zink_sampler_view(ctx->sampler_views[stage][idx]);
674       return sampler_view->base.texture ? sampler_view->buffer_view : NULL;
675    }
676    case ZINK_DESCRIPTOR_TYPE_IMAGE: {
677       struct zink_image_view *image_view = &ctx->image_views[stage][idx];
678       return image_view->base.resource ? image_view->buffer_view : NULL;
679    }
680    default:
681       break;
682    }
683    unreachable("ACK");
684    return VK_NULL_HANDLE;
685 }
686 
687 ALWAYS_INLINE static struct zink_resource *
update_descriptor_state_ubo(struct zink_context * ctx,gl_shader_stage shader,unsigned slot,struct zink_resource * res)688 update_descriptor_state_ubo(struct zink_context *ctx, gl_shader_stage shader, unsigned slot, struct zink_resource *res)
689 {
690    struct zink_screen *screen = zink_screen(ctx->base.screen);
691    bool have_null_descriptors = screen->info.rb2_feats.nullDescriptor;
692    const enum zink_descriptor_type type = ZINK_DESCRIPTOR_TYPE_UBO;
693    ctx->di.descriptor_res[type][shader][slot] = res;
694    if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
695       if (res)
696          ctx->di.db.ubos[shader][slot].address = res->obj->bda + ctx->ubos[shader][slot].buffer_offset;
697       else
698          ctx->di.db.ubos[shader][slot].address = 0;
699       ctx->di.db.ubos[shader][slot].range = res ? ctx->ubos[shader][slot].buffer_size : VK_WHOLE_SIZE;
700       assert(ctx->di.db.ubos[shader][slot].range == VK_WHOLE_SIZE ||
701              ctx->di.db.ubos[shader][slot].range <= screen->info.props.limits.maxUniformBufferRange);
702    } else {
703       ctx->di.t.ubos[shader][slot].offset = ctx->ubos[shader][slot].buffer_offset;
704       if (res) {
705          ctx->di.t.ubos[shader][slot].buffer = res->obj->buffer;
706          ctx->di.t.ubos[shader][slot].range = ctx->ubos[shader][slot].buffer_size;
707          assert(ctx->di.t.ubos[shader][slot].range <= screen->info.props.limits.maxUniformBufferRange);
708       } else {
709          VkBuffer null_buffer = zink_resource(ctx->dummy_vertex_buffer)->obj->buffer;
710          ctx->di.t.ubos[shader][slot].buffer = have_null_descriptors ? VK_NULL_HANDLE : null_buffer;
711          ctx->di.t.ubos[shader][slot].range = VK_WHOLE_SIZE;
712       }
713    }
714    if (!slot) {
715       if (res)
716          ctx->di.push_valid |= BITFIELD64_BIT(shader);
717       else
718          ctx->di.push_valid &= ~BITFIELD64_BIT(shader);
719    }
720    return res;
721 }
722 
723 ALWAYS_INLINE static struct zink_resource *
update_descriptor_state_ssbo(struct zink_context * ctx,gl_shader_stage shader,unsigned slot,struct zink_resource * res)724 update_descriptor_state_ssbo(struct zink_context *ctx, gl_shader_stage shader, unsigned slot, struct zink_resource *res)
725 {
726    struct zink_screen *screen = zink_screen(ctx->base.screen);
727    bool have_null_descriptors = screen->info.rb2_feats.nullDescriptor;
728    const enum zink_descriptor_type type = ZINK_DESCRIPTOR_TYPE_SSBO;
729    ctx->di.descriptor_res[type][shader][slot] = res;
730    if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
731       if (res)
732          ctx->di.db.ssbos[shader][slot].address = res->obj->bda + ctx->ssbos[shader][slot].buffer_offset;
733       else
734          ctx->di.db.ssbos[shader][slot].address = 0;
735       ctx->di.db.ssbos[shader][slot].range = res ? ctx->ssbos[shader][slot].buffer_size : VK_WHOLE_SIZE;
736    } else {
737       ctx->di.t.ssbos[shader][slot].offset = ctx->ssbos[shader][slot].buffer_offset;
738       if (res) {
739          ctx->di.t.ssbos[shader][slot].buffer = res->obj->buffer;
740          ctx->di.t.ssbos[shader][slot].range = ctx->ssbos[shader][slot].buffer_size;
741       } else {
742          VkBuffer null_buffer = zink_resource(ctx->dummy_vertex_buffer)->obj->buffer;
743          ctx->di.t.ssbos[shader][slot].buffer = have_null_descriptors ? VK_NULL_HANDLE : null_buffer;
744          ctx->di.t.ssbos[shader][slot].range = VK_WHOLE_SIZE;
745       }
746    }
747    return res;
748 }
749 
750 ALWAYS_INLINE static struct zink_resource *
update_descriptor_state_sampler(struct zink_context * ctx,gl_shader_stage shader,unsigned slot,struct zink_resource * res)751 update_descriptor_state_sampler(struct zink_context *ctx, gl_shader_stage shader, unsigned slot, struct zink_resource *res)
752 {
753    struct zink_screen *screen = zink_screen(ctx->base.screen);
754    bool have_null_descriptors = screen->info.rb2_feats.nullDescriptor;
755    const enum zink_descriptor_type type = ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW;
756    ctx->di.descriptor_res[type][shader][slot] = res;
757    if (res) {
758       if (res->obj->is_buffer) {
759          if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
760             ctx->di.db.tbos[shader][slot].address = res->obj->bda + ctx->sampler_views[shader][slot]->u.buf.offset;
761             ctx->di.db.tbos[shader][slot].range = zink_sampler_view(ctx->sampler_views[shader][slot])->tbo_size;
762             ctx->di.db.tbos[shader][slot].format = zink_get_format(screen, ctx->sampler_views[shader][slot]->format);
763          } else {
764             struct zink_buffer_view *bv = get_bufferview_for_binding(ctx, shader, type, slot);
765             ctx->di.t.tbos[shader][slot] = bv->buffer_view;
766          }
767       } else {
768          struct zink_surface *surface = get_imageview_for_binding(ctx, shader, type, slot);
769          ctx->di.textures[shader][slot].imageLayout = ctx->blitting ? res->layout : get_layout_for_binding(ctx, res, type, shader == MESA_SHADER_COMPUTE);
770          ctx->di.textures[shader][slot].imageView = surface->image_view;
771          if (!screen->have_D24_UNORM_S8_UINT &&
772              ctx->sampler_states[shader][slot] && ctx->sampler_states[shader][slot]->sampler_clamped) {
773             struct zink_sampler_state *state = ctx->sampler_states[shader][slot];
774             VkSampler sampler = (surface->base.format == PIPE_FORMAT_Z24X8_UNORM && surface->ivci.format == VK_FORMAT_D32_SFLOAT) ||
775                                 (surface->base.format == PIPE_FORMAT_Z24_UNORM_S8_UINT && surface->ivci.format == VK_FORMAT_D32_SFLOAT_S8_UINT) ?
776                                 state->sampler_clamped :
777                                 state->sampler;
778             if (ctx->di.textures[shader][slot].sampler != sampler) {
779                ctx->invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, slot, 1);
780                ctx->di.textures[shader][slot].sampler = sampler;
781             }
782          }
783       }
784    } else {
785       if (likely(have_null_descriptors)) {
786          ctx->di.textures[shader][slot].imageView = VK_NULL_HANDLE;
787          ctx->di.textures[shader][slot].imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
788          if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
789             ctx->di.db.tbos[shader][slot].address = 0;
790             ctx->di.db.tbos[shader][slot].range = VK_WHOLE_SIZE;
791          } else {
792             ctx->di.t.tbos[shader][slot] = VK_NULL_HANDLE;
793          }
794       } else {
795          assert(zink_descriptor_mode != ZINK_DESCRIPTOR_MODE_DB);
796          struct zink_surface *null_surface = zink_get_dummy_surface(ctx, 0);
797          struct zink_buffer_view *null_bufferview = ctx->dummy_bufferview;
798          ctx->di.textures[shader][slot].imageView = null_surface->image_view;
799          ctx->di.textures[shader][slot].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
800          ctx->di.t.tbos[shader][slot] = null_bufferview->buffer_view;
801       }
802    }
803    return res;
804 }
805 
806 void
zink_update_shadow_samplerviews(struct zink_context * ctx,unsigned mask)807 zink_update_shadow_samplerviews(struct zink_context *ctx, unsigned mask)
808 {
809    u_foreach_bit(slot, mask)
810       update_descriptor_state_sampler(ctx, MESA_SHADER_FRAGMENT, slot, ctx->di.descriptor_res[ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW][MESA_SHADER_FRAGMENT][slot]);
811 }
812 
813 ALWAYS_INLINE static struct zink_resource *
update_descriptor_state_image(struct zink_context * ctx,gl_shader_stage shader,unsigned slot,struct zink_resource * res)814 update_descriptor_state_image(struct zink_context *ctx, gl_shader_stage shader, unsigned slot, struct zink_resource *res)
815 {
816    struct zink_screen *screen = zink_screen(ctx->base.screen);
817    bool have_null_descriptors = screen->info.rb2_feats.nullDescriptor;
818    const enum zink_descriptor_type type = ZINK_DESCRIPTOR_TYPE_IMAGE;
819    ctx->di.descriptor_res[type][shader][slot] = res;
820    if (res) {
821       if (res->obj->is_buffer) {
822          if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
823             ctx->di.db.texel_images[shader][slot].address = res->obj->bda + ctx->image_views[shader][slot].base.u.buf.offset;
824             ctx->di.db.texel_images[shader][slot].range = ctx->image_views[shader][slot].base.u.buf.size;
825             ctx->di.db.texel_images[shader][slot].format = zink_get_format(screen, ctx->image_views[shader][slot].base.format);
826          } else {
827             struct zink_buffer_view *bv = get_bufferview_for_binding(ctx, shader, type, slot);
828             ctx->di.t.texel_images[shader][slot] = bv->buffer_view;
829          }
830       } else {
831          struct zink_surface *surface = get_imageview_for_binding(ctx, shader, type, slot);
832          ctx->di.images[shader][slot].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
833          ctx->di.images[shader][slot].imageView = surface->image_view;
834       }
835    } else {
836       if (likely(have_null_descriptors)) {
837          memset(&ctx->di.images[shader][slot], 0, sizeof(ctx->di.images[shader][slot]));
838          if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
839             ctx->di.db.texel_images[shader][slot].address = 0;
840             ctx->di.db.texel_images[shader][slot].range = VK_WHOLE_SIZE;
841          } else {
842             ctx->di.t.texel_images[shader][slot] = VK_NULL_HANDLE;
843          }
844       } else {
845          assert(zink_descriptor_mode != ZINK_DESCRIPTOR_MODE_DB);
846          struct zink_surface *null_surface = zink_get_dummy_surface(ctx, 0);
847          struct zink_buffer_view *null_bufferview = ctx->dummy_bufferview;
848          ctx->di.images[shader][slot].imageView = null_surface->image_view;
849          ctx->di.images[shader][slot].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
850          ctx->di.t.texel_images[shader][slot] = null_bufferview->buffer_view;
851       }
852    }
853    return res;
854 }
855 
856 static void
update_nonseamless_shader_key(struct zink_context * ctx,gl_shader_stage pstage)857 update_nonseamless_shader_key(struct zink_context *ctx, gl_shader_stage pstage)
858 {
859    const uint32_t new_mask = ctx->di.emulate_nonseamless[pstage] & ctx->di.cubes[pstage];
860    if (pstage == MESA_SHADER_COMPUTE) {
861       if (ctx->compute_pipeline_state.key.base.nonseamless_cube_mask != new_mask)
862          ctx->compute_dirty = true;
863       ctx->compute_pipeline_state.key.base.nonseamless_cube_mask = new_mask;
864    } else {
865       if (zink_get_shader_key_base(ctx, pstage)->nonseamless_cube_mask != new_mask)
866          zink_set_shader_key_base(ctx, pstage)->nonseamless_cube_mask = new_mask;
867    }
868 }
869 
870 static void
zink_bind_sampler_states(struct pipe_context * pctx,gl_shader_stage shader,unsigned start_slot,unsigned num_samplers,void ** samplers)871 zink_bind_sampler_states(struct pipe_context *pctx,
872                          gl_shader_stage shader,
873                          unsigned start_slot,
874                          unsigned num_samplers,
875                          void **samplers)
876 {
877    struct zink_context *ctx = zink_context(pctx);
878    struct zink_screen *screen = zink_screen(pctx->screen);
879    for (unsigned i = 0; i < num_samplers; ++i) {
880       struct zink_sampler_state *state = samplers[i];
881       if (samplers[i] == ctx->sampler_states[shader][start_slot + i])
882          continue;
883       ctx->invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot, 1);
884       ctx->sampler_states[shader][start_slot + i] = state;
885       if (state) {
886          ctx->di.textures[shader][start_slot + i].sampler = state->sampler;
887          if (state->sampler_clamped && !screen->have_D24_UNORM_S8_UINT) {
888             struct zink_surface *surface = get_imageview_for_binding(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot + i);
889             if (surface &&
890                 ((surface->base.format == PIPE_FORMAT_Z24X8_UNORM && surface->ivci.format == VK_FORMAT_D32_SFLOAT) ||
891                  (surface->base.format == PIPE_FORMAT_Z24_UNORM_S8_UINT && surface->ivci.format == VK_FORMAT_D32_SFLOAT_S8_UINT)))
892                ctx->di.textures[shader][start_slot + i].sampler = state->sampler_clamped;
893          }
894       } else {
895          ctx->di.textures[shader][start_slot + i].sampler = VK_NULL_HANDLE;
896       }
897    }
898    ctx->di.num_samplers[shader] = start_slot + num_samplers;
899 }
900 
901 static void
zink_bind_sampler_states_nonseamless(struct pipe_context * pctx,gl_shader_stage shader,unsigned start_slot,unsigned num_samplers,void ** samplers)902 zink_bind_sampler_states_nonseamless(struct pipe_context *pctx,
903                                      gl_shader_stage shader,
904                                      unsigned start_slot,
905                                      unsigned num_samplers,
906                                      void **samplers)
907 {
908    struct zink_context *ctx = zink_context(pctx);
909    uint32_t old_mask = ctx->di.emulate_nonseamless[shader];
910    uint32_t mask = BITFIELD_RANGE(start_slot, num_samplers);
911    ctx->di.emulate_nonseamless[shader] &= ~mask;
912    for (unsigned i = 0; i < num_samplers; ++i) {
913       struct zink_sampler_state *state = samplers[i];
914       const uint32_t bit = BITFIELD_BIT(start_slot + i);
915       if (!state)
916          continue;
917       if (state->emulate_nonseamless)
918          ctx->di.emulate_nonseamless[shader] |= bit;
919       if (state->emulate_nonseamless != (old_mask & bit) && (ctx->di.cubes[shader] & bit)) {
920          struct zink_surface *surface = get_imageview_for_binding(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot + i);
921          if (surface && ctx->di.images[shader][start_slot + i].imageView != surface->image_view) {
922             ctx->di.images[shader][start_slot + i].imageView = surface->image_view;
923             update_descriptor_state_sampler(ctx, shader, start_slot + i, zink_resource(surface->base.texture));
924             ctx->invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot + i, 1);
925          }
926       }
927    }
928    zink_bind_sampler_states(pctx, shader, start_slot, num_samplers, samplers);
929    update_nonseamless_shader_key(ctx, shader);
930 }
931 
932 static void
zink_delete_sampler_state(struct pipe_context * pctx,void * sampler_state)933 zink_delete_sampler_state(struct pipe_context *pctx,
934                           void *sampler_state)
935 {
936    struct zink_sampler_state *sampler = sampler_state;
937    struct zink_batch *batch = &zink_context(pctx)->batch;
938    /* may be called if context_create fails */
939    if (batch->state) {
940       util_dynarray_append(&batch->state->zombie_samplers, VkSampler,
941                            sampler->sampler);
942       if (sampler->sampler_clamped)
943          util_dynarray_append(&batch->state->zombie_samplers, VkSampler,
944                               sampler->sampler_clamped);
945    }
946    if (sampler->custom_border_color)
947       p_atomic_dec(&zink_screen(pctx->screen)->cur_custom_border_color_samplers);
948    FREE(sampler);
949 }
950 
951 static VkImageAspectFlags
sampler_aspect_from_format(enum pipe_format fmt)952 sampler_aspect_from_format(enum pipe_format fmt)
953 {
954    if (util_format_is_depth_or_stencil(fmt)) {
955       const struct util_format_description *desc = util_format_description(fmt);
956       if (util_format_has_depth(desc))
957          return VK_IMAGE_ASPECT_DEPTH_BIT;
958       assert(util_format_has_stencil(desc));
959       return VK_IMAGE_ASPECT_STENCIL_BIT;
960    } else
961      return VK_IMAGE_ASPECT_COLOR_BIT;
962 }
963 
964 static uint32_t
hash_bufferview(void * bvci)965 hash_bufferview(void *bvci)
966 {
967    size_t offset = offsetof(VkBufferViewCreateInfo, flags);
968    return _mesa_hash_data((char*)bvci + offset, sizeof(VkBufferViewCreateInfo) - offset);
969 }
970 
971 static VkBufferViewCreateInfo
create_bvci(struct zink_context * ctx,struct zink_resource * res,enum pipe_format format,uint32_t offset,uint32_t range)972 create_bvci(struct zink_context *ctx, struct zink_resource *res, enum pipe_format format, uint32_t offset, uint32_t range)
973 {
974    struct zink_screen *screen = zink_screen(ctx->base.screen);
975    VkBufferViewCreateInfo bvci;
976    // Zero whole struct (including alignment holes), so hash_bufferview
977    // does not access potentially uninitialized data.
978    memset(&bvci, 0, sizeof(bvci));
979    bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
980    bvci.pNext = NULL;
981    if (screen->format_props[format].bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)
982       bvci.buffer = res->obj->storage_buffer ? res->obj->storage_buffer : res->obj->buffer;
983    else
984       bvci.buffer = res->obj->buffer;
985    bvci.format = zink_get_format(screen, format);
986    assert(bvci.format);
987    bvci.offset = offset;
988    bvci.range = !offset && range == res->base.b.width0 ? VK_WHOLE_SIZE : range;
989    unsigned blocksize = util_format_get_blocksize(format);
990    if (bvci.range != VK_WHOLE_SIZE) {
991       /* clamp out partial texels */
992       bvci.range -= bvci.range % blocksize;
993       if (bvci.offset + bvci.range >= res->base.b.width0)
994          bvci.range = VK_WHOLE_SIZE;
995    }
996    uint64_t clamp = blocksize * screen->info.props.limits.maxTexelBufferElements;
997    if (bvci.range == VK_WHOLE_SIZE && res->base.b.width0 > clamp)
998       bvci.range = clamp;
999    bvci.flags = 0;
1000    return bvci;
1001 }
1002 
1003 static struct zink_buffer_view *
get_buffer_view(struct zink_context * ctx,struct zink_resource * res,VkBufferViewCreateInfo * bvci)1004 get_buffer_view(struct zink_context *ctx, struct zink_resource *res, VkBufferViewCreateInfo *bvci)
1005 {
1006    struct zink_screen *screen = zink_screen(ctx->base.screen);
1007    struct zink_buffer_view *buffer_view = NULL;
1008 
1009    uint32_t hash = hash_bufferview(bvci);
1010    simple_mtx_lock(&res->bufferview_mtx);
1011    struct hash_entry *he = _mesa_hash_table_search_pre_hashed(&res->bufferview_cache, hash, bvci);
1012    if (he) {
1013       buffer_view = he->data;
1014       p_atomic_inc(&buffer_view->reference.count);
1015    } else {
1016       VkBufferView view;
1017       VkResult result = VKSCR(CreateBufferView)(screen->dev, bvci, NULL, &view);
1018       if (result != VK_SUCCESS) {
1019          mesa_loge("ZINK: vkCreateBufferView failed (%s)", vk_Result_to_str(result));
1020          goto out;
1021       }
1022       buffer_view = CALLOC_STRUCT(zink_buffer_view);
1023       if (!buffer_view) {
1024          VKSCR(DestroyBufferView)(screen->dev, view, NULL);
1025          goto out;
1026       }
1027       pipe_reference_init(&buffer_view->reference, 1);
1028       pipe_resource_reference(&buffer_view->pres, &res->base.b);
1029       buffer_view->bvci = *bvci;
1030       buffer_view->buffer_view = view;
1031       buffer_view->hash = hash;
1032       _mesa_hash_table_insert_pre_hashed(&res->bufferview_cache, hash, &buffer_view->bvci, buffer_view);
1033    }
1034 out:
1035    simple_mtx_unlock(&res->bufferview_mtx);
1036    return buffer_view;
1037 }
1038 
1039 enum pipe_swizzle
zink_clamp_void_swizzle(const struct util_format_description * desc,enum pipe_swizzle swizzle)1040 zink_clamp_void_swizzle(const struct util_format_description *desc, enum pipe_swizzle swizzle)
1041 {
1042    switch (swizzle) {
1043    case PIPE_SWIZZLE_X:
1044    case PIPE_SWIZZLE_Y:
1045    case PIPE_SWIZZLE_Z:
1046    case PIPE_SWIZZLE_W:
1047       return desc->channel[swizzle].type == UTIL_FORMAT_TYPE_VOID ? PIPE_SWIZZLE_1 : swizzle;
1048    default:
1049       break;
1050    }
1051    return swizzle;
1052 }
1053 
1054 ALWAYS_INLINE static enum pipe_swizzle
clamp_zs_swizzle(enum pipe_swizzle swizzle)1055 clamp_zs_swizzle(enum pipe_swizzle swizzle)
1056 {
1057    switch (swizzle) {
1058    case PIPE_SWIZZLE_X:
1059    case PIPE_SWIZZLE_Y:
1060    case PIPE_SWIZZLE_Z:
1061    case PIPE_SWIZZLE_W:
1062       return PIPE_SWIZZLE_X;
1063    default:
1064       break;
1065    }
1066    return swizzle;
1067 }
1068 
1069 ALWAYS_INLINE static enum pipe_swizzle
clamp_alpha_swizzle(enum pipe_swizzle swizzle)1070 clamp_alpha_swizzle(enum pipe_swizzle swizzle)
1071 {
1072    if (swizzle == PIPE_SWIZZLE_W)
1073       return PIPE_SWIZZLE_X;
1074    if (swizzle < PIPE_SWIZZLE_W)
1075       return PIPE_SWIZZLE_0;
1076    return swizzle;
1077 }
1078 
1079 ALWAYS_INLINE static enum pipe_swizzle
clamp_luminance_swizzle(enum pipe_swizzle swizzle)1080 clamp_luminance_swizzle(enum pipe_swizzle swizzle)
1081 {
1082    if (swizzle == PIPE_SWIZZLE_W)
1083       return PIPE_SWIZZLE_1;
1084    if (swizzle < PIPE_SWIZZLE_W)
1085       return PIPE_SWIZZLE_X;
1086    return swizzle;
1087 }
1088 
1089 ALWAYS_INLINE static enum pipe_swizzle
clamp_luminance_alpha_swizzle(enum pipe_swizzle swizzle)1090 clamp_luminance_alpha_swizzle(enum pipe_swizzle swizzle)
1091 {
1092    if (swizzle == PIPE_SWIZZLE_W)
1093       return PIPE_SWIZZLE_Y;
1094    if (swizzle < PIPE_SWIZZLE_W)
1095       return PIPE_SWIZZLE_X;
1096    return swizzle;
1097 }
1098 
1099 ALWAYS_INLINE static bool
viewtype_is_cube(const VkImageViewCreateInfo * ivci)1100 viewtype_is_cube(const VkImageViewCreateInfo *ivci)
1101 {
1102    return ivci->viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
1103           ivci->viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
1104 }
1105 
1106 static struct pipe_sampler_view *
zink_create_sampler_view(struct pipe_context * pctx,struct pipe_resource * pres,const struct pipe_sampler_view * state)1107 zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres,
1108                          const struct pipe_sampler_view *state)
1109 {
1110    struct zink_screen *screen = zink_screen(pctx->screen);
1111    struct zink_resource *res = zink_resource(pres);
1112    struct zink_context *ctx = zink_context(pctx);
1113    struct zink_sampler_view *sampler_view = CALLOC_STRUCT_CL(zink_sampler_view);
1114    bool err;
1115 
1116    if (!sampler_view) {
1117       mesa_loge("ZINK: failed to allocate sampler_view!");
1118       return NULL;
1119    }
1120 
1121    sampler_view->base = *state;
1122    sampler_view->base.texture = NULL;
1123    pipe_resource_reference(&sampler_view->base.texture, pres);
1124    sampler_view->base.reference.count = 1;
1125    sampler_view->base.context = pctx;
1126 
1127    if (state->target != PIPE_BUFFER) {
1128       VkImageViewCreateInfo ivci;
1129 
1130       struct pipe_surface templ = {0};
1131       templ.u.tex.level = state->u.tex.first_level;
1132       templ.format = state->format;
1133       /* avoid needing mutable for depth/stencil sampling */
1134       if (util_format_is_depth_and_stencil(pres->format))
1135          templ.format = pres->format;
1136       if (state->target != PIPE_TEXTURE_3D) {
1137          templ.u.tex.first_layer = state->u.tex.first_layer;
1138          templ.u.tex.last_layer = state->u.tex.last_layer;
1139       }
1140 
1141       if (zink_is_swapchain(res)) {
1142          if (!zink_kopper_acquire(ctx, res, UINT64_MAX)) {
1143             FREE_CL(sampler_view);
1144             return NULL;
1145          }
1146       }
1147 
1148       ivci = create_ivci(screen, res, &templ, state->target);
1149       ivci.subresourceRange.levelCount = state->u.tex.last_level - state->u.tex.first_level + 1;
1150       ivci.subresourceRange.aspectMask = sampler_aspect_from_format(state->format);
1151       bool red_depth_sampler_view = false;
1152       /* samplers for stencil aspects of packed formats need to always use stencil swizzle */
1153       if (ivci.subresourceRange.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
1154          ivci.components.r = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_r));
1155          ivci.components.g = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_g));
1156          ivci.components.b = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_b));
1157          ivci.components.a = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_a));
1158 
1159          /* If we're sampling depth and we might need to do shader rewrites for
1160           * legacy shadow sampling, then set up an extra image view that just
1161           * returns the red (depth) component, so you can always have the shadow
1162           * result available in the red component for the in-shader swizzling.
1163           * (Or if we have PVR's needs_zs_shader_swizzle and are sampling ONE
1164           * value for stencil, which also uses that view).
1165           */
1166          if (ivci.subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT ||
1167              zink_screen(ctx->base.screen)->driver_workarounds.needs_zs_shader_swizzle) {
1168             VkComponentSwizzle *swizzle = (VkComponentSwizzle*)&ivci.components;
1169             for (unsigned i = 0; i < 4; i++) {
1170                if (swizzle[i] == VK_COMPONENT_SWIZZLE_ONE ||
1171                    (swizzle[i] == VK_COMPONENT_SWIZZLE_ZERO && ivci.subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT))
1172                   red_depth_sampler_view = true;
1173             }
1174             /* this is the data that will be used in shader rewrites */
1175             sampler_view->swizzle.s[0] = clamp_zs_swizzle(sampler_view->base.swizzle_r);
1176             sampler_view->swizzle.s[1] = clamp_zs_swizzle(sampler_view->base.swizzle_g);
1177             sampler_view->swizzle.s[2] = clamp_zs_swizzle(sampler_view->base.swizzle_b);
1178             sampler_view->swizzle.s[3] = clamp_zs_swizzle(sampler_view->base.swizzle_a);
1179          }
1180       } else {
1181          enum pipe_swizzle swizzle[4] = {
1182             sampler_view->base.swizzle_r,
1183             sampler_view->base.swizzle_g,
1184             sampler_view->base.swizzle_b,
1185             sampler_view->base.swizzle_a
1186          };
1187          /* if we have e.g., R8G8B8X8, then we have to ignore alpha since we're just emulating
1188           * these formats
1189           */
1190          if (zink_format_is_voidable_rgba_variant(state->format)) {
1191             const struct util_format_description *view_desc = util_format_description(state->format);
1192             for (int i = 0; i < 4; ++i)
1193                swizzle[i] = zink_clamp_void_swizzle(view_desc, swizzle[i]);
1194          } else if (util_format_is_alpha(state->format) && res->format != VK_FORMAT_A8_UNORM_KHR) {
1195             for (int i = 0; i < 4; ++i)
1196                swizzle[i] = clamp_alpha_swizzle(swizzle[i]);
1197          } else if (util_format_is_luminance(pres->format) ||
1198                     util_format_is_luminance_alpha(pres->format)) {
1199             if (util_format_is_luminance(pres->format)) {
1200                for (int i = 0; i < 4; ++i)
1201                   swizzle[i] = clamp_luminance_swizzle(swizzle[i]);
1202             } else {
1203                for (int i = 0; i < 4; ++i)
1204                   swizzle[i] = clamp_luminance_alpha_swizzle(swizzle[i]);
1205             }
1206             if (state->format != pres->format) {
1207                /* luminance / luminance-alpha formats can be reinterpreted
1208                 * as red / red-alpha formats by the state-tracker, and we
1209                 * need to whack the green/blue channels here to the
1210                 * correct values for that to work.
1211                 */
1212                enum pipe_format linear = util_format_linear(pres->format);
1213                if (state->format == util_format_luminance_to_red(linear)) {
1214                   assert(swizzle[1] == PIPE_SWIZZLE_X ||
1215                          swizzle[1] == PIPE_SWIZZLE_0);
1216                   assert(swizzle[2] == PIPE_SWIZZLE_X ||
1217                          swizzle[2] == PIPE_SWIZZLE_0);
1218                   swizzle[1] = swizzle[2] = PIPE_SWIZZLE_0;
1219                } else
1220                   assert(state->format == linear);
1221             }
1222          } else if (util_format_is_red_alpha(pres->format)) {
1223             /* RA formats are mapped to RG with adjusted swizzle */
1224             assert(util_format_is_red_green(vk_format_to_pipe_format(ivci.format)));
1225             swizzle[3] = PIPE_SWIZZLE_Y;
1226          }
1227 
1228          ivci.components.r = zink_component_mapping(swizzle[0]);
1229          ivci.components.g = zink_component_mapping(swizzle[1]);
1230          ivci.components.b = zink_component_mapping(swizzle[2]);
1231          ivci.components.a = zink_component_mapping(swizzle[3]);
1232       }
1233       assert(ivci.format);
1234 
1235       sampler_view->image_view = (struct zink_surface*)zink_get_surface(ctx, pres, &templ, &ivci);
1236       if (!screen->info.have_EXT_non_seamless_cube_map && viewtype_is_cube(&sampler_view->image_view->ivci)) {
1237          ivci.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
1238          sampler_view->cube_array = (struct zink_surface*)zink_get_surface(ctx, pres, &templ, &ivci);
1239       } else if (red_depth_sampler_view) {
1240          /* there is only one component, and real swizzling can't be done here,
1241           * so ensure the shader gets the sampled data
1242           */
1243          ivci.components.r = VK_COMPONENT_SWIZZLE_R;
1244          ivci.components.g = VK_COMPONENT_SWIZZLE_R;
1245          ivci.components.b = VK_COMPONENT_SWIZZLE_R;
1246          ivci.components.a = VK_COMPONENT_SWIZZLE_R;
1247          sampler_view->zs_view = (struct zink_surface*)zink_get_surface(ctx, pres, &templ, &ivci);
1248       }
1249       err = !sampler_view->image_view;
1250    } else {
1251       if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
1252          /* always enforce limit clamping */
1253          unsigned blocksize = util_format_get_blocksize(state->format);
1254          sampler_view->tbo_size = MIN2(state->u.buf.size / blocksize, screen->info.props.limits.maxTexelBufferElements) * blocksize;
1255          return &sampler_view->base;
1256       }
1257       VkBufferViewCreateInfo bvci = create_bvci(ctx, res, state->format, state->u.buf.offset, state->u.buf.size);
1258       sampler_view->buffer_view = get_buffer_view(ctx, res, &bvci);
1259       err = !sampler_view->buffer_view;
1260    }
1261    if (err) {
1262       FREE_CL(sampler_view);
1263       return NULL;
1264    }
1265    return &sampler_view->base;
1266 }
1267 
1268 void
zink_destroy_buffer_view(struct zink_screen * screen,struct zink_buffer_view * buffer_view)1269 zink_destroy_buffer_view(struct zink_screen *screen, struct zink_buffer_view *buffer_view)
1270 {
1271    struct zink_resource *res = zink_resource(buffer_view->pres);
1272    simple_mtx_lock(&res->bufferview_mtx);
1273    if (buffer_view->reference.count) {
1274       /* got a cache hit during deletion */
1275       simple_mtx_unlock(&res->bufferview_mtx);
1276       return;
1277    }
1278    struct hash_entry *he = _mesa_hash_table_search_pre_hashed(&res->bufferview_cache, buffer_view->hash, &buffer_view->bvci);
1279    assert(he);
1280    _mesa_hash_table_remove(&res->bufferview_cache, he);
1281    simple_mtx_unlock(&res->bufferview_mtx);
1282    simple_mtx_lock(&res->obj->view_lock);
1283    util_dynarray_append(&res->obj->views, VkBufferView, buffer_view->buffer_view);
1284    simple_mtx_unlock(&res->obj->view_lock);
1285    pipe_resource_reference(&buffer_view->pres, NULL);
1286    FREE(buffer_view);
1287 }
1288 
1289 static void
zink_sampler_view_destroy(struct pipe_context * pctx,struct pipe_sampler_view * pview)1290 zink_sampler_view_destroy(struct pipe_context *pctx,
1291                           struct pipe_sampler_view *pview)
1292 {
1293    struct zink_sampler_view *view = zink_sampler_view(pview);
1294    if (pview->texture->target == PIPE_BUFFER) {
1295       if (zink_descriptor_mode != ZINK_DESCRIPTOR_MODE_DB)
1296          zink_buffer_view_reference(zink_screen(pctx->screen), &view->buffer_view, NULL);
1297    } else {
1298       zink_surface_reference(zink_screen(pctx->screen), &view->image_view, NULL);
1299       zink_surface_reference(zink_screen(pctx->screen), &view->cube_array, NULL);
1300       zink_surface_reference(zink_screen(pctx->screen), &view->zs_view, NULL);
1301    }
1302    pipe_resource_reference(&pview->texture, NULL);
1303    FREE_CL(view);
1304 }
1305 
1306 static void
zink_get_sample_position(struct pipe_context * ctx,unsigned sample_count,unsigned sample_index,float * out_value)1307 zink_get_sample_position(struct pipe_context *ctx,
1308                          unsigned sample_count,
1309                          unsigned sample_index,
1310                          float *out_value)
1311 {
1312    /* TODO: handle this I guess */
1313    assert(zink_screen(ctx->screen)->info.props.limits.standardSampleLocations);
1314    u_default_get_sample_position(ctx, sample_count, sample_index, out_value);
1315 }
1316 
1317 static void
zink_set_polygon_stipple(struct pipe_context * pctx,const struct pipe_poly_stipple * ps)1318 zink_set_polygon_stipple(struct pipe_context *pctx,
1319                          const struct pipe_poly_stipple *ps)
1320 {
1321 }
1322 
1323 ALWAYS_INLINE static void
update_res_bind_count(struct zink_context * ctx,struct zink_resource * res,bool is_compute,bool decrement)1324 update_res_bind_count(struct zink_context *ctx, struct zink_resource *res, bool is_compute, bool decrement)
1325 {
1326    if (decrement) {
1327       assert(res->bind_count[is_compute]);
1328       if (!--res->bind_count[is_compute])
1329          _mesa_set_remove_key(ctx->need_barriers[is_compute], res);
1330       check_resource_for_batch_ref(ctx, res);
1331    } else
1332       res->bind_count[is_compute]++;
1333 }
1334 
1335 ALWAYS_INLINE static void
update_existing_vbo(struct zink_context * ctx,unsigned slot)1336 update_existing_vbo(struct zink_context *ctx, unsigned slot)
1337 {
1338    if (!ctx->vertex_buffers[slot].buffer.resource)
1339       return;
1340    struct zink_resource *res = zink_resource(ctx->vertex_buffers[slot].buffer.resource);
1341    res->vbo_bind_count--;
1342    res->vbo_bind_mask &= ~BITFIELD_BIT(slot);
1343    if (!res->vbo_bind_count) {
1344       res->gfx_barrier &= ~VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
1345       res->barrier_access[0] &= ~VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
1346    }
1347    update_res_bind_count(ctx, res, false, true);
1348 }
1349 
1350 static void
zink_set_vertex_buffers(struct pipe_context * pctx,unsigned num_buffers,const struct pipe_vertex_buffer * buffers)1351 zink_set_vertex_buffers(struct pipe_context *pctx,
1352                         unsigned num_buffers,
1353                         const struct pipe_vertex_buffer *buffers)
1354 {
1355    struct zink_context *ctx = zink_context(pctx);
1356    const bool have_input_state = zink_screen(pctx->screen)->info.have_EXT_vertex_input_dynamic_state;
1357    const bool need_state_change = !zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state &&
1358                                   !have_input_state;
1359    uint32_t enabled_buffers = ctx->gfx_pipeline_state.vertex_buffers_enabled_mask;
1360    unsigned last_count = util_last_bit(enabled_buffers);
1361    enabled_buffers = u_bit_consecutive(0, num_buffers);
1362 
1363    assert(!num_buffers || buffers);
1364 
1365    for (unsigned i = 0; i < num_buffers; ++i) {
1366       const struct pipe_vertex_buffer *vb = buffers + i;
1367       struct pipe_vertex_buffer *ctx_vb = &ctx->vertex_buffers[i];
1368       update_existing_vbo(ctx, i);
1369       pipe_resource_reference(&ctx_vb->buffer.resource, NULL);
1370       ctx_vb->buffer.resource = vb->buffer.resource;
1371 
1372       if (vb->buffer.resource) {
1373          struct zink_resource *res = zink_resource(vb->buffer.resource);
1374          res->vbo_bind_mask |= BITFIELD_BIT(i);
1375          res->vbo_bind_count++;
1376          res->gfx_barrier |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
1377          res->barrier_access[0] |= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
1378          update_res_bind_count(ctx, res, false, false);
1379          ctx_vb->buffer_offset = vb->buffer_offset;
1380          /* always barrier before possible rebind */
1381          zink_screen(ctx->base.screen)->buffer_barrier(ctx, res, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
1382                                       VK_PIPELINE_STAGE_VERTEX_INPUT_BIT);
1383          zink_batch_resource_usage_set(&ctx->batch, res, false, true);
1384          res->obj->unordered_read = false;
1385       } else {
1386          enabled_buffers &= ~BITFIELD_BIT(i);
1387       }
1388    }
1389    for (unsigned i = num_buffers; i < last_count; i++) {
1390       update_existing_vbo(ctx, i);
1391       pipe_resource_reference(&ctx->vertex_buffers[i].buffer.resource, NULL);
1392    }
1393    if (need_state_change)
1394       ctx->vertex_state_changed = true;
1395    else if (!have_input_state && ctx->gfx_pipeline_state.vertex_buffers_enabled_mask != enabled_buffers)
1396       ctx->vertex_state_changed = true;
1397    ctx->gfx_pipeline_state.vertex_buffers_enabled_mask = enabled_buffers;
1398    ctx->vertex_buffers_dirty = num_buffers > 0;
1399 #ifndef NDEBUG
1400    u_foreach_bit(b, enabled_buffers)
1401       assert(ctx->vertex_buffers[b].buffer.resource);
1402 #endif
1403 }
1404 
1405 static void
zink_set_viewport_states(struct pipe_context * pctx,unsigned start_slot,unsigned num_viewports,const struct pipe_viewport_state * state)1406 zink_set_viewport_states(struct pipe_context *pctx,
1407                          unsigned start_slot,
1408                          unsigned num_viewports,
1409                          const struct pipe_viewport_state *state)
1410 {
1411    struct zink_context *ctx = zink_context(pctx);
1412 
1413    for (unsigned i = 0; i < num_viewports; ++i)
1414       ctx->vp_state.viewport_states[start_slot + i] = state[i];
1415 
1416    ctx->vp_state_changed = true;
1417    zink_flush_dgc_if_enabled(ctx);
1418 }
1419 
1420 static void
zink_set_scissor_states(struct pipe_context * pctx,unsigned start_slot,unsigned num_scissors,const struct pipe_scissor_state * states)1421 zink_set_scissor_states(struct pipe_context *pctx,
1422                         unsigned start_slot, unsigned num_scissors,
1423                         const struct pipe_scissor_state *states)
1424 {
1425    struct zink_context *ctx = zink_context(pctx);
1426 
1427    for (unsigned i = 0; i < num_scissors; i++)
1428       ctx->vp_state.scissor_states[start_slot + i] = states[i];
1429    ctx->scissor_changed = true;
1430    zink_flush_dgc_if_enabled(ctx);
1431 }
1432 
1433 static void
zink_set_inlinable_constants(struct pipe_context * pctx,gl_shader_stage shader,uint num_values,uint32_t * values)1434 zink_set_inlinable_constants(struct pipe_context *pctx,
1435                              gl_shader_stage shader,
1436                              uint num_values, uint32_t *values)
1437 {
1438    struct zink_context *ctx = (struct zink_context *)pctx;
1439    const uint32_t bit = BITFIELD_BIT(shader);
1440    uint32_t *inlinable_uniforms;
1441    struct zink_shader_key *key = NULL;
1442 
1443    if (shader == MESA_SHADER_COMPUTE) {
1444       key = &ctx->compute_pipeline_state.key;
1445    } else {
1446       assert(!zink_screen(pctx->screen)->optimal_keys ||
1447              (shader == MESA_SHADER_GEOMETRY &&
1448               ctx->gfx_stages[MESA_SHADER_GEOMETRY] &&
1449               ctx->gfx_stages[MESA_SHADER_GEOMETRY]->non_fs.is_generated));
1450       key = &ctx->gfx_pipeline_state.shader_keys.key[shader];
1451    }
1452    inlinable_uniforms = key->base.inlined_uniform_values;
1453    if (!(ctx->inlinable_uniforms_valid_mask & bit) ||
1454        memcmp(inlinable_uniforms, values, num_values * 4)) {
1455       memcpy(inlinable_uniforms, values, num_values * 4);
1456       if (shader == MESA_SHADER_COMPUTE)
1457          ctx->compute_dirty = true;
1458       else
1459          ctx->dirty_gfx_stages |= bit;
1460       ctx->inlinable_uniforms_valid_mask |= bit;
1461       key->inline_uniforms = true;
1462    }
1463 }
1464 
1465 ALWAYS_INLINE static void
unbind_descriptor_stage(struct zink_resource * res,gl_shader_stage pstage)1466 unbind_descriptor_stage(struct zink_resource *res, gl_shader_stage pstage)
1467 {
1468    if (!res->sampler_binds[pstage] && !res->image_binds[pstage] && !res->all_bindless)
1469       res->gfx_barrier &= ~zink_pipeline_flags_from_pipe_stage(pstage);
1470 }
1471 
1472 ALWAYS_INLINE static void
unbind_buffer_descriptor_stage(struct zink_resource * res,gl_shader_stage pstage)1473 unbind_buffer_descriptor_stage(struct zink_resource *res, gl_shader_stage pstage)
1474 {
1475    if (!res->ubo_bind_mask[pstage] && !res->ssbo_bind_mask[pstage])
1476       unbind_descriptor_stage(res, pstage);
1477 }
1478 
1479 ALWAYS_INLINE static void
unbind_ubo(struct zink_context * ctx,struct zink_resource * res,gl_shader_stage pstage,unsigned slot)1480 unbind_ubo(struct zink_context *ctx, struct zink_resource *res, gl_shader_stage pstage, unsigned slot)
1481 {
1482    if (!res)
1483       return;
1484    res->ubo_bind_mask[pstage] &= ~BITFIELD_BIT(slot);
1485    res->ubo_bind_count[pstage == MESA_SHADER_COMPUTE]--;
1486    unbind_buffer_descriptor_stage(res, pstage);
1487    if (!res->ubo_bind_count[pstage == MESA_SHADER_COMPUTE])
1488       res->barrier_access[pstage == MESA_SHADER_COMPUTE] &= ~VK_ACCESS_UNIFORM_READ_BIT;
1489    update_res_bind_count(ctx, res, pstage == MESA_SHADER_COMPUTE, true);
1490 }
1491 
1492 static void
invalidate_inlined_uniforms(struct zink_context * ctx,gl_shader_stage pstage)1493 invalidate_inlined_uniforms(struct zink_context *ctx, gl_shader_stage pstage)
1494 {
1495    unsigned bit = BITFIELD_BIT(pstage);
1496    if (!(ctx->inlinable_uniforms_valid_mask & bit))
1497       return;
1498    ctx->inlinable_uniforms_valid_mask &= ~bit;
1499    if (pstage == MESA_SHADER_COMPUTE) {
1500       ctx->compute_dirty = true;
1501       return;
1502    }
1503    assert(!zink_screen(ctx->base.screen)->optimal_keys || (pstage == MESA_SHADER_GEOMETRY && ctx->is_generated_gs_bound));
1504    ctx->dirty_gfx_stages |= bit;
1505    struct zink_shader_key *key = &ctx->gfx_pipeline_state.shader_keys.key[pstage];
1506    key->inline_uniforms = false;
1507 }
1508 
1509 static void
zink_set_constant_buffer(struct pipe_context * pctx,gl_shader_stage shader,uint index,bool take_ownership,const struct pipe_constant_buffer * cb)1510 zink_set_constant_buffer(struct pipe_context *pctx,
1511                          gl_shader_stage shader, uint index,
1512                          bool take_ownership,
1513                          const struct pipe_constant_buffer *cb)
1514 {
1515    struct zink_context *ctx = zink_context(pctx);
1516    bool update = false;
1517 
1518    struct zink_resource *res = zink_resource(ctx->ubos[shader][index].buffer);
1519    if (cb) {
1520       struct pipe_resource *buffer = cb->buffer;
1521       unsigned offset = cb->buffer_offset;
1522       struct zink_screen *screen = zink_screen(pctx->screen);
1523       if (cb->user_buffer) {
1524          u_upload_data(ctx->base.const_uploader, 0, cb->buffer_size,
1525                        screen->info.props.limits.minUniformBufferOffsetAlignment,
1526                        cb->user_buffer, &offset, &buffer);
1527       }
1528       struct zink_resource *new_res = zink_resource(buffer);
1529       if (new_res) {
1530          if (new_res != res) {
1531             unbind_ubo(ctx, res, shader, index);
1532             new_res->ubo_bind_count[shader == MESA_SHADER_COMPUTE]++;
1533             new_res->ubo_bind_mask[shader] |= BITFIELD_BIT(index);
1534             new_res->gfx_barrier |= zink_pipeline_flags_from_pipe_stage(shader);
1535             new_res->barrier_access[shader == MESA_SHADER_COMPUTE] |= VK_ACCESS_UNIFORM_READ_BIT;
1536             update_res_bind_count(ctx, new_res, shader == MESA_SHADER_COMPUTE, false);
1537          }
1538          zink_screen(ctx->base.screen)->buffer_barrier(ctx, new_res, VK_ACCESS_UNIFORM_READ_BIT,
1539                                       new_res->gfx_barrier);
1540          zink_batch_resource_usage_set(&ctx->batch, new_res, false, true);
1541          if (!ctx->unordered_blitting)
1542             new_res->obj->unordered_read = false;
1543       }
1544       update |= ctx->ubos[shader][index].buffer_offset != offset ||
1545                 !!res != !!buffer || (res && res->obj->buffer != new_res->obj->buffer) ||
1546                 ctx->ubos[shader][index].buffer_size != cb->buffer_size;
1547 
1548       if (take_ownership) {
1549          pipe_resource_reference(&ctx->ubos[shader][index].buffer, NULL);
1550          ctx->ubos[shader][index].buffer = buffer;
1551       } else {
1552          pipe_resource_reference(&ctx->ubos[shader][index].buffer, buffer);
1553       }
1554       ctx->ubos[shader][index].buffer_offset = offset;
1555       ctx->ubos[shader][index].buffer_size = cb->buffer_size;
1556       ctx->ubos[shader][index].user_buffer = NULL;
1557 
1558       if (cb->user_buffer)
1559          pipe_resource_reference(&buffer, NULL);
1560 
1561       if (index + 1 >= ctx->di.num_ubos[shader])
1562          ctx->di.num_ubos[shader] = index + 1;
1563       update_descriptor_state_ubo(ctx, shader, index, new_res);
1564    } else {
1565       ctx->ubos[shader][index].buffer_offset = 0;
1566       ctx->ubos[shader][index].buffer_size = 0;
1567       ctx->ubos[shader][index].user_buffer = NULL;
1568       if (res) {
1569          unbind_ubo(ctx, res, shader, index);
1570          update_descriptor_state_ubo(ctx, shader, index, NULL);
1571       }
1572       update = !!ctx->ubos[shader][index].buffer;
1573 
1574       pipe_resource_reference(&ctx->ubos[shader][index].buffer, NULL);
1575       if (ctx->di.num_ubos[shader] == index + 1)
1576          ctx->di.num_ubos[shader]--;
1577    }
1578    if (index == 0) {
1579       /* Invalidate current inlinable uniforms. */
1580       invalidate_inlined_uniforms(ctx, shader);
1581    }
1582 
1583    if (update)
1584       ctx->invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_UBO, index, 1);
1585 }
1586 
1587 ALWAYS_INLINE static void
unbind_descriptor_reads(struct zink_resource * res,bool is_compute)1588 unbind_descriptor_reads(struct zink_resource *res, bool is_compute)
1589 {
1590    if (!res->sampler_bind_count[is_compute] && !res->image_bind_count[is_compute] && !res->all_bindless)
1591       res->barrier_access[is_compute] &= ~VK_ACCESS_SHADER_READ_BIT;
1592 }
1593 
1594 ALWAYS_INLINE static void
unbind_buffer_descriptor_reads(struct zink_resource * res,bool is_compute)1595 unbind_buffer_descriptor_reads(struct zink_resource *res, bool is_compute)
1596 {
1597    if (!res->ssbo_bind_count[is_compute] && !res->all_bindless)
1598       unbind_descriptor_reads(res, is_compute);
1599 }
1600 
1601 ALWAYS_INLINE static void
unbind_ssbo(struct zink_context * ctx,struct zink_resource * res,gl_shader_stage pstage,unsigned slot,bool writable)1602 unbind_ssbo(struct zink_context *ctx, struct zink_resource *res, gl_shader_stage pstage, unsigned slot, bool writable)
1603 {
1604    if (!res)
1605       return;
1606    res->ssbo_bind_mask[pstage] &= ~BITFIELD_BIT(slot);
1607    res->ssbo_bind_count[pstage == MESA_SHADER_COMPUTE]--;
1608    unbind_buffer_descriptor_stage(res, pstage);
1609    unbind_buffer_descriptor_reads(res, pstage == MESA_SHADER_COMPUTE);
1610    update_res_bind_count(ctx, res, pstage == MESA_SHADER_COMPUTE, true);
1611    if (writable)
1612       res->write_bind_count[pstage == MESA_SHADER_COMPUTE]--;
1613    if (!res->write_bind_count[pstage == MESA_SHADER_COMPUTE])
1614       res->barrier_access[pstage == MESA_SHADER_COMPUTE] &= ~VK_ACCESS_SHADER_WRITE_BIT;
1615 }
1616 
1617 static void
zink_set_shader_buffers(struct pipe_context * pctx,gl_shader_stage p_stage,unsigned start_slot,unsigned count,const struct pipe_shader_buffer * buffers,unsigned writable_bitmask)1618 zink_set_shader_buffers(struct pipe_context *pctx,
1619                         gl_shader_stage p_stage,
1620                         unsigned start_slot, unsigned count,
1621                         const struct pipe_shader_buffer *buffers,
1622                         unsigned writable_bitmask)
1623 {
1624    struct zink_context *ctx = zink_context(pctx);
1625    bool update = false;
1626    unsigned max_slot = 0;
1627 
1628    unsigned modified_bits = u_bit_consecutive(start_slot, count);
1629    unsigned old_writable_mask = ctx->writable_ssbos[p_stage];
1630    assert(!ctx->unordered_blitting);
1631    ctx->writable_ssbos[p_stage] &= ~modified_bits;
1632    ctx->writable_ssbos[p_stage] |= writable_bitmask << start_slot;
1633 
1634    for (unsigned i = 0; i < count; i++) {
1635       unsigned slot = start_slot + i;
1636       struct pipe_shader_buffer *ssbo = &ctx->ssbos[p_stage][slot];
1637       struct zink_resource *res = ssbo->buffer ? zink_resource(ssbo->buffer) : NULL;
1638       bool was_writable = old_writable_mask & BITFIELD64_BIT(slot);
1639       if (buffers && buffers[i].buffer) {
1640          struct zink_resource *new_res = zink_resource(buffers[i].buffer);
1641          if (new_res != res) {
1642             unbind_ssbo(ctx, res, p_stage, slot, was_writable);
1643             new_res->ssbo_bind_mask[p_stage] |= BITFIELD_BIT(slot);
1644             new_res->ssbo_bind_count[p_stage == MESA_SHADER_COMPUTE]++;
1645             new_res->gfx_barrier |= zink_pipeline_flags_from_pipe_stage(p_stage);
1646             update_res_bind_count(ctx, new_res, p_stage == MESA_SHADER_COMPUTE, false);
1647          }
1648          VkAccessFlags access = VK_ACCESS_SHADER_READ_BIT;
1649          if (ctx->writable_ssbos[p_stage] & BITFIELD64_BIT(slot)) {
1650             new_res->write_bind_count[p_stage == MESA_SHADER_COMPUTE]++;
1651             access |= VK_ACCESS_SHADER_WRITE_BIT;
1652          }
1653          pipe_resource_reference(&ssbo->buffer, &new_res->base.b);
1654          new_res->barrier_access[p_stage == MESA_SHADER_COMPUTE] |= access;
1655          ssbo->buffer_offset = buffers[i].buffer_offset;
1656          ssbo->buffer_size = MIN2(buffers[i].buffer_size, new_res->base.b.width0 - ssbo->buffer_offset);
1657          util_range_add(&new_res->base.b, &new_res->valid_buffer_range, ssbo->buffer_offset,
1658                         ssbo->buffer_offset + ssbo->buffer_size);
1659          zink_screen(ctx->base.screen)->buffer_barrier(ctx, new_res, access,
1660                                       new_res->gfx_barrier);
1661          zink_batch_resource_usage_set(&ctx->batch, new_res, access & VK_ACCESS_SHADER_WRITE_BIT, true);
1662          update = true;
1663          max_slot = MAX2(max_slot, slot);
1664          update_descriptor_state_ssbo(ctx, p_stage, slot, new_res);
1665          if (zink_resource_access_is_write(access))
1666             new_res->obj->unordered_write = false;
1667          new_res->obj->unordered_read = false;
1668       } else {
1669          if (res)
1670             update = true;
1671          ssbo->buffer_offset = 0;
1672          ssbo->buffer_size = 0;
1673          if (res) {
1674             unbind_ssbo(ctx, res, p_stage, slot, was_writable);
1675             update_descriptor_state_ssbo(ctx, p_stage, slot, NULL);
1676          }
1677          pipe_resource_reference(&ssbo->buffer, NULL);
1678       }
1679    }
1680    if (start_slot + count >= ctx->di.num_ssbos[p_stage])
1681       ctx->di.num_ssbos[p_stage] = max_slot + 1;
1682    if (update)
1683       ctx->invalidate_descriptor_state(ctx, p_stage, ZINK_DESCRIPTOR_TYPE_SSBO, start_slot, count);
1684 }
1685 
1686 static void
update_binds_for_samplerviews(struct zink_context * ctx,struct zink_resource * res,bool is_compute)1687 update_binds_for_samplerviews(struct zink_context *ctx, struct zink_resource *res, bool is_compute)
1688 {
1689     VkImageLayout layout = get_layout_for_binding(ctx, res, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, is_compute);
1690     if (is_compute) {
1691        u_foreach_bit(slot, res->sampler_binds[MESA_SHADER_COMPUTE]) {
1692           if (ctx->di.textures[MESA_SHADER_COMPUTE][slot].imageLayout != layout) {
1693              update_descriptor_state_sampler(ctx, MESA_SHADER_COMPUTE, slot, res);
1694              ctx->invalidate_descriptor_state(ctx, MESA_SHADER_COMPUTE, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, slot, 1);
1695           }
1696        }
1697     } else {
1698        for (unsigned i = 0; i < ZINK_GFX_SHADER_COUNT; i++) {
1699           u_foreach_bit(slot, res->sampler_binds[i]) {
1700              if (ctx->di.textures[i][slot].imageLayout != layout) {
1701                 update_descriptor_state_sampler(ctx, i, slot, res);
1702                 ctx->invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, slot, 1);
1703              }
1704           }
1705        }
1706     }
1707 }
1708 
1709 static void
flush_pending_clears(struct zink_context * ctx,struct zink_resource * res)1710 flush_pending_clears(struct zink_context *ctx, struct zink_resource *res)
1711 {
1712    if (res->fb_bind_count && ctx->clears_enabled)
1713       zink_fb_clears_apply(ctx, &res->base.b);
1714 }
1715 
1716 static inline void
unbind_shader_image_counts(struct zink_context * ctx,struct zink_resource * res,bool is_compute,bool writable)1717 unbind_shader_image_counts(struct zink_context *ctx, struct zink_resource *res, bool is_compute, bool writable)
1718 {
1719    update_res_bind_count(ctx, res, is_compute, true);
1720    if (writable)
1721       res->write_bind_count[is_compute]--;
1722    res->image_bind_count[is_compute]--;
1723    /* if this was the last image bind, the sampler bind layouts must be updated */
1724    if (!res->obj->is_buffer && !res->image_bind_count[is_compute] && res->bind_count[is_compute])
1725       update_binds_for_samplerviews(ctx, res, is_compute);
1726 }
1727 
1728 ALWAYS_INLINE static bool
check_for_layout_update(struct zink_context * ctx,struct zink_resource * res,bool is_compute)1729 check_for_layout_update(struct zink_context *ctx, struct zink_resource *res, bool is_compute)
1730 {
1731    VkImageLayout layout = res->bind_count[is_compute] ? zink_descriptor_util_image_layout_eval(ctx, res, is_compute) : VK_IMAGE_LAYOUT_UNDEFINED;
1732    VkImageLayout other_layout = res->bind_count[!is_compute] ? zink_descriptor_util_image_layout_eval(ctx, res, !is_compute) : VK_IMAGE_LAYOUT_UNDEFINED;
1733    bool ret = false;
1734    if (!is_compute && res->fb_binds && !(ctx->feedback_loops & res->fb_binds)) {
1735       /* always double check feedback loops */
1736       ret = !!_mesa_set_add(ctx->need_barriers[0], res);
1737    } else {
1738       if (res->bind_count[is_compute] && layout && res->layout != layout)
1739          ret = !!_mesa_set_add(ctx->need_barriers[is_compute], res);
1740       if (res->bind_count[!is_compute] && other_layout && (layout != other_layout || res->layout != other_layout))
1741          ret = !!_mesa_set_add(ctx->need_barriers[!is_compute], res);
1742    }
1743    return ret;
1744 }
1745 
1746 static void
unbind_shader_image(struct zink_context * ctx,gl_shader_stage stage,unsigned slot)1747 unbind_shader_image(struct zink_context *ctx, gl_shader_stage stage, unsigned slot)
1748 {
1749    struct zink_image_view *image_view = &ctx->image_views[stage][slot];
1750    bool is_compute = stage == MESA_SHADER_COMPUTE;
1751    if (!image_view->base.resource)
1752       return;
1753 
1754    struct zink_resource *res = zink_resource(image_view->base.resource);
1755    res->image_binds[stage] &= ~BITFIELD_BIT(slot);
1756    unbind_shader_image_counts(ctx, res, is_compute, image_view->base.access & PIPE_IMAGE_ACCESS_WRITE);
1757    if (!res->write_bind_count[is_compute])
1758       res->barrier_access[stage == MESA_SHADER_COMPUTE] &= ~VK_ACCESS_SHADER_WRITE_BIT;
1759 
1760    if (image_view->base.resource->target == PIPE_BUFFER) {
1761       unbind_buffer_descriptor_stage(res, stage);
1762       unbind_buffer_descriptor_reads(res, stage == MESA_SHADER_COMPUTE);
1763       zink_buffer_view_reference(zink_screen(ctx->base.screen), &image_view->buffer_view, NULL);
1764       if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB)
1765          pipe_resource_reference(&image_view->base.resource, NULL);
1766    } else {
1767       unbind_descriptor_stage(res, stage);
1768       unbind_descriptor_reads(res, stage == MESA_SHADER_COMPUTE);
1769       if (!res->image_bind_count[is_compute])
1770          check_for_layout_update(ctx, res, is_compute);
1771       zink_surface_reference(zink_screen(ctx->base.screen), &image_view->surface, NULL);
1772    }
1773    image_view->base.resource = NULL;
1774    image_view->surface = NULL;
1775 }
1776 
1777 static struct zink_buffer_view *
create_image_bufferview(struct zink_context * ctx,const struct pipe_image_view * view)1778 create_image_bufferview(struct zink_context *ctx, const struct pipe_image_view *view)
1779 {
1780    struct zink_resource *res = zink_resource(view->resource);
1781    VkBufferViewCreateInfo bvci = create_bvci(ctx, res, view->format, view->u.buf.offset, view->u.buf.size);
1782    struct zink_buffer_view *buffer_view = get_buffer_view(ctx, res, &bvci);
1783    if (!buffer_view)
1784       return NULL;
1785    util_range_add(&res->base.b, &res->valid_buffer_range, view->u.buf.offset,
1786                   view->u.buf.offset + view->u.buf.size);
1787    return buffer_view;
1788 }
1789 
1790 static void
finalize_image_bind(struct zink_context * ctx,struct zink_resource * res,bool is_compute)1791 finalize_image_bind(struct zink_context *ctx, struct zink_resource *res, bool is_compute)
1792 {
1793    /* if this is the first image bind and there are sampler binds, the image's sampler layout
1794     * must be updated to GENERAL
1795     */
1796    if (res->image_bind_count[is_compute] == 1 &&
1797        res->bind_count[is_compute] > 1)
1798       update_binds_for_samplerviews(ctx, res, is_compute);
1799    if (!check_for_layout_update(ctx, res, is_compute)) {
1800       /* no deferred barrier: unset unordered usage immediately */
1801       // TODO: figure out a way to link up layouts between unordered and main cmdbuf
1802       // if (zink_resource_access_is_write(res->barrier_access[is_compute]))
1803       res->obj->unordered_write = false;
1804       res->obj->unordered_read = false;
1805    }
1806 }
1807 
1808 static struct zink_surface *
create_image_surface(struct zink_context * ctx,const struct pipe_image_view * view,bool is_compute)1809 create_image_surface(struct zink_context *ctx, const struct pipe_image_view *view, bool is_compute)
1810 {
1811    struct zink_screen *screen = zink_screen(ctx->base.screen);
1812    struct zink_resource *res = zink_resource(view->resource);
1813    struct pipe_surface tmpl = {0};
1814    enum pipe_texture_target target = res->base.b.target;
1815    tmpl.format = view->format;
1816    tmpl.u.tex.level = view->u.tex.level;
1817    tmpl.u.tex.first_layer = view->u.tex.first_layer;
1818    tmpl.u.tex.last_layer = view->u.tex.last_layer;
1819    unsigned depth = 1 + tmpl.u.tex.last_layer - tmpl.u.tex.first_layer;
1820    switch (target) {
1821    case PIPE_TEXTURE_3D:
1822       if (depth < u_minify(res->base.b.depth0, view->u.tex.level)) {
1823          assert(depth == 1);
1824          target = PIPE_TEXTURE_2D;
1825          if (!screen->info.have_EXT_image_2d_view_of_3d ||
1826              !screen->info.view2d_feats.image2DViewOf3D) {
1827             static bool warned = false;
1828             warn_missing_feature(warned, "image2DViewOf3D");
1829          }
1830       } else {
1831          assert(tmpl.u.tex.first_layer == 0);
1832          tmpl.u.tex.last_layer = 0;
1833       }
1834       break;
1835    case PIPE_TEXTURE_2D_ARRAY:
1836    case PIPE_TEXTURE_1D_ARRAY:
1837       if (depth < res->base.b.array_size && depth == 1)
1838          target = target == PIPE_TEXTURE_2D_ARRAY ? PIPE_TEXTURE_2D : PIPE_TEXTURE_1D;
1839       break;
1840    default: break;
1841    }
1842    if (zink_format_needs_mutable(view->resource->format, view->format))
1843       /* mutable not set by default */
1844       zink_resource_object_init_mutable(ctx, res);
1845    VkImageViewCreateInfo ivci = create_ivci(screen, res, &tmpl, target);
1846    struct pipe_surface *psurf = zink_get_surface(ctx, view->resource, &tmpl, &ivci);
1847    if (!psurf)
1848       return NULL;
1849    struct zink_surface *surface = zink_surface(psurf);
1850    if (is_compute)
1851       flush_pending_clears(ctx, res);
1852    return surface;
1853 }
1854 
1855 static void
zink_set_shader_images(struct pipe_context * pctx,gl_shader_stage shader_type,unsigned start_slot,unsigned count,unsigned unbind_num_trailing_slots,const struct pipe_image_view * images)1856 zink_set_shader_images(struct pipe_context *pctx,
1857                        gl_shader_stage shader_type,
1858                        unsigned start_slot, unsigned count,
1859                        unsigned unbind_num_trailing_slots,
1860                        const struct pipe_image_view *images)
1861 {
1862    struct zink_context *ctx = zink_context(pctx);
1863    struct zink_screen *screen = zink_screen(pctx->screen);
1864    bool update = false;
1865    bool is_compute = shader_type == MESA_SHADER_COMPUTE;
1866    assert(!ctx->unordered_blitting);
1867    for (unsigned i = 0; i < count; i++) {
1868       struct zink_image_view *a = &ctx->image_views[shader_type][start_slot + i];
1869       const struct pipe_image_view *b = images ? &images[i] : NULL;
1870       struct zink_resource *res = b ? zink_resource(b->resource) : NULL;
1871       if (b && b->resource) {
1872          if (!zink_resource_object_init_storage(ctx, res)) {
1873             debug_printf("couldn't create storage image!");
1874             continue;
1875          }
1876 
1877          VkAccessFlags access = 0;
1878          if (b->access & PIPE_IMAGE_ACCESS_WRITE) {
1879             access |= VK_ACCESS_SHADER_WRITE_BIT;
1880          }
1881          if (b->access & PIPE_IMAGE_ACCESS_READ) {
1882             access |= VK_ACCESS_SHADER_READ_BIT;
1883          }
1884 
1885          bool changed = false;
1886          if (!a->base.resource || a->base.resource != b->resource) {
1887             /* this needs a full unbind+bind */
1888             changed = true;
1889             unbind_shader_image(ctx, shader_type, start_slot + i);
1890             update_res_bind_count(ctx, res, is_compute, false);
1891             res->image_bind_count[is_compute]++;
1892             /* always increment write_bind_count on new bind */
1893             if (b->access & PIPE_IMAGE_ACCESS_WRITE)
1894                res->write_bind_count[is_compute]++;
1895             /* db mode refcounts these */
1896             if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB && b->resource->target == PIPE_BUFFER)
1897                pipe_resource_reference(&a->base.resource, b->resource);
1898          } else {
1899             /* resource matches: check for write flag change and partial rebind */
1900 
1901             /* previous bind didn't have write: increment */
1902             if ((b->access & PIPE_IMAGE_ACCESS_WRITE) && !(a->base.access & PIPE_IMAGE_ACCESS_WRITE))
1903                res->write_bind_count[is_compute]++;
1904             /* previous bind had write: decrement */
1905             else if (!(b->access & PIPE_IMAGE_ACCESS_WRITE) && (a->base.access & PIPE_IMAGE_ACCESS_WRITE)) {
1906                res->write_bind_count[is_compute]--;
1907                if (!res->write_bind_count[is_compute])
1908                   res->barrier_access[is_compute] &= ~VK_ACCESS_SHADER_WRITE_BIT;
1909             }
1910 
1911             /* this may need a partial rebind */
1912             changed = a->base.format != b->format || zink_resource(a->base.resource)->obj != res->obj;
1913             if (!changed) {
1914                if (b->resource->target == PIPE_BUFFER) {
1915                   /* db mode has no partial rebind */
1916                   if (zink_descriptor_mode != ZINK_DESCRIPTOR_MODE_DB)
1917                      changed = !!memcmp(&a->base.u.buf, &b->u.buf, sizeof(b->u.buf));
1918                } else {
1919                   /* no memcmp, these are bitfields */
1920                   changed = a->base.u.tex.first_layer != b->u.tex.first_layer ||
1921                             a->base.u.tex.last_layer != b->u.tex.last_layer ||
1922                             a->base.u.tex.level != b->u.tex.level;
1923                }
1924             }
1925          }
1926 
1927          if (changed) {
1928             /* this is a partial rebind */
1929             if (b->resource->target == PIPE_BUFFER) {
1930                /* db has no partial rebind */
1931                if (zink_descriptor_mode != ZINK_DESCRIPTOR_MODE_DB) {
1932                   /* bufferview rebind: get updated bufferview and unref old one */
1933                   struct zink_buffer_view *bv = create_image_bufferview(ctx, b);
1934                   /* identical rebind was already checked above */
1935                   assert(bv && bv != a->buffer_view);
1936                   zink_buffer_view_reference(screen, &a->buffer_view, NULL);
1937                   /* ref already added by create */
1938                   a->buffer_view = bv;
1939                }
1940                if (zink_resource_access_is_write(access))
1941                   res->obj->unordered_write = false;
1942                res->obj->unordered_read = false;
1943             } else {
1944                /* image rebind: get updated surface and unref old one */
1945                struct zink_surface *surface = create_image_surface(ctx, b, is_compute);
1946                /* identical rebind was already checked above */
1947                assert(surface && surface != a->surface);
1948                zink_surface_reference(screen, &a->surface, NULL);
1949                /* ref already added by create */
1950                a->surface = surface;
1951             }
1952          }
1953 
1954          /* these operations occur regardless of binding/rebinding */
1955          res->gfx_barrier |= zink_pipeline_flags_from_pipe_stage(shader_type);
1956          res->barrier_access[is_compute] |= access;
1957          if (b->resource->target == PIPE_BUFFER) {
1958             screen->buffer_barrier(ctx, res, access,
1959                                          res->gfx_barrier);
1960             zink_batch_resource_usage_set(&ctx->batch, res,
1961                                           zink_resource_access_is_write(access), true);
1962          } else {
1963             finalize_image_bind(ctx, res, is_compute);
1964             zink_batch_resource_usage_set(&ctx->batch, res,
1965                                           zink_resource_access_is_write(access), false);
1966          }
1967          memcpy(&a->base, images + i, sizeof(struct pipe_image_view));
1968          if (b->resource->target == PIPE_BUFFER) {
1969             /* always enforce limit clamping */
1970             unsigned blocksize = util_format_get_blocksize(a->base.format);
1971             a->base.u.buf.size = MIN2(a->base.u.buf.size / blocksize, screen->info.props.limits.maxTexelBufferElements) * blocksize;
1972          }
1973          update = true;
1974          res->image_binds[shader_type] |= BITFIELD_BIT(start_slot + i);
1975       } else if (a->base.resource) {
1976          update = true;
1977          unbind_shader_image(ctx, shader_type, start_slot + i);
1978       }
1979       update_descriptor_state_image(ctx, shader_type, start_slot + i, res);
1980    }
1981    for (unsigned i = 0; i < unbind_num_trailing_slots; i++) {
1982       update |= !!ctx->image_views[shader_type][start_slot + count + i].base.resource;
1983       unbind_shader_image(ctx, shader_type, start_slot + count + i);
1984       update_descriptor_state_image(ctx, shader_type, start_slot + count + i, NULL);
1985    }
1986    ctx->di.num_images[shader_type] = start_slot + count;
1987    if (update)
1988       ctx->invalidate_descriptor_state(ctx, shader_type, ZINK_DESCRIPTOR_TYPE_IMAGE, start_slot, count);
1989 }
1990 
1991 static void
update_feedback_loop_dynamic_state(struct zink_context * ctx)1992 update_feedback_loop_dynamic_state(struct zink_context *ctx)
1993 {
1994    if (!zink_screen(ctx->base.screen)->info.have_EXT_attachment_feedback_loop_dynamic_state)
1995       return;
1996    VkImageAspectFlags aspects = 0;
1997    if (ctx->feedback_loops & BITFIELD_MASK(PIPE_MAX_COLOR_BUFS))
1998       aspects |= VK_IMAGE_ASPECT_COLOR_BIT;
1999    if (ctx->feedback_loops & BITFIELD_BIT(PIPE_MAX_COLOR_BUFS))
2000       aspects |= VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
2001    VKCTX(CmdSetAttachmentFeedbackLoopEnableEXT)(ctx->batch.state->cmdbuf, aspects);
2002 }
2003 
2004 static void
update_feedback_loop_state(struct zink_context * ctx,unsigned idx,unsigned feedback_loops)2005 update_feedback_loop_state(struct zink_context *ctx, unsigned idx, unsigned feedback_loops)
2006 {
2007    if (feedback_loops != ctx->feedback_loops) {
2008       if (idx == PIPE_MAX_COLOR_BUFS && !zink_screen(ctx->base.screen)->driver_workarounds.always_feedback_loop_zs) {
2009          if (ctx->gfx_pipeline_state.feedback_loop_zs)
2010             ctx->gfx_pipeline_state.dirty = true;
2011          ctx->gfx_pipeline_state.feedback_loop_zs = false;
2012       } else if (idx < PIPE_MAX_COLOR_BUFS && !zink_screen(ctx->base.screen)->driver_workarounds.always_feedback_loop) {
2013          if (ctx->gfx_pipeline_state.feedback_loop)
2014             ctx->gfx_pipeline_state.dirty = true;
2015          ctx->gfx_pipeline_state.feedback_loop = false;
2016       }
2017       update_feedback_loop_dynamic_state(ctx);
2018    }
2019    ctx->feedback_loops = feedback_loops;
2020 }
2021 
2022 ALWAYS_INLINE static void
unbind_samplerview(struct zink_context * ctx,gl_shader_stage stage,unsigned slot)2023 unbind_samplerview(struct zink_context *ctx, gl_shader_stage stage, unsigned slot)
2024 {
2025    struct zink_sampler_view *sv = zink_sampler_view(ctx->sampler_views[stage][slot]);
2026    if (!sv || !sv->base.texture)
2027       return;
2028    struct zink_resource *res = zink_resource(sv->base.texture);
2029    res->sampler_bind_count[stage == MESA_SHADER_COMPUTE]--;
2030    if (stage != MESA_SHADER_COMPUTE && !res->sampler_bind_count[0] && res->fb_bind_count) {
2031       u_foreach_bit(idx, res->fb_binds) {
2032          if (ctx->feedback_loops & BITFIELD_BIT(idx)) {
2033             ctx->dynamic_fb.attachments[idx].imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2034             ctx->rp_layout_changed = true;
2035          }
2036          update_feedback_loop_state(ctx, idx, ctx->feedback_loops & ~BITFIELD_BIT(idx));
2037       }
2038    }
2039    update_res_bind_count(ctx, res, stage == MESA_SHADER_COMPUTE, true);
2040    res->sampler_binds[stage] &= ~BITFIELD_BIT(slot);
2041    if (res->obj->is_buffer) {
2042       unbind_buffer_descriptor_stage(res, stage);
2043       unbind_buffer_descriptor_reads(res, stage == MESA_SHADER_COMPUTE);
2044    } else {
2045       unbind_descriptor_stage(res, stage);
2046       unbind_descriptor_reads(res, stage == MESA_SHADER_COMPUTE);
2047       if (!res->sampler_bind_count[stage == MESA_SHADER_COMPUTE])
2048          check_for_layout_update(ctx, res, stage == MESA_SHADER_COMPUTE);
2049    }
2050    assert(slot < 32);
2051    ctx->di.zs_swizzle[stage].mask &= ~BITFIELD_BIT(slot);
2052 }
2053 
2054 static void
zink_set_sampler_views(struct pipe_context * pctx,gl_shader_stage shader_type,unsigned start_slot,unsigned num_views,unsigned unbind_num_trailing_slots,bool take_ownership,struct pipe_sampler_view ** views)2055 zink_set_sampler_views(struct pipe_context *pctx,
2056                        gl_shader_stage shader_type,
2057                        unsigned start_slot,
2058                        unsigned num_views,
2059                        unsigned unbind_num_trailing_slots,
2060                        bool take_ownership,
2061                        struct pipe_sampler_view **views)
2062 {
2063    struct zink_context *ctx = zink_context(pctx);
2064 
2065    const uint32_t mask = BITFIELD_RANGE(start_slot, num_views);
2066    uint32_t shadow_mask = ctx->di.zs_swizzle[shader_type].mask;
2067    ctx->di.cubes[shader_type] &= ~mask;
2068 
2069    bool update = false;
2070    bool shadow_update = false;
2071    if (views) {
2072       for (unsigned i = 0; i < num_views; ++i) {
2073          struct pipe_sampler_view *pview = views[i];
2074          struct zink_sampler_view *a = zink_sampler_view(ctx->sampler_views[shader_type][start_slot + i]);
2075          struct zink_sampler_view *b = zink_sampler_view(pview);
2076 
2077          if (a == b) {
2078             if (take_ownership) {
2079                struct pipe_sampler_view *view = views[i];
2080                pipe_sampler_view_reference(&view, NULL);
2081             }
2082             continue;
2083          }
2084 
2085          struct zink_resource *res = b ? zink_resource(b->base.texture) : NULL;
2086          if (b && b->base.texture) {
2087             if (!a || zink_resource(a->base.texture) != res) {
2088                if (a)
2089                   unbind_samplerview(ctx, shader_type, start_slot + i);
2090                update_res_bind_count(ctx, res, shader_type == MESA_SHADER_COMPUTE, false);
2091                res->sampler_bind_count[shader_type == MESA_SHADER_COMPUTE]++;
2092                res->gfx_barrier |= zink_pipeline_flags_from_pipe_stage(shader_type);
2093                res->barrier_access[shader_type == MESA_SHADER_COMPUTE] |= VK_ACCESS_SHADER_READ_BIT;
2094             }
2095             if (res->base.b.target == PIPE_BUFFER) {
2096                if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
2097                   if (!a || a->base.texture != b->base.texture || zink_resource(a->base.texture)->obj != res->obj ||
2098                      memcmp(&a->base.u.buf, &b->base.u.buf, sizeof(b->base.u.buf)))
2099                      update = true;
2100                } else if (b->buffer_view->bvci.buffer != res->obj->buffer) {
2101                   /* if this resource has been rebound while it wasn't set here,
2102                   * its backing resource will have changed and thus we need to update
2103                   * the bufferview
2104                   */
2105                   VkBufferViewCreateInfo bvci = b->buffer_view->bvci;
2106                   bvci.buffer = res->obj->buffer;
2107                   struct zink_buffer_view *buffer_view = get_buffer_view(ctx, res, &bvci);
2108                   assert(buffer_view != b->buffer_view);
2109                   zink_buffer_view_reference(zink_screen(ctx->base.screen), &b->buffer_view, NULL);
2110                   b->buffer_view = buffer_view;
2111                   update = true;
2112                } else if (!a || a->buffer_view->buffer_view != b->buffer_view->buffer_view)
2113                      update = true;
2114                zink_screen(ctx->base.screen)->buffer_barrier(ctx, res, VK_ACCESS_SHADER_READ_BIT,
2115                                           res->gfx_barrier);
2116                zink_batch_resource_usage_set(&ctx->batch, res, false, true);
2117                if (!ctx->unordered_blitting)
2118                   res->obj->unordered_read = false;
2119             } else {
2120                if (zink_format_needs_mutable(res->base.b.format, b->image_view->base.format))
2121                   /* mutable not set by default */
2122                   zink_resource_object_init_mutable(ctx, res);
2123                if (res->obj != b->image_view->obj) {
2124                   struct pipe_surface *psurf = &b->image_view->base;
2125                   VkImageView iv = b->image_view->image_view;
2126                   zink_rebind_surface(ctx, &psurf);
2127                   b->image_view = zink_surface(psurf);
2128                   update |= iv != b->image_view->image_view;
2129                } else  if (a != b)
2130                   update = true;
2131                if (shader_type == MESA_SHADER_COMPUTE)
2132                   flush_pending_clears(ctx, res);
2133                if (b->cube_array) {
2134                   ctx->di.cubes[shader_type] |= BITFIELD_BIT(start_slot + i);
2135                }
2136                if (!check_for_layout_update(ctx, res, shader_type == MESA_SHADER_COMPUTE) && !ctx->unordered_blitting) {
2137                   /* no deferred barrier: unset unordered usage immediately */
2138                   res->obj->unordered_read = false;
2139                   // TODO: figure out a way to link up layouts between unordered and main cmdbuf
2140                   res->obj->unordered_write = false;
2141                }
2142                if (!a)
2143                   update = true;
2144                zink_batch_resource_usage_set(&ctx->batch, res, false, false);
2145                if (b->zs_view) {
2146                   assert(start_slot + i < 32); //bitfield size
2147                   ctx->di.zs_swizzle[shader_type].mask |= BITFIELD_BIT(start_slot + i);
2148                   /* this is already gonna be slow, so don't bother trying to micro-optimize */
2149                   shadow_update |= memcmp(&ctx->di.zs_swizzle[shader_type].swizzle[start_slot + i],
2150                                           &b->swizzle, sizeof(struct zink_zs_swizzle));
2151                   memcpy(&ctx->di.zs_swizzle[shader_type].swizzle[start_slot + i], &b->swizzle, sizeof(struct zink_zs_swizzle));
2152                } else {
2153                   assert(start_slot + i < 32); //bitfield size
2154                   ctx->di.zs_swizzle[shader_type].mask &= ~BITFIELD_BIT(start_slot + i);
2155                }
2156             }
2157             res->sampler_binds[shader_type] |= BITFIELD_BIT(start_slot + i);
2158          } else if (a) {
2159             unbind_samplerview(ctx, shader_type, start_slot + i);
2160             update = true;
2161          }
2162          if (take_ownership) {
2163             pipe_sampler_view_reference(&ctx->sampler_views[shader_type][start_slot + i], NULL);
2164             ctx->sampler_views[shader_type][start_slot + i] = pview;
2165          } else {
2166             pipe_sampler_view_reference(&ctx->sampler_views[shader_type][start_slot + i], pview);
2167          }
2168          update_descriptor_state_sampler(ctx, shader_type, start_slot + i, res);
2169       }
2170    } else {
2171       unbind_num_trailing_slots += num_views;
2172       num_views = 0;
2173    }
2174    for (unsigned i = 0; i < unbind_num_trailing_slots; ++i) {
2175       unsigned slot = start_slot + num_views + i;
2176       update |= !!ctx->sampler_views[shader_type][slot];
2177       unbind_samplerview(ctx, shader_type, slot);
2178       pipe_sampler_view_reference(
2179          &ctx->sampler_views[shader_type][slot],
2180          NULL);
2181       update_descriptor_state_sampler(ctx, shader_type, slot, NULL);
2182    }
2183    ctx->di.num_sampler_views[shader_type] = start_slot + num_views;
2184    if (update) {
2185       struct zink_screen *screen = zink_screen(pctx->screen);
2186       ctx->invalidate_descriptor_state(ctx, shader_type, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot, num_views);
2187       if (!screen->info.have_EXT_non_seamless_cube_map)
2188          update_nonseamless_shader_key(ctx, shader_type);
2189       shadow_update |= shadow_mask != ctx->di.zs_swizzle[shader_type].mask;
2190       zink_set_zs_needs_shader_swizzle_key(ctx, shader_type, shadow_update);
2191    }
2192 }
2193 
2194 static uint64_t
zink_create_texture_handle(struct pipe_context * pctx,struct pipe_sampler_view * view,const struct pipe_sampler_state * state)2195 zink_create_texture_handle(struct pipe_context *pctx, struct pipe_sampler_view *view, const struct pipe_sampler_state *state)
2196 {
2197    struct zink_context *ctx = zink_context(pctx);
2198    struct zink_resource *res = zink_resource(view->texture);
2199    struct zink_sampler_view *sv = zink_sampler_view(view);
2200    struct zink_bindless_descriptor *bd;
2201    bd = calloc(1, sizeof(struct zink_bindless_descriptor));
2202    if (!bd)
2203       return 0;
2204 
2205    bd->sampler = pctx->create_sampler_state(pctx, state);
2206    if (!bd->sampler) {
2207       free(bd);
2208       return 0;
2209    }
2210 
2211    bd->ds.is_buffer = res->base.b.target == PIPE_BUFFER;
2212    if (res->base.b.target == PIPE_BUFFER) {
2213       if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
2214          pipe_resource_reference(&bd->ds.db.pres, view->texture);
2215          bd->ds.db.format = view->format;
2216          bd->ds.db.offset = view->u.buf.offset;
2217          bd->ds.db.size = view->u.buf.size;
2218       } else {
2219          zink_buffer_view_reference(zink_screen(pctx->screen), &bd->ds.bufferview, sv->buffer_view);
2220       }
2221    } else {
2222       zink_surface_reference(zink_screen(pctx->screen), &bd->ds.surface, sv->image_view);
2223    }
2224    uint64_t handle = util_idalloc_alloc(&ctx->di.bindless[bd->ds.is_buffer].tex_slots);
2225    if (bd->ds.is_buffer)
2226       handle += ZINK_MAX_BINDLESS_HANDLES;
2227    bd->handle = handle;
2228    _mesa_hash_table_insert(&ctx->di.bindless[bd->ds.is_buffer].tex_handles, (void*)(uintptr_t)handle, bd);
2229    return handle;
2230 }
2231 
2232 static void
zink_delete_texture_handle(struct pipe_context * pctx,uint64_t handle)2233 zink_delete_texture_handle(struct pipe_context *pctx, uint64_t handle)
2234 {
2235    struct zink_context *ctx = zink_context(pctx);
2236    bool is_buffer = ZINK_BINDLESS_IS_BUFFER(handle);
2237    struct hash_entry *he = _mesa_hash_table_search(&ctx->di.bindless[is_buffer].tex_handles, (void*)(uintptr_t)handle);
2238    assert(he);
2239    struct zink_bindless_descriptor *bd = he->data;
2240    struct zink_descriptor_surface *ds = &bd->ds;
2241    _mesa_hash_table_remove(&ctx->di.bindless[is_buffer].tex_handles, he);
2242    uint32_t h = handle;
2243    util_dynarray_append(&ctx->batch.state->bindless_releases[0], uint32_t, h);
2244 
2245    if (ds->is_buffer) {
2246       if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
2247          pipe_resource_reference(&ds->db.pres, NULL);
2248       } else {
2249          zink_buffer_view_reference(zink_screen(pctx->screen), &ds->bufferview, NULL);
2250       }
2251    } else {
2252       zink_surface_reference(zink_screen(pctx->screen), &ds->surface, NULL);
2253       pctx->delete_sampler_state(pctx, bd->sampler);
2254    }
2255    free(ds);
2256 }
2257 
2258 static void
rebind_bindless_bufferview(struct zink_context * ctx,struct zink_resource * res,struct zink_descriptor_surface * ds)2259 rebind_bindless_bufferview(struct zink_context *ctx, struct zink_resource *res, struct zink_descriptor_surface *ds)
2260 {
2261    /* descriptor buffer is unaffected by this */
2262    if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB)
2263       return;
2264    /* if this resource has been rebound while it wasn't set here,
2265     * its backing resource will have changed and thus we need to update
2266     * the bufferview
2267     */
2268    VkBufferViewCreateInfo bvci = ds->bufferview->bvci;
2269    bvci.buffer = res->obj->buffer;
2270    struct zink_buffer_view *buffer_view = get_buffer_view(ctx, res, &bvci);
2271    assert(buffer_view != ds->bufferview);
2272    zink_buffer_view_reference(zink_screen(ctx->base.screen), &ds->bufferview, NULL);
2273    ds->bufferview = buffer_view;
2274 }
2275 
2276 static void
zero_bindless_descriptor(struct zink_context * ctx,uint32_t handle,bool is_buffer,bool is_image)2277 zero_bindless_descriptor(struct zink_context *ctx, uint32_t handle, bool is_buffer, bool is_image)
2278 {
2279    if (likely(zink_screen(ctx->base.screen)->info.rb2_feats.nullDescriptor)) {
2280       if (is_buffer) {
2281          if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
2282             ctx->di.bindless[is_image].db.buffer_infos[handle].address = 0;
2283             ctx->di.bindless[is_image].db.buffer_infos[handle].range = 0;
2284          } else {
2285             VkBufferView *bv = &ctx->di.bindless[is_image].t.buffer_infos[handle];
2286             *bv = VK_NULL_HANDLE;
2287          }
2288       } else {
2289          VkDescriptorImageInfo *ii = &ctx->di.bindless[is_image].img_infos[handle];
2290          memset(ii, 0, sizeof(*ii));
2291       }
2292    } else {
2293       if (is_buffer) {
2294          if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
2295             ctx->di.bindless[is_image].db.buffer_infos[handle].address = zink_resource(ctx->dummy_bufferview->pres)->obj->bda;
2296             ctx->di.bindless[is_image].db.buffer_infos[handle].range = 1;
2297          } else {
2298             VkBufferView *bv = &ctx->di.bindless[is_image].t.buffer_infos[handle];
2299             struct zink_buffer_view *null_bufferview = ctx->dummy_bufferview;
2300             *bv = null_bufferview->buffer_view;
2301          }
2302       } else {
2303          struct zink_surface *null_surface = zink_get_dummy_surface(ctx, 0);
2304          VkDescriptorImageInfo *ii = &ctx->di.bindless[is_image].img_infos[handle];
2305          ii->sampler = VK_NULL_HANDLE;
2306          ii->imageView = null_surface->image_view;
2307          ii->imageLayout = VK_IMAGE_LAYOUT_GENERAL;
2308       }
2309    }
2310 }
2311 
2312 static void
unbind_bindless_descriptor(struct zink_context * ctx,struct zink_resource * res)2313 unbind_bindless_descriptor(struct zink_context *ctx, struct zink_resource *res)
2314 {
2315    if (!res->bindless[1]) {
2316       /* check to remove write access */
2317       for (unsigned i = 0; i < 2; i++) {
2318          if (!res->write_bind_count[i])
2319             res->barrier_access[i] &= ~VK_ACCESS_SHADER_WRITE_BIT;
2320       }
2321    }
2322    bool is_buffer = res->base.b.target == PIPE_BUFFER;
2323    if (!res->all_bindless) {
2324       /* check to remove read access */
2325       if (is_buffer) {
2326          for (unsigned i = 0; i < 2; i++)
2327             unbind_buffer_descriptor_reads(res, i);
2328       } else {
2329          for (unsigned i = 0; i < 2; i++)
2330             unbind_descriptor_reads(res, i);
2331       }
2332    }
2333    for (unsigned i = 0; i < 2; i++) {
2334       if (!res->image_bind_count[i])
2335          check_for_layout_update(ctx, res, i);
2336    }
2337 }
2338 
2339 static void
zink_make_texture_handle_resident(struct pipe_context * pctx,uint64_t handle,bool resident)2340 zink_make_texture_handle_resident(struct pipe_context *pctx, uint64_t handle, bool resident)
2341 {
2342    struct zink_context *ctx = zink_context(pctx);
2343    bool is_buffer = ZINK_BINDLESS_IS_BUFFER(handle);
2344    struct hash_entry *he = _mesa_hash_table_search(&ctx->di.bindless[is_buffer].tex_handles, (void*)(uintptr_t)handle);
2345    assert(he);
2346    struct zink_bindless_descriptor *bd = he->data;
2347    struct zink_descriptor_surface *ds = &bd->ds;
2348    struct zink_resource *res = zink_descriptor_surface_resource(ds);
2349    if (is_buffer)
2350       handle -= ZINK_MAX_BINDLESS_HANDLES;
2351    if (resident) {
2352       update_res_bind_count(ctx, res, false, false);
2353       update_res_bind_count(ctx, res, true, false);
2354       res->bindless[0]++;
2355       if (is_buffer) {
2356          if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
2357             ctx->di.bindless[0].db.buffer_infos[handle].address = res->obj->bda + ds->db.offset;
2358             ctx->di.bindless[0].db.buffer_infos[handle].range = ds->db.size;
2359             ctx->di.bindless[0].db.buffer_infos[handle].format = zink_get_format(zink_screen(ctx->base.screen), ds->db.format);
2360          } else {
2361             if (ds->bufferview->bvci.buffer != res->obj->buffer)
2362                rebind_bindless_bufferview(ctx, res, ds);
2363             VkBufferView *bv = &ctx->di.bindless[0].t.buffer_infos[handle];
2364             *bv = ds->bufferview->buffer_view;
2365          }
2366          zink_screen(ctx->base.screen)->buffer_barrier(ctx, res, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
2367          zink_batch_resource_usage_set(&ctx->batch, res, false, true);
2368          res->obj->unordered_read = false;
2369       } else {
2370          VkDescriptorImageInfo *ii = &ctx->di.bindless[0].img_infos[handle];
2371          ii->sampler = bd->sampler->sampler;
2372          ii->imageView = ds->surface->image_view;
2373          ii->imageLayout = zink_descriptor_util_image_layout_eval(ctx, res, false);
2374          flush_pending_clears(ctx, res);
2375          if (!check_for_layout_update(ctx, res, false)) {
2376             res->obj->unordered_read = false;
2377             // TODO: figure out a way to link up layouts between unordered and main cmdbuf
2378             res->obj->unordered_write = false;
2379          }
2380          if (!check_for_layout_update(ctx, res, true)) {
2381             res->obj->unordered_read = false;
2382             // TODO: figure out a way to link up layouts between unordered and main cmdbuf
2383             res->obj->unordered_write = false;
2384          }
2385          zink_batch_resource_usage_set(&ctx->batch, res, false, false);
2386          res->obj->unordered_write = false;
2387       }
2388       res->gfx_barrier |= VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
2389       res->barrier_access[0] |= VK_ACCESS_SHADER_READ_BIT;
2390       res->barrier_access[1] |= VK_ACCESS_SHADER_READ_BIT;
2391       util_dynarray_append(&ctx->di.bindless[0].resident, struct zink_bindless_descriptor *, bd);
2392       uint32_t h = is_buffer ? handle + ZINK_MAX_BINDLESS_HANDLES : handle;
2393       util_dynarray_append(&ctx->di.bindless[0].updates, uint32_t, h);
2394    } else {
2395       zero_bindless_descriptor(ctx, handle, is_buffer, false);
2396       util_dynarray_delete_unordered(&ctx->di.bindless[0].resident, struct zink_bindless_descriptor *, bd);
2397       update_res_bind_count(ctx, res, false, true);
2398       update_res_bind_count(ctx, res, true, true);
2399       res->bindless[0]--;
2400       unbind_bindless_descriptor(ctx, res);
2401    }
2402    ctx->di.bindless_dirty[0] = true;
2403 }
2404 
2405 static uint64_t
zink_create_image_handle(struct pipe_context * pctx,const struct pipe_image_view * view)2406 zink_create_image_handle(struct pipe_context *pctx, const struct pipe_image_view *view)
2407 {
2408    struct zink_context *ctx = zink_context(pctx);
2409    struct zink_resource *res = zink_resource(view->resource);
2410    struct zink_bindless_descriptor *bd;
2411    if (!zink_resource_object_init_storage(ctx, res)) {
2412       debug_printf("couldn't create storage image!");
2413       return 0;
2414    }
2415    bd = calloc(1, sizeof(struct zink_bindless_descriptor));
2416    if (!bd)
2417       return 0;
2418    bd->sampler = NULL;
2419 
2420    bd->ds.is_buffer = res->base.b.target == PIPE_BUFFER;
2421    if (res->base.b.target == PIPE_BUFFER)
2422       if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
2423          pipe_resource_reference(&bd->ds.db.pres, view->resource);
2424          bd->ds.db.format = view->format;
2425          bd->ds.db.offset = view->u.buf.offset;
2426          bd->ds.db.size = view->u.buf.size;
2427       } else {
2428          bd->ds.bufferview = create_image_bufferview(ctx, view);
2429       }
2430    else
2431       bd->ds.surface = create_image_surface(ctx, view, false);
2432    uint64_t handle = util_idalloc_alloc(&ctx->di.bindless[bd->ds.is_buffer].img_slots);
2433    if (bd->ds.is_buffer)
2434       handle += ZINK_MAX_BINDLESS_HANDLES;
2435    bd->handle = handle;
2436    _mesa_hash_table_insert(&ctx->di.bindless[bd->ds.is_buffer].img_handles, (void*)(uintptr_t)handle, bd);
2437    return handle;
2438 }
2439 
2440 static void
zink_delete_image_handle(struct pipe_context * pctx,uint64_t handle)2441 zink_delete_image_handle(struct pipe_context *pctx, uint64_t handle)
2442 {
2443    struct zink_context *ctx = zink_context(pctx);
2444    bool is_buffer = ZINK_BINDLESS_IS_BUFFER(handle);
2445    struct hash_entry *he = _mesa_hash_table_search(&ctx->di.bindless[is_buffer].img_handles, (void*)(uintptr_t)handle);
2446    assert(he);
2447    struct zink_descriptor_surface *ds = he->data;
2448    _mesa_hash_table_remove(&ctx->di.bindless[is_buffer].img_handles, he);
2449    uint32_t h = handle;
2450    util_dynarray_append(&ctx->batch.state->bindless_releases[1], uint32_t, h);
2451 
2452    if (ds->is_buffer) {
2453       if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
2454          pipe_resource_reference(&ds->db.pres, NULL);
2455       } else {
2456          zink_buffer_view_reference(zink_screen(pctx->screen), &ds->bufferview, NULL);
2457       }
2458    } else {
2459       zink_surface_reference(zink_screen(pctx->screen), &ds->surface, NULL);
2460    }
2461    free(ds);
2462 }
2463 
2464 static void
zink_make_image_handle_resident(struct pipe_context * pctx,uint64_t handle,unsigned paccess,bool resident)2465 zink_make_image_handle_resident(struct pipe_context *pctx, uint64_t handle, unsigned paccess, bool resident)
2466 {
2467    struct zink_context *ctx = zink_context(pctx);
2468    bool is_buffer = ZINK_BINDLESS_IS_BUFFER(handle);
2469    struct hash_entry *he = _mesa_hash_table_search(&ctx->di.bindless[is_buffer].img_handles, (void*)(uintptr_t)handle);
2470    assert(he);
2471    struct zink_bindless_descriptor *bd = he->data;
2472    struct zink_descriptor_surface *ds = &bd->ds;
2473    bd->access = paccess;
2474    struct zink_resource *res = zink_descriptor_surface_resource(ds);
2475    VkAccessFlags access = 0;
2476    if (paccess & PIPE_IMAGE_ACCESS_WRITE) {
2477       if (resident) {
2478          res->write_bind_count[0]++;
2479          res->write_bind_count[1]++;
2480       } else {
2481          res->write_bind_count[0]--;
2482          res->write_bind_count[1]--;
2483       }
2484       access |= VK_ACCESS_SHADER_WRITE_BIT;
2485    }
2486    if (paccess & PIPE_IMAGE_ACCESS_READ) {
2487       access |= VK_ACCESS_SHADER_READ_BIT;
2488    }
2489    if (is_buffer)
2490       handle -= ZINK_MAX_BINDLESS_HANDLES;
2491    if (resident) {
2492       update_res_bind_count(ctx, res, false, false);
2493       update_res_bind_count(ctx, res, true, false);
2494       res->image_bind_count[0]++;
2495       res->image_bind_count[1]++;
2496       res->bindless[1]++;
2497       if (is_buffer) {
2498          if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
2499             ctx->di.bindless[0].db.buffer_infos[handle].address = res->obj->bda + ds->db.offset;
2500             ctx->di.bindless[0].db.buffer_infos[handle].range = ds->db.size;
2501             ctx->di.bindless[0].db.buffer_infos[handle].format = zink_get_format(zink_screen(ctx->base.screen), ds->db.format);
2502          } else {
2503             if (ds->bufferview->bvci.buffer != res->obj->buffer)
2504                rebind_bindless_bufferview(ctx, res, ds);
2505             VkBufferView *bv = &ctx->di.bindless[1].t.buffer_infos[handle];
2506             *bv = ds->bufferview->buffer_view;
2507          }
2508          zink_screen(ctx->base.screen)->buffer_barrier(ctx, res, access, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
2509          zink_batch_resource_usage_set(&ctx->batch, res, zink_resource_access_is_write(access), true);
2510          if (zink_resource_access_is_write(access))
2511             res->obj->unordered_write = false;
2512          res->obj->unordered_read = false;
2513       } else {
2514          VkDescriptorImageInfo *ii = &ctx->di.bindless[1].img_infos[handle];
2515          ii->sampler = VK_NULL_HANDLE;
2516          ii->imageView = ds->surface->image_view;
2517          ii->imageLayout = VK_IMAGE_LAYOUT_GENERAL;
2518          finalize_image_bind(ctx, res, false);
2519          finalize_image_bind(ctx, res, true);
2520          zink_batch_resource_usage_set(&ctx->batch, res, zink_resource_access_is_write(access), false);
2521          res->obj->unordered_write = false;
2522       }
2523       res->gfx_barrier |= VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
2524       res->barrier_access[0] |= access;
2525       res->barrier_access[1] |= access;
2526       util_dynarray_append(&ctx->di.bindless[1].resident, struct zink_bindless_descriptor *, bd);
2527       uint32_t h = is_buffer ? handle + ZINK_MAX_BINDLESS_HANDLES : handle;
2528       util_dynarray_append(&ctx->di.bindless[1].updates, uint32_t, h);
2529    } else {
2530       zero_bindless_descriptor(ctx, handle, is_buffer, true);
2531       util_dynarray_delete_unordered(&ctx->di.bindless[1].resident, struct zink_bindless_descriptor *, bd);
2532       unbind_shader_image_counts(ctx, res, false, false);
2533       unbind_shader_image_counts(ctx, res, true, false);
2534       res->bindless[1]--;
2535       unbind_bindless_descriptor(ctx, res);
2536    }
2537    ctx->di.bindless_dirty[1] = true;
2538 }
2539 
2540 static void
zink_set_global_binding(struct pipe_context * pctx,unsigned first,unsigned count,struct pipe_resource ** resources,uint32_t ** handles)2541 zink_set_global_binding(struct pipe_context *pctx,
2542                         unsigned first, unsigned count,
2543                         struct pipe_resource **resources,
2544                         uint32_t **handles)
2545 {
2546    struct zink_context *ctx = zink_context(pctx);
2547 
2548    size_t size = ctx->di.global_bindings.capacity;
2549    if (!util_dynarray_resize(&ctx->di.global_bindings, struct pipe_resource*, first + count + 8))
2550       unreachable("zink: out of memory somehow");
2551    if (size != ctx->di.global_bindings.capacity) {
2552       uint8_t *data = ctx->di.global_bindings.data;
2553       memset(data + size, 0, ctx->di.global_bindings.capacity - size);
2554    }
2555 
2556    struct pipe_resource **globals = ctx->di.global_bindings.data;
2557    for (unsigned i = 0; i < count; i++) {
2558       if (resources && resources[i]) {
2559          struct zink_resource *res = zink_resource(resources[i]);
2560 
2561          util_range_add(&res->base.b, &res->valid_buffer_range, 0, res->base.b.width0);
2562          pipe_resource_reference(&globals[first + i], resources[i]);
2563 
2564          uint64_t addr = 0;
2565          memcpy(&addr, handles[i], sizeof(addr));
2566          addr += zink_resource_get_address(zink_screen(pctx->screen), res);
2567          memcpy(handles[i], &addr, sizeof(addr));
2568          zink_resource_usage_set(res, ctx->batch.state, true);
2569          res->obj->unordered_read = res->obj->unordered_write = false;
2570          zink_screen(ctx->base.screen)->buffer_barrier(ctx, res, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
2571       } else if (globals[i]) {
2572          zink_batch_reference_resource(&ctx->batch, zink_resource(globals[first + i]));
2573          pipe_resource_reference(&globals[first + i], NULL);
2574       }
2575    }
2576 }
2577 
2578 static void
zink_set_stencil_ref(struct pipe_context * pctx,const struct pipe_stencil_ref ref)2579 zink_set_stencil_ref(struct pipe_context *pctx,
2580                      const struct pipe_stencil_ref ref)
2581 {
2582    struct zink_context *ctx = zink_context(pctx);
2583    ctx->stencil_ref = ref;
2584    ctx->stencil_ref_changed = true;
2585 }
2586 
2587 static void
zink_set_clip_state(struct pipe_context * pctx,const struct pipe_clip_state * pcs)2588 zink_set_clip_state(struct pipe_context *pctx,
2589                     const struct pipe_clip_state *pcs)
2590 {
2591 }
2592 
2593 static void
zink_set_tess_state(struct pipe_context * pctx,const float default_outer_level[4],const float default_inner_level[2])2594 zink_set_tess_state(struct pipe_context *pctx,
2595                     const float default_outer_level[4],
2596                     const float default_inner_level[2])
2597 {
2598    struct zink_context *ctx = zink_context(pctx);
2599    memcpy(&ctx->default_inner_level, default_inner_level, sizeof(ctx->default_inner_level));
2600    memcpy(&ctx->default_outer_level, default_outer_level, sizeof(ctx->default_outer_level));
2601 }
2602 
2603 static void
zink_set_patch_vertices(struct pipe_context * pctx,uint8_t patch_vertices)2604 zink_set_patch_vertices(struct pipe_context *pctx, uint8_t patch_vertices)
2605 {
2606    struct zink_context *ctx = zink_context(pctx);
2607    if (zink_set_tcs_key_patches(ctx, patch_vertices)) {
2608       ctx->gfx_pipeline_state.dyn_state2.vertices_per_patch = patch_vertices;
2609       if (zink_screen(ctx->base.screen)->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints)
2610          VKCTX(CmdSetPatchControlPointsEXT)(ctx->batch.state->cmdbuf, patch_vertices);
2611       else
2612          ctx->gfx_pipeline_state.dirty = true;
2613       zink_flush_dgc_if_enabled(ctx);
2614    }
2615 }
2616 
2617 static void
init_null_fbfetch(struct zink_context * ctx)2618 init_null_fbfetch(struct zink_context *ctx)
2619 {
2620    struct zink_screen *screen = zink_screen(ctx->base.screen);
2621    ctx->di.null_fbfetch_init = true;
2622    if (zink_descriptor_mode != ZINK_DESCRIPTOR_MODE_DB)
2623       return;
2624    VkDescriptorGetInfoEXT info;
2625    info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_GET_INFO_EXT;
2626    info.pNext = NULL;
2627    info.type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
2628    info.data.pInputAttachmentImage = &ctx->di.fbfetch;
2629    if (screen->info.db_props.inputAttachmentDescriptorSize)
2630       VKSCR(GetDescriptorEXT)(screen->dev, &info, screen->info.db_props.inputAttachmentDescriptorSize, ctx->di.fbfetch_db);
2631 }
2632 
2633 bool
zink_update_fbfetch(struct zink_context * ctx)2634 zink_update_fbfetch(struct zink_context *ctx)
2635 {
2636    const bool had_fbfetch = ctx->di.fbfetch.imageLayout == VK_IMAGE_LAYOUT_GENERAL;
2637    if (!ctx->gfx_stages[MESA_SHADER_FRAGMENT] ||
2638        !ctx->gfx_stages[MESA_SHADER_FRAGMENT]->info.fs.uses_fbfetch_output) {
2639       if (!had_fbfetch)
2640          return false;
2641       zink_batch_no_rp(ctx);
2642       ctx->di.fbfetch.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2643       ctx->di.fbfetch.imageView = zink_screen(ctx->base.screen)->info.rb2_feats.nullDescriptor ?
2644                                   VK_NULL_HANDLE :
2645                                   zink_get_dummy_surface(ctx, 0)->image_view;
2646       ctx->invalidate_descriptor_state(ctx, MESA_SHADER_FRAGMENT, ZINK_DESCRIPTOR_TYPE_UBO, 0, 1);
2647       return true;
2648    }
2649 
2650    bool changed = !had_fbfetch;
2651    if (ctx->fb_state.cbufs[0]) {
2652       VkImageView fbfetch = zink_csurface(ctx->fb_state.cbufs[0])->image_view;
2653       if (!fbfetch)
2654          /* swapchain image: retry later */
2655          return false;
2656       changed |= fbfetch != ctx->di.fbfetch.imageView;
2657       ctx->di.fbfetch.imageView = zink_csurface(ctx->fb_state.cbufs[0])->image_view;
2658 
2659       bool fbfetch_ms = ctx->fb_state.cbufs[0]->texture->nr_samples > 1;
2660       if (zink_get_fs_base_key(ctx)->fbfetch_ms != fbfetch_ms)
2661          zink_set_fs_base_key(ctx)->fbfetch_ms = fbfetch_ms;
2662    } else {
2663       ctx->di.fbfetch.imageView = zink_screen(ctx->base.screen)->info.rb2_feats.nullDescriptor ?
2664                                   VK_NULL_HANDLE :
2665                                   zink_get_dummy_surface(ctx, 0)->image_view;
2666    }
2667    bool ret = false;
2668    ctx->di.fbfetch.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
2669    if (changed) {
2670       ctx->invalidate_descriptor_state(ctx, MESA_SHADER_FRAGMENT, ZINK_DESCRIPTOR_TYPE_UBO, 0, 1);
2671       if (!had_fbfetch) {
2672          ret = true;
2673          zink_batch_no_rp(ctx);
2674       }
2675    }
2676    return ret;
2677 }
2678 
2679 void
zink_update_vk_sample_locations(struct zink_context * ctx)2680 zink_update_vk_sample_locations(struct zink_context *ctx)
2681 {
2682    if (ctx->gfx_pipeline_state.sample_locations_enabled && ctx->sample_locations_changed) {
2683       unsigned samples = ctx->gfx_pipeline_state.rast_samples + 1;
2684       unsigned idx = util_logbase2_ceil(MAX2(samples, 1));
2685       VkExtent2D grid_size = zink_screen(ctx->base.screen)->maxSampleLocationGridSize[idx];
2686 
2687       for (unsigned pixel = 0; pixel < grid_size.width * grid_size.height; pixel++) {
2688          for (unsigned sample = 0; sample < samples; sample++) {
2689             unsigned pixel_x = pixel % grid_size.width;
2690             unsigned pixel_y = pixel / grid_size.width;
2691             unsigned wi = pixel * samples + sample;
2692             unsigned ri = (pixel_y * grid_size.width + pixel_x % grid_size.width);
2693             ri = ri * samples + sample;
2694             ctx->vk_sample_locations[wi].x = (ctx->sample_locations[ri] & 0xf) / 16.0f;
2695             ctx->vk_sample_locations[wi].y = (16 - (ctx->sample_locations[ri] >> 4)) / 16.0f;
2696          }
2697       }
2698    }
2699 }
2700 
2701 static unsigned
find_rp_state(struct zink_context * ctx)2702 find_rp_state(struct zink_context *ctx)
2703 {
2704    bool found = false;
2705    /* calc the state idx using the samples to account for msrtss */
2706    unsigned idx = zink_screen(ctx->base.screen)->info.have_EXT_multisampled_render_to_single_sampled && ctx->transient_attachments ?
2707                   util_logbase2_ceil(ctx->gfx_pipeline_state.rast_samples + 1) : 0;
2708    struct set_entry *he = _mesa_set_search_or_add(&ctx->rendering_state_cache[idx], &ctx->gfx_pipeline_state.rendering_info, &found);
2709    struct zink_rendering_info *info;
2710    if (found) {
2711       info = (void*)he->key;
2712       return info->id;
2713    }
2714    info = ralloc(ctx, struct zink_rendering_info);
2715    memcpy(info, &ctx->gfx_pipeline_state.rendering_info, sizeof(VkPipelineRenderingCreateInfo));
2716    info->id = ctx->rendering_state_cache[idx].entries;
2717    he->key = info;
2718    return info->id;
2719 }
2720 
2721 unsigned
zink_update_rendering_info(struct zink_context * ctx)2722 zink_update_rendering_info(struct zink_context *ctx)
2723 {
2724    for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
2725       struct zink_surface *surf = zink_csurface(ctx->fb_state.cbufs[i]);
2726       ctx->gfx_pipeline_state.rendering_formats[i] = surf ? surf->info.format[0] : VK_FORMAT_UNDEFINED;
2727    }
2728    ctx->gfx_pipeline_state.rendering_info.depthAttachmentFormat = VK_FORMAT_UNDEFINED;
2729    ctx->gfx_pipeline_state.rendering_info.stencilAttachmentFormat = VK_FORMAT_UNDEFINED;
2730    if (ctx->fb_state.zsbuf && zink_is_zsbuf_used(ctx)) {
2731       struct zink_surface *surf = zink_csurface(ctx->fb_state.zsbuf);
2732       bool has_depth = util_format_has_depth(util_format_description(ctx->fb_state.zsbuf->format));
2733       bool has_stencil = util_format_has_stencil(util_format_description(ctx->fb_state.zsbuf->format));
2734 
2735       if (has_depth)
2736          ctx->gfx_pipeline_state.rendering_info.depthAttachmentFormat = surf->info.format[0];
2737       if (has_stencil)
2738          ctx->gfx_pipeline_state.rendering_info.stencilAttachmentFormat = surf->info.format[0];
2739    }
2740    return find_rp_state(ctx);
2741 }
2742 
2743 static unsigned
calc_max_dummy_fbo_size(struct zink_context * ctx)2744 calc_max_dummy_fbo_size(struct zink_context *ctx)
2745 {
2746    unsigned size = MAX2(ctx->fb_state.width, ctx->fb_state.height);
2747    return size ? size : MIN2(256, zink_screen(ctx->base.screen)->info.props.limits.maxImageDimension2D);
2748 }
2749 
2750 static unsigned
begin_rendering(struct zink_context * ctx)2751 begin_rendering(struct zink_context *ctx)
2752 {
2753    unsigned clear_buffers = 0;
2754    ctx->gfx_pipeline_state.render_pass = NULL;
2755    zink_update_vk_sample_locations(ctx);
2756    bool has_swapchain = zink_render_update_swapchain(ctx);
2757    if (has_swapchain)
2758       zink_render_fixup_swapchain(ctx);
2759    bool has_depth = false;
2760    bool has_stencil = false;
2761    bool changed_layout = false;
2762    bool changed_size = false;
2763    bool zsbuf_used = zink_is_zsbuf_used(ctx);
2764    bool use_tc_info = !ctx->blitting && ctx->track_renderpasses;
2765    if (ctx->rp_changed || ctx->rp_layout_changed || (!ctx->batch.in_rp && ctx->rp_loadop_changed)) {
2766       /* init imageviews, base loadOp, formats */
2767       for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
2768          struct zink_surface *surf = zink_csurface(ctx->fb_state.cbufs[i]);
2769          if (!surf)
2770             continue;
2771 
2772          if (!zink_resource(surf->base.texture)->valid)
2773             ctx->dynamic_fb.attachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
2774          else
2775             ctx->dynamic_fb.attachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
2776          if (use_tc_info) {
2777             if (ctx->dynamic_fb.tc_info.cbuf_invalidate & BITFIELD_BIT(i))
2778                ctx->dynamic_fb.attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
2779             else
2780                ctx->dynamic_fb.attachments[i].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
2781          }
2782       }
2783 
2784       /* unset depth and stencil info: reset below */
2785       VkImageLayout zlayout = ctx->dynamic_fb.info.pDepthAttachment ? ctx->dynamic_fb.info.pDepthAttachment->imageLayout : VK_IMAGE_LAYOUT_UNDEFINED;
2786       VkImageLayout slayout = ctx->dynamic_fb.info.pStencilAttachment ? ctx->dynamic_fb.info.pStencilAttachment->imageLayout : VK_IMAGE_LAYOUT_UNDEFINED;
2787       ctx->dynamic_fb.info.pDepthAttachment = NULL;
2788       ctx->dynamic_fb.info.pStencilAttachment = NULL;
2789 
2790       if (ctx->fb_state.zsbuf && zsbuf_used) {
2791          struct zink_surface *surf = zink_csurface(ctx->fb_state.zsbuf);
2792          has_depth = util_format_has_depth(util_format_description(ctx->fb_state.zsbuf->format));
2793          has_stencil = util_format_has_stencil(util_format_description(ctx->fb_state.zsbuf->format));
2794 
2795          /* depth may or may not be used but init it anyway */
2796          if (zink_resource(surf->base.texture)->valid)
2797             ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
2798          else
2799             ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
2800 
2801          if (use_tc_info) {
2802             if (ctx->dynamic_fb.tc_info.zsbuf_invalidate)
2803                ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
2804             else
2805                ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
2806          }
2807 
2808          /* stencil may or may not be used but init it anyway */
2809          ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].loadOp = ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].loadOp;
2810          ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].storeOp = ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].storeOp;
2811 
2812          if (has_depth) {
2813             ctx->dynamic_fb.info.pDepthAttachment = &ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS];
2814             /* stencil info only set for clears below */
2815          }
2816          if (has_stencil) {
2817             /* must be stencil-only */
2818             ctx->dynamic_fb.info.pStencilAttachment = &ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS + 1];
2819          }
2820       } else {
2821          ctx->dynamic_fb.info.pDepthAttachment = NULL;
2822       }
2823       if (zlayout != (ctx->dynamic_fb.info.pDepthAttachment ? ctx->dynamic_fb.info.pDepthAttachment->imageLayout : VK_IMAGE_LAYOUT_UNDEFINED))
2824          changed_layout = true;
2825       if (slayout != (ctx->dynamic_fb.info.pStencilAttachment ? ctx->dynamic_fb.info.pStencilAttachment->imageLayout : VK_IMAGE_LAYOUT_UNDEFINED))
2826          changed_layout = true;
2827 
2828       /* similar to begin_render_pass(), but just filling in VkRenderingInfo */
2829       for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
2830          /* these are no-ops */
2831          if (!ctx->fb_state.cbufs[i] || !zink_fb_clear_enabled(ctx, i))
2832             continue;
2833          /* these need actual clear calls inside the rp */
2834          struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(&ctx->fb_clears[i], 0);
2835          if (zink_fb_clear_needs_explicit(&ctx->fb_clears[i])) {
2836             clear_buffers |= (PIPE_CLEAR_COLOR0 << i);
2837             if (zink_fb_clear_count(&ctx->fb_clears[i]) < 2 ||
2838                 zink_fb_clear_element_needs_explicit(clear))
2839                continue;
2840          }
2841          /* we now know there's one clear that can be done here */
2842          memcpy(&ctx->dynamic_fb.attachments[i].clearValue, &clear->color, sizeof(float) * 4);
2843          ctx->dynamic_fb.attachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
2844       }
2845       if (ctx->fb_state.zsbuf && zink_fb_clear_enabled(ctx, PIPE_MAX_COLOR_BUFS)) {
2846          struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[PIPE_MAX_COLOR_BUFS];
2847          struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(fb_clear, 0);
2848          if (!zink_fb_clear_element_needs_explicit(clear)) {
2849             /* base zs clear info */
2850             ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].clearValue.depthStencil.depth = clear->zs.depth;
2851             ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].clearValue.depthStencil.stencil = clear->zs.stencil;
2852             /* always init separate stencil attachment */
2853             ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].clearValue.depthStencil.stencil = clear->zs.stencil;
2854             if ((zink_fb_clear_element(fb_clear, 0)->zs.bits & PIPE_CLEAR_DEPTH))
2855                /* initiate a depth clear */
2856                ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
2857             if ((zink_fb_clear_element(fb_clear, 0)->zs.bits & PIPE_CLEAR_STENCIL)) {
2858                /* use a stencil clear, also set stencil attachment */
2859                ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
2860             }
2861          }
2862       }
2863       if (changed_size || changed_layout)
2864          ctx->rp_changed = true;
2865       ctx->rp_loadop_changed = false;
2866       ctx->rp_layout_changed = false;
2867    }
2868    /* always assemble clear_buffers mask:
2869     * if a scissored clear must be triggered during glFlush,
2870     * the renderpass metadata may be unchanged (e.g., LOAD from previous rp),
2871     * but the buffer mask must still be returned
2872     */
2873    if (ctx->clears_enabled) {
2874       for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
2875          /* these are no-ops */
2876          if (!ctx->fb_state.cbufs[i] || !zink_fb_clear_enabled(ctx, i))
2877             continue;
2878          /* these need actual clear calls inside the rp */
2879          if (zink_fb_clear_needs_explicit(&ctx->fb_clears[i]))
2880             clear_buffers |= (PIPE_CLEAR_COLOR0 << i);
2881       }
2882       if (ctx->fb_state.zsbuf && zink_fb_clear_enabled(ctx, PIPE_MAX_COLOR_BUFS)) {
2883          struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[PIPE_MAX_COLOR_BUFS];
2884          struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(fb_clear, 0);
2885          if (zink_fb_clear_needs_explicit(fb_clear)) {
2886             for (int j = !zink_fb_clear_element_needs_explicit(clear);
2887                  (clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL && j < zink_fb_clear_count(fb_clear);
2888                  j++)
2889                clear_buffers |= zink_fb_clear_element(fb_clear, j)->zs.bits;
2890          }
2891       }
2892    }
2893 
2894    if (!ctx->rp_changed && ctx->batch.in_rp)
2895       return 0;
2896    ctx->rp_changed = false;
2897 
2898    /* update pipeline info id for compatibility VUs */
2899    unsigned rp_state = zink_update_rendering_info(ctx);
2900    /* validate zs VUs: attachment must be null or format must be valid */
2901    assert(!ctx->dynamic_fb.info.pDepthAttachment || ctx->gfx_pipeline_state.rendering_info.depthAttachmentFormat);
2902    assert(!ctx->dynamic_fb.info.pStencilAttachment || ctx->gfx_pipeline_state.rendering_info.stencilAttachmentFormat);
2903    bool rp_changed = ctx->gfx_pipeline_state.rp_state != rp_state;
2904    if (!rp_changed && ctx->batch.in_rp)
2905       return 0;
2906 
2907    zink_batch_no_rp(ctx);
2908    for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
2909       VkImageView iv = VK_NULL_HANDLE;
2910       struct zink_surface *surf = zink_csurface(ctx->fb_state.cbufs[i]);
2911       if (surf) {
2912          iv = zink_prep_fb_attachment(ctx, surf, i);
2913          if (!iv)
2914             /* dead swapchain */
2915             return 0;
2916       }
2917       ctx->dynamic_fb.attachments[i].imageView = iv;
2918    }
2919    if (has_swapchain) {
2920       ASSERTED struct zink_resource *res = zink_resource(ctx->fb_state.cbufs[0]->texture);
2921       zink_render_fixup_swapchain(ctx);
2922       assert(ctx->dynamic_fb.info.renderArea.extent.width <= res->base.b.width0);
2923       assert(ctx->dynamic_fb.info.renderArea.extent.height <= res->base.b.height0);
2924       assert(ctx->fb_state.width <= res->base.b.width0);
2925       assert(ctx->fb_state.height <= res->base.b.height0);
2926    }
2927    if (ctx->fb_state.zsbuf && zsbuf_used) {
2928       struct zink_surface *surf = zink_csurface(ctx->fb_state.zsbuf);
2929       VkImageView iv = zink_prep_fb_attachment(ctx, surf, ctx->fb_state.nr_cbufs);
2930       ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].imageView = iv;
2931       ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].imageLayout = zink_resource(surf->base.texture)->layout;
2932       assert(ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].imageLayout != VK_IMAGE_LAYOUT_UNDEFINED);
2933       ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].imageView = iv;
2934       ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].imageLayout = zink_resource(surf->base.texture)->layout;
2935       assert(ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].imageLayout != VK_IMAGE_LAYOUT_UNDEFINED);
2936       if (ctx->transient_attachments & BITFIELD_BIT(PIPE_MAX_COLOR_BUFS)) {
2937          ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].resolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
2938          ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS + 1].resolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
2939       } else {
2940          ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].resolveMode = 0;
2941          ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS + 1].resolveMode = 0;
2942       }
2943    }
2944    ctx->zsbuf_unused = !zsbuf_used;
2945    assert(ctx->fb_state.width >= ctx->dynamic_fb.info.renderArea.extent.width);
2946    assert(ctx->fb_state.height >= ctx->dynamic_fb.info.renderArea.extent.height);
2947    ctx->gfx_pipeline_state.dirty |= rp_changed;
2948    ctx->gfx_pipeline_state.rp_state = rp_state;
2949 
2950    VkMultisampledRenderToSingleSampledInfoEXT msrtss = {
2951       VK_STRUCTURE_TYPE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT,
2952       NULL,
2953       VK_TRUE,
2954       ctx->gfx_pipeline_state.rast_samples + 1,
2955    };
2956 
2957    if (zink_screen(ctx->base.screen)->info.have_EXT_multisampled_render_to_single_sampled)
2958       ctx->dynamic_fb.info.pNext = ctx->transient_attachments ? &msrtss : NULL;
2959    assert(!ctx->transient_attachments || msrtss.rasterizationSamples != VK_SAMPLE_COUNT_1_BIT);
2960    VKCTX(CmdBeginRendering)(ctx->batch.state->cmdbuf, &ctx->dynamic_fb.info);
2961    ctx->batch.in_rp = true;
2962    return clear_buffers;
2963 }
2964 
2965 ALWAYS_INLINE static void
update_layered_rendering_state(struct zink_context * ctx)2966 update_layered_rendering_state(struct zink_context *ctx)
2967 {
2968    if (!zink_screen(ctx->base.screen)->driver_workarounds.needs_sanitised_layer)
2969       return;
2970    unsigned framebffer_is_layered = zink_framebuffer_get_num_layers(&ctx->fb_state) > 1;
2971    VKCTX(CmdPushConstants)(
2972          ctx->batch.state->cmdbuf,
2973          zink_screen(ctx->base.screen)->gfx_push_constant_layout,
2974          VK_SHADER_STAGE_ALL_GRAPHICS,
2975          offsetof(struct zink_gfx_push_constant, framebuffer_is_layered), sizeof(unsigned),
2976          &framebffer_is_layered);
2977 }
2978 
2979 ALWAYS_INLINE static void
batch_ref_fb_surface(struct zink_context * ctx,struct pipe_surface * psurf)2980 batch_ref_fb_surface(struct zink_context *ctx, struct pipe_surface *psurf)
2981 {
2982    if (!psurf)
2983       return;
2984    zink_batch_reference_resource(&ctx->batch, zink_resource(psurf->texture));
2985    struct zink_surface *transient = zink_transient_surface(psurf);
2986    if (transient)
2987       zink_batch_reference_resource(&ctx->batch, zink_resource(transient->base.texture));
2988 }
2989 
2990 void
zink_batch_rp(struct zink_context * ctx)2991 zink_batch_rp(struct zink_context *ctx)
2992 {
2993    assert(!(ctx->batch.in_rp && ctx->rp_changed));
2994    if (!ctx->track_renderpasses && !ctx->blitting) {
2995       if (ctx->rp_tc_info_updated)
2996          zink_parse_tc_info(ctx);
2997    }
2998    if (ctx->batch.in_rp && !ctx->rp_layout_changed)
2999       return;
3000    bool in_rp = ctx->batch.in_rp;
3001    if (!in_rp && ctx->void_clears) {
3002       union pipe_color_union color;
3003       color.f[0] = color.f[1] = color.f[2] = 0;
3004       color.f[3] = 1.0;
3005       ctx->base.clear(&ctx->base, ctx->void_clears, NULL, &color, 0, 0);
3006       ctx->void_clears = 0;
3007    }
3008    if (!ctx->blitting) {
3009       if (ctx->rp_tc_info_updated)
3010          update_tc_info(ctx);
3011       ctx->rp_tc_info_updated = false;
3012    }
3013    bool maybe_has_query_ends = !ctx->track_renderpasses || ctx->dynamic_fb.tc_info.has_query_ends;
3014    ctx->queries_in_rp = maybe_has_query_ends;
3015    /* if possible, out-of-renderpass resume any queries that were stopped when previous rp ended */
3016    if (!ctx->queries_disabled && !maybe_has_query_ends) {
3017       zink_resume_queries(ctx, &ctx->batch);
3018       zink_query_update_gs_states(ctx);
3019    }
3020    unsigned clear_buffers;
3021    /* use renderpass for multisample-to-singlesample or fbfetch:
3022     * - msrtss is TODO
3023     * - dynamic rendering doesn't have input attachments
3024     */
3025    if (!zink_screen(ctx->base.screen)->info.have_KHR_dynamic_rendering ||
3026        (ctx->transient_attachments && !zink_screen(ctx->base.screen)->info.have_EXT_multisampled_render_to_single_sampled) ||
3027        (ctx->fbfetch_outputs && !zink_screen(ctx->base.screen)->info.have_KHR_dynamic_rendering_local_read))
3028       clear_buffers = zink_begin_render_pass(ctx);
3029    else
3030       clear_buffers = begin_rendering(ctx);
3031    assert(!ctx->rp_changed);
3032 
3033    /* update the render-passes HUD query */
3034    ctx->hud.render_passes++;
3035 
3036    if (!in_rp && ctx->batch.in_rp) {
3037       /* only hit this for valid swapchain and new renderpass */
3038       if (ctx->render_condition.query)
3039          zink_start_conditional_render(ctx);
3040       zink_clear_framebuffer(ctx, clear_buffers);
3041       if (ctx->pipeline_changed[0]) {
3042          for (unsigned i = 0; i < ctx->fb_state.nr_cbufs; i++)
3043             batch_ref_fb_surface(ctx, ctx->fb_state.cbufs[i]);
3044          batch_ref_fb_surface(ctx, ctx->fb_state.zsbuf);
3045       }
3046    }
3047    /* unable to previously determine that queries didn't split renderpasses: ensure queries start inside renderpass */
3048    if (!ctx->queries_disabled && maybe_has_query_ends) {
3049       zink_resume_queries(ctx, &ctx->batch);
3050       zink_query_update_gs_states(ctx);
3051    }
3052 }
3053 
3054 void
zink_batch_no_rp_safe(struct zink_context * ctx)3055 zink_batch_no_rp_safe(struct zink_context *ctx)
3056 {
3057    if (!ctx->batch.in_rp)
3058       return;
3059    zink_flush_dgc_if_enabled(ctx);
3060    if (ctx->render_condition.query)
3061       zink_stop_conditional_render(ctx);
3062    /* suspend all queries that were started in a renderpass
3063     * they can then be resumed upon beginning a new renderpass
3064     */
3065    if (!ctx->queries_disabled)
3066       zink_query_renderpass_suspend(ctx);
3067    if (ctx->gfx_pipeline_state.render_pass)
3068       zink_end_render_pass(ctx);
3069    else {
3070       VKCTX(CmdEndRendering)(ctx->batch.state->cmdbuf);
3071       ctx->batch.in_rp = false;
3072    }
3073    assert(!ctx->batch.in_rp);
3074 }
3075 
3076 void
zink_batch_no_rp(struct zink_context * ctx)3077 zink_batch_no_rp(struct zink_context *ctx)
3078 {
3079    if (!ctx->batch.in_rp)
3080       return;
3081    if (ctx->track_renderpasses && !ctx->blitting)
3082       tc_renderpass_info_reset(&ctx->dynamic_fb.tc_info);
3083    zink_batch_no_rp_safe(ctx);
3084 }
3085 
3086 ALWAYS_INLINE static void
update_res_sampler_layouts(struct zink_context * ctx,struct zink_resource * res)3087 update_res_sampler_layouts(struct zink_context *ctx, struct zink_resource *res)
3088 {
3089    unsigned find = res->sampler_bind_count[0];
3090    for (unsigned i = 0; find && i < MESA_SHADER_COMPUTE; i++) {
3091       u_foreach_bit(slot, res->sampler_binds[i]) {
3092          /* only set layout, skip rest of update */
3093          if (ctx->di.descriptor_res[ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW][i][slot] == res)
3094             ctx->di.textures[i][slot].imageLayout = zink_descriptor_util_image_layout_eval(ctx, res, false);
3095          find--;
3096          if (!find) break;
3097       }
3098    }
3099 }
3100 
3101 VkImageView
zink_prep_fb_attachment(struct zink_context * ctx,struct zink_surface * surf,unsigned i)3102 zink_prep_fb_attachment(struct zink_context *ctx, struct zink_surface *surf, unsigned i)
3103 {
3104    struct zink_resource *res;
3105    if (!surf) {
3106       surf = zink_get_dummy_surface(ctx, util_logbase2_ceil(ctx->fb_state.samples));
3107       res = zink_resource(surf->base.texture);
3108    } else {
3109       res = zink_resource(surf->base.texture);
3110       zink_batch_resource_usage_set(&ctx->batch, res, true, false);
3111    }
3112 
3113    VkAccessFlags access;
3114    VkPipelineStageFlags pipeline;
3115    if (zink_is_swapchain(res)) {
3116       if (!zink_kopper_acquire(ctx, res, UINT64_MAX))
3117          return VK_NULL_HANDLE;
3118       zink_surface_swapchain_update(ctx, surf);
3119       if (!i)
3120          zink_update_fbfetch(ctx);
3121    }
3122    if (ctx->blitting)
3123       return surf->image_view;
3124    VkImageLayout layout;
3125    /* depth attachment is stored as the last attachment, but bitfields always use PIPE_MAX_COLOR_BUFS */
3126    int idx = i == ctx->fb_state.nr_cbufs ? PIPE_MAX_COLOR_BUFS : i;
3127    if (ctx->feedback_loops & BITFIELD_BIT(idx)) {
3128       /* reevaluate feedback loop in case layout change eliminates the loop */
3129       if (!res->sampler_bind_count[0] || (idx == PIPE_MAX_COLOR_BUFS && !zink_is_zsbuf_write(ctx)))
3130          update_feedback_loop_state(ctx, i, ctx->feedback_loops & ~BITFIELD_BIT(idx));
3131    }
3132    if (ctx->track_renderpasses) {
3133       layout = zink_tc_renderpass_info_parse(ctx, &ctx->dynamic_fb.tc_info, idx, &pipeline, &access);
3134       assert(i < ctx->fb_state.nr_cbufs || layout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL || !zink_fb_clear_enabled(ctx, PIPE_MAX_COLOR_BUFS));
3135       if (i == ctx->fb_state.nr_cbufs && zink_fb_clear_enabled(ctx, PIPE_MAX_COLOR_BUFS))
3136          assert(ctx->dynamic_fb.tc_info.zsbuf_clear || ctx->dynamic_fb.tc_info.zsbuf_clear_partial || ctx->dynamic_fb.tc_info.zsbuf_load);
3137    } else {
3138       if (ctx->gfx_pipeline_state.render_pass) {
3139          layout = zink_render_pass_attachment_get_barrier_info(&ctx->gfx_pipeline_state.render_pass->state.rts[i],
3140                                                                i < ctx->fb_state.nr_cbufs, &pipeline, &access);
3141       } else {
3142          struct zink_rt_attrib rt;
3143          if (i < ctx->fb_state.nr_cbufs)
3144             zink_init_color_attachment(ctx, i, &rt);
3145          else
3146             zink_init_zs_attachment(ctx, &rt);
3147          layout = zink_render_pass_attachment_get_barrier_info(&rt, i < ctx->fb_state.nr_cbufs, &pipeline, &access);
3148          /* avoid unnecessary read-only layout change */
3149          if (layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL &&
3150              res->layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL &&
3151              !res->bind_count[0])
3152             layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
3153       }
3154    }
3155    /*
3156       The image subresources for a storage image must be in the VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR or
3157       VK_IMAGE_LAYOUT_GENERAL layout in order to access its data in a shader.
3158       - 14.1.1. Storage Image
3159     */
3160    if (res->image_bind_count[0])
3161       layout = VK_IMAGE_LAYOUT_GENERAL;
3162    else if (!zink_screen(ctx->base.screen)->info.have_EXT_attachment_feedback_loop_layout &&
3163             layout == VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT)
3164       layout = VK_IMAGE_LAYOUT_GENERAL;
3165    if (res->valid || res->layout != layout)
3166       zink_screen(ctx->base.screen)->image_barrier(ctx, res, layout, access, pipeline);
3167    if (!(res->aspect & VK_IMAGE_ASPECT_COLOR_BIT))
3168       ctx->zsbuf_readonly = res->layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
3169    res->obj->unordered_read = res->obj->unordered_write = false;
3170    if (i == ctx->fb_state.nr_cbufs && res->sampler_bind_count[0])
3171       update_res_sampler_layouts(ctx, res);
3172    return surf->image_view;
3173 }
3174 
3175 static uint32_t
hash_rendering_state(const void * key)3176 hash_rendering_state(const void *key)
3177 {
3178    const VkPipelineRenderingCreateInfo *info = key;
3179    uint32_t hash = 0;
3180    /*
3181     uint32_t           colorAttachmentCount;
3182     const VkFormat*    pColorAttachmentFormats;
3183     VkFormat           depthAttachmentFormat;
3184     VkFormat           stencilAttachmentFormat;
3185     * this data is not optimally arranged, so it must be manually hashed
3186     */
3187    hash = XXH32(&info->colorAttachmentCount, sizeof(uint32_t), hash);
3188    hash = XXH32(&info->depthAttachmentFormat, sizeof(uint32_t), hash);
3189    hash = XXH32(&info->stencilAttachmentFormat, sizeof(VkFormat), hash);
3190    return XXH32(info->pColorAttachmentFormats, sizeof(VkFormat) * info->colorAttachmentCount, hash);
3191 }
3192 
3193 static bool
equals_rendering_state(const void * a,const void * b)3194 equals_rendering_state(const void *a, const void *b)
3195 {
3196    const VkPipelineRenderingCreateInfo *ai = a;
3197    const VkPipelineRenderingCreateInfo *bi = b;
3198    return ai->colorAttachmentCount == bi->colorAttachmentCount &&
3199           ai->depthAttachmentFormat == bi->depthAttachmentFormat &&
3200           ai->stencilAttachmentFormat == bi->stencilAttachmentFormat &&
3201           !memcmp(ai->pColorAttachmentFormats, bi->pColorAttachmentFormats, sizeof(VkFormat) * ai->colorAttachmentCount);
3202 }
3203 
3204 static uint32_t
hash_framebuffer_imageless(const void * key)3205 hash_framebuffer_imageless(const void *key)
3206 {
3207    struct zink_framebuffer_state* s = (struct zink_framebuffer_state*)key;
3208    return _mesa_hash_data(key, offsetof(struct zink_framebuffer_state, infos) + sizeof(s->infos[0]) * s->num_attachments);
3209 }
3210 
3211 static bool
equals_framebuffer_imageless(const void * a,const void * b)3212 equals_framebuffer_imageless(const void *a, const void *b)
3213 {
3214    struct zink_framebuffer_state *s = (struct zink_framebuffer_state*)a;
3215    return memcmp(a, b, offsetof(struct zink_framebuffer_state, infos) + sizeof(s->infos[0]) * s->num_attachments) == 0;
3216 }
3217 
3218 void
zink_init_vk_sample_locations(struct zink_context * ctx,VkSampleLocationsInfoEXT * loc)3219 zink_init_vk_sample_locations(struct zink_context *ctx, VkSampleLocationsInfoEXT *loc)
3220 {
3221    struct zink_screen *screen = zink_screen(ctx->base.screen);
3222    unsigned idx = util_logbase2_ceil(MAX2(ctx->gfx_pipeline_state.rast_samples + 1, 1));
3223    loc->sType = VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT;
3224    loc->pNext = NULL;
3225    loc->sampleLocationsPerPixel = 1 << idx;
3226    loc->sampleLocationsCount = ctx->gfx_pipeline_state.rast_samples + 1;
3227    loc->sampleLocationGridSize = screen->maxSampleLocationGridSize[idx];
3228    loc->pSampleLocations = ctx->vk_sample_locations;
3229 }
3230 
3231 static void
zink_evaluate_depth_buffer(struct pipe_context * pctx)3232 zink_evaluate_depth_buffer(struct pipe_context *pctx)
3233 {
3234    struct zink_context *ctx = zink_context(pctx);
3235 
3236    if (!ctx->fb_state.zsbuf)
3237       return;
3238 
3239    struct zink_resource *res = zink_resource(ctx->fb_state.zsbuf->texture);
3240    res->obj->needs_zs_evaluate = true;
3241    zink_init_vk_sample_locations(ctx, &res->obj->zs_evaluate);
3242    zink_batch_no_rp(ctx);
3243 }
3244 
3245 static void
sync_flush(struct zink_context * ctx,struct zink_batch_state * bs)3246 sync_flush(struct zink_context *ctx, struct zink_batch_state *bs)
3247 {
3248    if (zink_screen(ctx->base.screen)->threaded_submit)
3249       util_queue_fence_wait(&bs->flush_completed);
3250 }
3251 
3252 static inline VkAccessFlags
get_access_flags_for_binding(struct zink_context * ctx,enum zink_descriptor_type type,gl_shader_stage stage,unsigned idx)3253 get_access_flags_for_binding(struct zink_context *ctx, enum zink_descriptor_type type, gl_shader_stage stage, unsigned idx)
3254 {
3255    VkAccessFlags flags = 0;
3256    switch (type) {
3257    case ZINK_DESCRIPTOR_TYPE_UBO:
3258       return VK_ACCESS_UNIFORM_READ_BIT;
3259    case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
3260       return VK_ACCESS_SHADER_READ_BIT;
3261    case ZINK_DESCRIPTOR_TYPE_SSBO: {
3262       flags = VK_ACCESS_SHADER_READ_BIT;
3263       if (ctx->writable_ssbos[stage] & (1 << idx))
3264          flags |= VK_ACCESS_SHADER_WRITE_BIT;
3265       return flags;
3266    }
3267    case ZINK_DESCRIPTOR_TYPE_IMAGE: {
3268       struct zink_image_view *image_view = &ctx->image_views[stage][idx];
3269       if (image_view->base.access & PIPE_IMAGE_ACCESS_READ)
3270          flags |= VK_ACCESS_SHADER_READ_BIT;
3271       if (image_view->base.access & PIPE_IMAGE_ACCESS_WRITE)
3272          flags |= VK_ACCESS_SHADER_WRITE_BIT;
3273       return flags;
3274    }
3275    default:
3276       break;
3277    }
3278    unreachable("ACK");
3279    return 0;
3280 }
3281 
3282 static void
update_resource_refs_for_stage(struct zink_context * ctx,gl_shader_stage stage)3283 update_resource_refs_for_stage(struct zink_context *ctx, gl_shader_stage stage)
3284 {
3285    struct zink_batch *batch = &ctx->batch;
3286    unsigned max_slot[] = {
3287       [ZINK_DESCRIPTOR_TYPE_UBO] = ctx->di.num_ubos[stage],
3288       [ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW] = ctx->di.num_samplers[stage],
3289       [ZINK_DESCRIPTOR_TYPE_SSBO] = ctx->di.num_ssbos[stage],
3290       [ZINK_DESCRIPTOR_TYPE_IMAGE] = ctx->di.num_images[stage]
3291    };
3292    for (unsigned i = 0; i < ZINK_DESCRIPTOR_BASE_TYPES; i++) {
3293       for (unsigned j = 0; j < max_slot[i]; j++) {
3294          if (ctx->di.descriptor_res[i][stage][j]) {
3295             struct zink_resource *res = ctx->di.descriptor_res[i][stage][j];
3296             if (!res)
3297                continue;
3298             bool is_buffer = res->obj->is_buffer;
3299             bool is_write = zink_resource_access_is_write(get_access_flags_for_binding(ctx, i, stage, j));
3300             if (zink_is_swapchain(res)) {
3301                if (!zink_kopper_acquire(ctx, res, UINT64_MAX))
3302                   /* technically this is a failure condition, but there's no safe way out */
3303                   continue;
3304             }
3305             zink_batch_resource_usage_set(batch, res, is_write, is_buffer);
3306             if (!ctx->unordered_blitting) {
3307                if (is_write || !res->obj->is_buffer)
3308                   res->obj->unordered_read = res->obj->unordered_write = false;
3309                else
3310                   res->obj->unordered_read = false;
3311             }
3312          }
3313       }
3314    }
3315 }
3316 
3317 void
zink_update_descriptor_refs(struct zink_context * ctx,bool compute)3318 zink_update_descriptor_refs(struct zink_context *ctx, bool compute)
3319 {
3320    struct zink_batch *batch = &ctx->batch;
3321    if (compute) {
3322       update_resource_refs_for_stage(ctx, MESA_SHADER_COMPUTE);
3323       if (ctx->curr_compute)
3324          zink_batch_reference_program(batch, &ctx->curr_compute->base);
3325    } else {
3326       for (unsigned i = 0; i < ZINK_GFX_SHADER_COUNT; i++)
3327          update_resource_refs_for_stage(ctx, i);
3328       unsigned vertex_buffers_enabled_mask = ctx->gfx_pipeline_state.vertex_buffers_enabled_mask;
3329       unsigned last_vbo = util_last_bit(vertex_buffers_enabled_mask);
3330       for (unsigned i = 0; i < last_vbo + 1; i++) {
3331          struct zink_resource *res = zink_resource(ctx->vertex_buffers[i].buffer.resource);
3332          if (res) {
3333             zink_batch_resource_usage_set(batch, res, false, true);
3334             if (!ctx->unordered_blitting)
3335                res->obj->unordered_read = false;
3336          }
3337       }
3338       if (ctx->curr_program)
3339          zink_batch_reference_program(batch, &ctx->curr_program->base);
3340    }
3341    if (ctx->di.bindless_refs_dirty) {
3342       ctx->di.bindless_refs_dirty = false;
3343       for (unsigned i = 0; i < 2; i++) {
3344          util_dynarray_foreach(&ctx->di.bindless[i].resident, struct zink_bindless_descriptor*, bd) {
3345             struct zink_resource *res = zink_descriptor_surface_resource(&(*bd)->ds);
3346             zink_batch_resource_usage_set(&ctx->batch, res, (*bd)->access & PIPE_IMAGE_ACCESS_WRITE, res->obj->is_buffer);
3347             if (!ctx->unordered_blitting) {
3348                if ((*bd)->access & PIPE_IMAGE_ACCESS_WRITE || !res->obj->is_buffer)
3349                   res->obj->unordered_read = res->obj->unordered_write = false;
3350                else
3351                   res->obj->unordered_read = false;
3352             }
3353          }
3354       }
3355    }
3356 
3357    unsigned global_count = util_dynarray_num_elements(&ctx->di.global_bindings, struct zink_resource*);
3358    struct zink_resource **globals = ctx->di.global_bindings.data;
3359    for (unsigned i = 0; i < global_count; i++) {
3360       struct zink_resource *res = globals[i];
3361       if (!res)
3362          continue;
3363       zink_batch_resource_usage_set(batch, res, true, true);
3364       res->obj->unordered_read = res->obj->unordered_write = false;
3365    }
3366 }
3367 
3368 static void
reapply_color_write(struct zink_context * ctx)3369 reapply_color_write(struct zink_context *ctx)
3370 {
3371    struct zink_screen *screen = zink_screen(ctx->base.screen);
3372    assert(screen->info.have_EXT_color_write_enable);
3373    const VkBool32 enables[PIPE_MAX_COLOR_BUFS] = {1, 1, 1, 1, 1, 1, 1, 1};
3374    const VkBool32 disables[PIPE_MAX_COLOR_BUFS] = {0};
3375    const unsigned max_att = MIN2(PIPE_MAX_COLOR_BUFS, screen->info.props.limits.maxColorAttachments);
3376    VKCTX(CmdSetColorWriteEnableEXT)(ctx->batch.state->cmdbuf, max_att, ctx->disable_color_writes ? disables : enables);
3377    VKCTX(CmdSetColorWriteEnableEXT)(ctx->batch.state->reordered_cmdbuf, max_att, enables);
3378    assert(screen->info.have_EXT_extended_dynamic_state);
3379    if (ctx->dsa_state)
3380       VKCTX(CmdSetDepthWriteEnable)(ctx->batch.state->cmdbuf, ctx->disable_color_writes ? VK_FALSE : ctx->dsa_state->hw_state.depth_write);
3381 }
3382 
3383 static void
stall(struct zink_context * ctx)3384 stall(struct zink_context *ctx)
3385 {
3386    struct zink_screen *screen = zink_screen(ctx->base.screen);
3387    sync_flush(ctx, zink_batch_state(ctx->last_fence));
3388    zink_screen_timeline_wait(screen, ctx->last_fence->batch_id, OS_TIMEOUT_INFINITE);
3389    zink_batch_reset_all(ctx);
3390 }
3391 
3392 void
zink_reset_ds3_states(struct zink_context * ctx)3393 zink_reset_ds3_states(struct zink_context *ctx)
3394 {
3395    struct zink_screen *screen = zink_screen(ctx->base.screen);
3396    if (!screen->info.have_EXT_extended_dynamic_state3)
3397       return;
3398    if (screen->have_full_ds3)
3399       ctx->ds3_states = UINT32_MAX;
3400    else
3401       ctx->ds3_states = BITFIELD_MASK(ZINK_DS3_BLEND_A2C);
3402    if (!screen->info.dynamic_state3_feats.extendedDynamicState3AlphaToOneEnable)
3403       ctx->ds3_states &= ~BITFIELD_BIT(ZINK_DS3_BLEND_A21);
3404    if (!screen->info.dynamic_state3_feats.extendedDynamicState3LineStippleEnable)
3405       ctx->ds3_states &= ~BITFIELD_BIT(ZINK_DS3_RAST_STIPPLE_ON);
3406    if (screen->driver_workarounds.no_linestipple)
3407       ctx->ds3_states &= ~BITFIELD_BIT(ZINK_DS3_RAST_STIPPLE);
3408 }
3409 
3410 static void
flush_batch(struct zink_context * ctx,bool sync)3411 flush_batch(struct zink_context *ctx, bool sync)
3412 {
3413    struct zink_batch *batch = &ctx->batch;
3414    assert(!ctx->unordered_blitting);
3415    if (ctx->clears_enabled)
3416       /* start rp to do all the clears */
3417       zink_batch_rp(ctx);
3418    zink_batch_no_rp_safe(ctx);
3419 
3420    util_queue_fence_wait(&ctx->unsync_fence);
3421    util_queue_fence_reset(&ctx->flush_fence);
3422    zink_end_batch(ctx, batch);
3423    ctx->deferred_fence = NULL;
3424 
3425    if (sync)
3426       sync_flush(ctx, ctx->batch.state);
3427 
3428    if (ctx->batch.state->is_device_lost) {
3429       check_device_lost(ctx);
3430    } else {
3431       struct zink_screen *screen = zink_screen(ctx->base.screen);
3432       zink_start_batch(ctx, batch);
3433       if (screen->info.have_EXT_transform_feedback && ctx->num_so_targets)
3434          ctx->dirty_so_targets = true;
3435       ctx->pipeline_changed[0] = ctx->pipeline_changed[1] = true;
3436       zink_select_draw_vbo(ctx);
3437       zink_select_launch_grid(ctx);
3438 
3439       if (ctx->oom_stall)
3440          stall(ctx);
3441       zink_reset_ds3_states(ctx);
3442 
3443       ctx->oom_flush = false;
3444       ctx->oom_stall = false;
3445       ctx->dd.bindless_bound = false;
3446       ctx->di.bindless_refs_dirty = true;
3447       ctx->sample_locations_changed = ctx->gfx_pipeline_state.sample_locations_enabled;
3448       if (zink_screen(ctx->base.screen)->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints) {
3449          VKCTX(CmdSetPatchControlPointsEXT)(ctx->batch.state->cmdbuf, ctx->gfx_pipeline_state.dyn_state2.vertices_per_patch);
3450          VKCTX(CmdSetPatchControlPointsEXT)(ctx->batch.state->reordered_cmdbuf, 1);
3451       }
3452       update_feedback_loop_dynamic_state(ctx);
3453       if (screen->info.have_EXT_color_write_enable)
3454          reapply_color_write(ctx);
3455       update_layered_rendering_state(ctx);
3456       tc_renderpass_info_reset(&ctx->dynamic_fb.tc_info);
3457       ctx->rp_tc_info_updated = true;
3458    }
3459    util_queue_fence_signal(&ctx->flush_fence);
3460 }
3461 
3462 void
zink_flush_queue(struct zink_context * ctx)3463 zink_flush_queue(struct zink_context *ctx)
3464 {
3465    flush_batch(ctx, true);
3466 }
3467 
3468 static bool
rebind_fb_surface(struct zink_context * ctx,struct pipe_surface ** surf,struct zink_resource * match_res)3469 rebind_fb_surface(struct zink_context *ctx, struct pipe_surface **surf, struct zink_resource *match_res)
3470 {
3471    if (!*surf)
3472       return false;
3473    struct zink_resource *surf_res = zink_resource((*surf)->texture);
3474    if ((match_res == surf_res) || surf_res->obj != zink_csurface(*surf)->obj)
3475       return zink_rebind_ctx_surface(ctx, surf);
3476    return false;
3477 }
3478 
3479 static bool
rebind_fb_state(struct zink_context * ctx,struct zink_resource * match_res,bool from_set_fb)3480 rebind_fb_state(struct zink_context *ctx, struct zink_resource *match_res, bool from_set_fb)
3481 {
3482    bool rebind = false;
3483    for (int i = 0; i < ctx->fb_state.nr_cbufs; i++)
3484       rebind |= rebind_fb_surface(ctx, &ctx->fb_state.cbufs[i], match_res);
3485    rebind |= rebind_fb_surface(ctx, &ctx->fb_state.zsbuf, match_res);
3486    return rebind;
3487 }
3488 
3489 static void
unbind_fb_surface(struct zink_context * ctx,struct pipe_surface * surf,unsigned idx,bool changed)3490 unbind_fb_surface(struct zink_context *ctx, struct pipe_surface *surf, unsigned idx, bool changed)
3491 {
3492    ctx->dynamic_fb.attachments[idx].imageView = VK_NULL_HANDLE;
3493    if (!surf)
3494       return;
3495    struct zink_resource *res = zink_resource(surf->texture);
3496    if (changed) {
3497       ctx->rp_changed = true;
3498    }
3499    res->fb_bind_count--;
3500    if (!res->fb_bind_count && !res->bind_count[0])
3501       _mesa_set_remove_key(ctx->need_barriers[0], res);
3502    unsigned feedback_loops = ctx->feedback_loops;
3503    if (ctx->feedback_loops & BITFIELD_BIT(idx)) {
3504       ctx->dynamic_fb.attachments[idx].imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
3505       ctx->rp_layout_changed = true;
3506    }
3507    ctx->feedback_loops &= ~BITFIELD_BIT(idx);
3508    if (feedback_loops != ctx->feedback_loops) {
3509       if (idx == PIPE_MAX_COLOR_BUFS && !zink_screen(ctx->base.screen)->driver_workarounds.always_feedback_loop_zs) {
3510          if (ctx->gfx_pipeline_state.feedback_loop_zs)
3511             ctx->gfx_pipeline_state.dirty = true;
3512          ctx->gfx_pipeline_state.feedback_loop_zs = false;
3513       } else if (idx < PIPE_MAX_COLOR_BUFS && !zink_screen(ctx->base.screen)->driver_workarounds.always_feedback_loop) {
3514          if (ctx->gfx_pipeline_state.feedback_loop)
3515             ctx->gfx_pipeline_state.dirty = true;
3516          ctx->gfx_pipeline_state.feedback_loop = false;
3517       }
3518    }
3519    res->fb_binds &= ~BITFIELD_BIT(idx);
3520    /* this is called just before the resource loses a reference, so a refcount==1 means the resource will be destroyed */
3521    if (!res->fb_bind_count && res->base.b.reference.count > 1) {
3522       if (ctx->track_renderpasses && !ctx->blitting) {
3523          if (!(res->base.b.bind & PIPE_BIND_DISPLAY_TARGET) && util_format_is_depth_or_stencil(surf->format))
3524             /* assume that all depth buffers which are not swapchain images will be used for sampling to avoid splitting renderpasses */
3525             zink_screen(ctx->base.screen)->image_barrier(ctx, res, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
3526          if (!zink_is_swapchain(res) && !util_format_is_depth_or_stencil(surf->format))
3527             /* assume that all color buffers which are not swapchain images will be used for sampling to avoid splitting renderpasses */
3528             zink_screen(ctx->base.screen)->image_barrier(ctx, res, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
3529       }
3530       if (res->sampler_bind_count[0]) {
3531          update_res_sampler_layouts(ctx, res);
3532          if (res->layout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL && !ctx->blitting)
3533             _mesa_set_add(ctx->need_barriers[0], res);
3534       }
3535    }
3536 }
3537 
3538 void
zink_set_null_fs(struct zink_context * ctx)3539 zink_set_null_fs(struct zink_context *ctx)
3540 {
3541    struct zink_screen *screen = zink_screen(ctx->base.screen);
3542    bool prev_disable_fs = ctx->disable_fs;
3543    ctx->disable_fs = ctx->rast_state && ctx->rast_state->base.rasterizer_discard &&
3544                      (ctx->primitives_generated_active || (!ctx->queries_disabled && ctx->primitives_generated_suspended));
3545    struct zink_shader *zs = ctx->gfx_stages[MESA_SHADER_FRAGMENT];
3546    unsigned compact = screen->compact_descriptors ? ZINK_DESCRIPTOR_COMPACT : 0;
3547    /* can't use CWE if side effects */
3548    bool no_cwe = (zs && (zs->ssbos_used || zs->bindless || zs->num_bindings[ZINK_DESCRIPTOR_TYPE_IMAGE - compact])) ||
3549                  ctx->fs_query_active || ctx->occlusion_query_active || !screen->info.have_EXT_color_write_enable;
3550    bool prev_disable_color_writes = ctx->disable_color_writes;
3551    ctx->disable_color_writes = ctx->disable_fs && !no_cwe;
3552 
3553    if (ctx->disable_fs == prev_disable_fs) {
3554       /* if this is a true no-op then return */
3555       if (!ctx->disable_fs || ctx->disable_color_writes == !no_cwe)
3556          return;
3557       /* else changing disable modes */
3558    }
3559 
3560    /* either of these cases requires removing the previous mode */
3561    if (!ctx->disable_fs || (prev_disable_fs && prev_disable_color_writes != !no_cwe)) {
3562       if (prev_disable_color_writes)
3563          reapply_color_write(ctx);
3564       else
3565          ctx->base.bind_fs_state(&ctx->base, ctx->saved_fs);
3566       ctx->saved_fs = NULL;
3567       /* fs/CWE reenabled, fs active, done */
3568       if (!ctx->disable_fs)
3569          return;
3570    }
3571 
3572    /* always use CWE when possible */
3573    if (!no_cwe) {
3574       reapply_color_write(ctx);
3575       return;
3576    }
3577    /* otherwise need to bind a null fs */
3578    if (!ctx->null_fs) {
3579       nir_shader *nir = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, &screen->nir_options, "null_fs").shader;
3580       nir->info.separate_shader = true;
3581       ctx->null_fs = pipe_shader_from_nir(&ctx->base, nir);
3582    }
3583    ctx->saved_fs = ctx->gfx_stages[MESA_SHADER_FRAGMENT];
3584    ctx->base.bind_fs_state(&ctx->base, ctx->null_fs);
3585 }
3586 
3587 static void
check_framebuffer_surface_mutable(struct pipe_context * pctx,struct pipe_surface * psurf)3588 check_framebuffer_surface_mutable(struct pipe_context *pctx, struct pipe_surface *psurf)
3589 {
3590    struct zink_context *ctx = zink_context(pctx);
3591    struct zink_ctx_surface *csurf = (struct zink_ctx_surface *)psurf;
3592    if (!csurf->needs_mutable)
3593       return;
3594    zink_resource_object_init_mutable(ctx, zink_resource(psurf->texture));
3595    struct pipe_surface *psurf2 = pctx->create_surface(pctx, psurf->texture, psurf);
3596    pipe_resource_reference(&psurf2->texture, NULL);
3597    struct zink_ctx_surface *csurf2 = (struct zink_ctx_surface *)psurf2;
3598    zink_surface_reference(zink_screen(pctx->screen), &csurf->surf, csurf2->surf);
3599    pctx->surface_destroy(pctx, psurf2);
3600    csurf->needs_mutable = false;
3601 }
3602 
3603 static void
zink_set_framebuffer_state(struct pipe_context * pctx,const struct pipe_framebuffer_state * state)3604 zink_set_framebuffer_state(struct pipe_context *pctx,
3605                            const struct pipe_framebuffer_state *state)
3606 {
3607    struct zink_context *ctx = zink_context(pctx);
3608    struct zink_screen *screen = zink_screen(pctx->screen);
3609    unsigned samples = state->nr_cbufs || state->zsbuf ? 0 : state->samples;
3610    unsigned w = ctx->fb_state.width;
3611    unsigned h = ctx->fb_state.height;
3612    unsigned layers = MAX2(zink_framebuffer_get_num_layers(state), 1);
3613 
3614    bool flush_clears = ctx->clears_enabled &&
3615                        (ctx->dynamic_fb.info.layerCount != layers ||
3616                         state->width != w || state->height != h);
3617    if (ctx->clears_enabled && !flush_clears) {
3618       for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
3619          if (i >= state->nr_cbufs || !ctx->fb_state.cbufs[i] || !state->cbufs[i])
3620             flush_clears |= zink_fb_clear_enabled(ctx, i);
3621          else if (zink_fb_clear_enabled(ctx, i) && ctx->fb_state.cbufs[i] != state->cbufs[i]) {
3622             struct zink_surface *a = zink_csurface(ctx->fb_state.cbufs[i]);
3623             struct zink_surface *b = zink_csurface(state->cbufs[i]);
3624             if (a == b)
3625                continue;
3626             if (!a || !b || memcmp(&a->base.u.tex, &b->base.u.tex, sizeof(b->base.u.tex)) ||
3627                 a->base.texture != b->base.texture)
3628                flush_clears = true;
3629             else if (a->base.format != b->base.format)
3630                zink_fb_clear_rewrite(ctx, i, a->base.format, b->base.format);
3631          }
3632       }
3633    }
3634    if (ctx->fb_state.zsbuf != state->zsbuf)
3635       flush_clears |= zink_fb_clear_enabled(ctx, PIPE_MAX_COLOR_BUFS);
3636    if (flush_clears) {
3637       bool queries_disabled = ctx->queries_disabled;
3638       ctx->queries_disabled = true;
3639       zink_batch_rp(ctx);
3640       ctx->queries_disabled = queries_disabled;
3641    }
3642    /* need to ensure we start a new rp on next draw */
3643    zink_batch_no_rp_safe(ctx);
3644    for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
3645       struct pipe_surface *psurf = ctx->fb_state.cbufs[i];
3646       if (i < state->nr_cbufs)
3647          ctx->rp_changed |= !!zink_transient_surface(psurf) != !!zink_transient_surface(state->cbufs[i]);
3648       unbind_fb_surface(ctx, psurf, i, i >= state->nr_cbufs || psurf != state->cbufs[i]);
3649       if (psurf && ctx->needs_present == zink_resource(psurf->texture))
3650          ctx->needs_present = NULL;
3651    }
3652    if (ctx->fb_state.zsbuf) {
3653       struct pipe_surface *psurf = ctx->fb_state.zsbuf;
3654       struct zink_resource *res = zink_resource(psurf->texture);
3655       bool changed = psurf != state->zsbuf;
3656       unbind_fb_surface(ctx, psurf, PIPE_MAX_COLOR_BUFS, changed);
3657       if (!changed)
3658          ctx->rp_changed |= !!zink_transient_surface(psurf) != !!zink_transient_surface(state->zsbuf);
3659       if (changed && unlikely(res->obj->needs_zs_evaluate))
3660          /* have to flush zs eval while the sample location data still exists,
3661           * so just throw some random barrier */
3662          zink_screen(ctx->base.screen)->image_barrier(ctx, res, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
3663                                      VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
3664    }
3665    /* renderpass changes if the number or types of attachments change */
3666    ctx->rp_changed |= ctx->fb_state.nr_cbufs != state->nr_cbufs;
3667    ctx->rp_changed |= !!ctx->fb_state.zsbuf != !!state->zsbuf;
3668    if (ctx->fb_state.nr_cbufs != state->nr_cbufs) {
3669       ctx->blend_state_changed |= screen->have_full_ds3;
3670       if (state->nr_cbufs && screen->have_full_ds3)
3671          ctx->ds3_states |= BITFIELD_BIT(ZINK_DS3_BLEND_ON) | BITFIELD_BIT(ZINK_DS3_BLEND_WRITE) | BITFIELD_BIT(ZINK_DS3_BLEND_EQ);
3672    }
3673 
3674    util_copy_framebuffer_state(&ctx->fb_state, state);
3675    ctx->rp_changed |= zink_update_fbfetch(ctx);
3676    ctx->transient_attachments = 0;
3677    ctx->fb_layer_mismatch = 0;
3678 
3679    ctx->dynamic_fb.info.renderArea.offset.x = 0;
3680    ctx->dynamic_fb.info.renderArea.offset.y = 0;
3681    ctx->dynamic_fb.info.renderArea.extent.width = state->width;
3682    ctx->dynamic_fb.info.renderArea.extent.height = state->height;
3683    ctx->dynamic_fb.info.colorAttachmentCount = ctx->fb_state.nr_cbufs;
3684    ctx->rp_changed |= ctx->dynamic_fb.info.layerCount != layers;
3685    ctx->dynamic_fb.info.layerCount = layers;
3686    ctx->gfx_pipeline_state.rendering_info.colorAttachmentCount = ctx->fb_state.nr_cbufs;
3687 
3688    ctx->void_clears = 0;
3689    for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
3690       struct pipe_surface *psurf = ctx->fb_state.cbufs[i];
3691       if (psurf) {
3692          struct zink_surface *transient = zink_transient_surface(psurf);
3693          if (transient || psurf->nr_samples)
3694             ctx->transient_attachments |= BITFIELD_BIT(i);
3695          if (!samples)
3696             samples = MAX3(transient ? transient->base.nr_samples : 1, psurf->texture->nr_samples, psurf->nr_samples ? psurf->nr_samples : 1);
3697          struct zink_resource *res = zink_resource(psurf->texture);
3698          check_framebuffer_surface_mutable(pctx, psurf);
3699          if (zink_csurface(psurf)->info.layerCount > layers)
3700             ctx->fb_layer_mismatch |= BITFIELD_BIT(i);
3701          if (res->modifiers) {
3702             assert(!ctx->needs_present || ctx->needs_present == res);
3703             ctx->needs_present = res;
3704          }
3705          if (res->obj->dt) {
3706             /* #6274 */
3707             if (!zink_screen(ctx->base.screen)->info.have_KHR_swapchain_mutable_format &&
3708                 psurf->format != res->base.b.format) {
3709                static bool warned = false;
3710                if (!warned) {
3711                   mesa_loge("zink: SRGB framebuffer unsupported without KHR_swapchain_mutable_format");
3712                   warned = true;
3713                }
3714             }
3715          }
3716          res->fb_bind_count++;
3717          res->fb_binds |= BITFIELD_BIT(i);
3718          batch_ref_fb_surface(ctx, ctx->fb_state.cbufs[i]);
3719          if (util_format_has_alpha1(psurf->format)) {
3720             if (!res->valid && !zink_fb_clear_full_exists(ctx, i))
3721                ctx->void_clears |= (PIPE_CLEAR_COLOR0 << i);
3722          }
3723       }
3724    }
3725    unsigned depth_bias_scale_factor = ctx->depth_bias_scale_factor;
3726    if (ctx->fb_state.zsbuf) {
3727       struct pipe_surface *psurf = ctx->fb_state.zsbuf;
3728       struct zink_surface *transient = zink_transient_surface(psurf);
3729       check_framebuffer_surface_mutable(pctx, psurf);
3730       batch_ref_fb_surface(ctx, ctx->fb_state.zsbuf);
3731       if (transient || psurf->nr_samples)
3732          ctx->transient_attachments |= BITFIELD_BIT(PIPE_MAX_COLOR_BUFS);
3733       if (!samples)
3734          samples = MAX3(transient ? transient->base.nr_samples : 1, psurf->texture->nr_samples, psurf->nr_samples ? psurf->nr_samples : 1);
3735       if (zink_csurface(psurf)->info.layerCount > layers)
3736          ctx->fb_layer_mismatch |= BITFIELD_BIT(PIPE_MAX_COLOR_BUFS);
3737       zink_resource(psurf->texture)->fb_bind_count++;
3738       zink_resource(psurf->texture)->fb_binds |= BITFIELD_BIT(PIPE_MAX_COLOR_BUFS);
3739       switch (psurf->format) {
3740       case PIPE_FORMAT_Z16_UNORM:
3741       case PIPE_FORMAT_Z16_UNORM_S8_UINT:
3742          ctx->depth_bias_scale_factor = zink_screen(ctx->base.screen)->driver_workarounds.z16_unscaled_bias;
3743          break;
3744       case PIPE_FORMAT_Z24X8_UNORM:
3745       case PIPE_FORMAT_Z24_UNORM_S8_UINT:
3746       case PIPE_FORMAT_X24S8_UINT:
3747       case PIPE_FORMAT_X8Z24_UNORM:
3748          ctx->depth_bias_scale_factor = zink_screen(ctx->base.screen)->driver_workarounds.z24_unscaled_bias;
3749          break;
3750       case PIPE_FORMAT_Z32_FLOAT:
3751       case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
3752       case PIPE_FORMAT_Z32_UNORM:
3753          ctx->depth_bias_scale_factor = 1<<23;
3754          break;
3755       default:
3756          ctx->depth_bias_scale_factor = 0;
3757       }
3758    } else {
3759       ctx->depth_bias_scale_factor = 0;
3760    }
3761    if (depth_bias_scale_factor != ctx->depth_bias_scale_factor &&
3762        ctx->rast_state && ctx->rast_state->base.offset_units_unscaled)
3763       ctx->rast_state_changed = true;
3764    rebind_fb_state(ctx, NULL, true);
3765    ctx->fb_state.samples = MAX2(samples, 1);
3766    zink_update_framebuffer_state(ctx);
3767    if (ctx->fb_state.width != w || ctx->fb_state.height != h)
3768       ctx->scissor_changed = true;
3769 
3770    uint8_t rast_samples = ctx->fb_state.samples - 1;
3771    if (rast_samples != ctx->gfx_pipeline_state.rast_samples)
3772       zink_update_fs_key_samples(ctx);
3773    if (ctx->gfx_pipeline_state.rast_samples != rast_samples) {
3774       ctx->sample_locations_changed |= ctx->gfx_pipeline_state.sample_locations_enabled;
3775       zink_flush_dgc_if_enabled(ctx);
3776       if (screen->have_full_ds3)
3777          ctx->sample_mask_changed = true;
3778       else
3779          ctx->gfx_pipeline_state.dirty = true;
3780    }
3781    ctx->gfx_pipeline_state.rast_samples = rast_samples;
3782 
3783    /* this is an ideal time to oom flush since it won't split a renderpass */
3784    if (ctx->oom_flush && !ctx->unordered_blitting)
3785       flush_batch(ctx, false);
3786    else
3787       update_layered_rendering_state(ctx);
3788 
3789    ctx->rp_tc_info_updated = !ctx->blitting;
3790 }
3791 
3792 static void
zink_set_blend_color(struct pipe_context * pctx,const struct pipe_blend_color * color)3793 zink_set_blend_color(struct pipe_context *pctx,
3794                      const struct pipe_blend_color *color)
3795 {
3796    struct zink_context *ctx = zink_context(pctx);
3797    memcpy(ctx->blend_constants, color->color, sizeof(float) * 4);
3798 
3799    ctx->blend_color_changed = true;
3800    zink_flush_dgc_if_enabled(ctx);
3801 }
3802 
3803 static void
zink_set_sample_mask(struct pipe_context * pctx,unsigned sample_mask)3804 zink_set_sample_mask(struct pipe_context *pctx, unsigned sample_mask)
3805 {
3806    struct zink_context *ctx = zink_context(pctx);
3807    if (ctx->gfx_pipeline_state.sample_mask == sample_mask)
3808       return;
3809    ctx->gfx_pipeline_state.sample_mask = sample_mask;
3810    zink_flush_dgc_if_enabled(ctx);
3811    if (zink_screen(pctx->screen)->have_full_ds3)
3812       ctx->sample_mask_changed = true;
3813    else
3814       ctx->gfx_pipeline_state.dirty = true;
3815 }
3816 
3817 static void
zink_set_min_samples(struct pipe_context * pctx,unsigned min_samples)3818 zink_set_min_samples(struct pipe_context *pctx, unsigned min_samples)
3819 {
3820    struct zink_context *ctx = zink_context(pctx);
3821    ctx->gfx_pipeline_state.min_samples = min_samples - 1;
3822    ctx->gfx_pipeline_state.dirty = true;
3823    zink_flush_dgc_if_enabled(ctx);
3824 }
3825 
3826 static void
zink_set_sample_locations(struct pipe_context * pctx,size_t size,const uint8_t * locations)3827 zink_set_sample_locations(struct pipe_context *pctx, size_t size, const uint8_t *locations)
3828 {
3829    struct zink_context *ctx = zink_context(pctx);
3830 
3831    ctx->gfx_pipeline_state.sample_locations_enabled = size && locations;
3832    ctx->sample_locations_changed = ctx->gfx_pipeline_state.sample_locations_enabled;
3833    if (size > sizeof(ctx->sample_locations))
3834       size = sizeof(ctx->sample_locations);
3835 
3836    if (locations)
3837       memcpy(ctx->sample_locations, locations, size);
3838    zink_flush_dgc_if_enabled(ctx);
3839 }
3840 
3841 static void
zink_flush(struct pipe_context * pctx,struct pipe_fence_handle ** pfence,unsigned flags)3842 zink_flush(struct pipe_context *pctx,
3843            struct pipe_fence_handle **pfence,
3844            unsigned flags)
3845 {
3846    struct zink_context *ctx = zink_context(pctx);
3847    bool deferred = flags & PIPE_FLUSH_DEFERRED;
3848    bool deferred_fence = false;
3849    struct zink_batch *batch = &ctx->batch;
3850    struct zink_fence *fence = NULL;
3851    struct zink_screen *screen = zink_screen(ctx->base.screen);
3852    VkSemaphore export_sem = VK_NULL_HANDLE;
3853 
3854    /* triggering clears will force has_work */
3855    if (!deferred && ctx->clears_enabled) {
3856       /* if fbfetch outputs are active, disable them when flushing clears */
3857       unsigned fbfetch_outputs = ctx->fbfetch_outputs;
3858       if (fbfetch_outputs) {
3859          ctx->fbfetch_outputs = 0;
3860          ctx->rp_changed = true;
3861       }
3862       if (ctx->fb_state.zsbuf)
3863          zink_blit_barriers(ctx, NULL, zink_resource(ctx->fb_state.zsbuf->texture), false);
3864 
3865       for (unsigned i = 0; i < ctx->fb_state.nr_cbufs; i++) {
3866          if (ctx->fb_state.cbufs[i])
3867             zink_blit_barriers(ctx, NULL, zink_resource(ctx->fb_state.cbufs[i]->texture), false);
3868       }
3869       ctx->blitting = true;
3870       /* start rp to do all the clears */
3871       zink_batch_rp(ctx);
3872       ctx->blitting = false;
3873       ctx->fbfetch_outputs = fbfetch_outputs;
3874       ctx->rp_changed |= fbfetch_outputs > 0;
3875    }
3876 
3877    if (flags & PIPE_FLUSH_END_OF_FRAME) {
3878 #ifdef HAVE_RENDERDOC_APP_H
3879       p_atomic_inc(&screen->renderdoc_frame);
3880 #endif
3881       if (ctx->needs_present && ctx->needs_present->obj->dt_idx != UINT32_MAX &&
3882           zink_is_swapchain(ctx->needs_present)) {
3883          zink_kopper_readback_update(ctx, ctx->needs_present);
3884          screen->image_barrier(ctx, ctx->needs_present, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, 0, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
3885       }
3886       ctx->needs_present = NULL;
3887    }
3888 
3889    if (flags & PIPE_FLUSH_FENCE_FD) {
3890       assert(!deferred && pfence);
3891       const VkExportSemaphoreCreateInfo esci = {
3892          .sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
3893          .handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
3894       };
3895       const VkSemaphoreCreateInfo sci = {
3896          .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
3897          .pNext = &esci,
3898       };
3899       VkResult result = VKSCR(CreateSemaphore)(screen->dev, &sci, NULL, &export_sem);
3900       if (zink_screen_handle_vkresult(screen, result)) {
3901          assert(!batch->state->signal_semaphore);
3902          batch->state->signal_semaphore = export_sem;
3903          batch->has_work = true;
3904       } else {
3905          mesa_loge("ZINK: vkCreateSemaphore failed (%s)", vk_Result_to_str(result));
3906 
3907          /* let flush proceed and ensure a null sem for fence_get_fd to return -1 */
3908          export_sem = VK_NULL_HANDLE;
3909       }
3910    }
3911 
3912    if (!batch->has_work) {
3913        if (pfence) {
3914           /* reuse last fence */
3915           fence = ctx->last_fence;
3916        }
3917        if (!deferred) {
3918           struct zink_batch_state *last = zink_batch_state(ctx->last_fence);
3919           if (last) {
3920              sync_flush(ctx, last);
3921              if (last->is_device_lost)
3922                 check_device_lost(ctx);
3923           }
3924        }
3925        if (ctx->tc && !ctx->track_renderpasses)
3926          tc_driver_internal_flush_notify(ctx->tc);
3927    } else {
3928       fence = &batch->state->fence;
3929       if (deferred && !(flags & PIPE_FLUSH_FENCE_FD) && pfence)
3930          deferred_fence = true;
3931       else
3932          flush_batch(ctx, true);
3933    }
3934 
3935    if (pfence) {
3936       struct zink_tc_fence *mfence;
3937 
3938       if (flags & TC_FLUSH_ASYNC) {
3939          mfence = zink_tc_fence(*pfence);
3940          assert(mfence);
3941       } else {
3942          mfence = zink_create_tc_fence();
3943 
3944          screen->base.fence_reference(&screen->base, pfence, NULL);
3945          *pfence = (struct pipe_fence_handle *)mfence;
3946       }
3947 
3948       assert(!mfence->fence);
3949       mfence->fence = fence;
3950       mfence->sem = export_sem;
3951       if (fence) {
3952          mfence->submit_count = zink_batch_state(fence)->usage.submit_count;
3953          util_dynarray_append(&fence->mfences, struct zink_tc_fence *, mfence);
3954       }
3955       if (export_sem) {
3956          pipe_reference(NULL, &mfence->reference);
3957          util_dynarray_append(&ctx->batch.state->fences, struct zink_tc_fence*, mfence);
3958       }
3959 
3960       if (deferred_fence) {
3961          assert(fence);
3962          mfence->deferred_ctx = pctx;
3963          assert(!ctx->deferred_fence || ctx->deferred_fence == fence);
3964          ctx->deferred_fence = fence;
3965       }
3966 
3967       if (!fence || flags & TC_FLUSH_ASYNC) {
3968          if (!util_queue_fence_is_signalled(&mfence->ready))
3969             util_queue_fence_signal(&mfence->ready);
3970       }
3971    }
3972    if (fence) {
3973       if (!(flags & (PIPE_FLUSH_DEFERRED | PIPE_FLUSH_ASYNC)))
3974          sync_flush(ctx, zink_batch_state(fence));
3975    }
3976 }
3977 
3978 void
zink_fence_wait(struct pipe_context * pctx)3979 zink_fence_wait(struct pipe_context *pctx)
3980 {
3981    struct zink_context *ctx = zink_context(pctx);
3982 
3983    if (ctx->batch.has_work)
3984       pctx->flush(pctx, NULL, PIPE_FLUSH_HINT_FINISH);
3985    if (ctx->last_fence)
3986       stall(ctx);
3987 }
3988 
3989 void
zink_wait_on_batch(struct zink_context * ctx,uint64_t batch_id)3990 zink_wait_on_batch(struct zink_context *ctx, uint64_t batch_id)
3991 {
3992    struct zink_batch_state *bs;
3993    if (!batch_id) {
3994       /* not submitted yet */
3995       flush_batch(ctx, true);
3996       bs = zink_batch_state(ctx->last_fence);
3997       assert(bs);
3998       batch_id = bs->fence.batch_id;
3999    }
4000    assert(batch_id);
4001    if (!zink_screen_timeline_wait(zink_screen(ctx->base.screen), batch_id, UINT64_MAX))
4002       check_device_lost(ctx);
4003 }
4004 
4005 bool
zink_check_batch_completion(struct zink_context * ctx,uint64_t batch_id)4006 zink_check_batch_completion(struct zink_context *ctx, uint64_t batch_id)
4007 {
4008    assert(ctx->batch.state);
4009    if (!batch_id)
4010       /* not submitted yet */
4011       return false;
4012 
4013    if (zink_screen_check_last_finished(zink_screen(ctx->base.screen), batch_id))
4014       return true;
4015 
4016    bool success = zink_screen_timeline_wait(zink_screen(ctx->base.screen), batch_id, 0);
4017    if (!success)
4018       check_device_lost(ctx);
4019    return success;
4020 }
4021 
4022 static void
zink_texture_barrier(struct pipe_context * pctx,unsigned flags)4023 zink_texture_barrier(struct pipe_context *pctx, unsigned flags)
4024 {
4025    struct zink_context *ctx = zink_context(pctx);
4026    VkAccessFlags dst = flags == PIPE_TEXTURE_BARRIER_FRAMEBUFFER ?
4027                        VK_ACCESS_INPUT_ATTACHMENT_READ_BIT :
4028                        VK_ACCESS_SHADER_READ_BIT;
4029 
4030    if (!ctx->framebuffer || !ctx->framebuffer->state.num_attachments)
4031       return;
4032 
4033    /* if this is a fb barrier, flush all pending clears */
4034    if (ctx->rp_clears_enabled && dst == VK_ACCESS_INPUT_ATTACHMENT_READ_BIT)
4035       zink_batch_rp(ctx);
4036 
4037    /* this is not an in-renderpass barrier */
4038    if (!ctx->fbfetch_outputs)
4039       zink_batch_no_rp(ctx);
4040 
4041    if (zink_screen(ctx->base.screen)->info.have_KHR_synchronization2) {
4042       VkDependencyInfo dep = {0};
4043       dep.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
4044       dep.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
4045       dep.memoryBarrierCount = 1;
4046 
4047       VkMemoryBarrier2 dmb = {0};
4048       dmb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2;
4049       dmb.pNext = NULL;
4050       dmb.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
4051       dmb.dstAccessMask = dst;
4052       dmb.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
4053       dmb.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT;
4054       dep.pMemoryBarriers = &dmb;
4055 
4056       /* if zs fbfetch is a thing?
4057       if (ctx->fb_state.zsbuf) {
4058          const VkPipelineStageFlagBits2 depth_flags = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT;
4059          dmb.dstAccessMask |= VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
4060          dmb.srcStageMask |= depth_flags;
4061          dmb.dstStageMask |= depth_flags;
4062       }
4063       */
4064       VKCTX(CmdPipelineBarrier2)(ctx->batch.state->cmdbuf, &dep);
4065    } else {
4066       VkMemoryBarrier bmb = {0};
4067       bmb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
4068       bmb.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
4069       bmb.dstAccessMask = dst;
4070       VKCTX(CmdPipelineBarrier)(
4071          ctx->batch.state->cmdbuf,
4072          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
4073          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
4074          0,
4075          1, &bmb,
4076          0, NULL,
4077          0, NULL
4078       );
4079    }
4080 }
4081 
4082 static inline void
mem_barrier(struct zink_context * ctx,VkPipelineStageFlags src_stage,VkPipelineStageFlags dst_stage,VkAccessFlags src,VkAccessFlags dst)4083 mem_barrier(struct zink_context *ctx, VkPipelineStageFlags src_stage, VkPipelineStageFlags dst_stage, VkAccessFlags src, VkAccessFlags dst)
4084 {
4085    struct zink_batch *batch = &ctx->batch;
4086    VkMemoryBarrier mb;
4087    mb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
4088    mb.pNext = NULL;
4089    mb.srcAccessMask = src;
4090    mb.dstAccessMask = dst;
4091    zink_batch_no_rp(ctx);
4092    VKCTX(CmdPipelineBarrier)(batch->state->cmdbuf, src_stage, dst_stage, 0, 1, &mb, 0, NULL, 0, NULL);
4093 }
4094 
4095 void
zink_flush_memory_barrier(struct zink_context * ctx,bool is_compute)4096 zink_flush_memory_barrier(struct zink_context *ctx, bool is_compute)
4097 {
4098    const VkPipelineStageFlags gfx_flags = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
4099                                           VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
4100                                           VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT |
4101                                           VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT |
4102                                           VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
4103    const VkPipelineStageFlags cs_flags = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
4104    VkPipelineStageFlags src = ctx->batch.last_was_compute ? cs_flags : gfx_flags;
4105    VkPipelineStageFlags dst = is_compute ? cs_flags : gfx_flags;
4106 
4107    if (ctx->memory_barrier & (PIPE_BARRIER_TEXTURE | PIPE_BARRIER_SHADER_BUFFER | PIPE_BARRIER_IMAGE))
4108       mem_barrier(ctx, src, dst, VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT);
4109 
4110    if (ctx->memory_barrier & PIPE_BARRIER_CONSTANT_BUFFER)
4111       mem_barrier(ctx, src, dst,
4112                   VK_ACCESS_SHADER_WRITE_BIT,
4113                   VK_ACCESS_UNIFORM_READ_BIT);
4114 
4115    if (ctx->memory_barrier & PIPE_BARRIER_INDIRECT_BUFFER)
4116       mem_barrier(ctx, src, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
4117                   VK_ACCESS_SHADER_WRITE_BIT,
4118                   VK_ACCESS_INDIRECT_COMMAND_READ_BIT);
4119    if (!is_compute) {
4120       if (ctx->memory_barrier & PIPE_BARRIER_VERTEX_BUFFER)
4121          mem_barrier(ctx, gfx_flags, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
4122                      VK_ACCESS_SHADER_WRITE_BIT,
4123                      VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT);
4124 
4125       if (ctx->memory_barrier & PIPE_BARRIER_INDEX_BUFFER)
4126          mem_barrier(ctx, gfx_flags, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
4127                      VK_ACCESS_SHADER_WRITE_BIT,
4128                      VK_ACCESS_INDEX_READ_BIT);
4129       if (ctx->memory_barrier & PIPE_BARRIER_FRAMEBUFFER)
4130          zink_texture_barrier(&ctx->base, 0);
4131       if (ctx->memory_barrier & PIPE_BARRIER_STREAMOUT_BUFFER)
4132          mem_barrier(ctx, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
4133                             VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT |
4134                             VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT,
4135                      VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT,
4136                      VK_ACCESS_SHADER_READ_BIT,
4137                      VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT |
4138                      VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT);
4139    }
4140    ctx->memory_barrier = 0;
4141 }
4142 
4143 static void
zink_memory_barrier(struct pipe_context * pctx,unsigned flags)4144 zink_memory_barrier(struct pipe_context *pctx, unsigned flags)
4145 {
4146    struct zink_context *ctx = zink_context(pctx);
4147 
4148    flags &= ~PIPE_BARRIER_UPDATE;
4149    if (!flags)
4150       return;
4151 
4152    if (flags & PIPE_BARRIER_MAPPED_BUFFER) {
4153       /* TODO: this should flush all persistent buffers in use as I think */
4154       flags &= ~PIPE_BARRIER_MAPPED_BUFFER;
4155    }
4156    ctx->memory_barrier = flags;
4157 }
4158 
4159 static void
zink_flush_resource(struct pipe_context * pctx,struct pipe_resource * pres)4160 zink_flush_resource(struct pipe_context *pctx,
4161                     struct pipe_resource *pres)
4162 {
4163    struct zink_context *ctx = zink_context(pctx);
4164    struct zink_resource *res = zink_resource(pres);
4165    if (res->obj->dt) {
4166       if (zink_kopper_acquired(res->obj->dt, res->obj->dt_idx)) {
4167          zink_batch_no_rp_safe(ctx);
4168          zink_kopper_readback_update(ctx, res);
4169          zink_screen(ctx->base.screen)->image_barrier(ctx, res, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, 0, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
4170          zink_batch_reference_resource_rw(&ctx->batch, res, true);
4171       } else {
4172          ctx->needs_present = res;
4173       }
4174       ctx->batch.swapchain = res;
4175    } else if (res->dmabuf)
4176       res->queue = VK_QUEUE_FAMILY_FOREIGN_EXT;
4177 }
4178 
4179 static struct pipe_stream_output_target *
zink_create_stream_output_target(struct pipe_context * pctx,struct pipe_resource * pres,unsigned buffer_offset,unsigned buffer_size)4180 zink_create_stream_output_target(struct pipe_context *pctx,
4181                                  struct pipe_resource *pres,
4182                                  unsigned buffer_offset,
4183                                  unsigned buffer_size)
4184 {
4185    struct zink_so_target *t;
4186    t = CALLOC_STRUCT(zink_so_target);
4187    if (!t)
4188       return NULL;
4189 
4190    t->counter_buffer = pipe_buffer_create(pctx->screen, PIPE_BIND_STREAM_OUTPUT, PIPE_USAGE_DEFAULT, 4);
4191    if (!t->counter_buffer) {
4192       FREE(t);
4193       return NULL;
4194    }
4195 
4196    t->base.reference.count = 1;
4197    t->base.context = pctx;
4198    pipe_resource_reference(&t->base.buffer, pres);
4199    t->base.buffer_offset = buffer_offset;
4200    t->base.buffer_size = buffer_size;
4201 
4202    zink_resource(t->base.buffer)->so_valid = true;
4203 
4204    return &t->base;
4205 }
4206 
4207 static void
zink_stream_output_target_destroy(struct pipe_context * pctx,struct pipe_stream_output_target * psot)4208 zink_stream_output_target_destroy(struct pipe_context *pctx,
4209                                   struct pipe_stream_output_target *psot)
4210 {
4211    struct zink_so_target *t = (struct zink_so_target *)psot;
4212    pipe_resource_reference(&t->counter_buffer, NULL);
4213    pipe_resource_reference(&t->base.buffer, NULL);
4214    FREE(t);
4215 }
4216 
4217 static void
zink_set_stream_output_targets(struct pipe_context * pctx,unsigned num_targets,struct pipe_stream_output_target ** targets,const unsigned * offsets)4218 zink_set_stream_output_targets(struct pipe_context *pctx,
4219                                unsigned num_targets,
4220                                struct pipe_stream_output_target **targets,
4221                                const unsigned *offsets)
4222 {
4223    struct zink_context *ctx = zink_context(pctx);
4224 
4225    /* always set counter_buffer_valid=false on unbind:
4226     * - on resume (indicated by offset==-1), set counter_buffer_valid=true
4227     * - otherwise the counter buffer is invalidated
4228     */
4229 
4230    if (num_targets == 0) {
4231       for (unsigned i = 0; i < ctx->num_so_targets; i++) {
4232          if (ctx->so_targets[i]) {
4233             struct zink_resource *so = zink_resource(ctx->so_targets[i]->buffer);
4234             if (so) {
4235                so->so_bind_count--;
4236                update_res_bind_count(ctx, so, false, true);
4237             }
4238          }
4239          pipe_so_target_reference(&ctx->so_targets[i], NULL);
4240       }
4241       ctx->num_so_targets = 0;
4242    } else {
4243       for (unsigned i = 0; i < num_targets; i++) {
4244          struct zink_so_target *t = zink_so_target(targets[i]);
4245          pipe_so_target_reference(&ctx->so_targets[i], targets[i]);
4246          if (!t)
4247             continue;
4248          if (offsets[0] != (unsigned)-1)
4249             t->counter_buffer_valid = false;
4250          struct zink_resource *so = zink_resource(ctx->so_targets[i]->buffer);
4251          if (so) {
4252             so->so_bind_count++;
4253             update_res_bind_count(ctx, so, false, false);
4254          }
4255       }
4256       for (unsigned i = num_targets; i < ctx->num_so_targets; i++) {
4257          if (ctx->so_targets[i]) {
4258             struct zink_resource *so = zink_resource(ctx->so_targets[i]->buffer);
4259             if (so) {
4260                so->so_bind_count--;
4261                update_res_bind_count(ctx, so, false, true);
4262             }
4263          }
4264          pipe_so_target_reference(&ctx->so_targets[i], NULL);
4265       }
4266       ctx->num_so_targets = num_targets;
4267 
4268       /* TODO: possibly avoid rebinding on resume if resuming from same buffers? */
4269       ctx->dirty_so_targets = true;
4270    }
4271    zink_flush_dgc_if_enabled(ctx);
4272 }
4273 
4274 void
zink_rebind_framebuffer(struct zink_context * ctx,struct zink_resource * res)4275 zink_rebind_framebuffer(struct zink_context *ctx, struct zink_resource *res)
4276 {
4277    if (!ctx->framebuffer)
4278       return;
4279    bool did_rebind = false;
4280    if (res->aspect & VK_IMAGE_ASPECT_COLOR_BIT) {
4281       for (unsigned i = 0; i < ctx->fb_state.nr_cbufs; i++) {
4282          if (!ctx->fb_state.cbufs[i] ||
4283              zink_resource(ctx->fb_state.cbufs[i]->texture) != res)
4284             continue;
4285          zink_rebind_ctx_surface(ctx, &ctx->fb_state.cbufs[i]);
4286          did_rebind = true;
4287       }
4288    } else {
4289       if (ctx->fb_state.zsbuf && zink_resource(ctx->fb_state.zsbuf->texture) != res) {
4290          zink_rebind_ctx_surface(ctx, &ctx->fb_state.zsbuf);
4291          did_rebind = true;
4292       }
4293    }
4294 
4295    did_rebind |= rebind_fb_state(ctx, res, false);
4296 
4297    if (!did_rebind)
4298       return;
4299 
4300    zink_batch_no_rp(ctx);
4301    struct zink_framebuffer *fb = zink_get_framebuffer(ctx);
4302    ctx->fb_changed |= ctx->framebuffer != fb;
4303    ctx->framebuffer = fb;
4304 }
4305 
4306 ALWAYS_INLINE static struct zink_resource *
rebind_ubo(struct zink_context * ctx,gl_shader_stage shader,unsigned slot)4307 rebind_ubo(struct zink_context *ctx, gl_shader_stage shader, unsigned slot)
4308 {
4309    struct zink_resource *res = update_descriptor_state_ubo(ctx, shader, slot,
4310                                                            ctx->di.descriptor_res[ZINK_DESCRIPTOR_TYPE_UBO][shader][slot]);
4311    if (res) {
4312       res->obj->unordered_read = false;
4313       res->obj->access |= VK_ACCESS_SHADER_READ_BIT;
4314    }
4315    ctx->invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_UBO, slot, 1);
4316    return res;
4317 }
4318 
4319 ALWAYS_INLINE static struct zink_resource *
rebind_ssbo(struct zink_context * ctx,gl_shader_stage shader,unsigned slot)4320 rebind_ssbo(struct zink_context *ctx, gl_shader_stage shader, unsigned slot)
4321 {
4322    const struct pipe_shader_buffer *ssbo = &ctx->ssbos[shader][slot];
4323    struct zink_resource *res = zink_resource(ssbo->buffer);
4324    if (!res)
4325       return NULL;
4326    util_range_add(&res->base.b, &res->valid_buffer_range, ssbo->buffer_offset,
4327                   ssbo->buffer_offset + ssbo->buffer_size);
4328    update_descriptor_state_ssbo(ctx, shader, slot, res);
4329    if (res) {
4330       res->obj->unordered_read = false;
4331       res->obj->access |= VK_ACCESS_SHADER_READ_BIT;
4332       if (ctx->writable_ssbos[shader] & BITFIELD_BIT(slot)) {
4333          res->obj->unordered_write = false;
4334          res->obj->access |= VK_ACCESS_SHADER_WRITE_BIT;
4335       }
4336    }
4337    ctx->invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SSBO, slot, 1);
4338    return res;
4339 }
4340 
4341 ALWAYS_INLINE static struct zink_resource *
rebind_tbo(struct zink_context * ctx,gl_shader_stage shader,unsigned slot)4342 rebind_tbo(struct zink_context *ctx, gl_shader_stage shader, unsigned slot)
4343 {
4344    struct zink_sampler_view *sampler_view = zink_sampler_view(ctx->sampler_views[shader][slot]);
4345    if (!sampler_view || sampler_view->base.texture->target != PIPE_BUFFER)
4346       return NULL;
4347    struct zink_resource *res = zink_resource(sampler_view->base.texture);
4348    if (zink_descriptor_mode != ZINK_DESCRIPTOR_MODE_DB) {
4349       VkBufferViewCreateInfo bvci = sampler_view->buffer_view->bvci;
4350       bvci.buffer = res->obj->buffer;
4351       zink_buffer_view_reference(zink_screen(ctx->base.screen), &sampler_view->buffer_view, NULL);
4352       sampler_view->buffer_view = get_buffer_view(ctx, res, &bvci);
4353    }
4354    update_descriptor_state_sampler(ctx, shader, slot, res);
4355    if (res) {
4356       res->obj->unordered_read = false;
4357       res->obj->access |= VK_ACCESS_SHADER_READ_BIT;
4358    }
4359    ctx->invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, slot, 1);
4360    return res;
4361 }
4362 
4363 ALWAYS_INLINE static struct zink_resource *
rebind_ibo(struct zink_context * ctx,gl_shader_stage shader,unsigned slot)4364 rebind_ibo(struct zink_context *ctx, gl_shader_stage shader, unsigned slot)
4365 {
4366    struct zink_image_view *image_view = &ctx->image_views[shader][slot];
4367    struct zink_resource *res = zink_resource(image_view->base.resource);
4368    if (!res || res->base.b.target != PIPE_BUFFER)
4369       return NULL;
4370    VkBufferViewCreateInfo bvci;
4371    if (zink_descriptor_mode != ZINK_DESCRIPTOR_MODE_DB) {
4372       bvci = image_view->buffer_view->bvci;
4373       bvci.buffer = res->obj->buffer;
4374       zink_buffer_view_reference(zink_screen(ctx->base.screen), &image_view->buffer_view, NULL);
4375    }
4376    if (!zink_resource_object_init_storage(ctx, res)) {
4377       debug_printf("couldn't create storage image!");
4378       return NULL;
4379    }
4380    if (zink_descriptor_mode != ZINK_DESCRIPTOR_MODE_DB) {
4381       image_view->buffer_view = get_buffer_view(ctx, res, &bvci);
4382       assert(image_view->buffer_view);
4383    }
4384    if (res) {
4385       res->obj->unordered_read = false;
4386       res->obj->access |= VK_ACCESS_SHADER_READ_BIT;
4387       if (image_view->base.access & PIPE_IMAGE_ACCESS_WRITE) {
4388          res->obj->unordered_write = false;
4389          res->obj->access |= VK_ACCESS_SHADER_WRITE_BIT;
4390       }
4391    }
4392    util_range_add(&res->base.b, &res->valid_buffer_range, image_view->base.u.buf.offset,
4393                   image_view->base.u.buf.offset + image_view->base.u.buf.size);
4394    update_descriptor_state_image(ctx, shader, slot, res);
4395    ctx->invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_IMAGE, slot, 1);
4396    return res;
4397 }
4398 
4399 static unsigned
rebind_buffer(struct zink_context * ctx,struct zink_resource * res,uint32_t rebind_mask,const unsigned expected_num_rebinds)4400 rebind_buffer(struct zink_context *ctx, struct zink_resource *res, uint32_t rebind_mask, const unsigned expected_num_rebinds)
4401 {
4402    unsigned num_rebinds = 0;
4403    bool has_write = false;
4404 
4405    if (!zink_resource_has_binds(res))
4406       return 0;
4407 
4408    assert(!res->bindless[1]); //TODO
4409    if ((rebind_mask & BITFIELD_BIT(TC_BINDING_STREAMOUT_BUFFER)) || (!rebind_mask && res->so_bind_count && ctx->num_so_targets)) {
4410       for (unsigned i = 0; i < ctx->num_so_targets; i++) {
4411          if (ctx->so_targets[i]) {
4412             struct zink_resource *so = zink_resource(ctx->so_targets[i]->buffer);
4413             if (so && so == res) {
4414                ctx->dirty_so_targets = true;
4415                num_rebinds++;
4416             }
4417          }
4418       }
4419       rebind_mask &= ~BITFIELD_BIT(TC_BINDING_STREAMOUT_BUFFER);
4420    }
4421    if (expected_num_rebinds && num_rebinds >= expected_num_rebinds && !rebind_mask)
4422       goto end;
4423 
4424    if ((rebind_mask & BITFIELD_BIT(TC_BINDING_VERTEX_BUFFER)) || (!rebind_mask && res->vbo_bind_mask)) {
4425       u_foreach_bit(slot, res->vbo_bind_mask) {
4426          if (ctx->vertex_buffers[slot].buffer.resource != &res->base.b) //wrong context
4427             goto end;
4428          res->obj->access |= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
4429          res->obj->access_stage |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
4430          res->obj->unordered_read = false;
4431          num_rebinds++;
4432       }
4433       rebind_mask &= ~BITFIELD_BIT(TC_BINDING_VERTEX_BUFFER);
4434       ctx->vertex_buffers_dirty = true;
4435    }
4436    if (expected_num_rebinds && num_rebinds >= expected_num_rebinds && !rebind_mask)
4437       goto end;
4438 
4439    const uint32_t ubo_mask = rebind_mask ?
4440                              rebind_mask & BITFIELD_RANGE(TC_BINDING_UBO_VS, MESA_SHADER_STAGES) :
4441                              ((res->ubo_bind_count[0] ? BITFIELD_RANGE(TC_BINDING_UBO_VS, (MESA_SHADER_STAGES - 1)) : 0) |
4442                               (res->ubo_bind_count[1] ? BITFIELD_BIT(TC_BINDING_UBO_CS) : 0));
4443    u_foreach_bit(shader, ubo_mask >> TC_BINDING_UBO_VS) {
4444       u_foreach_bit(slot, res->ubo_bind_mask[shader]) {
4445          if (&res->base.b != ctx->ubos[shader][slot].buffer) //wrong context
4446             goto end;
4447          rebind_ubo(ctx, shader, slot);
4448          num_rebinds++;
4449       }
4450    }
4451    rebind_mask &= ~BITFIELD_RANGE(TC_BINDING_UBO_VS, MESA_SHADER_STAGES);
4452    if (expected_num_rebinds && num_rebinds >= expected_num_rebinds && !rebind_mask)
4453       goto end;
4454 
4455    const unsigned ssbo_mask = rebind_mask ?
4456                               rebind_mask & BITFIELD_RANGE(TC_BINDING_SSBO_VS, MESA_SHADER_STAGES) :
4457                               BITFIELD_RANGE(TC_BINDING_SSBO_VS, MESA_SHADER_STAGES);
4458    u_foreach_bit(shader, ssbo_mask >> TC_BINDING_SSBO_VS) {
4459       u_foreach_bit(slot, res->ssbo_bind_mask[shader]) {
4460          struct pipe_shader_buffer *ssbo = &ctx->ssbos[shader][slot];
4461          if (&res->base.b != ssbo->buffer) //wrong context
4462             goto end;
4463          rebind_ssbo(ctx, shader, slot);
4464          has_write |= (ctx->writable_ssbos[shader] & BITFIELD64_BIT(slot)) != 0;
4465          num_rebinds++;
4466       }
4467    }
4468    rebind_mask &= ~BITFIELD_RANGE(TC_BINDING_SSBO_VS, MESA_SHADER_STAGES);
4469    if (expected_num_rebinds && num_rebinds >= expected_num_rebinds && !rebind_mask)
4470       goto end;
4471    const unsigned sampler_mask = rebind_mask ?
4472                                  rebind_mask & BITFIELD_RANGE(TC_BINDING_SAMPLERVIEW_VS, MESA_SHADER_STAGES) :
4473                                  BITFIELD_RANGE(TC_BINDING_SAMPLERVIEW_VS, MESA_SHADER_STAGES);
4474    u_foreach_bit(shader, sampler_mask >> TC_BINDING_SAMPLERVIEW_VS) {
4475       u_foreach_bit(slot, res->sampler_binds[shader]) {
4476          struct zink_sampler_view *sampler_view = zink_sampler_view(ctx->sampler_views[shader][slot]);
4477          if (&res->base.b != sampler_view->base.texture) //wrong context
4478             goto end;
4479          rebind_tbo(ctx, shader, slot);
4480          num_rebinds++;
4481       }
4482    }
4483    rebind_mask &= ~BITFIELD_RANGE(TC_BINDING_SAMPLERVIEW_VS, MESA_SHADER_STAGES);
4484    if (expected_num_rebinds && num_rebinds >= expected_num_rebinds && !rebind_mask)
4485       goto end;
4486 
4487    const unsigned image_mask = rebind_mask ?
4488                                rebind_mask & BITFIELD_RANGE(TC_BINDING_IMAGE_VS, MESA_SHADER_STAGES) :
4489                                BITFIELD_RANGE(TC_BINDING_IMAGE_VS, MESA_SHADER_STAGES);
4490    unsigned num_image_rebinds_remaining = rebind_mask ? expected_num_rebinds - num_rebinds : res->image_bind_count[0] + res->image_bind_count[1];
4491    u_foreach_bit(shader, image_mask >> TC_BINDING_IMAGE_VS) {
4492       for (unsigned slot = 0; num_image_rebinds_remaining && slot < ctx->di.num_images[shader]; slot++) {
4493          struct zink_resource *cres = ctx->di.descriptor_res[ZINK_DESCRIPTOR_TYPE_IMAGE][shader][slot];
4494          if (res != cres)
4495             continue;
4496 
4497          rebind_ibo(ctx, shader, slot);
4498          const struct zink_image_view *image_view = &ctx->image_views[shader][slot];
4499          has_write |= (image_view->base.access & PIPE_IMAGE_ACCESS_WRITE) != 0;
4500          num_image_rebinds_remaining--;
4501          num_rebinds++;
4502       }
4503    }
4504 end:
4505    if (num_rebinds)
4506       zink_batch_resource_usage_set(&ctx->batch, res, has_write, true);
4507    return num_rebinds;
4508 }
4509 
4510 void
zink_copy_buffer(struct zink_context * ctx,struct zink_resource * dst,struct zink_resource * src,unsigned dst_offset,unsigned src_offset,unsigned size)4511 zink_copy_buffer(struct zink_context *ctx, struct zink_resource *dst, struct zink_resource *src,
4512                  unsigned dst_offset, unsigned src_offset, unsigned size)
4513 {
4514    VkBufferCopy region;
4515    region.srcOffset = src_offset;
4516    region.dstOffset = dst_offset;
4517    region.size = size;
4518 
4519    struct zink_batch *batch = &ctx->batch;
4520 
4521    struct pipe_box box = {(int)src_offset, 0, 0, (int)size, 0, 0};
4522    /* must barrier if something wrote the valid buffer range */
4523    bool valid_write = zink_check_valid_buffer_src_access(ctx, src, src_offset, size);
4524    bool unordered_src = !valid_write && !zink_check_unordered_transfer_access(src, 0, &box);
4525    zink_screen(ctx->base.screen)->buffer_barrier(ctx, src, VK_ACCESS_TRANSFER_READ_BIT, 0);
4526    bool unordered_dst = zink_resource_buffer_transfer_dst_barrier(ctx, dst, dst_offset, size);
4527    bool can_unorder = unordered_dst && unordered_src && !(zink_debug & ZINK_DEBUG_NOREORDER);
4528    VkCommandBuffer cmdbuf = can_unorder ? ctx->batch.state->reordered_cmdbuf : zink_get_cmdbuf(ctx, src, dst);
4529    ctx->batch.state->has_barriers |= can_unorder;
4530    zink_batch_reference_resource_rw(batch, src, false);
4531    zink_batch_reference_resource_rw(batch, dst, true);
4532    if (unlikely(zink_debug & ZINK_DEBUG_SYNC)) {
4533       VkMemoryBarrier mb;
4534       mb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
4535       mb.pNext = NULL;
4536       mb.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
4537       mb.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
4538       VKCTX(CmdPipelineBarrier)(cmdbuf,
4539                                 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
4540                                 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
4541                                 0, 1, &mb, 0, NULL, 0, NULL);
4542    }
4543    bool marker = zink_cmd_debug_marker_begin(ctx, cmdbuf, "copy_buffer(%d)", size);
4544    VKCTX(CmdCopyBuffer)(cmdbuf, src->obj->buffer, dst->obj->buffer, 1, &region);
4545    zink_cmd_debug_marker_end(ctx, cmdbuf, marker);
4546 }
4547 
4548 void
zink_copy_image_buffer(struct zink_context * ctx,struct zink_resource * dst,struct zink_resource * src,unsigned dst_level,unsigned dstx,unsigned dsty,unsigned dstz,unsigned src_level,const struct pipe_box * src_box,enum pipe_map_flags map_flags)4549 zink_copy_image_buffer(struct zink_context *ctx, struct zink_resource *dst, struct zink_resource *src,
4550                        unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz,
4551                        unsigned src_level, const struct pipe_box *src_box, enum pipe_map_flags map_flags)
4552 {
4553    struct zink_resource *img = dst->base.b.target == PIPE_BUFFER ? src : dst;
4554    struct zink_resource *use_img = img;
4555    struct zink_resource *buf = dst->base.b.target == PIPE_BUFFER ? dst : src;
4556    struct zink_batch *batch = &ctx->batch;
4557    bool needs_present_readback = false;
4558 
4559    bool buf2img = buf == src;
4560    bool unsync = !!(map_flags & PIPE_MAP_UNSYNCHRONIZED);
4561    if (unsync) {
4562       util_queue_fence_wait(&ctx->flush_fence);
4563       util_queue_fence_reset(&ctx->unsync_fence);
4564    }
4565 
4566    if (buf2img) {
4567       if (zink_is_swapchain(img)) {
4568          if (!zink_kopper_acquire(ctx, img, UINT64_MAX))
4569             return;
4570       }
4571       struct pipe_box box = *src_box;
4572       box.x = dstx;
4573       box.y = dsty;
4574       box.z = dstz;
4575       zink_resource_image_transfer_dst_barrier(ctx, img, dst_level, &box, unsync);
4576       if (!unsync)
4577          zink_screen(ctx->base.screen)->buffer_barrier(ctx, buf, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
4578    } else {
4579       assert(!(map_flags & PIPE_MAP_UNSYNCHRONIZED));
4580       if (zink_is_swapchain(img))
4581          needs_present_readback = zink_kopper_acquire_readback(ctx, img, &use_img);
4582       zink_screen(ctx->base.screen)->image_barrier(ctx, use_img, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 0, 0);
4583       zink_resource_buffer_transfer_dst_barrier(ctx, buf, dstx, src_box->width);
4584    }
4585 
4586    VkBufferImageCopy region = {0};
4587    region.bufferOffset = buf2img ? src_box->x : dstx;
4588    region.bufferRowLength = 0;
4589    region.bufferImageHeight = 0;
4590    region.imageSubresource.mipLevel = buf2img ? dst_level : src_level;
4591    enum pipe_texture_target img_target = img->base.b.target;
4592    if (img->need_2D)
4593       img_target = img_target == PIPE_TEXTURE_1D ? PIPE_TEXTURE_2D : PIPE_TEXTURE_2D_ARRAY;
4594    switch (img_target) {
4595    case PIPE_TEXTURE_CUBE:
4596    case PIPE_TEXTURE_CUBE_ARRAY:
4597    case PIPE_TEXTURE_2D_ARRAY:
4598    case PIPE_TEXTURE_1D_ARRAY:
4599       /* these use layer */
4600       region.imageSubresource.baseArrayLayer = buf2img ? dstz : src_box->z;
4601       region.imageSubresource.layerCount = src_box->depth;
4602       region.imageOffset.z = 0;
4603       region.imageExtent.depth = 1;
4604       break;
4605    case PIPE_TEXTURE_3D:
4606       /* this uses depth */
4607       region.imageSubresource.baseArrayLayer = 0;
4608       region.imageSubresource.layerCount = 1;
4609       region.imageOffset.z = buf2img ? dstz : src_box->z;
4610       region.imageExtent.depth = src_box->depth;
4611       break;
4612    default:
4613       /* these must only copy one layer */
4614       region.imageSubresource.baseArrayLayer = 0;
4615       region.imageSubresource.layerCount = 1;
4616       region.imageOffset.z = 0;
4617       region.imageExtent.depth = 1;
4618    }
4619    region.imageOffset.x = buf2img ? dstx : src_box->x;
4620    region.imageOffset.y = buf2img ? dsty : src_box->y;
4621 
4622    region.imageExtent.width = src_box->width;
4623    region.imageExtent.height = src_box->height;
4624 
4625    VkCommandBuffer cmdbuf = unsync ?
4626                             ctx->batch.state->unsynchronized_cmdbuf :
4627                             /* never promote to unordered if swapchain was acquired */
4628                             needs_present_readback ?
4629                             ctx->batch.state->cmdbuf :
4630                             buf2img ? zink_get_cmdbuf(ctx, buf, use_img) : zink_get_cmdbuf(ctx, use_img, buf);
4631    zink_batch_reference_resource_rw(batch, use_img, buf2img);
4632    zink_batch_reference_resource_rw(batch, buf, !buf2img);
4633    if (unsync) {
4634       ctx->batch.state->has_unsync = true;
4635       use_img->obj->unsync_access = true;
4636    }
4637 
4638    /* we're using u_transfer_helper_deinterleave, which means we'll be getting PIPE_MAP_* usage
4639     * to indicate whether to copy either the depth or stencil aspects
4640     */
4641    unsigned aspects = 0;
4642    if (map_flags) {
4643       assert((map_flags & (PIPE_MAP_DEPTH_ONLY | PIPE_MAP_STENCIL_ONLY)) !=
4644              (PIPE_MAP_DEPTH_ONLY | PIPE_MAP_STENCIL_ONLY));
4645       if (map_flags & PIPE_MAP_DEPTH_ONLY)
4646          aspects = VK_IMAGE_ASPECT_DEPTH_BIT;
4647       else if (map_flags & PIPE_MAP_STENCIL_ONLY)
4648          aspects = VK_IMAGE_ASPECT_STENCIL_BIT;
4649    }
4650    if (!aspects)
4651       aspects = img->aspect;
4652    if (unlikely(zink_debug & ZINK_DEBUG_SYNC)) {
4653       VkMemoryBarrier mb;
4654       mb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
4655       mb.pNext = NULL;
4656       mb.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
4657       mb.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
4658       VKCTX(CmdPipelineBarrier)(cmdbuf,
4659                                 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
4660                                 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
4661                                 0, 1, &mb, 0, NULL, 0, NULL);
4662    }
4663    while (aspects) {
4664       int aspect = 1 << u_bit_scan(&aspects);
4665       region.imageSubresource.aspectMask = aspect;
4666 
4667       /* MSAA transfers should have already been handled by U_TRANSFER_HELPER_MSAA_MAP, since
4668        * there's no way to resolve using this interface:
4669        *
4670        * srcImage must have a sample count equal to VK_SAMPLE_COUNT_1_BIT
4671        * - vkCmdCopyImageToBuffer spec
4672        *
4673        * dstImage must have a sample count equal to VK_SAMPLE_COUNT_1_BIT
4674        * - vkCmdCopyBufferToImage spec
4675        */
4676       assert(img->base.b.nr_samples <= 1);
4677       bool marker;
4678       if (buf2img) {
4679          marker = zink_cmd_debug_marker_begin(ctx, cmdbuf, "copy_buffer2image(%s, %dx%dx%d)",
4680                                                    util_format_short_name(dst->base.b.format),
4681                                                    region.imageExtent.width,
4682                                                    region.imageExtent.height,
4683                                                    MAX2(region.imageSubresource.layerCount, region.imageExtent.depth));
4684          VKCTX(CmdCopyBufferToImage)(cmdbuf, buf->obj->buffer, use_img->obj->image, use_img->layout, 1, &region);
4685       } else {
4686          marker = zink_cmd_debug_marker_begin(ctx, cmdbuf, "copy_image2buffer(%s, %dx%dx%d)",
4687                                                    util_format_short_name(src->base.b.format),
4688                                                    region.imageExtent.width,
4689                                                    region.imageExtent.height,
4690                                                    MAX2(region.imageSubresource.layerCount, region.imageExtent.depth));
4691          VKCTX(CmdCopyImageToBuffer)(cmdbuf, use_img->obj->image, use_img->layout, buf->obj->buffer, 1, &region);
4692       }
4693       zink_cmd_debug_marker_end(ctx, cmdbuf, marker);
4694    }
4695    if (unsync)
4696       util_queue_fence_signal(&ctx->unsync_fence);
4697    if (needs_present_readback) {
4698       assert(!unsync);
4699       if (buf2img) {
4700          img->obj->unordered_write = false;
4701          buf->obj->unordered_read = false;
4702       } else {
4703          img->obj->unordered_read = false;
4704          buf->obj->unordered_write = false;
4705       }
4706       zink_kopper_present_readback(ctx, img);
4707    }
4708 
4709    if (ctx->oom_flush && !ctx->batch.in_rp && !ctx->unordered_blitting)
4710       flush_batch(ctx, false);
4711 }
4712 
4713 static void
zink_resource_copy_region(struct pipe_context * pctx,struct pipe_resource * pdst,unsigned dst_level,unsigned dstx,unsigned dsty,unsigned dstz,struct pipe_resource * psrc,unsigned src_level,const struct pipe_box * src_box)4714 zink_resource_copy_region(struct pipe_context *pctx,
4715                           struct pipe_resource *pdst,
4716                           unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz,
4717                           struct pipe_resource *psrc,
4718                           unsigned src_level, const struct pipe_box *src_box)
4719 {
4720    struct zink_resource *dst = zink_resource(pdst);
4721    struct zink_resource *src = zink_resource(psrc);
4722    struct zink_context *ctx = zink_context(pctx);
4723    if (dst->base.b.target != PIPE_BUFFER && src->base.b.target != PIPE_BUFFER) {
4724       VkImageCopy region;
4725       /* fill struct holes */
4726       memset(&region, 0, sizeof(region));
4727       if (util_format_get_num_planes(src->base.b.format) == 1 &&
4728           util_format_get_num_planes(dst->base.b.format) == 1) {
4729       /* If neither the calling command’s srcImage nor the calling command’s dstImage
4730        * has a multi-planar image format then the aspectMask member of srcSubresource
4731        * and dstSubresource must match
4732        *
4733        * -VkImageCopy spec
4734        */
4735          assert(src->aspect == dst->aspect);
4736       } else
4737          unreachable("planar formats not yet handled");
4738 
4739 
4740       region.srcSubresource.aspectMask = src->aspect;
4741       region.srcSubresource.mipLevel = src_level;
4742       enum pipe_texture_target src_target = src->base.b.target;
4743       if (src->need_2D)
4744          src_target = src_target == PIPE_TEXTURE_1D ? PIPE_TEXTURE_2D : PIPE_TEXTURE_2D_ARRAY;
4745       switch (src_target) {
4746       case PIPE_TEXTURE_CUBE:
4747       case PIPE_TEXTURE_CUBE_ARRAY:
4748       case PIPE_TEXTURE_2D_ARRAY:
4749       case PIPE_TEXTURE_1D_ARRAY:
4750          /* these use layer */
4751          region.srcSubresource.baseArrayLayer = src_box->z;
4752          region.srcSubresource.layerCount = src_box->depth;
4753          region.srcOffset.z = 0;
4754          region.extent.depth = 1;
4755          break;
4756       case PIPE_TEXTURE_3D:
4757          /* this uses depth */
4758          region.srcSubresource.baseArrayLayer = 0;
4759          region.srcSubresource.layerCount = 1;
4760          region.srcOffset.z = src_box->z;
4761          region.extent.depth = src_box->depth;
4762          break;
4763       default:
4764          /* these must only copy one layer */
4765          region.srcSubresource.baseArrayLayer = 0;
4766          region.srcSubresource.layerCount = 1;
4767          region.srcOffset.z = 0;
4768          region.extent.depth = 1;
4769       }
4770 
4771       region.srcOffset.x = src_box->x;
4772       region.srcOffset.y = src_box->y;
4773 
4774       region.dstSubresource.aspectMask = dst->aspect;
4775       region.dstSubresource.mipLevel = dst_level;
4776       enum pipe_texture_target dst_target = dst->base.b.target;
4777       if (dst->need_2D)
4778          dst_target = dst_target == PIPE_TEXTURE_1D ? PIPE_TEXTURE_2D : PIPE_TEXTURE_2D_ARRAY;
4779       switch (dst_target) {
4780       case PIPE_TEXTURE_CUBE:
4781       case PIPE_TEXTURE_CUBE_ARRAY:
4782       case PIPE_TEXTURE_2D_ARRAY:
4783       case PIPE_TEXTURE_1D_ARRAY:
4784          /* these use layer */
4785          region.dstSubresource.baseArrayLayer = dstz;
4786          region.dstSubresource.layerCount = src_box->depth;
4787          region.dstOffset.z = 0;
4788          break;
4789       case PIPE_TEXTURE_3D:
4790          /* this uses depth */
4791          region.dstSubresource.baseArrayLayer = 0;
4792          region.dstSubresource.layerCount = 1;
4793          region.dstOffset.z = dstz;
4794          break;
4795       default:
4796          /* these must only copy one layer */
4797          region.dstSubresource.baseArrayLayer = 0;
4798          region.dstSubresource.layerCount = 1;
4799          region.dstOffset.z = 0;
4800       }
4801 
4802       region.dstOffset.x = dstx;
4803       region.dstOffset.y = dsty;
4804       region.extent.width = src_box->width;
4805       region.extent.height = src_box->height;
4806 
4807       /* ignore no-op copies */
4808       if (src == dst &&
4809           !memcmp(&region.dstOffset, &region.srcOffset, sizeof(region.srcOffset)) &&
4810           !memcmp(&region.dstSubresource, &region.srcSubresource, sizeof(region.srcSubresource)))
4811          return;
4812 
4813       zink_fb_clears_apply_or_discard(ctx, pdst, (struct u_rect){dstx, dstx + src_box->width, dsty, dsty + src_box->height}, false);
4814       zink_fb_clears_apply_region(ctx, psrc, zink_rect_from_box(src_box));
4815 
4816       struct zink_batch *batch = &ctx->batch;
4817       zink_resource_setup_transfer_layouts(ctx, src, dst);
4818       VkCommandBuffer cmdbuf = zink_get_cmdbuf(ctx, src, dst);
4819       zink_batch_reference_resource_rw(batch, src, false);
4820       zink_batch_reference_resource_rw(batch, dst, true);
4821 
4822       if (unlikely(zink_debug & ZINK_DEBUG_SYNC)) {
4823          VkMemoryBarrier mb;
4824          mb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
4825          mb.pNext = NULL;
4826          mb.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
4827          mb.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
4828          VKCTX(CmdPipelineBarrier)(cmdbuf,
4829                                    VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
4830                                    VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
4831                                    0, 1, &mb, 0, NULL, 0, NULL);
4832       }
4833       bool marker = zink_cmd_debug_marker_begin(ctx, cmdbuf, "copy_image(%s->%s, %dx%dx%d)",
4834                                                 util_format_short_name(psrc->format),
4835                                                 util_format_short_name(pdst->format),
4836                                                 region.extent.width,
4837                                                 region.extent.height,
4838                                                 MAX2(region.srcSubresource.layerCount, region.extent.depth));
4839       VKCTX(CmdCopyImage)(cmdbuf, src->obj->image, src->layout,
4840                      dst->obj->image, dst->layout,
4841                      1, &region);
4842       zink_cmd_debug_marker_end(ctx, cmdbuf, marker);
4843    } else if (dst->base.b.target == PIPE_BUFFER &&
4844               src->base.b.target == PIPE_BUFFER) {
4845       zink_copy_buffer(ctx, dst, src, dstx, src_box->x, src_box->width);
4846    } else
4847       zink_copy_image_buffer(ctx, dst, src, dst_level, dstx, dsty, dstz, src_level, src_box, 0);
4848    if (ctx->oom_flush && !ctx->batch.in_rp && !ctx->unordered_blitting)
4849       flush_batch(ctx, false);
4850 }
4851 
4852 static bool
zink_resource_commit(struct pipe_context * pctx,struct pipe_resource * pres,unsigned level,struct pipe_box * box,bool commit)4853 zink_resource_commit(struct pipe_context *pctx, struct pipe_resource *pres, unsigned level, struct pipe_box *box, bool commit)
4854 {
4855    struct zink_context *ctx = zink_context(pctx);
4856    struct zink_resource *res = zink_resource(pres);
4857 
4858    /* if any current usage exists, flush the queue */
4859    if (zink_resource_has_unflushed_usage(res))
4860       zink_flush_queue(ctx);
4861 
4862    VkSemaphore sem = VK_NULL_HANDLE;
4863    bool ret = zink_bo_commit(ctx, res, level, box, commit, &sem);
4864    if (ret) {
4865       if (sem)
4866          zink_batch_add_wait_semaphore(&ctx->batch, sem);
4867    } else {
4868       check_device_lost(ctx);
4869    }
4870 
4871    return ret;
4872 }
4873 
4874 static void
rebind_image(struct zink_context * ctx,struct zink_resource * res)4875 rebind_image(struct zink_context *ctx, struct zink_resource *res)
4876 {
4877    assert(!ctx->blitting);
4878    if (res->fb_binds)
4879       zink_rebind_framebuffer(ctx, res);
4880    if (!zink_resource_has_binds(res))
4881       return;
4882    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
4883       if (res->sampler_binds[i]) {
4884          for (unsigned j = 0; j < ctx->di.num_sampler_views[i]; j++) {
4885             struct zink_sampler_view *sv = zink_sampler_view(ctx->sampler_views[i][j]);
4886             if (sv && sv->base.texture == &res->base.b) {
4887                struct pipe_surface *psurf = &sv->image_view->base;
4888                zink_rebind_surface(ctx, &psurf);
4889                sv->image_view = zink_surface(psurf);
4890                ctx->invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, j, 1);
4891                update_descriptor_state_sampler(ctx, i, j, res);
4892             }
4893          }
4894       }
4895       if (!res->image_bind_count[i == MESA_SHADER_COMPUTE])
4896          continue;
4897       for (unsigned j = 0; j < ctx->di.num_images[i]; j++) {
4898          if (zink_resource(ctx->image_views[i][j].base.resource) == res) {
4899             ctx->invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_IMAGE, j, 1);
4900             update_descriptor_state_image(ctx, i, j, res);
4901             _mesa_set_add(ctx->need_barriers[i == MESA_SHADER_COMPUTE], res);
4902          }
4903       }
4904    }
4905 }
4906 
4907 bool
zink_resource_rebind(struct zink_context * ctx,struct zink_resource * res)4908 zink_resource_rebind(struct zink_context *ctx, struct zink_resource *res)
4909 {
4910    if (res->base.b.target == PIPE_BUFFER) {
4911       /* force counter buffer reset */
4912       res->so_valid = false;
4913       return rebind_buffer(ctx, res, 0, 0) == res->bind_count[0] + res->bind_count[1];
4914    }
4915    rebind_image(ctx, res);
4916    return false;
4917 }
4918 
4919 void
zink_rebind_all_buffers(struct zink_context * ctx)4920 zink_rebind_all_buffers(struct zink_context *ctx)
4921 {
4922    struct zink_batch *batch = &ctx->batch;
4923    ctx->vertex_buffers_dirty = ctx->gfx_pipeline_state.vertex_buffers_enabled_mask > 0;
4924    ctx->dirty_so_targets = ctx->num_so_targets > 0;
4925    if (ctx->num_so_targets)
4926       zink_screen(ctx->base.screen)->buffer_barrier(ctx, zink_resource(ctx->dummy_xfb_buffer),
4927                                    VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT);
4928    for (unsigned shader = MESA_SHADER_VERTEX; shader < MESA_SHADER_STAGES; shader++) {
4929       for (unsigned slot = 0; slot < ctx->di.num_ubos[shader]; slot++) {
4930          struct zink_resource *res = rebind_ubo(ctx, shader, slot);
4931          if (res)
4932             zink_batch_resource_usage_set(batch, res, false, true);
4933       }
4934       for (unsigned slot = 0; slot < ctx->di.num_sampler_views[shader]; slot++) {
4935          struct zink_resource *res = rebind_tbo(ctx, shader, slot);
4936          if (res)
4937             zink_batch_resource_usage_set(batch, res, false, true);
4938       }
4939       for (unsigned slot = 0; slot < ctx->di.num_ssbos[shader]; slot++) {
4940          struct zink_resource *res = rebind_ssbo(ctx, shader, slot);
4941          if (res)
4942             zink_batch_resource_usage_set(batch, res, (ctx->writable_ssbos[shader] & BITFIELD64_BIT(slot)) != 0, true);
4943       }
4944       for (unsigned slot = 0; slot < ctx->di.num_images[shader]; slot++) {
4945          struct zink_resource *res = rebind_ibo(ctx, shader, slot);
4946          if (res)
4947             zink_batch_resource_usage_set(batch, res, (ctx->image_views[shader][slot].base.access & PIPE_IMAGE_ACCESS_WRITE) != 0, true);
4948       }
4949    }
4950 }
4951 
4952 void
zink_rebind_all_images(struct zink_context * ctx)4953 zink_rebind_all_images(struct zink_context *ctx)
4954 {
4955    assert(!ctx->blitting);
4956    rebind_fb_state(ctx, NULL, false);
4957     for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
4958       for (unsigned j = 0; j < ctx->di.num_sampler_views[i]; j++) {
4959          struct zink_sampler_view *sv = zink_sampler_view(ctx->sampler_views[i][j]);
4960          if (!sv || !sv->image_view || sv->image_view->base.texture->target == PIPE_BUFFER)
4961             continue;
4962          struct zink_resource *res = zink_resource(sv->image_view->base.texture);
4963          if (res->obj != sv->image_view->obj) {
4964              struct pipe_surface *psurf = &sv->image_view->base;
4965              zink_rebind_surface(ctx, &psurf);
4966              sv->image_view = zink_surface(psurf);
4967              ctx->invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, j, 1);
4968              update_descriptor_state_sampler(ctx, i, j, res);
4969          }
4970       }
4971       for (unsigned j = 0; j < ctx->di.num_images[i]; j++) {
4972          struct zink_image_view *image_view = &ctx->image_views[i][j];
4973          struct zink_resource *res = zink_resource(image_view->base.resource);
4974          if (!res || res->base.b.target == PIPE_BUFFER)
4975             continue;
4976          if (ctx->image_views[i][j].surface->obj != res->obj) {
4977             zink_surface_reference(zink_screen(ctx->base.screen), &image_view->surface, NULL);
4978             image_view->surface = create_image_surface(ctx, &image_view->base, i == MESA_SHADER_COMPUTE);
4979             ctx->invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_IMAGE, j, 1);
4980             update_descriptor_state_image(ctx, i, j, res);
4981             _mesa_set_add(ctx->need_barriers[i == MESA_SHADER_COMPUTE], res);
4982          }
4983       }
4984    }
4985 }
4986 
4987 static void
zink_context_replace_buffer_storage(struct pipe_context * pctx,struct pipe_resource * dst,struct pipe_resource * src,unsigned num_rebinds,uint32_t rebind_mask,uint32_t delete_buffer_id)4988 zink_context_replace_buffer_storage(struct pipe_context *pctx, struct pipe_resource *dst,
4989                                     struct pipe_resource *src, unsigned num_rebinds,
4990                                     uint32_t rebind_mask, uint32_t delete_buffer_id)
4991 {
4992    struct zink_resource *d = zink_resource(dst);
4993    struct zink_resource *s = zink_resource(src);
4994    struct zink_context *ctx = zink_context(pctx);
4995    struct zink_screen *screen = zink_screen(pctx->screen);
4996 
4997    assert(d->internal_format == s->internal_format);
4998    assert(d->obj);
4999    assert(s->obj);
5000    util_idalloc_mt_free(&screen->buffer_ids, delete_buffer_id);
5001    zink_batch_reference_resource(&ctx->batch, d);
5002    /* don't be too creative */
5003    zink_resource_object_reference(screen, &d->obj, s->obj);
5004    d->valid_buffer_range = s->valid_buffer_range;
5005    zink_resource_copies_reset(d);
5006    /* force counter buffer reset */
5007    d->so_valid = false;
5008    /* FIXME: tc buffer sharedness tracking */
5009    if (!num_rebinds) {
5010       num_rebinds = d->bind_count[0] + d->bind_count[1];
5011       rebind_mask = 0;
5012    }
5013    if (num_rebinds && rebind_buffer(ctx, d, rebind_mask, num_rebinds) < num_rebinds)
5014       ctx->buffer_rebind_counter = p_atomic_inc_return(&screen->buffer_rebind_counter);
5015 }
5016 
5017 static bool
zink_context_is_resource_busy(struct pipe_screen * pscreen,struct pipe_resource * pres,unsigned usage)5018 zink_context_is_resource_busy(struct pipe_screen *pscreen, struct pipe_resource *pres, unsigned usage)
5019 {
5020    struct zink_screen *screen = zink_screen(pscreen);
5021    struct zink_resource *res = zink_resource(pres);
5022    uint32_t check_usage = 0;
5023    if (usage & PIPE_MAP_UNSYNCHRONIZED && (!res->obj->unsync_access || zink_is_swapchain(res)))
5024       return true;
5025    if (usage & PIPE_MAP_READ)
5026       check_usage |= ZINK_RESOURCE_ACCESS_WRITE;
5027    if (usage & PIPE_MAP_WRITE)
5028       check_usage |= ZINK_RESOURCE_ACCESS_RW;
5029    return !zink_resource_usage_check_completion(screen, res, check_usage);
5030 }
5031 
5032 static void
zink_emit_string_marker(struct pipe_context * pctx,const char * string,int len)5033 zink_emit_string_marker(struct pipe_context *pctx,
5034                         const char *string, int len)
5035 {
5036    struct zink_screen *screen = zink_screen(pctx->screen);
5037    struct zink_batch *batch = &zink_context(pctx)->batch;
5038 
5039    /* make sure string is nul-terminated */
5040    char buf[512], *temp = NULL;
5041    if (len < ARRAY_SIZE(buf)) {
5042       memcpy(buf, string, len);
5043       buf[len] = '\0';
5044       string = buf;
5045    } else
5046       string = temp = strndup(string, len);
5047 
5048    VkDebugUtilsLabelEXT label = {
5049       VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, NULL,
5050       string,
5051       { 0 }
5052    };
5053    screen->vk.CmdInsertDebugUtilsLabelEXT(batch->state->cmdbuf, &label);
5054    free(temp);
5055 }
5056 
5057 VkIndirectCommandsLayoutTokenNV *
zink_dgc_add_token(struct zink_context * ctx,VkIndirectCommandsTokenTypeNV type,void ** mem)5058 zink_dgc_add_token(struct zink_context *ctx, VkIndirectCommandsTokenTypeNV type, void **mem)
5059 {
5060    size_t size = 0;
5061    struct zink_screen *screen = zink_screen(ctx->base.screen);
5062    VkIndirectCommandsLayoutTokenNV *ret = util_dynarray_grow(&ctx->dgc.tokens, VkIndirectCommandsLayoutTokenNV, 1);
5063    ret->sType = VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_TOKEN_NV;
5064    ret->pNext = NULL;
5065    ret->tokenType = type;
5066    ret->vertexDynamicStride = ctx->gfx_pipeline_state.uses_dynamic_stride;
5067    ret->indirectStateFlags = 0;
5068    ret->indexTypeCount = 0;
5069    switch (type) {
5070    case VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NV:
5071       ret->stream = ZINK_DGC_VBO;
5072       size = sizeof(VkBindVertexBufferIndirectCommandNV);
5073       break;
5074    case VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NV:
5075       ret->stream = ZINK_DGC_IB;
5076       size = sizeof(VkBindIndexBufferIndirectCommandNV);
5077       break;
5078    case VK_INDIRECT_COMMANDS_TOKEN_TYPE_SHADER_GROUP_NV:
5079       ret->stream = ZINK_DGC_PSO;
5080       size = sizeof(VkBindShaderGroupIndirectCommandNV);
5081       break;
5082    case VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV:
5083       ret->stream = ZINK_DGC_PUSH;
5084       ret->pushconstantPipelineLayout = ctx->dgc.last_prog->base.layout;
5085       ret->pushconstantShaderStageFlags = VK_SHADER_STAGE_ALL_GRAPHICS;
5086       size = sizeof(float) * 6; //size for full tess level upload every time
5087       break;
5088    case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NV:
5089       ret->stream = ZINK_DGC_DRAW;
5090       size = sizeof(VkDrawIndirectCommand);
5091       break;
5092    case VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NV:
5093       ret->stream = ZINK_DGC_DRAW;
5094       size = sizeof(VkDrawIndexedIndirectCommand);
5095       break;
5096    default:
5097       unreachable("ack");
5098    }
5099    struct zink_resource *old = NULL;
5100    unsigned stream_count = screen->info.nv_dgc_props.maxIndirectCommandsStreamCount >= ZINK_DGC_MAX ? ZINK_DGC_MAX : 1;
5101    if (stream_count == 1)
5102       ret->stream = 0;
5103    unsigned stream = ret->stream;
5104    bool max_exceeded = !ctx->dgc.max_size[stream];
5105    ret->offset = ctx->dgc.cur_offsets[stream];
5106    if (ctx->dgc.buffers[stream]) {
5107       /* detect end of buffer */
5108       if (ctx->dgc.bind_offsets[stream] + ctx->dgc.cur_offsets[stream] + size > ctx->dgc.buffers[stream]->base.b.width0) {
5109          old = ctx->dgc.buffers[stream];
5110          ctx->dgc.buffers[stream] = NULL;
5111          max_exceeded = true;
5112       }
5113    }
5114    if (!ctx->dgc.buffers[stream]) {
5115       if (max_exceeded)
5116          ctx->dgc.max_size[stream] += size * 5;
5117       uint8_t *ptr;
5118       unsigned offset;
5119       u_upload_alloc(ctx->dgc.upload[stream], 0, ctx->dgc.max_size[stream],
5120                      screen->info.props.limits.minMemoryMapAlignment, &offset,
5121                      (struct pipe_resource **)&ctx->dgc.buffers[stream], (void **)&ptr);
5122       size_t cur_size = old ? (ctx->dgc.cur_offsets[stream] - ctx->dgc.bind_offsets[stream]) : 0;
5123       if (old) {
5124          struct pipe_resource *pold = &old->base.b;
5125          /* copy and delete old buffer */
5126          zink_batch_reference_resource_rw(&ctx->batch, old, true);
5127          memcpy(ptr + offset, ctx->dgc.maps[stream] + ctx->dgc.bind_offsets[stream], cur_size);
5128          pipe_resource_reference(&pold, NULL);
5129       }
5130       ctx->dgc.maps[stream] = ptr;
5131       ctx->dgc.bind_offsets[stream] = offset;
5132       ctx->dgc.cur_offsets[stream] = cur_size;
5133    }
5134    *mem = ctx->dgc.maps[stream] + ctx->dgc.cur_offsets[stream];
5135    ctx->dgc.cur_offsets[stream] += size;
5136    return ret;
5137 }
5138 
5139 void
zink_flush_dgc(struct zink_context * ctx)5140 zink_flush_dgc(struct zink_context *ctx)
5141 {
5142    struct zink_screen *screen = zink_screen(ctx->base.screen);
5143    struct zink_batch_state *bs = ctx->batch.state;
5144    if (!ctx->dgc.valid)
5145       return;
5146 
5147    /* tokens should be created as they are used */
5148    unsigned num_cmds = util_dynarray_num_elements(&ctx->dgc.tokens, VkIndirectCommandsLayoutTokenNV);
5149    assert(num_cmds);
5150    VkIndirectCommandsLayoutTokenNV *cmds = ctx->dgc.tokens.data;
5151    uint32_t strides[ZINK_DGC_MAX] = {0};
5152 
5153    unsigned stream_count = screen->info.nv_dgc_props.maxIndirectCommandsStreamCount >= ZINK_DGC_MAX ? ZINK_DGC_MAX : 1;
5154    VkIndirectCommandsStreamNV streams[ZINK_DGC_MAX];
5155    for (unsigned i = 0; i < stream_count; i++) {
5156       if (ctx->dgc.buffers[i]) {
5157          streams[i].buffer = ctx->dgc.buffers[i]->obj->buffer;
5158          streams[i].offset = ctx->dgc.bind_offsets[i];
5159       } else {
5160          streams[i].buffer = zink_resource(ctx->dummy_vertex_buffer)->obj->buffer;
5161          streams[i].offset = 0;
5162       }
5163    }
5164    /* this is a stupid pipeline that will never actually be used as anything but a container */
5165    VkPipeline pipeline = VK_NULL_HANDLE;
5166    if (screen->info.nv_dgc_props.maxGraphicsShaderGroupCount == 1) {
5167       /* RADV doesn't support shader pipeline binds, so use this hacky path */
5168       pipeline = ctx->gfx_pipeline_state.pipeline;
5169    } else {
5170       VkPrimitiveTopology vkmode = zink_primitive_topology(ctx->gfx_pipeline_state.gfx_prim_mode);
5171       pipeline = zink_create_gfx_pipeline(screen, ctx->dgc.last_prog, ctx->dgc.last_prog->objs, &ctx->gfx_pipeline_state, ctx->gfx_pipeline_state.element_state->binding_map, vkmode, false, &ctx->dgc.pipelines);
5172       assert(pipeline);
5173       util_dynarray_append(&bs->dgc.pipelines, VkPipeline, pipeline);
5174       VKCTX(CmdBindPipelineShaderGroupNV)(bs->cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline, 0);
5175    }
5176    unsigned remaining = num_cmds;
5177    for (unsigned i = 0; i < num_cmds; i += screen->info.nv_dgc_props.maxIndirectCommandsTokenCount, remaining -= screen->info.nv_dgc_props.maxIndirectCommandsTokenCount) {
5178       VkIndirectCommandsLayoutCreateInfoNV lci = {
5179          VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NV,
5180          NULL,
5181          0,
5182          VK_PIPELINE_BIND_POINT_GRAPHICS,
5183          MIN2(remaining, screen->info.nv_dgc_props.maxIndirectCommandsTokenCount),
5184          cmds + i,
5185          stream_count,
5186          strides
5187       };
5188       VkIndirectCommandsLayoutNV iclayout;
5189       ASSERTED VkResult res = VKSCR(CreateIndirectCommandsLayoutNV)(screen->dev, &lci, NULL, &iclayout);
5190       assert(res == VK_SUCCESS);
5191       util_dynarray_append(&bs->dgc.layouts, VkIndirectCommandsLayoutNV, iclayout);
5192 
5193       /* a lot of hacks to set up a preprocess buffer */
5194       VkGeneratedCommandsMemoryRequirementsInfoNV info = {
5195          VK_STRUCTURE_TYPE_GENERATED_COMMANDS_MEMORY_REQUIREMENTS_INFO_NV,
5196          NULL,
5197          VK_PIPELINE_BIND_POINT_GRAPHICS,
5198          pipeline,
5199          iclayout,
5200          1
5201       };
5202       VkMemoryRequirements2 reqs = {
5203          VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2
5204       };
5205       VKSCR(GetGeneratedCommandsMemoryRequirementsNV)(screen->dev, &info, &reqs);
5206       struct pipe_resource templ = {0};
5207       templ.target = PIPE_BUFFER;
5208       templ.format = PIPE_FORMAT_R8_UNORM;
5209       templ.bind = 0;
5210       templ.usage = PIPE_USAGE_IMMUTABLE;
5211       templ.flags = 0;
5212       templ.width0 = reqs.memoryRequirements.size;
5213       templ.height0 = 1;
5214       templ.depth0 = 1;
5215       templ.array_size = 1;
5216       uint64_t params[] = {reqs.memoryRequirements.size, reqs.memoryRequirements.alignment, reqs.memoryRequirements.memoryTypeBits};
5217       struct pipe_resource *pres = screen->base.resource_create_with_modifiers(&screen->base, &templ, params, 3);
5218       assert(pres);
5219       zink_batch_reference_resource_rw(&ctx->batch, zink_resource(pres), true);
5220 
5221       VkGeneratedCommandsInfoNV gen = {
5222          VK_STRUCTURE_TYPE_GENERATED_COMMANDS_INFO_NV,
5223          NULL,
5224          VK_PIPELINE_BIND_POINT_GRAPHICS,
5225          pipeline,
5226          iclayout,
5227          stream_count,
5228          streams,
5229          1,
5230          zink_resource(pres)->obj->buffer,
5231          0,
5232          pres->width0,
5233          VK_NULL_HANDLE,
5234          0,
5235          VK_NULL_HANDLE,
5236          0
5237       };
5238       VKCTX(CmdExecuteGeneratedCommandsNV)(ctx->batch.state->cmdbuf, VK_FALSE, &gen);
5239 
5240       pipe_resource_reference(&pres, NULL);
5241    }
5242    util_dynarray_clear(&ctx->dgc.pipelines);
5243    util_dynarray_clear(&ctx->dgc.tokens);
5244    ctx->dgc.valid = false;
5245    ctx->pipeline_changed[0] = true;
5246    zink_select_draw_vbo(ctx);
5247 }
5248 
5249 struct pipe_surface *
zink_get_dummy_pipe_surface(struct zink_context * ctx,int samples_index)5250 zink_get_dummy_pipe_surface(struct zink_context *ctx, int samples_index)
5251 {
5252    unsigned size = calc_max_dummy_fbo_size(ctx);
5253    bool needs_null_init = false;
5254    if (ctx->dummy_surface[samples_index]) {
5255       /* delete old surface if ETOOSMALL */
5256       struct zink_resource *res = zink_resource(ctx->dummy_surface[samples_index]->texture);
5257       if (res->base.b.width0 > size || res->base.b.height0 > size) {
5258          pipe_surface_release(&ctx->base, &ctx->dummy_surface[samples_index]);
5259          needs_null_init = !samples_index && ctx->di.null_fbfetch_init;
5260          if (!samples_index)
5261             ctx->di.null_fbfetch_init = false;
5262       }
5263    }
5264    if (!ctx->dummy_surface[samples_index]) {
5265       ctx->dummy_surface[samples_index] = zink_surface_create_null(ctx, PIPE_TEXTURE_2D, size, size, BITFIELD_BIT(samples_index));
5266       assert(ctx->dummy_surface[samples_index]);
5267       /* This is possibly used with imageLoad which according to GL spec must return 0 */
5268       if (!samples_index) {
5269          union pipe_color_union color = {0};
5270          struct pipe_box box;
5271          u_box_2d(0, 0, size, size, &box);
5272          ctx->base.clear_texture(&ctx->base, ctx->dummy_surface[samples_index]->texture, 0, &box, &color);
5273       }
5274    }
5275    if (needs_null_init)
5276       init_null_fbfetch(ctx);
5277    return ctx->dummy_surface[samples_index];
5278 }
5279 
5280 struct zink_surface *
zink_get_dummy_surface(struct zink_context * ctx,int samples_index)5281 zink_get_dummy_surface(struct zink_context *ctx, int samples_index)
5282 {
5283    return zink_csurface(zink_get_dummy_pipe_surface(ctx, samples_index));
5284 
5285 }
5286 
5287 static void
zink_tc_parse_dsa(void * state,struct tc_renderpass_info * info)5288 zink_tc_parse_dsa(void *state, struct tc_renderpass_info *info)
5289 {
5290    struct zink_depth_stencil_alpha_state *cso = state;
5291    info->zsbuf_write_dsa |= (cso->hw_state.depth_write || cso->hw_state.stencil_test);
5292    info->zsbuf_read_dsa |= (cso->hw_state.depth_test || cso->hw_state.stencil_test);
5293    /* TODO: if zsbuf fbfetch is ever supported */
5294 }
5295 
5296 static void
zink_tc_parse_fs(void * state,struct tc_renderpass_info * info)5297 zink_tc_parse_fs(void *state, struct tc_renderpass_info *info)
5298 {
5299    struct zink_shader *zs = state;
5300    info->zsbuf_write_fs |= zs->info.outputs_written & (BITFIELD64_BIT(FRAG_RESULT_DEPTH) | BITFIELD64_BIT(FRAG_RESULT_STENCIL));
5301    /* TODO: if >1 fbfetch attachment is ever supported */
5302    info->cbuf_fbfetch |= zs->info.fs.uses_fbfetch_output ? BITFIELD_BIT(0) : 0;
5303 }
5304 
5305 void
zink_parse_tc_info(struct zink_context * ctx)5306 zink_parse_tc_info(struct zink_context *ctx)
5307 {
5308    struct tc_renderpass_info *info = &ctx->dynamic_fb.tc_info;
5309    /* reset cso info first */
5310    info->data16[2] = 0;
5311    if (ctx->gfx_stages[MESA_SHADER_FRAGMENT])
5312       zink_tc_parse_fs(ctx->gfx_stages[MESA_SHADER_FRAGMENT], info);
5313    if (ctx->dsa_state)
5314       zink_tc_parse_dsa(ctx->dsa_state, info);
5315    if (ctx->zsbuf_unused == zink_is_zsbuf_used(ctx))
5316       ctx->rp_layout_changed = true;
5317 }
5318 
5319 struct pipe_context *
zink_context_create(struct pipe_screen * pscreen,void * priv,unsigned flags)5320 zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
5321 {
5322    struct zink_screen *screen = zink_screen(pscreen);
5323    struct zink_context *ctx = rzalloc(NULL, struct zink_context);
5324    bool is_copy_only = (flags & ZINK_CONTEXT_COPY_ONLY) > 0;
5325    bool is_compute_only = (flags & PIPE_CONTEXT_COMPUTE_ONLY) > 0;
5326    bool is_robust = (flags & PIPE_CONTEXT_ROBUST_BUFFER_ACCESS) > 0;
5327    if (!ctx)
5328       goto fail;
5329 
5330    ctx->flags = flags;
5331    ctx->pipeline_changed[0] = ctx->pipeline_changed[1] = true;
5332    ctx->gfx_pipeline_state.dirty = true;
5333    ctx->gfx_pipeline_state.dyn_state2.vertices_per_patch = 1;
5334    ctx->gfx_pipeline_state.uses_dynamic_stride = screen->info.have_EXT_extended_dynamic_state ||
5335                                                  screen->info.have_EXT_vertex_input_dynamic_state;
5336    ctx->compute_pipeline_state.dirty = true;
5337    ctx->fb_changed = ctx->rp_changed = true;
5338    ctx->sample_mask_changed = true;
5339    ctx->gfx_pipeline_state.gfx_prim_mode = MESA_PRIM_COUNT;
5340    ctx->gfx_pipeline_state.shader_rast_prim = MESA_PRIM_COUNT;
5341    ctx->gfx_pipeline_state.rast_prim = MESA_PRIM_COUNT;
5342 
5343    zink_init_draw_functions(ctx, screen);
5344    zink_init_grid_functions(ctx);
5345 
5346    ctx->base.screen = pscreen;
5347    ctx->base.priv = priv;
5348 
5349    ctx->base.destroy = zink_context_destroy;
5350    ctx->base.set_debug_callback = zink_set_debug_callback;
5351    ctx->base.get_device_reset_status = zink_get_device_reset_status;
5352    ctx->base.set_device_reset_callback = zink_set_device_reset_callback;
5353 
5354    zink_context_state_init(&ctx->base);
5355 
5356    ctx->base.create_sampler_state = zink_create_sampler_state;
5357    ctx->base.bind_sampler_states = screen->info.have_EXT_non_seamless_cube_map ? zink_bind_sampler_states : zink_bind_sampler_states_nonseamless;
5358    ctx->base.delete_sampler_state = zink_delete_sampler_state;
5359 
5360    ctx->base.create_sampler_view = zink_create_sampler_view;
5361    ctx->base.set_sampler_views = zink_set_sampler_views;
5362    ctx->base.sampler_view_destroy = zink_sampler_view_destroy;
5363    ctx->base.get_sample_position = zink_get_sample_position;
5364    ctx->base.set_sample_locations = zink_set_sample_locations;
5365 
5366    zink_program_init(ctx);
5367 
5368    ctx->base.set_polygon_stipple = zink_set_polygon_stipple;
5369    ctx->base.set_vertex_buffers = zink_set_vertex_buffers;
5370    ctx->base.set_viewport_states = zink_set_viewport_states;
5371    ctx->base.set_scissor_states = zink_set_scissor_states;
5372    ctx->base.set_inlinable_constants = zink_set_inlinable_constants;
5373    ctx->base.set_constant_buffer = zink_set_constant_buffer;
5374    ctx->base.set_shader_buffers = zink_set_shader_buffers;
5375    ctx->base.set_shader_images = zink_set_shader_images;
5376    ctx->base.set_framebuffer_state = zink_set_framebuffer_state;
5377    ctx->base.set_stencil_ref = zink_set_stencil_ref;
5378    ctx->base.set_clip_state = zink_set_clip_state;
5379    ctx->base.set_blend_color = zink_set_blend_color;
5380    ctx->base.set_tess_state = zink_set_tess_state;
5381    ctx->base.set_patch_vertices = zink_set_patch_vertices;
5382 
5383    ctx->base.set_min_samples = zink_set_min_samples;
5384    ctx->gfx_pipeline_state.min_samples = 0;
5385    ctx->base.set_sample_mask = zink_set_sample_mask;
5386    ctx->gfx_pipeline_state.sample_mask = UINT32_MAX;
5387 
5388    ctx->base.clear = zink_clear;
5389    ctx->base.clear_texture = screen->info.have_KHR_dynamic_rendering ? zink_clear_texture_dynamic : zink_clear_texture;
5390    ctx->base.clear_buffer = zink_clear_buffer;
5391    ctx->base.clear_render_target = zink_clear_render_target;
5392    ctx->base.clear_depth_stencil = zink_clear_depth_stencil;
5393 
5394    ctx->base.create_fence_fd = zink_create_fence_fd;
5395    ctx->base.fence_server_sync = zink_fence_server_sync;
5396    ctx->base.fence_server_signal = zink_fence_server_signal;
5397    ctx->base.flush = zink_flush;
5398    ctx->base.memory_barrier = zink_memory_barrier;
5399    ctx->base.texture_barrier = zink_texture_barrier;
5400    ctx->base.evaluate_depth_buffer = zink_evaluate_depth_buffer;
5401 
5402    ctx->base.resource_commit = zink_resource_commit;
5403    ctx->base.resource_copy_region = zink_resource_copy_region;
5404    ctx->base.blit = zink_blit;
5405    ctx->base.create_stream_output_target = zink_create_stream_output_target;
5406    ctx->base.stream_output_target_destroy = zink_stream_output_target_destroy;
5407 
5408    ctx->base.set_stream_output_targets = zink_set_stream_output_targets;
5409    ctx->base.flush_resource = zink_flush_resource;
5410    if (screen->info.have_KHR_buffer_device_address)
5411       ctx->base.set_global_binding = zink_set_global_binding;
5412 
5413    ctx->base.emit_string_marker = zink_emit_string_marker;
5414 
5415    zink_context_surface_init(&ctx->base);
5416    zink_context_resource_init(&ctx->base);
5417    zink_context_query_init(&ctx->base);
5418 
5419    util_queue_fence_init(&ctx->flush_fence);
5420    util_queue_fence_init(&ctx->unsync_fence);
5421 
5422    list_inithead(&ctx->query_pools);
5423    _mesa_set_init(&ctx->update_barriers[0][0], ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);
5424    _mesa_set_init(&ctx->update_barriers[1][0], ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);
5425    _mesa_set_init(&ctx->update_barriers[0][1], ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);
5426    _mesa_set_init(&ctx->update_barriers[1][1], ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);
5427    ctx->need_barriers[0] = &ctx->update_barriers[0][0];
5428    ctx->need_barriers[1] = &ctx->update_barriers[1][0];
5429 
5430    slab_create_child(&ctx->transfer_pool, &screen->transfer_pool);
5431    slab_create_child(&ctx->transfer_pool_unsync, &screen->transfer_pool);
5432 
5433    ctx->base.stream_uploader = u_upload_create_default(&ctx->base);
5434    ctx->base.const_uploader = u_upload_create_default(&ctx->base);
5435    for (int i = 0; i < ARRAY_SIZE(ctx->fb_clears); i++)
5436       util_dynarray_init(&ctx->fb_clears[i].clears, ctx);
5437 
5438    if (zink_debug & ZINK_DEBUG_DGC) {
5439       util_dynarray_init(&ctx->dgc.pipelines, ctx);
5440       util_dynarray_init(&ctx->dgc.tokens, ctx);
5441       for (unsigned i = 0; i < ARRAY_SIZE(ctx->dgc.upload); i++)
5442          ctx->dgc.upload[i] = u_upload_create_default(&ctx->base);
5443    }
5444 
5445    if (!is_copy_only) {
5446       ctx->blitter = util_blitter_create(&ctx->base);
5447       if (!ctx->blitter)
5448          goto fail;
5449    }
5450 
5451    zink_set_last_vertex_key(ctx)->last_vertex_stage = true;
5452    ctx->gfx_pipeline_state.shader_keys.last_vertex.key.vs_base.last_vertex_stage = true;
5453    zink_set_tcs_key_patches(ctx, 1);
5454    if (!screen->optimal_keys) {
5455       ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_VERTEX].size = sizeof(struct zink_vs_key_base);
5456       ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_TESS_EVAL].size = sizeof(struct zink_vs_key_base);
5457       ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_TESS_CTRL].size = sizeof(struct zink_tcs_key);
5458       ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_GEOMETRY].size = sizeof(struct zink_gs_key);
5459       ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].size = sizeof(struct zink_fs_key);
5460 
5461       /* this condition must be updated if new fields are added to zink_cs_key */
5462       if (screen->driver_workarounds.lower_robustImageAccess2)
5463     	  ctx->compute_pipeline_state.key.size = sizeof(struct zink_cs_key);
5464 
5465       if (is_robust && screen->driver_workarounds.lower_robustImageAccess2) {
5466          ctx->compute_pipeline_state.key.key.cs.robust_access = true;
5467          for (gl_shader_stage pstage = MESA_SHADER_VERTEX; pstage < MESA_SHADER_FRAGMENT; pstage++)
5468             ctx->gfx_pipeline_state.shader_keys.key[pstage].key.vs_base.robust_access = true;
5469          ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs.robust_access = true;
5470       }
5471    }
5472    _mesa_hash_table_init(&ctx->framebuffer_cache, ctx, hash_framebuffer_imageless, equals_framebuffer_imageless);
5473    if (!zink_init_render_pass(ctx))
5474       goto fail;
5475    for (unsigned i = 0; i < ARRAY_SIZE(ctx->rendering_state_cache); i++)
5476       _mesa_set_init(&ctx->rendering_state_cache[i], ctx, hash_rendering_state, equals_rendering_state);
5477    ctx->dynamic_fb.info.pColorAttachments = ctx->dynamic_fb.attachments;
5478    ctx->dynamic_fb.info.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
5479    for (unsigned i = 0; i < ARRAY_SIZE(ctx->dynamic_fb.attachments); i++) {
5480       VkRenderingAttachmentInfo *att = &ctx->dynamic_fb.attachments[i];
5481       att->sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
5482       att->imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
5483       att->storeOp = VK_ATTACHMENT_STORE_OP_STORE;
5484    }
5485    ctx->gfx_pipeline_state.rendering_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
5486    ctx->gfx_pipeline_state.rendering_info.pColorAttachmentFormats = ctx->gfx_pipeline_state.rendering_formats;
5487    ctx->gfx_pipeline_state.feedback_loop = screen->driver_workarounds.always_feedback_loop;
5488    ctx->gfx_pipeline_state.feedback_loop_zs = screen->driver_workarounds.always_feedback_loop_zs;
5489 
5490    const uint32_t data[] = {0};
5491    if (!is_copy_only) {
5492       ctx->dummy_vertex_buffer = pipe_buffer_create(&screen->base,
5493          PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_SHADER_IMAGE, PIPE_USAGE_IMMUTABLE, sizeof(data));
5494       if (!ctx->dummy_vertex_buffer)
5495          goto fail;
5496       ctx->dummy_xfb_buffer = pipe_buffer_create(&screen->base,
5497          PIPE_BIND_STREAM_OUTPUT, PIPE_USAGE_IMMUTABLE, sizeof(data));
5498       if (!ctx->dummy_xfb_buffer)
5499          goto fail;
5500    }
5501    if (!is_copy_only) {
5502       VkBufferViewCreateInfo bvci = create_bvci(ctx, zink_resource(ctx->dummy_vertex_buffer), PIPE_FORMAT_R8G8B8A8_UNORM, 0, sizeof(data));
5503       ctx->dummy_bufferview = get_buffer_view(ctx, zink_resource(ctx->dummy_vertex_buffer), &bvci);
5504       if (!ctx->dummy_bufferview)
5505          goto fail;
5506 
5507       if (!zink_descriptors_init(ctx))
5508          goto fail;
5509    }
5510 
5511    if (!is_copy_only && !is_compute_only) {
5512       ctx->base.create_texture_handle = zink_create_texture_handle;
5513       ctx->base.delete_texture_handle = zink_delete_texture_handle;
5514       ctx->base.make_texture_handle_resident = zink_make_texture_handle_resident;
5515       ctx->base.create_image_handle = zink_create_image_handle;
5516       ctx->base.delete_image_handle = zink_delete_image_handle;
5517       ctx->base.make_image_handle_resident = zink_make_image_handle_resident;
5518       for (unsigned i = 0; i < 2; i++) {
5519          _mesa_hash_table_init(&ctx->di.bindless[i].img_handles, ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);
5520          _mesa_hash_table_init(&ctx->di.bindless[i].tex_handles, ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);
5521 
5522          /* allocate 1024 slots and reserve slot 0 */
5523          util_idalloc_init(&ctx->di.bindless[i].tex_slots, ZINK_MAX_BINDLESS_HANDLES);
5524          util_idalloc_alloc(&ctx->di.bindless[i].tex_slots);
5525          util_idalloc_init(&ctx->di.bindless[i].img_slots, ZINK_MAX_BINDLESS_HANDLES);
5526          util_idalloc_alloc(&ctx->di.bindless[i].img_slots);
5527          if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB) {
5528             ctx->di.bindless[i].db.buffer_infos = malloc(sizeof(VkDescriptorAddressInfoEXT) * ZINK_MAX_BINDLESS_HANDLES);
5529             if (!ctx->di.bindless[i].db.buffer_infos) {
5530                mesa_loge("ZINK: failed to allocate ctx->di.bindless[%d].db.buffer_infos!",i);
5531                goto fail;
5532             }
5533             for (unsigned j = 0; j < ZINK_MAX_BINDLESS_HANDLES; j++) {
5534                ctx->di.bindless[i].db.buffer_infos[j].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_ADDRESS_INFO_EXT;
5535                ctx->di.bindless[i].db.buffer_infos[j].pNext = NULL;
5536             }
5537          } else {
5538             ctx->di.bindless[i].t.buffer_infos = malloc(sizeof(VkBufferView) * ZINK_MAX_BINDLESS_HANDLES);
5539             if (!ctx->di.bindless[i].t.buffer_infos) {
5540                mesa_loge("ZINK: failed to allocate ctx->di.bindless[%d].t.buffer_infos!",i);
5541                goto fail;
5542             }
5543          }
5544          ctx->di.bindless[i].img_infos = malloc(sizeof(VkDescriptorImageInfo) * ZINK_MAX_BINDLESS_HANDLES);
5545          if (!ctx->di.bindless[i].img_infos) {
5546             mesa_loge("ZINK: failed to allocate ctx->di.bindless[%d].img_infos!",i);
5547             goto fail;
5548          }
5549          util_dynarray_init(&ctx->di.bindless[i].updates, NULL);
5550          util_dynarray_init(&ctx->di.bindless[i].resident, NULL);
5551       }
5552    }
5553 
5554    simple_mtx_init(&ctx->batch.ref_lock, mtx_plain);
5555    zink_start_batch(ctx, &ctx->batch);
5556    if (!ctx->batch.state)
5557       goto fail;
5558 
5559    if (screen->compact_descriptors)
5560       ctx->invalidate_descriptor_state = zink_context_invalidate_descriptor_state_compact;
5561    else
5562       ctx->invalidate_descriptor_state = zink_context_invalidate_descriptor_state;
5563    if (!is_copy_only && !is_compute_only) {
5564       pipe_buffer_write_nooverlap(&ctx->base, ctx->dummy_vertex_buffer, 0, sizeof(data), data);
5565       pipe_buffer_write_nooverlap(&ctx->base, ctx->dummy_xfb_buffer, 0, sizeof(data), data);
5566       if (screen->info.have_EXT_color_write_enable)
5567          reapply_color_write(ctx);
5568 
5569       /* set on startup just to avoid validation errors if a draw comes through without
5570       * a tess shader later
5571       */
5572       if (screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints) {
5573          VKCTX(CmdSetPatchControlPointsEXT)(ctx->batch.state->cmdbuf, 1);
5574          VKCTX(CmdSetPatchControlPointsEXT)(ctx->batch.state->reordered_cmdbuf, 1);
5575       }
5576    }
5577    if (!is_copy_only) {
5578       for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
5579          /* need to update these based on screen config for null descriptors */
5580          for (unsigned j = 0; j < ARRAY_SIZE(ctx->di.t.ubos[i]); j++) {
5581             update_descriptor_state_ubo(ctx, i, j, NULL);
5582             if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB)
5583                ctx->di.db.ubos[i][j].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_ADDRESS_INFO_EXT;
5584          }
5585          for (unsigned j = 0; j < ARRAY_SIZE(ctx->di.textures[i]); j++) {
5586             update_descriptor_state_sampler(ctx, i, j, NULL);
5587             if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB)
5588                ctx->di.db.tbos[i][j].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_ADDRESS_INFO_EXT;
5589          }
5590          for (unsigned j = 0; j < ARRAY_SIZE(ctx->di.t.ssbos[i]); j++) {
5591             update_descriptor_state_ssbo(ctx, i, j, NULL);
5592             if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB)
5593                ctx->di.db.ssbos[i][j].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_ADDRESS_INFO_EXT;
5594          }
5595          for (unsigned j = 0; j < ARRAY_SIZE(ctx->di.images[i]); j++) {
5596             update_descriptor_state_image(ctx, i, j, NULL);
5597             if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB)
5598                ctx->di.db.texel_images[i][j].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_ADDRESS_INFO_EXT;
5599          }
5600       }
5601 
5602       p_atomic_inc(&screen->base.num_contexts);
5603    }
5604 
5605    zink_select_draw_vbo(ctx);
5606    zink_select_launch_grid(ctx);
5607 
5608    if (!is_copy_only && zink_debug & ZINK_DEBUG_SHADERDB) {
5609       if (!screen->info.have_EXT_vertex_input_dynamic_state) {
5610          struct pipe_vertex_element velems[32] = {0};
5611          for (unsigned i = 0; i < ARRAY_SIZE(velems); i++)
5612             velems[i].src_format = PIPE_FORMAT_R8G8B8_UNORM;
5613          void *state = ctx->base.create_vertex_elements_state(&ctx->base, ARRAY_SIZE(velems), velems);
5614          ctx->base.bind_vertex_elements_state(&ctx->base, state);
5615       }
5616       ctx->gfx_pipeline_state.sample_mask = BITFIELD_MASK(32);
5617       struct pipe_framebuffer_state fb = {0};
5618       fb.cbufs[0] = zink_get_dummy_pipe_surface(ctx, 0);
5619       fb.nr_cbufs = 1;
5620       fb.width = fb.height = 256;
5621       ctx->base.set_framebuffer_state(&ctx->base, &fb);
5622       ctx->disable_fs = true;
5623       struct pipe_depth_stencil_alpha_state dsa = {0};
5624       void *state = ctx->base.create_depth_stencil_alpha_state(&ctx->base, &dsa);
5625       ctx->base.bind_depth_stencil_alpha_state(&ctx->base, state);
5626 
5627       struct pipe_blend_state blend = {
5628          .rt[0].colormask = 0xF
5629       };
5630 
5631       void *blend_state = ctx->base.create_blend_state(&ctx->base, &blend);
5632       ctx->base.bind_blend_state(&ctx->base, blend_state);
5633 
5634       zink_batch_rp(ctx);
5635    }
5636 
5637    if (!(flags & PIPE_CONTEXT_PREFER_THREADED) || flags & PIPE_CONTEXT_COMPUTE_ONLY) {
5638       return &ctx->base;
5639    }
5640 
5641    struct threaded_context *tc = (struct threaded_context*)threaded_context_create(&ctx->base, &screen->transfer_pool,
5642                                                      zink_context_replace_buffer_storage,
5643                                                      &(struct threaded_context_options){
5644                                                         .create_fence = zink_create_tc_fence_for_tc,
5645                                                         .is_resource_busy = zink_context_is_resource_busy,
5646                                                         .driver_calls_flush_notify = !screen->driver_workarounds.track_renderpasses,
5647                                                         .unsynchronized_get_device_reset_status = true,
5648                                                         .unsynchronized_texture_subdata = true,
5649                                                         .parse_renderpass_info = screen->driver_workarounds.track_renderpasses,
5650                                                         .dsa_parse = zink_tc_parse_dsa,
5651                                                         .fs_parse = zink_tc_parse_fs,
5652                                                      },
5653                                                      &ctx->tc);
5654 
5655    if (tc && (struct zink_context*)tc != ctx) {
5656       ctx->track_renderpasses = screen->driver_workarounds.track_renderpasses;
5657       threaded_context_init_bytes_mapped_limit(tc, 4);
5658       ctx->base.set_context_param = zink_set_context_param;
5659    }
5660 
5661    return (struct pipe_context*)tc;
5662 
5663 fail:
5664    if (ctx)
5665       zink_context_destroy(&ctx->base);
5666    return NULL;
5667 }
5668 
5669 struct zink_context *
zink_tc_context_unwrap(struct pipe_context * pctx,bool threaded)5670 zink_tc_context_unwrap(struct pipe_context *pctx, bool threaded)
5671 {
5672    /* need to get the actual zink_context, not the threaded context */
5673    if (threaded)
5674       pctx = threaded_context_unwrap_sync(pctx);
5675    pctx = trace_get_possibly_threaded_context(pctx);
5676    return zink_context(pctx);
5677 }
5678 
5679 
5680 static bool
add_implicit_feedback_loop(struct zink_context * ctx,struct zink_resource * res)5681 add_implicit_feedback_loop(struct zink_context *ctx, struct zink_resource *res)
5682 {
5683    /* can only feedback loop with fb+sampler bind; image bind must be GENERAL */
5684    if (!res->fb_bind_count || !res->sampler_bind_count[0] || res->image_bind_count[0])
5685       return false;
5686    if (!(res->aspect & VK_IMAGE_ASPECT_COLOR_BIT) && !zink_is_zsbuf_write(ctx))
5687       /* if zsbuf isn't used then it effectively has no fb binds */
5688       /* if zsbuf isn't written to then it'll be fine with read-only access */
5689       return false;
5690    bool is_feedback = false;
5691    /* avoid false positives when a texture is bound but not used */
5692    u_foreach_bit(vkstage, res->gfx_barrier) {
5693       VkPipelineStageFlags vkstagebit = BITFIELD_BIT(vkstage);
5694       if (vkstagebit < VK_PIPELINE_STAGE_VERTEX_SHADER_BIT || vkstagebit > VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT)
5695          continue;
5696       /* in-range VkPipelineStageFlagBits can be converted to VkShaderStageFlags with a bitshift */
5697       gl_shader_stage stage = vk_to_mesa_shader_stage((VkShaderStageFlagBits)(vkstagebit >> 3));
5698       /* check shader texture usage against resource's sampler binds */
5699       if ((ctx->gfx_stages[stage] && (res->sampler_binds[stage] & ctx->gfx_stages[stage]->info.textures_used[0])))
5700          is_feedback = true;
5701    }
5702    if (!is_feedback)
5703       return false;
5704    if (ctx->feedback_loops & res->fb_binds)
5705       /* already added */
5706       return true;
5707    /* new feedback loop detected */
5708    if (res->aspect == VK_IMAGE_ASPECT_COLOR_BIT) {
5709       if (!ctx->gfx_pipeline_state.feedback_loop)
5710          ctx->gfx_pipeline_state.dirty = true;
5711       ctx->gfx_pipeline_state.feedback_loop = true;
5712    } else {
5713       if (!ctx->gfx_pipeline_state.feedback_loop_zs)
5714          ctx->gfx_pipeline_state.dirty = true;
5715       ctx->gfx_pipeline_state.feedback_loop_zs = true;
5716    }
5717    ctx->rp_layout_changed = true;
5718    ctx->feedback_loops |= res->fb_binds;
5719    u_foreach_bit(idx, res->fb_binds) {
5720       if (zink_screen(ctx->base.screen)->info.have_EXT_attachment_feedback_loop_layout)
5721          ctx->dynamic_fb.attachments[idx].imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT;
5722       else
5723          ctx->dynamic_fb.attachments[idx].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
5724    }
5725    update_feedback_loop_dynamic_state(ctx);
5726    return true;
5727 }
5728 
5729 void
zink_update_barriers(struct zink_context * ctx,bool is_compute,struct pipe_resource * index,struct pipe_resource * indirect,struct pipe_resource * indirect_draw_count)5730 zink_update_barriers(struct zink_context *ctx, bool is_compute,
5731                      struct pipe_resource *index, struct pipe_resource *indirect, struct pipe_resource *indirect_draw_count)
5732 {
5733    assert(!ctx->blitting);
5734    if (!ctx->need_barriers[is_compute]->entries)
5735       return;
5736    struct set *need_barriers = ctx->need_barriers[is_compute];
5737    ctx->barrier_set_idx[is_compute] = !ctx->barrier_set_idx[is_compute];
5738    ctx->need_barriers[is_compute] = &ctx->update_barriers[is_compute][ctx->barrier_set_idx[is_compute]];
5739    ASSERTED bool check_rp = ctx->batch.in_rp && ctx->dynamic_fb.tc_info.zsbuf_invalidate;
5740    set_foreach(need_barriers, he) {
5741       struct zink_resource *res = (struct zink_resource *)he->key;
5742       if (res->bind_count[is_compute]) {
5743          VkPipelineStageFlagBits pipeline = is_compute ? VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT : res->gfx_barrier;
5744          if (res->base.b.target == PIPE_BUFFER)
5745             zink_screen(ctx->base.screen)->buffer_barrier(ctx, res, res->barrier_access[is_compute], pipeline);
5746          else {
5747             bool is_feedback = is_compute ? false : add_implicit_feedback_loop(ctx, res);
5748             VkImageLayout layout = zink_descriptor_util_image_layout_eval(ctx, res, is_compute);
5749             /* GENERAL is only used for feedback loops and storage image binds */
5750             if (is_feedback || layout != VK_IMAGE_LAYOUT_GENERAL || res->image_bind_count[is_compute])
5751                zink_screen(ctx->base.screen)->image_barrier(ctx, res, layout, res->barrier_access[is_compute], pipeline);
5752             assert(!check_rp || check_rp == ctx->batch.in_rp);
5753             if (is_feedback)
5754                update_res_sampler_layouts(ctx, res);
5755          }
5756          if (zink_resource_access_is_write(res->barrier_access[is_compute]) ||
5757              // TODO: figure out a way to link up layouts between unordered and main cmdbuf
5758              res->base.b.target != PIPE_BUFFER)
5759             res->obj->unordered_write = false;
5760          res->obj->unordered_read = false;
5761          /* always barrier on draw if this resource has either multiple image write binds or
5762           * image write binds and image read binds
5763           */
5764          if (res->write_bind_count[is_compute] && res->bind_count[is_compute] > 1)
5765             _mesa_set_add_pre_hashed(ctx->need_barriers[is_compute], he->hash, res);
5766       }
5767       _mesa_set_remove(need_barriers, he);
5768       if (!need_barriers->entries)
5769          break;
5770    }
5771 }
5772 
5773 /**
5774  * Emits a debug marker in the cmd stream to be captured by perfetto during
5775  * execution on the GPU.
5776  */
5777 bool
zink_cmd_debug_marker_begin(struct zink_context * ctx,VkCommandBuffer cmdbuf,const char * fmt,...)5778 zink_cmd_debug_marker_begin(struct zink_context *ctx, VkCommandBuffer cmdbuf, const char *fmt, ...)
5779 {
5780    if (!zink_tracing)
5781       return false;
5782 
5783    char *name;
5784    va_list va;
5785    va_start(va, fmt);
5786    int ret = vasprintf(&name, fmt, va);
5787    va_end(va);
5788 
5789    if (ret == -1)
5790       return false;
5791 
5792    VkDebugUtilsLabelEXT info = { 0 };
5793    info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
5794    info.pLabelName = name;
5795 
5796    VKCTX(CmdBeginDebugUtilsLabelEXT)(cmdbuf ? cmdbuf : ctx->batch.state->cmdbuf, &info);
5797 
5798    free(name);
5799    return true;
5800 }
5801 
5802 void
zink_cmd_debug_marker_end(struct zink_context * ctx,VkCommandBuffer cmdbuf,bool emitted)5803 zink_cmd_debug_marker_end(struct zink_context *ctx, VkCommandBuffer cmdbuf, bool emitted)
5804 {
5805    if (emitted)
5806       VKCTX(CmdEndDebugUtilsLabelEXT)(cmdbuf);
5807 }
5808