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