• 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_context.h"
25 
26 #include "zink_batch.h"
27 #include "zink_compiler.h"
28 #include "zink_kopper.h"
29 #include "zink_fence.h"
30 #include "zink_format.h"
31 #include "zink_framebuffer.h"
32 #include "zink_helpers.h"
33 #include "zink_program.h"
34 #include "zink_pipeline.h"
35 #include "zink_query.h"
36 #include "zink_render_pass.h"
37 #include "zink_resource.h"
38 #include "zink_screen.h"
39 #include "zink_state.h"
40 #include "zink_surface.h"
41 #include "zink_inlines.h"
42 
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_thread.h"
50 #include "util/u_cpu_detect.h"
51 #include "util/strndup.h"
52 #include "nir.h"
53 
54 #include "driver_trace/tr_context.h"
55 
56 #include "util/u_memory.h"
57 #include "util/u_upload_mgr.h"
58 
59 #define XXH_INLINE_ALL
60 #include "util/xxhash.h"
61 
62 static void
calc_descriptor_hash_sampler_state(struct zink_sampler_state * sampler_state)63 calc_descriptor_hash_sampler_state(struct zink_sampler_state *sampler_state)
64 {
65    void *hash_data = &sampler_state->sampler;
66    size_t data_size = sizeof(VkSampler);
67    sampler_state->hash = XXH32(hash_data, data_size, 0);
68 }
69 
70 void
debug_describe_zink_buffer_view(char * buf,const struct zink_buffer_view * ptr)71 debug_describe_zink_buffer_view(char *buf, const struct zink_buffer_view *ptr)
72 {
73    sprintf(buf, "zink_buffer_view");
74 }
75 
76 ALWAYS_INLINE static void
check_resource_for_batch_ref(struct zink_context * ctx,struct zink_resource * res)77 check_resource_for_batch_ref(struct zink_context *ctx, struct zink_resource *res)
78 {
79    if (!zink_resource_has_binds(res)) {
80       /* avoid desync between usage and tracking:
81        * - if usage exists, it must be removed before the context is destroyed
82        * - having usage does not imply having tracking
83        * - if tracking will be added here, also reapply usage to avoid dangling usage once tracking is removed
84        * TODO: somehow fix this for perf because it's an extra hash lookup
85        */
86       if (!res->obj->dt && (res->obj->bo->reads || res->obj->bo->writes))
87          zink_batch_reference_resource_rw(&ctx->batch, res, !!res->obj->bo->writes);
88       else
89          zink_batch_reference_resource(&ctx->batch, res);
90    }
91 }
92 
93 static void
zink_context_destroy(struct pipe_context * pctx)94 zink_context_destroy(struct pipe_context *pctx)
95 {
96    struct zink_context *ctx = zink_context(pctx);
97    struct zink_screen *screen = zink_screen(pctx->screen);
98 
99    if (util_queue_is_initialized(&screen->flush_queue))
100       util_queue_finish(&screen->flush_queue);
101    if (ctx->batch.state && !screen->device_lost) {
102       VkResult result = VKSCR(QueueWaitIdle)(screen->queue);
103 
104       if (result != VK_SUCCESS)
105          mesa_loge("ZINK: vkQueueWaitIdle failed (%s)", vk_Result_to_str(result));
106    }
107 
108    for (unsigned i = 0; i < ARRAY_SIZE(ctx->program_cache); i++) {
109       hash_table_foreach(&ctx->program_cache[i], entry) {
110          struct zink_program *pg = entry->data;
111          pg->removed = true;
112          screen->descriptor_program_deinit(ctx, pg);
113       }
114    }
115    hash_table_foreach(&ctx->compute_program_cache, entry) {
116       struct zink_program *pg = entry->data;
117       pg->removed = true;
118       screen->descriptor_program_deinit(ctx, pg);
119    }
120 
121    if (ctx->blitter)
122       util_blitter_destroy(ctx->blitter);
123    for (unsigned i = 0; i < ctx->fb_state.nr_cbufs; i++)
124       pipe_surface_release(&ctx->base, &ctx->fb_state.cbufs[i]);
125    pipe_surface_release(&ctx->base, &ctx->fb_state.zsbuf);
126 
127    pipe_resource_reference(&ctx->dummy_vertex_buffer, NULL);
128    pipe_resource_reference(&ctx->dummy_xfb_buffer, NULL);
129 
130    for (unsigned i = 0; i < ARRAY_SIZE(ctx->dummy_surface); i++)
131       pipe_surface_release(&ctx->base, &ctx->dummy_surface[i]);
132    zink_buffer_view_reference(screen, &ctx->dummy_bufferview, NULL);
133 
134    if (ctx->dd)
135       zink_descriptors_deinit_bindless(ctx);
136 
137    if (ctx->batch.state) {
138       zink_clear_batch_state(ctx, ctx->batch.state);
139       zink_batch_state_destroy(screen, ctx->batch.state);
140    }
141    struct zink_batch_state *bs = ctx->batch_states;
142    while (bs) {
143       struct zink_batch_state *bs_next = bs->next;
144       zink_clear_batch_state(ctx, bs);
145       zink_batch_state_destroy(screen, bs);
146       bs = bs_next;
147    }
148    util_dynarray_foreach(&ctx->free_batch_states, struct zink_batch_state*, bs) {
149       zink_clear_batch_state(ctx, *bs);
150       zink_batch_state_destroy(screen, *bs);
151    }
152 
153    for (unsigned i = 0; i < 2; i++) {
154       util_idalloc_fini(&ctx->di.bindless[i].tex_slots);
155       util_idalloc_fini(&ctx->di.bindless[i].img_slots);
156       free(ctx->di.bindless[i].buffer_infos);
157       free(ctx->di.bindless[i].img_infos);
158       util_dynarray_fini(&ctx->di.bindless[i].updates);
159       util_dynarray_fini(&ctx->di.bindless[i].resident);
160    }
161 
162    hash_table_foreach(&ctx->framebuffer_cache, he)
163       zink_destroy_framebuffer(screen, he->data);
164 
165    hash_table_foreach(ctx->render_pass_cache, he)
166       zink_destroy_render_pass(screen, he->data);
167 
168    zink_context_destroy_query_pools(ctx);
169    u_upload_destroy(pctx->stream_uploader);
170    u_upload_destroy(pctx->const_uploader);
171    slab_destroy_child(&ctx->transfer_pool);
172    for (unsigned i = 0; i < ARRAY_SIZE(ctx->program_cache); i++)
173       _mesa_hash_table_clear(&ctx->program_cache[i], NULL);
174    _mesa_hash_table_clear(&ctx->compute_program_cache, NULL);
175    _mesa_hash_table_destroy(ctx->render_pass_cache, NULL);
176    slab_destroy_child(&ctx->transfer_pool_unsync);
177 
178    if (ctx->dd)
179       screen->descriptors_deinit(ctx);
180 
181    zink_descriptor_layouts_deinit(ctx);
182 
183    if (!(ctx->flags & ZINK_CONTEXT_COPY_ONLY))
184       p_atomic_dec(&screen->base.num_contexts);
185 
186    ralloc_free(ctx);
187 }
188 
189 static void
check_device_lost(struct zink_context * ctx)190 check_device_lost(struct zink_context *ctx)
191 {
192    if (!zink_screen(ctx->base.screen)->device_lost || ctx->is_device_lost)
193       return;
194    debug_printf("ZINK: device lost detected!\n");
195    if (ctx->reset.reset)
196       ctx->reset.reset(ctx->reset.data, PIPE_GUILTY_CONTEXT_RESET);
197    ctx->is_device_lost = true;
198 }
199 
200 static enum pipe_reset_status
zink_get_device_reset_status(struct pipe_context * pctx)201 zink_get_device_reset_status(struct pipe_context *pctx)
202 {
203    struct zink_context *ctx = zink_context(pctx);
204 
205    enum pipe_reset_status status = PIPE_NO_RESET;
206 
207    if (ctx->is_device_lost) {
208       // Since we don't know what really happened to the hardware, just
209       // assume that we are in the wrong
210       status = PIPE_GUILTY_CONTEXT_RESET;
211 
212       debug_printf("ZINK: device lost detected!\n");
213 
214       if (ctx->reset.reset)
215          ctx->reset.reset(ctx->reset.data, status);
216    }
217 
218    return status;
219 }
220 
221 static void
zink_set_device_reset_callback(struct pipe_context * pctx,const struct pipe_device_reset_callback * cb)222 zink_set_device_reset_callback(struct pipe_context *pctx,
223                                const struct pipe_device_reset_callback *cb)
224 {
225    struct zink_context *ctx = zink_context(pctx);
226    bool had_reset = !!ctx->reset.reset;
227 
228    if (cb)
229       ctx->reset = *cb;
230    else
231       memset(&ctx->reset, 0, sizeof(ctx->reset));
232 
233    bool have_reset = !!ctx->reset.reset;
234    if (had_reset != have_reset) {
235       if (have_reset)
236          p_atomic_inc(&zink_screen(pctx->screen)->robust_ctx_count);
237       else
238          p_atomic_dec(&zink_screen(pctx->screen)->robust_ctx_count);
239    }
240 }
241 
242 static void
zink_set_context_param(struct pipe_context * pctx,enum pipe_context_param param,unsigned value)243 zink_set_context_param(struct pipe_context *pctx, enum pipe_context_param param,
244                        unsigned value)
245 {
246    struct zink_context *ctx = zink_context(pctx);
247 
248    switch (param) {
249    case PIPE_CONTEXT_PARAM_PIN_THREADS_TO_L3_CACHE:
250       util_set_thread_affinity(zink_screen(ctx->base.screen)->flush_queue.threads[0],
251                                util_get_cpu_caps()->L3_affinity_mask[value],
252                                NULL, util_get_cpu_caps()->num_cpu_mask_bits);
253       break;
254    default:
255       break;
256    }
257 }
258 
259 static VkSamplerMipmapMode
sampler_mipmap_mode(enum pipe_tex_mipfilter filter)260 sampler_mipmap_mode(enum pipe_tex_mipfilter filter)
261 {
262    switch (filter) {
263    case PIPE_TEX_MIPFILTER_NEAREST: return VK_SAMPLER_MIPMAP_MODE_NEAREST;
264    case PIPE_TEX_MIPFILTER_LINEAR: return VK_SAMPLER_MIPMAP_MODE_LINEAR;
265    case PIPE_TEX_MIPFILTER_NONE:
266       unreachable("PIPE_TEX_MIPFILTER_NONE should be dealt with earlier");
267    }
268    unreachable("unexpected filter");
269 }
270 
271 static VkSamplerAddressMode
sampler_address_mode(enum pipe_tex_wrap filter)272 sampler_address_mode(enum pipe_tex_wrap filter)
273 {
274    switch (filter) {
275    case PIPE_TEX_WRAP_REPEAT: return VK_SAMPLER_ADDRESS_MODE_REPEAT;
276    case PIPE_TEX_WRAP_CLAMP_TO_EDGE: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
277    case PIPE_TEX_WRAP_CLAMP_TO_BORDER: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
278    case PIPE_TEX_WRAP_MIRROR_REPEAT: return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
279    case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
280    case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; /* not technically correct, but kinda works */
281    default: break;
282    }
283    unreachable("unexpected wrap");
284 }
285 
286 static VkCompareOp
compare_op(enum pipe_compare_func op)287 compare_op(enum pipe_compare_func op)
288 {
289    switch (op) {
290       case PIPE_FUNC_NEVER: return VK_COMPARE_OP_NEVER;
291       case PIPE_FUNC_LESS: return VK_COMPARE_OP_LESS;
292       case PIPE_FUNC_EQUAL: return VK_COMPARE_OP_EQUAL;
293       case PIPE_FUNC_LEQUAL: return VK_COMPARE_OP_LESS_OR_EQUAL;
294       case PIPE_FUNC_GREATER: return VK_COMPARE_OP_GREATER;
295       case PIPE_FUNC_NOTEQUAL: return VK_COMPARE_OP_NOT_EQUAL;
296       case PIPE_FUNC_GEQUAL: return VK_COMPARE_OP_GREATER_OR_EQUAL;
297       case PIPE_FUNC_ALWAYS: return VK_COMPARE_OP_ALWAYS;
298    }
299    unreachable("unexpected compare");
300 }
301 
302 static inline bool
wrap_needs_border_color(unsigned wrap)303 wrap_needs_border_color(unsigned wrap)
304 {
305    return wrap == PIPE_TEX_WRAP_CLAMP || wrap == PIPE_TEX_WRAP_CLAMP_TO_BORDER ||
306           wrap == PIPE_TEX_WRAP_MIRROR_CLAMP || wrap == PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER;
307 }
308 
309 static VkBorderColor
get_border_color(const union pipe_color_union * color,bool is_integer,bool need_custom)310 get_border_color(const union pipe_color_union *color, bool is_integer, bool need_custom)
311 {
312    if (is_integer) {
313       if (color->ui[0] == 0 && color->ui[1] == 0 && color->ui[2] == 0 && color->ui[3] == 0)
314          return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
315       if (color->ui[0] == 0 && color->ui[1] == 0 && color->ui[2] == 0 && color->ui[3] == 1)
316          return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
317       if (color->ui[0] == 1 && color->ui[1] == 1 && color->ui[2] == 1 && color->ui[3] == 1)
318          return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
319       return need_custom ? VK_BORDER_COLOR_INT_CUSTOM_EXT : VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
320    }
321 
322    if (color->f[0] == 0 && color->f[1] == 0 && color->f[2] == 0 && color->f[3] == 0)
323       return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
324    if (color->f[0] == 0 && color->f[1] == 0 && color->f[2] == 0 && color->f[3] == 1)
325       return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
326    if (color->f[0] == 1 && color->f[1] == 1 && color->f[2] == 1 && color->f[3] == 1)
327       return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
328    return need_custom ? VK_BORDER_COLOR_FLOAT_CUSTOM_EXT : VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
329 }
330 
331 static void *
zink_create_sampler_state(struct pipe_context * pctx,const struct pipe_sampler_state * state)332 zink_create_sampler_state(struct pipe_context *pctx,
333                           const struct pipe_sampler_state *state)
334 {
335    struct zink_screen *screen = zink_screen(pctx->screen);
336    bool need_custom = false;
337    bool need_clamped_border_color = false;
338    VkSamplerCreateInfo sci = {0};
339    VkSamplerCustomBorderColorCreateInfoEXT cbci = {0};
340    VkSamplerCustomBorderColorCreateInfoEXT cbci_clamped = {0};
341    sci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
342    if (screen->info.have_EXT_non_seamless_cube_map && !state->seamless_cube_map)
343       sci.flags |= VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT;
344    sci.unnormalizedCoordinates = !state->normalized_coords;
345    sci.magFilter = zink_filter(state->mag_img_filter);
346    if (sci.unnormalizedCoordinates)
347       sci.minFilter = sci.magFilter;
348    else
349       sci.minFilter = zink_filter(state->min_img_filter);
350 
351    VkSamplerReductionModeCreateInfo rci;
352    rci.sType = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO;
353    rci.pNext = NULL;
354    switch (state->reduction_mode) {
355    case PIPE_TEX_REDUCTION_MIN:
356       rci.reductionMode = VK_SAMPLER_REDUCTION_MODE_MIN;
357       break;
358    case PIPE_TEX_REDUCTION_MAX:
359       rci.reductionMode = VK_SAMPLER_REDUCTION_MODE_MAX;
360       break;
361    default:
362       rci.reductionMode = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE;
363       break;
364    }
365    if (state->reduction_mode)
366       sci.pNext = &rci;
367 
368    if (sci.unnormalizedCoordinates) {
369       sci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
370    } else if (state->min_mip_filter != PIPE_TEX_MIPFILTER_NONE) {
371       sci.mipmapMode = sampler_mipmap_mode(state->min_mip_filter);
372       sci.minLod = state->min_lod;
373       sci.maxLod = state->max_lod;
374    } else {
375       sci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
376       sci.minLod = 0;
377       sci.maxLod = 0.25f;
378    }
379 
380    if (!sci.unnormalizedCoordinates) {
381       sci.addressModeU = sampler_address_mode(state->wrap_s);
382       sci.addressModeV = sampler_address_mode(state->wrap_t);
383       sci.addressModeW = sampler_address_mode(state->wrap_r);
384    } else {
385       sci.addressModeU = sci.addressModeV = sci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
386    }
387 
388    sci.mipLodBias = CLAMP(state->lod_bias,
389                           -screen->info.props.limits.maxSamplerLodBias,
390                           screen->info.props.limits.maxSamplerLodBias);
391 
392    need_custom |= wrap_needs_border_color(state->wrap_s);
393    need_custom |= wrap_needs_border_color(state->wrap_t);
394    need_custom |= wrap_needs_border_color(state->wrap_r);
395 
396    if (state->compare_mode == PIPE_TEX_COMPARE_NONE)
397       sci.compareOp = VK_COMPARE_OP_NEVER;
398    else {
399       sci.compareOp = compare_op(state->compare_func);
400       sci.compareEnable = VK_TRUE;
401    }
402 
403    bool is_integer = state->border_color_is_integer;
404 
405    sci.borderColor = get_border_color(&state->border_color, is_integer, need_custom);
406    if (sci.borderColor > VK_BORDER_COLOR_INT_OPAQUE_WHITE && need_custom) {
407       if (!screen->info.border_color_feats.customBorderColorWithoutFormat &&
408           screen->info.driver_props.driverID != VK_DRIVER_ID_MESA_TURNIP) {
409          static bool warned = false;
410          warn_missing_feature(warned, "customBorderColorWithoutFormat");
411       }
412       if (screen->info.have_EXT_custom_border_color &&
413           (screen->info.border_color_feats.customBorderColorWithoutFormat || state->border_color_format)) {
414          if (!screen->info.have_EXT_border_color_swizzle) {
415             static bool warned = false;
416             warn_missing_feature(warned, "VK_EXT_border_color_swizzle");
417          }
418 
419          if (!is_integer && !screen->have_D24_UNORM_S8_UINT) {
420             union pipe_color_union clamped_border_color;
421             for (unsigned i = 0; i < 4; ++i) {
422                /* Use channel 0 on purpose, so that we can use OPAQUE_WHITE
423                 * when the border color is 1.0. */
424                clamped_border_color.f[i] = CLAMP(state->border_color.f[0], 0, 1);
425             }
426             if (memcmp(&state->border_color, &clamped_border_color, sizeof(clamped_border_color)) != 0) {
427                need_clamped_border_color = true;
428                cbci_clamped.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT;
429                cbci_clamped.format = VK_FORMAT_UNDEFINED;
430                /* these are identical unions */
431                memcpy(&cbci_clamped.customBorderColor, &clamped_border_color, sizeof(union pipe_color_union));
432             }
433          }
434          cbci.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT;
435          cbci.format = screen->info.border_color_feats.customBorderColorWithoutFormat ? VK_FORMAT_UNDEFINED : zink_get_format(screen, state->border_color_format);
436          /* these are identical unions */
437          memcpy(&cbci.customBorderColor, &state->border_color, sizeof(union pipe_color_union));
438          cbci.pNext = sci.pNext;
439          sci.pNext = &cbci;
440          UNUSED uint32_t check = p_atomic_inc_return(&screen->cur_custom_border_color_samplers);
441          assert(check <= screen->info.border_color_props.maxCustomBorderColorSamplers);
442       } else
443          sci.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; // TODO with custom shader if we're super interested?
444       if (sci.unnormalizedCoordinates)
445          sci.addressModeU = sci.addressModeV = sci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
446    }
447 
448    if (state->max_anisotropy > 1) {
449       sci.maxAnisotropy = state->max_anisotropy;
450       sci.anisotropyEnable = VK_TRUE;
451    }
452 
453    struct zink_sampler_state *sampler = CALLOC_STRUCT(zink_sampler_state);
454    if (!sampler)
455       return NULL;
456 
457    VkResult result = VKSCR(CreateSampler)(screen->dev, &sci, NULL, &sampler->sampler);
458    if (result != VK_SUCCESS) {
459       mesa_loge("ZINK: vkCreateSampler failed (%s)", vk_Result_to_str(result));
460       FREE(sampler);
461       return NULL;
462    }
463    if (need_clamped_border_color) {
464       sci.pNext = &cbci_clamped;
465       result = VKSCR(CreateSampler)(screen->dev, &sci, NULL, &sampler->sampler_clamped);
466       if (result != VK_SUCCESS) {
467          mesa_loge("ZINK: vkCreateSampler failed (%s)", vk_Result_to_str(result));
468          VKSCR(DestroySampler)(screen->dev, sampler->sampler, NULL);
469          FREE(sampler);
470          return NULL;
471       }
472    }
473    util_dynarray_init(&sampler->desc_set_refs.refs, NULL);
474    calc_descriptor_hash_sampler_state(sampler);
475    sampler->custom_border_color = need_custom;
476    if (!screen->info.have_EXT_non_seamless_cube_map)
477       sampler->emulate_nonseamless = !state->seamless_cube_map;
478 
479    return sampler;
480 }
481 
482 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)483 get_layout_for_binding(const struct zink_context *ctx, struct zink_resource *res, enum zink_descriptor_type type, bool is_compute)
484 {
485    if (res->obj->is_buffer)
486       return 0;
487    switch (type) {
488    case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
489       return zink_descriptor_util_image_layout_eval(ctx, res, is_compute);
490    case ZINK_DESCRIPTOR_TYPE_IMAGE:
491       return VK_IMAGE_LAYOUT_GENERAL;
492    default:
493       break;
494    }
495    return 0;
496 }
497 
498 ALWAYS_INLINE static struct zink_surface *
get_imageview_for_binding(struct zink_context * ctx,enum pipe_shader_type stage,enum zink_descriptor_type type,unsigned idx)499 get_imageview_for_binding(struct zink_context *ctx, enum pipe_shader_type stage, enum zink_descriptor_type type, unsigned idx)
500 {
501    switch (type) {
502    case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW: {
503       struct zink_sampler_view *sampler_view = zink_sampler_view(ctx->sampler_views[stage][idx]);
504       if (!sampler_view || !sampler_view->base.texture)
505          return NULL;
506       /* if this is a non-seamless cube sampler, return the cube array view */
507       return (ctx->di.emulate_nonseamless[stage] & ctx->di.cubes[stage] & BITFIELD_BIT(idx)) ?
508              sampler_view->cube_array :
509              sampler_view->image_view;
510    }
511    case ZINK_DESCRIPTOR_TYPE_IMAGE: {
512       struct zink_image_view *image_view = &ctx->image_views[stage][idx];
513       return image_view->base.resource ? image_view->surface : NULL;
514    }
515    default:
516       break;
517    }
518    unreachable("ACK");
519    return VK_NULL_HANDLE;
520 }
521 
522 ALWAYS_INLINE static struct zink_buffer_view *
get_bufferview_for_binding(struct zink_context * ctx,enum pipe_shader_type stage,enum zink_descriptor_type type,unsigned idx)523 get_bufferview_for_binding(struct zink_context *ctx, enum pipe_shader_type stage, enum zink_descriptor_type type, unsigned idx)
524 {
525    switch (type) {
526    case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW: {
527       struct zink_sampler_view *sampler_view = zink_sampler_view(ctx->sampler_views[stage][idx]);
528       return sampler_view->base.texture ? sampler_view->buffer_view : NULL;
529    }
530    case ZINK_DESCRIPTOR_TYPE_IMAGE: {
531       struct zink_image_view *image_view = &ctx->image_views[stage][idx];
532       return image_view->base.resource ? image_view->buffer_view : NULL;
533    }
534    default:
535       break;
536    }
537    unreachable("ACK");
538    return VK_NULL_HANDLE;
539 }
540 
541 ALWAYS_INLINE static struct zink_resource *
update_descriptor_state_ubo(struct zink_context * ctx,enum pipe_shader_type shader,unsigned slot,struct zink_resource * res)542 update_descriptor_state_ubo(struct zink_context *ctx, enum pipe_shader_type shader, unsigned slot, struct zink_resource *res)
543 {
544    struct zink_screen *screen = zink_screen(ctx->base.screen);
545    bool have_null_descriptors = screen->info.rb2_feats.nullDescriptor;
546    const enum zink_descriptor_type type = ZINK_DESCRIPTOR_TYPE_UBO;
547    ctx->di.descriptor_res[type][shader][slot] = res;
548    ctx->di.ubos[shader][slot].offset = ctx->ubos[shader][slot].buffer_offset;
549    if (res) {
550       ctx->di.ubos[shader][slot].buffer = res->obj->buffer;
551       ctx->di.ubos[shader][slot].range = ctx->ubos[shader][slot].buffer_size;
552       assert(ctx->di.ubos[shader][slot].range <= screen->info.props.limits.maxUniformBufferRange);
553    } else {
554       VkBuffer null_buffer = zink_resource(ctx->dummy_vertex_buffer)->obj->buffer;
555       ctx->di.ubos[shader][slot].buffer = have_null_descriptors ? VK_NULL_HANDLE : null_buffer;
556       ctx->di.ubos[shader][slot].range = VK_WHOLE_SIZE;
557    }
558    if (!slot) {
559       if (res)
560          ctx->di.push_valid |= BITFIELD64_BIT(shader);
561       else
562          ctx->di.push_valid &= ~BITFIELD64_BIT(shader);
563    }
564    return res;
565 }
566 
567 ALWAYS_INLINE static struct zink_resource *
update_descriptor_state_ssbo(struct zink_context * ctx,enum pipe_shader_type shader,unsigned slot,struct zink_resource * res)568 update_descriptor_state_ssbo(struct zink_context *ctx, enum pipe_shader_type shader, unsigned slot, struct zink_resource *res)
569 {
570    struct zink_screen *screen = zink_screen(ctx->base.screen);
571    bool have_null_descriptors = screen->info.rb2_feats.nullDescriptor;
572    const enum zink_descriptor_type type = ZINK_DESCRIPTOR_TYPE_SSBO;
573    ctx->di.descriptor_res[type][shader][slot] = res;
574    ctx->di.ssbos[shader][slot].offset = ctx->ssbos[shader][slot].buffer_offset;
575    if (res) {
576       ctx->di.ssbos[shader][slot].buffer = res->obj->buffer;
577       ctx->di.ssbos[shader][slot].range = ctx->ssbos[shader][slot].buffer_size;
578    } else {
579       VkBuffer null_buffer = zink_resource(ctx->dummy_vertex_buffer)->obj->buffer;
580       ctx->di.ssbos[shader][slot].buffer = have_null_descriptors ? VK_NULL_HANDLE : null_buffer;
581       ctx->di.ssbos[shader][slot].range = VK_WHOLE_SIZE;
582    }
583    return res;
584 }
585 
586 ALWAYS_INLINE static struct zink_resource *
update_descriptor_state_sampler(struct zink_context * ctx,enum pipe_shader_type shader,unsigned slot,struct zink_resource * res)587 update_descriptor_state_sampler(struct zink_context *ctx, enum pipe_shader_type shader, unsigned slot, struct zink_resource *res)
588 {
589    struct zink_screen *screen = zink_screen(ctx->base.screen);
590    bool have_null_descriptors = screen->info.rb2_feats.nullDescriptor;
591    const enum zink_descriptor_type type = ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW;
592    ctx->di.descriptor_res[type][shader][slot] = res;
593    if (res) {
594       if (res->obj->is_buffer) {
595          struct zink_buffer_view *bv = get_bufferview_for_binding(ctx, shader, type, slot);
596          ctx->di.tbos[shader][slot] = bv->buffer_view;
597          ctx->di.sampler_surfaces[shader][slot].bufferview = bv;
598          ctx->di.sampler_surfaces[shader][slot].is_buffer = true;
599       } else {
600          struct zink_surface *surface = get_imageview_for_binding(ctx, shader, type, slot);
601          ctx->di.textures[shader][slot].imageLayout = get_layout_for_binding(ctx, res, type, shader == PIPE_SHADER_COMPUTE);
602          ctx->di.textures[shader][slot].imageView = surface->image_view;
603          if (!screen->have_D24_UNORM_S8_UINT &&
604              ctx->sampler_states[shader][slot] && ctx->sampler_states[shader][slot]->sampler_clamped) {
605             struct zink_sampler_state *state = ctx->sampler_states[shader][slot];
606             VkSampler sampler = (surface->base.format == PIPE_FORMAT_Z24X8_UNORM && surface->ivci.format == VK_FORMAT_D32_SFLOAT) ||
607                                 (surface->base.format == PIPE_FORMAT_Z24_UNORM_S8_UINT && surface->ivci.format == VK_FORMAT_D32_SFLOAT_S8_UINT) ?
608                                 state->sampler_clamped :
609                                 state->sampler;
610             if (ctx->di.textures[shader][slot].sampler != sampler) {
611                screen->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, slot, 1);
612                ctx->di.textures[shader][slot].sampler = sampler;
613             }
614          }
615          ctx->di.sampler_surfaces[shader][slot].surface = surface;
616          ctx->di.sampler_surfaces[shader][slot].is_buffer = false;
617       }
618    } else {
619       if (likely(have_null_descriptors)) {
620          ctx->di.textures[shader][slot].imageView = VK_NULL_HANDLE;
621          ctx->di.textures[shader][slot].imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
622          ctx->di.tbos[shader][slot] = VK_NULL_HANDLE;
623       } else {
624          struct zink_surface *null_surface = zink_csurface(ctx->dummy_surface[0]);
625          struct zink_buffer_view *null_bufferview = ctx->dummy_bufferview;
626          ctx->di.textures[shader][slot].imageView = null_surface->image_view;
627          ctx->di.textures[shader][slot].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
628          ctx->di.tbos[shader][slot] = null_bufferview->buffer_view;
629       }
630       memset(&ctx->di.sampler_surfaces[shader][slot], 0, sizeof(ctx->di.sampler_surfaces[shader][slot]));
631    }
632    return res;
633 }
634 
635 ALWAYS_INLINE static struct zink_resource *
update_descriptor_state_image(struct zink_context * ctx,enum pipe_shader_type shader,unsigned slot,struct zink_resource * res)636 update_descriptor_state_image(struct zink_context *ctx, enum pipe_shader_type shader, unsigned slot, struct zink_resource *res)
637 {
638    struct zink_screen *screen = zink_screen(ctx->base.screen);
639    bool have_null_descriptors = screen->info.rb2_feats.nullDescriptor;
640    const enum zink_descriptor_type type = ZINK_DESCRIPTOR_TYPE_IMAGE;
641    ctx->di.descriptor_res[type][shader][slot] = res;
642    if (res) {
643       if (res->obj->is_buffer) {
644          struct zink_buffer_view *bv = get_bufferview_for_binding(ctx, shader, type, slot);
645          ctx->di.texel_images[shader][slot] = bv->buffer_view;
646          ctx->di.image_surfaces[shader][slot].bufferview = bv;
647          ctx->di.image_surfaces[shader][slot].is_buffer = true;
648       } else {
649          struct zink_surface *surface = get_imageview_for_binding(ctx, shader, type, slot);
650          ctx->di.images[shader][slot].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
651          ctx->di.images[shader][slot].imageView = surface->image_view;
652          ctx->di.image_surfaces[shader][slot].surface = surface;
653          ctx->di.image_surfaces[shader][slot].is_buffer = false;
654       }
655    } else {
656       if (likely(have_null_descriptors)) {
657          memset(&ctx->di.images[shader][slot], 0, sizeof(ctx->di.images[shader][slot]));
658          ctx->di.texel_images[shader][slot] = VK_NULL_HANDLE;
659       } else {
660          struct zink_surface *null_surface = zink_csurface(ctx->dummy_surface[0]);
661          struct zink_buffer_view *null_bufferview = ctx->dummy_bufferview;
662          ctx->di.images[shader][slot].imageView = null_surface->image_view;
663          ctx->di.images[shader][slot].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
664          ctx->di.texel_images[shader][slot] = null_bufferview->buffer_view;
665       }
666       memset(&ctx->di.image_surfaces[shader][slot], 0, sizeof(ctx->di.image_surfaces[shader][slot]));
667    }
668    return res;
669 }
670 
671 static void
update_nonseamless_shader_key(struct zink_context * ctx,enum pipe_shader_type pstage)672 update_nonseamless_shader_key(struct zink_context *ctx, enum pipe_shader_type pstage)
673 {
674    uint32_t *mask;
675    if (pstage == PIPE_SHADER_COMPUTE)
676       mask = &ctx->compute_pipeline_state.key.base.nonseamless_cube_mask;
677    else
678       mask = &ctx->gfx_pipeline_state.shader_keys.key[pstage].base.nonseamless_cube_mask;
679 
680    const uint32_t new_mask = ctx->di.emulate_nonseamless[pstage] & ctx->di.cubes[pstage];
681    if (new_mask != *mask)
682       ctx->dirty_shader_stages |= BITFIELD_BIT(pstage);
683    *mask = new_mask;
684 }
685 
686 static void
zink_bind_sampler_states(struct pipe_context * pctx,enum pipe_shader_type shader,unsigned start_slot,unsigned num_samplers,void ** samplers)687 zink_bind_sampler_states(struct pipe_context *pctx,
688                          enum pipe_shader_type shader,
689                          unsigned start_slot,
690                          unsigned num_samplers,
691                          void **samplers)
692 {
693    struct zink_context *ctx = zink_context(pctx);
694    struct zink_screen *screen = zink_screen(pctx->screen);
695    uint32_t mask = BITFIELD_RANGE(start_slot, num_samplers);
696    ctx->di.emulate_nonseamless[shader] &= ~mask;
697    for (unsigned i = 0; i < num_samplers; ++i) {
698       struct zink_sampler_state *state = samplers[i];
699       if (ctx->sampler_states[shader][start_slot + i] != state)
700          zink_screen(pctx->screen)->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot, 1);
701       bool was_nonseamless = false;
702       if (ctx->sampler_states[shader][start_slot + i])
703          was_nonseamless = ctx->sampler_states[shader][start_slot + i]->emulate_nonseamless;
704       ctx->sampler_states[shader][start_slot + i] = state;
705       if (state) {
706          ctx->di.textures[shader][start_slot + i].sampler = state->sampler;
707          if (state->sampler_clamped && !screen->have_D24_UNORM_S8_UINT) {
708             struct zink_surface *surface = get_imageview_for_binding(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot + i);
709             if (surface &&
710                 ((surface->base.format == PIPE_FORMAT_Z24X8_UNORM && surface->ivci.format == VK_FORMAT_D32_SFLOAT) ||
711                  (surface->base.format == PIPE_FORMAT_Z24_UNORM_S8_UINT && surface->ivci.format == VK_FORMAT_D32_SFLOAT_S8_UINT)))
712                ctx->di.textures[shader][start_slot + i].sampler = state->sampler_clamped;
713          }
714          zink_batch_usage_set(&state->batch_uses, ctx->batch.state);
715          if (screen->info.have_EXT_non_seamless_cube_map)
716             continue;
717          const uint32_t bit = BITFIELD_BIT(start_slot + i);
718          if (state->emulate_nonseamless)
719             ctx->di.emulate_nonseamless[shader] |= bit;
720          if (state->emulate_nonseamless != was_nonseamless && (ctx->di.cubes[shader] & bit)) {
721             struct zink_surface *surface = get_imageview_for_binding(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot + i);
722             if (surface && ctx->di.image_surfaces[shader][start_slot + i].surface != surface) {
723                ctx->di.images[shader][start_slot + i].imageView = surface->image_view;
724                ctx->di.image_surfaces[shader][start_slot + i].surface = surface;
725                update_descriptor_state_sampler(ctx, shader, start_slot + i, zink_resource(surface->base.texture));
726                screen->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot + i, 1);
727             }
728          }
729       } else {
730          ctx->di.textures[shader][start_slot + i].sampler = VK_NULL_HANDLE;
731       }
732    }
733    ctx->di.num_samplers[shader] = start_slot + num_samplers;
734    if (!screen->info.have_EXT_non_seamless_cube_map)
735       update_nonseamless_shader_key(ctx, shader);
736 }
737 
738 static void
zink_delete_sampler_state(struct pipe_context * pctx,void * sampler_state)739 zink_delete_sampler_state(struct pipe_context *pctx,
740                           void *sampler_state)
741 {
742    struct zink_sampler_state *sampler = sampler_state;
743    struct zink_batch *batch = &zink_context(pctx)->batch;
744    zink_descriptor_set_refs_clear(&sampler->desc_set_refs, sampler_state);
745    /* may be called if context_create fails */
746    if (batch->state) {
747       util_dynarray_append(&batch->state->zombie_samplers, VkSampler,
748                            sampler->sampler);
749       if (sampler->sampler_clamped)
750          util_dynarray_append(&batch->state->zombie_samplers, VkSampler,
751                               sampler->sampler_clamped);
752    }
753    if (sampler->custom_border_color)
754       p_atomic_dec(&zink_screen(pctx->screen)->cur_custom_border_color_samplers);
755    FREE(sampler);
756 }
757 
758 static VkImageAspectFlags
sampler_aspect_from_format(enum pipe_format fmt)759 sampler_aspect_from_format(enum pipe_format fmt)
760 {
761    if (util_format_is_depth_or_stencil(fmt)) {
762       const struct util_format_description *desc = util_format_description(fmt);
763       if (util_format_has_depth(desc))
764          return VK_IMAGE_ASPECT_DEPTH_BIT;
765       assert(util_format_has_stencil(desc));
766       return VK_IMAGE_ASPECT_STENCIL_BIT;
767    } else
768      return VK_IMAGE_ASPECT_COLOR_BIT;
769 }
770 
771 static uint32_t
hash_bufferview(void * bvci)772 hash_bufferview(void *bvci)
773 {
774    size_t offset = offsetof(VkBufferViewCreateInfo, flags);
775    return _mesa_hash_data((char*)bvci + offset, sizeof(VkBufferViewCreateInfo) - offset);
776 }
777 
778 static VkBufferViewCreateInfo
create_bvci(struct zink_context * ctx,struct zink_resource * res,enum pipe_format format,uint32_t offset,uint32_t range)779 create_bvci(struct zink_context *ctx, struct zink_resource *res, enum pipe_format format, uint32_t offset, uint32_t range)
780 {
781    struct zink_screen *screen = zink_screen(ctx->base.screen);
782    VkBufferViewCreateInfo bvci;
783    // Zero whole struct (including alignment holes), so hash_bufferview
784    // does not access potentially uninitialized data.
785    memset(&bvci, 0, sizeof(bvci));
786    bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
787    bvci.pNext = NULL;
788    if (screen->format_props[format].bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)
789       bvci.buffer = res->obj->storage_buffer ? res->obj->storage_buffer : res->obj->buffer;
790    else
791       bvci.buffer = res->obj->buffer;
792    bvci.format = zink_get_format(screen, format);
793    assert(bvci.format);
794    bvci.offset = offset;
795    bvci.range = !offset && range == res->base.b.width0 ? VK_WHOLE_SIZE : range;
796    unsigned blocksize = util_format_get_blocksize(format);
797    if (bvci.range != VK_WHOLE_SIZE) {
798       /* clamp out partial texels */
799       bvci.range -= bvci.range % blocksize;
800       if (bvci.offset + bvci.range >= res->base.b.width0)
801          bvci.range = VK_WHOLE_SIZE;
802    }
803    uint64_t clamp = blocksize * screen->info.props.limits.maxTexelBufferElements;
804    if (bvci.range == VK_WHOLE_SIZE && res->base.b.width0 > clamp)
805       bvci.range = clamp;
806    bvci.flags = 0;
807    return bvci;
808 }
809 
810 static struct zink_buffer_view *
get_buffer_view(struct zink_context * ctx,struct zink_resource * res,VkBufferViewCreateInfo * bvci)811 get_buffer_view(struct zink_context *ctx, struct zink_resource *res, VkBufferViewCreateInfo *bvci)
812 {
813    struct zink_screen *screen = zink_screen(ctx->base.screen);
814    struct zink_buffer_view *buffer_view = NULL;
815 
816    uint32_t hash = hash_bufferview(bvci);
817    simple_mtx_lock(&res->bufferview_mtx);
818    struct hash_entry *he = _mesa_hash_table_search_pre_hashed(&res->bufferview_cache, hash, bvci);
819    if (he) {
820       buffer_view = he->data;
821       p_atomic_inc(&buffer_view->reference.count);
822    } else {
823       VkBufferView view;
824       VkResult result = VKSCR(CreateBufferView)(screen->dev, bvci, NULL, &view);
825       if (result != VK_SUCCESS) {
826          mesa_loge("ZINK: vkCreateBufferView failed (%s)", vk_Result_to_str(result));
827          goto out;
828       }
829       buffer_view = CALLOC_STRUCT(zink_buffer_view);
830       if (!buffer_view) {
831          VKSCR(DestroyBufferView)(screen->dev, view, NULL);
832          goto out;
833       }
834       pipe_reference_init(&buffer_view->reference, 1);
835       pipe_resource_reference(&buffer_view->pres, &res->base.b);
836       util_dynarray_init(&buffer_view->desc_set_refs.refs, NULL);
837       buffer_view->bvci = *bvci;
838       buffer_view->buffer_view = view;
839       buffer_view->hash = hash;
840       _mesa_hash_table_insert_pre_hashed(&res->bufferview_cache, hash, &buffer_view->bvci, buffer_view);
841    }
842 out:
843    simple_mtx_unlock(&res->bufferview_mtx);
844    return buffer_view;
845 }
846 
847 enum pipe_swizzle
zink_clamp_void_swizzle(const struct util_format_description * desc,enum pipe_swizzle swizzle)848 zink_clamp_void_swizzle(const struct util_format_description *desc, enum pipe_swizzle swizzle)
849 {
850    switch (swizzle) {
851    case PIPE_SWIZZLE_X:
852    case PIPE_SWIZZLE_Y:
853    case PIPE_SWIZZLE_Z:
854    case PIPE_SWIZZLE_W:
855       return desc->channel[swizzle].type == UTIL_FORMAT_TYPE_VOID ? PIPE_SWIZZLE_1 : swizzle;
856    default:
857       break;
858    }
859    return swizzle;
860 }
861 
862 ALWAYS_INLINE static enum pipe_swizzle
clamp_zs_swizzle(enum pipe_swizzle swizzle)863 clamp_zs_swizzle(enum pipe_swizzle swizzle)
864 {
865    switch (swizzle) {
866    case PIPE_SWIZZLE_X:
867    case PIPE_SWIZZLE_Y:
868    case PIPE_SWIZZLE_Z:
869    case PIPE_SWIZZLE_W:
870       return PIPE_SWIZZLE_X;
871    default:
872       break;
873    }
874    return swizzle;
875 }
876 
877 ALWAYS_INLINE static bool
viewtype_is_cube(const VkImageViewCreateInfo * ivci)878 viewtype_is_cube(const VkImageViewCreateInfo *ivci)
879 {
880    return ivci->viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
881           ivci->viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
882 }
883 
884 static struct pipe_sampler_view *
zink_create_sampler_view(struct pipe_context * pctx,struct pipe_resource * pres,const struct pipe_sampler_view * state)885 zink_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *pres,
886                          const struct pipe_sampler_view *state)
887 {
888    struct zink_screen *screen = zink_screen(pctx->screen);
889    struct zink_resource *res = zink_resource(pres);
890    struct zink_context *ctx = zink_context(pctx);
891    struct zink_sampler_view *sampler_view = CALLOC_STRUCT_CL(zink_sampler_view);
892    bool err;
893 
894    sampler_view->base = *state;
895    sampler_view->base.texture = NULL;
896    pipe_resource_reference(&sampler_view->base.texture, pres);
897    sampler_view->base.reference.count = 1;
898    sampler_view->base.context = pctx;
899 
900    if (state->target != PIPE_BUFFER) {
901       VkImageViewCreateInfo ivci;
902 
903       struct pipe_surface templ = {0};
904       templ.u.tex.level = state->u.tex.first_level;
905       templ.format = state->format;
906       if (state->target != PIPE_TEXTURE_3D) {
907          templ.u.tex.first_layer = state->u.tex.first_layer;
908          templ.u.tex.last_layer = state->u.tex.last_layer;
909       }
910 
911       if (zink_is_swapchain(res)) {
912          if (!zink_kopper_acquire(ctx, res, UINT64_MAX)) {
913             FREE_CL(sampler_view);
914             return NULL;
915          }
916       }
917 
918       ivci = create_ivci(screen, res, &templ, state->target);
919       ivci.subresourceRange.levelCount = state->u.tex.last_level - state->u.tex.first_level + 1;
920       ivci.subresourceRange.aspectMask = sampler_aspect_from_format(state->format);
921       /* samplers for stencil aspects of packed formats need to always use stencil swizzle */
922       if (ivci.subresourceRange.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
923          if (sampler_view->base.swizzle_r == PIPE_SWIZZLE_0 &&
924              sampler_view->base.swizzle_g == PIPE_SWIZZLE_0 &&
925              sampler_view->base.swizzle_b == PIPE_SWIZZLE_0 &&
926              sampler_view->base.swizzle_a == PIPE_SWIZZLE_X) {
927             /*
928              * When the state tracker asks for 000x swizzles, this is depth mode GL_ALPHA,
929              * however with the single dref fetch this will fail, so just spam all the channels.
930              */
931             ivci.components.r = VK_COMPONENT_SWIZZLE_R;
932             ivci.components.g = VK_COMPONENT_SWIZZLE_R;
933             ivci.components.b = VK_COMPONENT_SWIZZLE_R;
934             ivci.components.a = VK_COMPONENT_SWIZZLE_R;
935          } else {
936             ivci.components.r = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_r));
937             ivci.components.g = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_g));
938             ivci.components.b = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_b));
939             ivci.components.a = zink_component_mapping(clamp_zs_swizzle(sampler_view->base.swizzle_a));
940          }
941       } else {
942          /* if we have e.g., R8G8B8X8, then we have to ignore alpha since we're just emulating
943           * these formats
944           */
945           if (zink_format_is_voidable_rgba_variant(state->format)) {
946              const struct util_format_description *desc = util_format_description(state->format);
947              sampler_view->base.swizzle_r = zink_clamp_void_swizzle(desc, sampler_view->base.swizzle_r);
948              sampler_view->base.swizzle_g = zink_clamp_void_swizzle(desc, sampler_view->base.swizzle_g);
949              sampler_view->base.swizzle_b = zink_clamp_void_swizzle(desc, sampler_view->base.swizzle_b);
950              sampler_view->base.swizzle_a = zink_clamp_void_swizzle(desc, sampler_view->base.swizzle_a);
951           }
952           ivci.components.r = zink_component_mapping(sampler_view->base.swizzle_r);
953           ivci.components.g = zink_component_mapping(sampler_view->base.swizzle_g);
954           ivci.components.b = zink_component_mapping(sampler_view->base.swizzle_b);
955           ivci.components.a = zink_component_mapping(sampler_view->base.swizzle_a);
956       }
957       assert(ivci.format);
958 
959       sampler_view->image_view = (struct zink_surface*)zink_get_surface(ctx, pres, &templ, &ivci);
960       if (!screen->info.have_EXT_non_seamless_cube_map && viewtype_is_cube(&sampler_view->image_view->ivci)) {
961          ivci.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
962          sampler_view->cube_array = (struct zink_surface*)zink_get_surface(ctx, pres, &templ, &ivci);
963       }
964       err = !sampler_view->image_view;
965    } else {
966       VkBufferViewCreateInfo bvci = create_bvci(ctx, res, state->format, state->u.buf.offset, state->u.buf.size);
967       sampler_view->buffer_view = get_buffer_view(ctx, res, &bvci);
968       err = !sampler_view->buffer_view;
969    }
970    if (err) {
971       FREE_CL(sampler_view);
972       return NULL;
973    }
974    return &sampler_view->base;
975 }
976 
977 void
zink_destroy_buffer_view(struct zink_screen * screen,struct zink_buffer_view * buffer_view)978 zink_destroy_buffer_view(struct zink_screen *screen, struct zink_buffer_view *buffer_view)
979 {
980    struct zink_resource *res = zink_resource(buffer_view->pres);
981    simple_mtx_lock(&res->bufferview_mtx);
982    if (buffer_view->reference.count) {
983       /* got a cache hit during deletion */
984       simple_mtx_unlock(&res->bufferview_mtx);
985       return;
986    }
987    struct hash_entry *he = _mesa_hash_table_search_pre_hashed(&res->bufferview_cache, buffer_view->hash, &buffer_view->bvci);
988    assert(he);
989    _mesa_hash_table_remove(&res->bufferview_cache, he);
990    simple_mtx_unlock(&res->bufferview_mtx);
991    pipe_resource_reference(&buffer_view->pres, NULL);
992    VKSCR(DestroyBufferView)(screen->dev, buffer_view->buffer_view, NULL);
993    zink_descriptor_set_refs_clear(&buffer_view->desc_set_refs, buffer_view);
994    FREE(buffer_view);
995 }
996 
997 static void
zink_sampler_view_destroy(struct pipe_context * pctx,struct pipe_sampler_view * pview)998 zink_sampler_view_destroy(struct pipe_context *pctx,
999                           struct pipe_sampler_view *pview)
1000 {
1001    struct zink_sampler_view *view = zink_sampler_view(pview);
1002    if (pview->texture->target == PIPE_BUFFER)
1003       zink_buffer_view_reference(zink_screen(pctx->screen), &view->buffer_view, NULL);
1004    else {
1005       zink_surface_reference(zink_screen(pctx->screen), &view->image_view, NULL);
1006       zink_surface_reference(zink_screen(pctx->screen), &view->cube_array, NULL);
1007    }
1008    pipe_resource_reference(&pview->texture, NULL);
1009    FREE_CL(view);
1010 }
1011 
1012 static void
zink_get_sample_position(struct pipe_context * ctx,unsigned sample_count,unsigned sample_index,float * out_value)1013 zink_get_sample_position(struct pipe_context *ctx,
1014                          unsigned sample_count,
1015                          unsigned sample_index,
1016                          float *out_value)
1017 {
1018    /* TODO: handle this I guess */
1019    assert(zink_screen(ctx->screen)->info.props.limits.standardSampleLocations);
1020    /* from 26.4. Multisampling */
1021    switch (sample_count) {
1022    case 0:
1023    case 1: {
1024       float pos[][2] = { {0.5,0.5}, };
1025       out_value[0] = pos[sample_index][0];
1026       out_value[1] = pos[sample_index][1];
1027       break;
1028    }
1029    case 2: {
1030       float pos[][2] = { {0.75,0.75},
1031                         {0.25,0.25}, };
1032       out_value[0] = pos[sample_index][0];
1033       out_value[1] = pos[sample_index][1];
1034       break;
1035    }
1036    case 4: {
1037       float pos[][2] = { {0.375, 0.125},
1038                         {0.875, 0.375},
1039                         {0.125, 0.625},
1040                         {0.625, 0.875}, };
1041       out_value[0] = pos[sample_index][0];
1042       out_value[1] = pos[sample_index][1];
1043       break;
1044    }
1045    case 8: {
1046       float pos[][2] = { {0.5625, 0.3125},
1047                         {0.4375, 0.6875},
1048                         {0.8125, 0.5625},
1049                         {0.3125, 0.1875},
1050                         {0.1875, 0.8125},
1051                         {0.0625, 0.4375},
1052                         {0.6875, 0.9375},
1053                         {0.9375, 0.0625}, };
1054       out_value[0] = pos[sample_index][0];
1055       out_value[1] = pos[sample_index][1];
1056       break;
1057    }
1058    case 16: {
1059       float pos[][2] = { {0.5625, 0.5625},
1060                         {0.4375, 0.3125},
1061                         {0.3125, 0.625},
1062                         {0.75, 0.4375},
1063                         {0.1875, 0.375},
1064                         {0.625, 0.8125},
1065                         {0.8125, 0.6875},
1066                         {0.6875, 0.1875},
1067                         {0.375, 0.875},
1068                         {0.5, 0.0625},
1069                         {0.25, 0.125},
1070                         {0.125, 0.75},
1071                         {0.0, 0.5},
1072                         {0.9375, 0.25},
1073                         {0.875, 0.9375},
1074                         {0.0625, 0.0}, };
1075       out_value[0] = pos[sample_index][0];
1076       out_value[1] = pos[sample_index][1];
1077       break;
1078    }
1079    default:
1080       unreachable("unhandled sample count!");
1081    }
1082 }
1083 
1084 static void
zink_set_polygon_stipple(struct pipe_context * pctx,const struct pipe_poly_stipple * ps)1085 zink_set_polygon_stipple(struct pipe_context *pctx,
1086                          const struct pipe_poly_stipple *ps)
1087 {
1088 }
1089 
1090 ALWAYS_INLINE static void
update_res_bind_count(struct zink_context * ctx,struct zink_resource * res,bool is_compute,bool decrement)1091 update_res_bind_count(struct zink_context *ctx, struct zink_resource *res, bool is_compute, bool decrement)
1092 {
1093    if (decrement) {
1094       assert(res->bind_count[is_compute]);
1095       if (!--res->bind_count[is_compute])
1096          _mesa_set_remove_key(ctx->need_barriers[is_compute], res);
1097       check_resource_for_batch_ref(ctx, res);
1098    } else
1099       res->bind_count[is_compute]++;
1100 }
1101 
1102 ALWAYS_INLINE static void
update_existing_vbo(struct zink_context * ctx,unsigned slot)1103 update_existing_vbo(struct zink_context *ctx, unsigned slot)
1104 {
1105    if (!ctx->vertex_buffers[slot].buffer.resource)
1106       return;
1107    struct zink_resource *res = zink_resource(ctx->vertex_buffers[slot].buffer.resource);
1108    res->vbo_bind_count--;
1109    res->vbo_bind_mask &= ~BITFIELD_BIT(slot);
1110    if (!res->vbo_bind_count) {
1111       res->gfx_barrier &= ~VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
1112       res->barrier_access[0] &= ~VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
1113    }
1114    update_res_bind_count(ctx, res, false, true);
1115 }
1116 
1117 static void
zink_set_vertex_buffers(struct pipe_context * pctx,unsigned start_slot,unsigned num_buffers,unsigned unbind_num_trailing_slots,bool take_ownership,const struct pipe_vertex_buffer * buffers)1118 zink_set_vertex_buffers(struct pipe_context *pctx,
1119                         unsigned start_slot,
1120                         unsigned num_buffers,
1121                         unsigned unbind_num_trailing_slots,
1122                         bool take_ownership,
1123                         const struct pipe_vertex_buffer *buffers)
1124 {
1125    struct zink_context *ctx = zink_context(pctx);
1126    const bool have_input_state = zink_screen(pctx->screen)->info.have_EXT_vertex_input_dynamic_state;
1127    const bool need_state_change = !zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state &&
1128                                   !have_input_state;
1129    uint32_t enabled_buffers = ctx->gfx_pipeline_state.vertex_buffers_enabled_mask;
1130    enabled_buffers |= u_bit_consecutive(start_slot, num_buffers);
1131    enabled_buffers &= ~u_bit_consecutive(start_slot + num_buffers, unbind_num_trailing_slots);
1132    bool stride_changed = false;
1133 
1134    if (buffers) {
1135       for (unsigned i = 0; i < num_buffers; ++i) {
1136          const struct pipe_vertex_buffer *vb = buffers + i;
1137          struct pipe_vertex_buffer *ctx_vb = &ctx->vertex_buffers[start_slot + i];
1138          stride_changed |= ctx_vb->stride != vb->stride;
1139          update_existing_vbo(ctx, start_slot + i);
1140          if (!take_ownership)
1141             pipe_resource_reference(&ctx_vb->buffer.resource, vb->buffer.resource);
1142          else {
1143             pipe_resource_reference(&ctx_vb->buffer.resource, NULL);
1144             ctx_vb->buffer.resource = vb->buffer.resource;
1145          }
1146          if (vb->buffer.resource) {
1147             struct zink_resource *res = zink_resource(vb->buffer.resource);
1148             res->vbo_bind_mask |= BITFIELD_BIT(start_slot + i);
1149             res->vbo_bind_count++;
1150             res->gfx_barrier |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
1151             res->barrier_access[0] |= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
1152             update_res_bind_count(ctx, res, false, false);
1153             ctx_vb->stride = vb->stride;
1154             ctx_vb->buffer_offset = vb->buffer_offset;
1155             zink_batch_resource_usage_set(&ctx->batch, res, false);
1156             /* always barrier before possible rebind */
1157             zink_resource_buffer_barrier(ctx, res, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
1158                                          VK_PIPELINE_STAGE_VERTEX_INPUT_BIT);
1159             res->obj->unordered_read = false;
1160          } else {
1161             enabled_buffers &= ~BITFIELD_BIT(start_slot + i);
1162          }
1163       }
1164    } else {
1165       for (unsigned i = 0; i < num_buffers; ++i) {
1166          update_existing_vbo(ctx, start_slot + i);
1167          pipe_resource_reference(&ctx->vertex_buffers[start_slot + i].buffer.resource, NULL);
1168       }
1169    }
1170    for (unsigned i = 0; i < unbind_num_trailing_slots; i++) {
1171       update_existing_vbo(ctx, start_slot + i);
1172       pipe_resource_reference(&ctx->vertex_buffers[start_slot + i].buffer.resource, NULL);
1173    }
1174    if (need_state_change)
1175       ctx->vertex_state_changed = true;
1176    else if (!have_input_state && (stride_changed || ctx->gfx_pipeline_state.vertex_buffers_enabled_mask != enabled_buffers))
1177       ctx->vertex_state_changed = true;
1178    ctx->gfx_pipeline_state.vertex_buffers_enabled_mask = enabled_buffers;
1179    ctx->vertex_buffers_dirty = num_buffers > 0;
1180 #ifndef NDEBUG
1181    u_foreach_bit(b, enabled_buffers)
1182       assert(ctx->vertex_buffers[b].buffer.resource);
1183 #endif
1184 }
1185 
1186 static void
zink_set_viewport_states(struct pipe_context * pctx,unsigned start_slot,unsigned num_viewports,const struct pipe_viewport_state * state)1187 zink_set_viewport_states(struct pipe_context *pctx,
1188                          unsigned start_slot,
1189                          unsigned num_viewports,
1190                          const struct pipe_viewport_state *state)
1191 {
1192    struct zink_context *ctx = zink_context(pctx);
1193 
1194    for (unsigned i = 0; i < num_viewports; ++i)
1195       ctx->vp_state.viewport_states[start_slot + i] = state[i];
1196 
1197    ctx->vp_state_changed = true;
1198 }
1199 
1200 static void
zink_set_scissor_states(struct pipe_context * pctx,unsigned start_slot,unsigned num_scissors,const struct pipe_scissor_state * states)1201 zink_set_scissor_states(struct pipe_context *pctx,
1202                         unsigned start_slot, unsigned num_scissors,
1203                         const struct pipe_scissor_state *states)
1204 {
1205    struct zink_context *ctx = zink_context(pctx);
1206 
1207    for (unsigned i = 0; i < num_scissors; i++)
1208       ctx->vp_state.scissor_states[start_slot + i] = states[i];
1209    ctx->scissor_changed = true;
1210 }
1211 
1212 static void
zink_set_inlinable_constants(struct pipe_context * pctx,enum pipe_shader_type shader,uint num_values,uint32_t * values)1213 zink_set_inlinable_constants(struct pipe_context *pctx,
1214                              enum pipe_shader_type shader,
1215                              uint num_values, uint32_t *values)
1216 {
1217    struct zink_context *ctx = (struct zink_context *)pctx;
1218    const uint32_t bit = BITFIELD_BIT(shader);
1219    uint32_t *inlinable_uniforms;
1220    struct zink_shader_key *key = NULL;
1221 
1222    if (shader == PIPE_SHADER_COMPUTE) {
1223       key = &ctx->compute_pipeline_state.key;
1224    } else {
1225       key = &ctx->gfx_pipeline_state.shader_keys.key[shader];
1226    }
1227    inlinable_uniforms = key->base.inlined_uniform_values;
1228    if (!(ctx->inlinable_uniforms_valid_mask & bit) ||
1229        memcmp(inlinable_uniforms, values, num_values * 4)) {
1230       memcpy(inlinable_uniforms, values, num_values * 4);
1231       ctx->dirty_shader_stages |= bit;
1232       ctx->inlinable_uniforms_valid_mask |= bit;
1233       key->inline_uniforms = true;
1234    }
1235 }
1236 
1237 ALWAYS_INLINE static void
unbind_descriptor_stage(struct zink_resource * res,enum pipe_shader_type pstage)1238 unbind_descriptor_stage(struct zink_resource *res, enum pipe_shader_type pstage)
1239 {
1240    if (!res->sampler_binds[pstage] && !res->image_binds[pstage])
1241       res->gfx_barrier &= ~zink_pipeline_flags_from_pipe_stage(pstage);
1242 }
1243 
1244 ALWAYS_INLINE static void
unbind_buffer_descriptor_stage(struct zink_resource * res,enum pipe_shader_type pstage)1245 unbind_buffer_descriptor_stage(struct zink_resource *res, enum pipe_shader_type pstage)
1246 {
1247    if (!res->ubo_bind_mask[pstage] && !res->ssbo_bind_mask[pstage])
1248       unbind_descriptor_stage(res, pstage);
1249 }
1250 
1251 ALWAYS_INLINE static void
unbind_ubo(struct zink_context * ctx,struct zink_resource * res,enum pipe_shader_type pstage,unsigned slot)1252 unbind_ubo(struct zink_context *ctx, struct zink_resource *res, enum pipe_shader_type pstage, unsigned slot)
1253 {
1254    if (!res)
1255       return;
1256    res->ubo_bind_mask[pstage] &= ~BITFIELD_BIT(slot);
1257    res->ubo_bind_count[pstage == PIPE_SHADER_COMPUTE]--;
1258    unbind_buffer_descriptor_stage(res, pstage);
1259    if (!res->ubo_bind_count[pstage == PIPE_SHADER_COMPUTE])
1260       res->barrier_access[pstage == PIPE_SHADER_COMPUTE] &= ~VK_ACCESS_UNIFORM_READ_BIT;
1261    update_res_bind_count(ctx, res, pstage == PIPE_SHADER_COMPUTE, true);
1262 }
1263 
1264 static void
invalidate_inlined_uniforms(struct zink_context * ctx,enum pipe_shader_type pstage)1265 invalidate_inlined_uniforms(struct zink_context *ctx, enum pipe_shader_type pstage)
1266 {
1267    unsigned bit = BITFIELD_BIT(pstage);
1268    if (!(ctx->inlinable_uniforms_valid_mask & bit))
1269       return;
1270    ctx->inlinable_uniforms_valid_mask &= ~bit;
1271    ctx->dirty_shader_stages |= bit;
1272    if (pstage == PIPE_SHADER_COMPUTE)
1273       return;
1274 
1275    struct zink_shader_key *key = &ctx->gfx_pipeline_state.shader_keys.key[pstage];
1276    key->inline_uniforms = false;
1277 }
1278 
1279 static void
zink_set_constant_buffer(struct pipe_context * pctx,enum pipe_shader_type shader,uint index,bool take_ownership,const struct pipe_constant_buffer * cb)1280 zink_set_constant_buffer(struct pipe_context *pctx,
1281                          enum pipe_shader_type shader, uint index,
1282                          bool take_ownership,
1283                          const struct pipe_constant_buffer *cb)
1284 {
1285    struct zink_context *ctx = zink_context(pctx);
1286    bool update = false;
1287 
1288    struct zink_resource *res = zink_resource(ctx->ubos[shader][index].buffer);
1289    if (cb) {
1290       struct pipe_resource *buffer = cb->buffer;
1291       unsigned offset = cb->buffer_offset;
1292       struct zink_screen *screen = zink_screen(pctx->screen);
1293       if (cb->user_buffer) {
1294          u_upload_data(ctx->base.const_uploader, 0, cb->buffer_size,
1295                        screen->info.props.limits.minUniformBufferOffsetAlignment,
1296                        cb->user_buffer, &offset, &buffer);
1297       }
1298       struct zink_resource *new_res = zink_resource(buffer);
1299       if (new_res) {
1300          if (new_res != res) {
1301             unbind_ubo(ctx, res, shader, index);
1302             new_res->ubo_bind_count[shader == PIPE_SHADER_COMPUTE]++;
1303             new_res->ubo_bind_mask[shader] |= BITFIELD_BIT(index);
1304             new_res->gfx_barrier |= zink_pipeline_flags_from_pipe_stage(shader);
1305             new_res->barrier_access[shader == PIPE_SHADER_COMPUTE] |= VK_ACCESS_UNIFORM_READ_BIT;
1306             update_res_bind_count(ctx, new_res, shader == PIPE_SHADER_COMPUTE, false);
1307          }
1308          zink_batch_resource_usage_set(&ctx->batch, new_res, false);
1309          zink_resource_buffer_barrier(ctx, new_res, VK_ACCESS_UNIFORM_READ_BIT,
1310                                       new_res->gfx_barrier);
1311          new_res->obj->unordered_read = false;
1312       }
1313       update |= ((index || zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_LAZY) && ctx->ubos[shader][index].buffer_offset != offset) ||
1314                 !!res != !!buffer || (res && res->obj->buffer != new_res->obj->buffer) ||
1315                 ctx->ubos[shader][index].buffer_size != cb->buffer_size;
1316 
1317       if (take_ownership) {
1318          pipe_resource_reference(&ctx->ubos[shader][index].buffer, NULL);
1319          ctx->ubos[shader][index].buffer = buffer;
1320       } else {
1321          pipe_resource_reference(&ctx->ubos[shader][index].buffer, buffer);
1322       }
1323       ctx->ubos[shader][index].buffer_offset = offset;
1324       ctx->ubos[shader][index].buffer_size = cb->buffer_size;
1325       ctx->ubos[shader][index].user_buffer = NULL;
1326 
1327       if (cb->user_buffer)
1328          pipe_resource_reference(&buffer, NULL);
1329 
1330       if (index + 1 >= ctx->di.num_ubos[shader])
1331          ctx->di.num_ubos[shader] = index + 1;
1332       update_descriptor_state_ubo(ctx, shader, index, new_res);
1333    } else {
1334       ctx->ubos[shader][index].buffer_offset = 0;
1335       ctx->ubos[shader][index].buffer_size = 0;
1336       ctx->ubos[shader][index].user_buffer = NULL;
1337       if (res) {
1338          unbind_ubo(ctx, res, shader, index);
1339          update_descriptor_state_ubo(ctx, shader, index, NULL);
1340       }
1341       update = !!ctx->ubos[shader][index].buffer;
1342 
1343       pipe_resource_reference(&ctx->ubos[shader][index].buffer, NULL);
1344       if (ctx->di.num_ubos[shader] == index + 1)
1345          ctx->di.num_ubos[shader]--;
1346    }
1347    if (index == 0) {
1348       /* Invalidate current inlinable uniforms. */
1349       invalidate_inlined_uniforms(ctx, shader);
1350    }
1351 
1352    if (update)
1353       zink_screen(pctx->screen)->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_UBO, index, 1);
1354 }
1355 
1356 ALWAYS_INLINE static void
unbind_descriptor_reads(struct zink_resource * res,enum pipe_shader_type pstage)1357 unbind_descriptor_reads(struct zink_resource *res, enum pipe_shader_type pstage)
1358 {
1359    if (!res->sampler_binds[pstage] && !res->image_binds[pstage])
1360       res->barrier_access[pstage == PIPE_SHADER_COMPUTE] &= ~VK_ACCESS_SHADER_READ_BIT;
1361 }
1362 
1363 ALWAYS_INLINE static void
unbind_buffer_descriptor_reads(struct zink_resource * res,enum pipe_shader_type pstage)1364 unbind_buffer_descriptor_reads(struct zink_resource *res, enum pipe_shader_type pstage)
1365 {
1366    if (!res->ssbo_bind_count[pstage == PIPE_SHADER_COMPUTE])
1367       unbind_descriptor_reads(res, pstage);
1368 }
1369 
1370 ALWAYS_INLINE static void
unbind_ssbo(struct zink_context * ctx,struct zink_resource * res,enum pipe_shader_type pstage,unsigned slot,bool writable)1371 unbind_ssbo(struct zink_context *ctx, struct zink_resource *res, enum pipe_shader_type pstage, unsigned slot, bool writable)
1372 {
1373    if (!res)
1374       return;
1375    res->ssbo_bind_mask[pstage] &= ~BITFIELD_BIT(slot);
1376    res->ssbo_bind_count[pstage == PIPE_SHADER_COMPUTE]--;
1377    unbind_buffer_descriptor_stage(res, pstage);
1378    unbind_buffer_descriptor_reads(res, pstage);
1379    update_res_bind_count(ctx, res, pstage == PIPE_SHADER_COMPUTE, true);
1380    if (writable)
1381       res->write_bind_count[pstage == PIPE_SHADER_COMPUTE]--;
1382    if (!res->write_bind_count[pstage == PIPE_SHADER_COMPUTE])
1383       res->barrier_access[pstage == PIPE_SHADER_COMPUTE] &= ~VK_ACCESS_SHADER_WRITE_BIT;
1384 }
1385 
1386 static void
zink_set_shader_buffers(struct pipe_context * pctx,enum pipe_shader_type p_stage,unsigned start_slot,unsigned count,const struct pipe_shader_buffer * buffers,unsigned writable_bitmask)1387 zink_set_shader_buffers(struct pipe_context *pctx,
1388                         enum pipe_shader_type p_stage,
1389                         unsigned start_slot, unsigned count,
1390                         const struct pipe_shader_buffer *buffers,
1391                         unsigned writable_bitmask)
1392 {
1393    struct zink_context *ctx = zink_context(pctx);
1394    bool update = false;
1395    unsigned max_slot = 0;
1396 
1397    unsigned modified_bits = u_bit_consecutive(start_slot, count);
1398    unsigned old_writable_mask = ctx->writable_ssbos[p_stage];
1399    ctx->writable_ssbos[p_stage] &= ~modified_bits;
1400    ctx->writable_ssbos[p_stage] |= writable_bitmask << start_slot;
1401 
1402    for (unsigned i = 0; i < count; i++) {
1403       struct pipe_shader_buffer *ssbo = &ctx->ssbos[p_stage][start_slot + i];
1404       struct zink_resource *res = ssbo->buffer ? zink_resource(ssbo->buffer) : NULL;
1405       bool was_writable = old_writable_mask & BITFIELD64_BIT(start_slot + i);
1406       if (buffers && buffers[i].buffer) {
1407          struct zink_resource *new_res = zink_resource(buffers[i].buffer);
1408          if (new_res != res) {
1409             unbind_ssbo(ctx, res, p_stage, i, was_writable);
1410             new_res->ssbo_bind_mask[p_stage] |= BITFIELD_BIT(i);
1411             new_res->ssbo_bind_count[p_stage == PIPE_SHADER_COMPUTE]++;
1412             new_res->gfx_barrier |= zink_pipeline_flags_from_pipe_stage(p_stage);
1413             update_res_bind_count(ctx, new_res, p_stage == PIPE_SHADER_COMPUTE, false);
1414          }
1415          VkAccessFlags access = VK_ACCESS_SHADER_READ_BIT;
1416          if (ctx->writable_ssbos[p_stage] & BITFIELD64_BIT(start_slot + i)) {
1417             new_res->write_bind_count[p_stage == PIPE_SHADER_COMPUTE]++;
1418             access |= VK_ACCESS_SHADER_WRITE_BIT;
1419          }
1420          pipe_resource_reference(&ssbo->buffer, &new_res->base.b);
1421          new_res->barrier_access[p_stage == PIPE_SHADER_COMPUTE] |= access;
1422          zink_batch_resource_usage_set(&ctx->batch, new_res, access & VK_ACCESS_SHADER_WRITE_BIT);
1423          ssbo->buffer_offset = buffers[i].buffer_offset;
1424          ssbo->buffer_size = MIN2(buffers[i].buffer_size, new_res->base.b.width0 - ssbo->buffer_offset);
1425          util_range_add(&new_res->base.b, &new_res->valid_buffer_range, ssbo->buffer_offset,
1426                         ssbo->buffer_offset + ssbo->buffer_size);
1427          zink_resource_buffer_barrier(ctx, new_res, access,
1428                                       new_res->gfx_barrier);
1429          update = true;
1430          max_slot = MAX2(max_slot, start_slot + i);
1431          update_descriptor_state_ssbo(ctx, p_stage, start_slot + i, new_res);
1432          if (zink_resource_access_is_write(access))
1433             new_res->obj->unordered_read = new_res->obj->unordered_write = false;
1434          else
1435             new_res->obj->unordered_read = false;
1436       } else {
1437          update = !!res;
1438          ssbo->buffer_offset = 0;
1439          ssbo->buffer_size = 0;
1440          if (res) {
1441             unbind_ssbo(ctx, res, p_stage, i, was_writable);
1442             update_descriptor_state_ssbo(ctx, p_stage, start_slot + i, NULL);
1443          }
1444          pipe_resource_reference(&ssbo->buffer, NULL);
1445       }
1446    }
1447    if (start_slot + count >= ctx->di.num_ssbos[p_stage])
1448       ctx->di.num_ssbos[p_stage] = max_slot + 1;
1449    if (update)
1450       zink_screen(pctx->screen)->context_invalidate_descriptor_state(ctx, p_stage, ZINK_DESCRIPTOR_TYPE_SSBO, start_slot, count);
1451 }
1452 
1453 static void
update_binds_for_samplerviews(struct zink_context * ctx,struct zink_resource * res,bool is_compute)1454 update_binds_for_samplerviews(struct zink_context *ctx, struct zink_resource *res, bool is_compute)
1455 {
1456     VkImageLayout layout = get_layout_for_binding(ctx, res, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, is_compute);
1457     if (is_compute) {
1458        u_foreach_bit(slot, res->sampler_binds[PIPE_SHADER_COMPUTE]) {
1459           if (ctx->di.textures[PIPE_SHADER_COMPUTE][slot].imageLayout != layout) {
1460              update_descriptor_state_sampler(ctx, PIPE_SHADER_COMPUTE, slot, res);
1461              zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, PIPE_SHADER_COMPUTE, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, slot, 1);
1462           }
1463        }
1464     } else {
1465        for (unsigned i = 0; i < ZINK_SHADER_COUNT; i++) {
1466           u_foreach_bit(slot, res->sampler_binds[i]) {
1467              if (ctx->di.textures[i][slot].imageLayout != layout) {
1468                 update_descriptor_state_sampler(ctx, i, slot, res);
1469                 zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, slot, 1);
1470              }
1471           }
1472        }
1473     }
1474 }
1475 
1476 static void
flush_pending_clears(struct zink_context * ctx,struct zink_resource * res)1477 flush_pending_clears(struct zink_context *ctx, struct zink_resource *res)
1478 {
1479    if (res->fb_binds && ctx->clears_enabled)
1480       zink_fb_clears_apply(ctx, &res->base.b);
1481 }
1482 
1483 static inline void
unbind_shader_image_counts(struct zink_context * ctx,struct zink_resource * res,bool is_compute,bool writable)1484 unbind_shader_image_counts(struct zink_context *ctx, struct zink_resource *res, bool is_compute, bool writable)
1485 {
1486    update_res_bind_count(ctx, res, is_compute, true);
1487    if (writable)
1488       res->write_bind_count[is_compute]--;
1489    res->image_bind_count[is_compute]--;
1490    /* if this was the last image bind, the sampler bind layouts must be updated */
1491    if (!res->obj->is_buffer && !res->image_bind_count[is_compute] && res->bind_count[is_compute])
1492       update_binds_for_samplerviews(ctx, res, is_compute);
1493 }
1494 
1495 ALWAYS_INLINE static void
check_for_layout_update(struct zink_context * ctx,struct zink_resource * res,bool is_compute)1496 check_for_layout_update(struct zink_context *ctx, struct zink_resource *res, bool is_compute)
1497 {
1498    VkImageLayout layout = res->bind_count[is_compute] ? zink_descriptor_util_image_layout_eval(ctx, res, is_compute) : VK_IMAGE_LAYOUT_UNDEFINED;
1499    VkImageLayout other_layout = res->bind_count[!is_compute] ? zink_descriptor_util_image_layout_eval(ctx, res, !is_compute) : VK_IMAGE_LAYOUT_UNDEFINED;
1500    if (res->bind_count[is_compute] && layout && res->layout != layout)
1501       _mesa_set_add(ctx->need_barriers[is_compute], res);
1502    if (res->bind_count[!is_compute] && other_layout && (layout != other_layout || res->layout != other_layout))
1503       _mesa_set_add(ctx->need_barriers[!is_compute], res);
1504 }
1505 
1506 static void
unbind_shader_image(struct zink_context * ctx,enum pipe_shader_type stage,unsigned slot)1507 unbind_shader_image(struct zink_context *ctx, enum pipe_shader_type stage, unsigned slot)
1508 {
1509    struct zink_image_view *image_view = &ctx->image_views[stage][slot];
1510    bool is_compute = stage == PIPE_SHADER_COMPUTE;
1511    if (!image_view->base.resource)
1512       return;
1513 
1514    struct zink_resource *res = zink_resource(image_view->base.resource);
1515    res->image_binds[stage] &= ~BITFIELD_BIT(slot);
1516    unbind_shader_image_counts(ctx, res, is_compute, image_view->base.access & PIPE_IMAGE_ACCESS_WRITE);
1517    if (!res->write_bind_count[is_compute])
1518       res->barrier_access[stage == PIPE_SHADER_COMPUTE] &= ~VK_ACCESS_SHADER_WRITE_BIT;
1519 
1520    if (image_view->base.resource->target == PIPE_BUFFER) {
1521       unbind_buffer_descriptor_stage(res, stage);
1522       unbind_buffer_descriptor_reads(res, stage);
1523       if (zink_batch_usage_exists(image_view->buffer_view->batch_uses))
1524          zink_batch_reference_bufferview(&ctx->batch, image_view->buffer_view);
1525       zink_buffer_view_reference(zink_screen(ctx->base.screen), &image_view->buffer_view, NULL);
1526    } else {
1527       unbind_descriptor_stage(res, stage);
1528       if (!res->image_bind_count[is_compute])
1529          check_for_layout_update(ctx, res, is_compute);
1530       if (zink_batch_usage_exists(image_view->surface->batch_uses))
1531          zink_batch_reference_surface(&ctx->batch, image_view->surface);
1532       zink_surface_reference(zink_screen(ctx->base.screen), &image_view->surface, NULL);
1533    }
1534    image_view->base.resource = NULL;
1535    image_view->surface = NULL;
1536 }
1537 
1538 static struct zink_buffer_view *
create_image_bufferview(struct zink_context * ctx,const struct pipe_image_view * view)1539 create_image_bufferview(struct zink_context *ctx, const struct pipe_image_view *view)
1540 {
1541    struct zink_resource *res = zink_resource(view->resource);
1542    VkBufferViewCreateInfo bvci = create_bvci(ctx, res, view->format, view->u.buf.offset, view->u.buf.size);
1543    struct zink_buffer_view *buffer_view = get_buffer_view(ctx, res, &bvci);
1544    if (!buffer_view)
1545       return NULL;
1546    util_range_add(&res->base.b, &res->valid_buffer_range, view->u.buf.offset,
1547                   view->u.buf.offset + view->u.buf.size);
1548    return buffer_view;
1549 }
1550 
1551 static void
finalize_image_bind(struct zink_context * ctx,struct zink_resource * res,bool is_compute)1552 finalize_image_bind(struct zink_context *ctx, struct zink_resource *res, bool is_compute)
1553 {
1554    /* if this is the first image bind and there are sampler binds, the image's sampler layout
1555     * must be updated to GENERAL
1556     */
1557    if (res->image_bind_count[is_compute] == 1 &&
1558        res->bind_count[is_compute] > 1)
1559       update_binds_for_samplerviews(ctx, res, is_compute);
1560    check_for_layout_update(ctx, res, is_compute);
1561 }
1562 
1563 static struct zink_surface *
create_image_surface(struct zink_context * ctx,const struct pipe_image_view * view,bool is_compute)1564 create_image_surface(struct zink_context *ctx, const struct pipe_image_view *view, bool is_compute)
1565 {
1566    struct zink_screen *screen = zink_screen(ctx->base.screen);
1567    struct zink_resource *res = zink_resource(view->resource);
1568    struct pipe_surface tmpl = {0};
1569    enum pipe_texture_target target = res->base.b.target;
1570    tmpl.format = view->format;
1571    tmpl.u.tex.level = view->u.tex.level;
1572    tmpl.u.tex.first_layer = view->u.tex.first_layer;
1573    tmpl.u.tex.last_layer = view->u.tex.last_layer;
1574    unsigned depth = 1 + tmpl.u.tex.last_layer - tmpl.u.tex.first_layer;
1575    switch (target) {
1576    case PIPE_TEXTURE_3D:
1577       if (depth < u_minify(res->base.b.depth0, view->u.tex.level)) {
1578          assert(depth == 1);
1579          target = PIPE_TEXTURE_2D;
1580          if (!screen->info.have_EXT_image_2d_view_of_3d ||
1581              !screen->info.view2d_feats.image2DViewOf3D) {
1582             static bool warned = false;
1583             warn_missing_feature(warned, "image2DViewOf3D");
1584          }
1585       } else {
1586          assert(tmpl.u.tex.first_layer == 0);
1587          tmpl.u.tex.last_layer = 0;
1588       }
1589       break;
1590    case PIPE_TEXTURE_2D_ARRAY:
1591    case PIPE_TEXTURE_1D_ARRAY:
1592       if (depth < res->base.b.array_size && depth == 1)
1593          target = target == PIPE_TEXTURE_2D_ARRAY ? PIPE_TEXTURE_2D : PIPE_TEXTURE_1D;
1594       break;
1595    default: break;
1596    }
1597    VkImageViewCreateInfo ivci = create_ivci(screen, res, &tmpl, target);
1598    struct pipe_surface *psurf = zink_get_surface(ctx, view->resource, &tmpl, &ivci);
1599    if (!psurf)
1600       return NULL;
1601    struct zink_surface *surface = zink_surface(psurf);
1602    if (is_compute)
1603       flush_pending_clears(ctx, res);
1604    return surface;
1605 }
1606 
1607 static void
zink_set_shader_images(struct pipe_context * pctx,enum pipe_shader_type p_stage,unsigned start_slot,unsigned count,unsigned unbind_num_trailing_slots,const struct pipe_image_view * images)1608 zink_set_shader_images(struct pipe_context *pctx,
1609                        enum pipe_shader_type p_stage,
1610                        unsigned start_slot, unsigned count,
1611                        unsigned unbind_num_trailing_slots,
1612                        const struct pipe_image_view *images)
1613 {
1614    struct zink_context *ctx = zink_context(pctx);
1615    bool update = false;
1616    for (unsigned i = 0; i < count; i++) {
1617       struct zink_image_view *image_view = &ctx->image_views[p_stage][start_slot + i];
1618       if (images && images[i].resource) {
1619          struct zink_resource *res = zink_resource(images[i].resource);
1620          if (!zink_resource_object_init_storage(ctx, res)) {
1621             debug_printf("couldn't create storage image!");
1622             continue;
1623          }
1624          /* no refs */
1625          VkAccessFlags access = 0;
1626          if (images[i].access & PIPE_IMAGE_ACCESS_WRITE) {
1627             res->write_bind_count[p_stage == PIPE_SHADER_COMPUTE]++;
1628             access |= VK_ACCESS_SHADER_WRITE_BIT;
1629          }
1630          if (images[i].access & PIPE_IMAGE_ACCESS_READ) {
1631             access |= VK_ACCESS_SHADER_READ_BIT;
1632          }
1633          res->gfx_barrier |= zink_pipeline_flags_from_pipe_stage(p_stage);
1634          res->barrier_access[p_stage == PIPE_SHADER_COMPUTE] |= access;
1635          if (images[i].resource->target == PIPE_BUFFER) {
1636             struct zink_buffer_view *bv = create_image_bufferview(ctx, &images[i]);
1637             assert(bv);
1638             if (image_view->buffer_view != bv) {
1639                update_res_bind_count(ctx, res, p_stage == PIPE_SHADER_COMPUTE, false);
1640                res->image_bind_count[p_stage == PIPE_SHADER_COMPUTE]++;
1641                unbind_shader_image(ctx, p_stage, start_slot + i);
1642             }
1643             image_view->buffer_view = bv;
1644             zink_batch_usage_set(&image_view->buffer_view->batch_uses, ctx->batch.state);
1645             zink_resource_buffer_barrier(ctx, res, access,
1646                                          res->gfx_barrier);
1647          } else {
1648             struct zink_surface *surface = create_image_surface(ctx, &images[i], p_stage == PIPE_SHADER_COMPUTE);
1649             assert(surface);
1650             if (image_view->surface != surface) {
1651                res->image_bind_count[p_stage == PIPE_SHADER_COMPUTE]++;
1652                update_res_bind_count(ctx, res, p_stage == PIPE_SHADER_COMPUTE, false);
1653                unbind_shader_image(ctx, p_stage, start_slot + i);
1654             }
1655             image_view->surface = surface;
1656             finalize_image_bind(ctx, res, p_stage == PIPE_SHADER_COMPUTE);
1657             zink_batch_usage_set(&image_view->surface->batch_uses, ctx->batch.state);
1658          }
1659          memcpy(&image_view->base, images + i, sizeof(struct pipe_image_view));
1660          zink_batch_resource_usage_set(&ctx->batch, res,
1661                                        zink_resource_access_is_write(access));
1662          update = true;
1663          update_descriptor_state_image(ctx, p_stage, start_slot + i, res);
1664          if (zink_resource_access_is_write(access))
1665             res->obj->unordered_read = res->obj->unordered_write = false;
1666          else
1667             res->obj->unordered_read = false;
1668          res->image_binds[p_stage] |= BITFIELD_BIT(start_slot + i);
1669       } else if (image_view->base.resource) {
1670          update = true;
1671 
1672          unbind_shader_image(ctx, p_stage, start_slot + i);
1673          update_descriptor_state_image(ctx, p_stage, start_slot + i, NULL);
1674       }
1675    }
1676    for (unsigned i = 0; i < unbind_num_trailing_slots; i++) {
1677       update |= !!ctx->image_views[p_stage][start_slot + count + i].base.resource;
1678       unbind_shader_image(ctx, p_stage, start_slot + count + i);
1679       update_descriptor_state_image(ctx, p_stage, start_slot + count + i, NULL);
1680    }
1681    ctx->di.num_images[p_stage] = start_slot + count;
1682    if (update)
1683       zink_screen(pctx->screen)->context_invalidate_descriptor_state(ctx, p_stage, ZINK_DESCRIPTOR_TYPE_IMAGE, start_slot, count);
1684 }
1685 
1686 ALWAYS_INLINE static void
check_samplerview_for_batch_ref(struct zink_context * ctx,struct zink_sampler_view * sv)1687 check_samplerview_for_batch_ref(struct zink_context *ctx, struct zink_sampler_view *sv)
1688 {
1689    const struct zink_resource *res = zink_resource(sv->base.texture);
1690    if ((res->obj->is_buffer && zink_batch_usage_exists(sv->buffer_view->batch_uses)) ||
1691        (!res->obj->is_buffer && zink_batch_usage_exists(sv->image_view->batch_uses)))
1692       zink_batch_reference_sampler_view(&ctx->batch, sv);
1693 }
1694 
1695 ALWAYS_INLINE static void
unbind_samplerview(struct zink_context * ctx,enum pipe_shader_type stage,unsigned slot)1696 unbind_samplerview(struct zink_context *ctx, enum pipe_shader_type stage, unsigned slot)
1697 {
1698    struct zink_sampler_view *sv = zink_sampler_view(ctx->sampler_views[stage][slot]);
1699    if (!sv || !sv->base.texture)
1700       return;
1701    struct zink_resource *res = zink_resource(sv->base.texture);
1702    res->sampler_bind_count[stage == PIPE_SHADER_COMPUTE]--;
1703    check_samplerview_for_batch_ref(ctx, sv);
1704    update_res_bind_count(ctx, res, stage == PIPE_SHADER_COMPUTE, true);
1705    res->sampler_binds[stage] &= ~BITFIELD_BIT(slot);
1706    if (res->obj->is_buffer) {
1707       unbind_buffer_descriptor_stage(res, stage);
1708       unbind_buffer_descriptor_reads(res, stage);
1709    } else {
1710       unbind_descriptor_stage(res, stage);
1711       unbind_descriptor_reads(res, stage);
1712    }
1713 }
1714 
1715 static void
zink_set_sampler_views(struct pipe_context * pctx,enum pipe_shader_type shader_type,unsigned start_slot,unsigned num_views,unsigned unbind_num_trailing_slots,bool take_ownership,struct pipe_sampler_view ** views)1716 zink_set_sampler_views(struct pipe_context *pctx,
1717                        enum pipe_shader_type shader_type,
1718                        unsigned start_slot,
1719                        unsigned num_views,
1720                        unsigned unbind_num_trailing_slots,
1721                        bool take_ownership,
1722                        struct pipe_sampler_view **views)
1723 {
1724    struct zink_context *ctx = zink_context(pctx);
1725    unsigned i;
1726 
1727    const uint32_t mask = BITFIELD_RANGE(start_slot, num_views);
1728    ctx->di.cubes[shader_type] &= ~mask;
1729 
1730    bool update = false;
1731    for (i = 0; i < num_views; ++i) {
1732       struct pipe_sampler_view *pview = views ? views[i] : NULL;
1733       struct zink_sampler_view *a = zink_sampler_view(ctx->sampler_views[shader_type][start_slot + i]);
1734       struct zink_sampler_view *b = zink_sampler_view(pview);
1735       struct zink_resource *res = b ? zink_resource(b->base.texture) : NULL;
1736       if (b && b->base.texture) {
1737          if (!a || zink_resource(a->base.texture) != res) {
1738             if (a)
1739                unbind_samplerview(ctx, shader_type, start_slot + i);
1740             update_res_bind_count(ctx, res, shader_type == PIPE_SHADER_COMPUTE, false);
1741             res->sampler_bind_count[shader_type == PIPE_SHADER_COMPUTE]++;
1742             res->gfx_barrier |= zink_pipeline_flags_from_pipe_stage(shader_type);
1743             res->barrier_access[shader_type == PIPE_SHADER_COMPUTE] |= VK_ACCESS_SHADER_READ_BIT;
1744          } else if (a != b) {
1745             check_samplerview_for_batch_ref(ctx, a);
1746          }
1747          if (res->base.b.target == PIPE_BUFFER) {
1748             if (b->buffer_view->bvci.buffer != res->obj->buffer) {
1749                /* if this resource has been rebound while it wasn't set here,
1750                 * its backing resource will have changed and thus we need to update
1751                 * the bufferview
1752                 */
1753                VkBufferViewCreateInfo bvci = b->buffer_view->bvci;
1754                bvci.buffer = res->obj->buffer;
1755                struct zink_buffer_view *buffer_view = get_buffer_view(ctx, res, &bvci);
1756                assert(buffer_view != b->buffer_view);
1757                if (zink_batch_usage_exists(b->buffer_view->batch_uses))
1758                   zink_batch_reference_bufferview(&ctx->batch, b->buffer_view);
1759                zink_buffer_view_reference(zink_screen(ctx->base.screen), &b->buffer_view, NULL);
1760                b->buffer_view = buffer_view;
1761                update = true;
1762             }
1763             zink_batch_usage_set(&b->buffer_view->batch_uses, ctx->batch.state);
1764             zink_resource_buffer_barrier(ctx, res, VK_ACCESS_SHADER_READ_BIT,
1765                                          res->gfx_barrier);
1766             if (!a || a->buffer_view->buffer_view != b->buffer_view->buffer_view)
1767                update = true;
1768          } else if (!res->obj->is_buffer) {
1769              if (res->obj != b->image_view->obj) {
1770                 struct pipe_surface *psurf = &b->image_view->base;
1771                 VkImageView iv = b->image_view->image_view;
1772                 zink_rebind_surface(ctx, &psurf);
1773                 b->image_view = zink_surface(psurf);
1774                 update |= iv != b->image_view->image_view;
1775              } else  if (a != b)
1776                 update = true;
1777              if (shader_type == PIPE_SHADER_COMPUTE)
1778                 flush_pending_clears(ctx, res);
1779              if (b->cube_array) {
1780                 ctx->di.cubes[shader_type] |= BITFIELD_BIT(start_slot + i);
1781                 zink_batch_usage_set(&b->cube_array->batch_uses, ctx->batch.state);
1782              }
1783              check_for_layout_update(ctx, res, shader_type == PIPE_SHADER_COMPUTE);
1784              zink_batch_usage_set(&b->image_view->batch_uses, ctx->batch.state);
1785              if (!a)
1786                 update = true;
1787          }
1788          res->sampler_binds[shader_type] |= BITFIELD_BIT(start_slot + i);
1789          zink_batch_resource_usage_set(&ctx->batch, res, false);
1790          res->obj->unordered_read = false;
1791       } else if (a) {
1792          unbind_samplerview(ctx, shader_type, start_slot + i);
1793          update = true;
1794       }
1795       if (take_ownership) {
1796          pipe_sampler_view_reference(&ctx->sampler_views[shader_type][start_slot + i], NULL);
1797          ctx->sampler_views[shader_type][start_slot + i] = pview;
1798       } else {
1799          pipe_sampler_view_reference(&ctx->sampler_views[shader_type][start_slot + i], pview);
1800       }
1801       update_descriptor_state_sampler(ctx, shader_type, start_slot + i, res);
1802    }
1803    for (; i < num_views + unbind_num_trailing_slots; ++i) {
1804       update |= !!ctx->sampler_views[shader_type][start_slot + i];
1805       unbind_samplerview(ctx, shader_type, start_slot + i);
1806       pipe_sampler_view_reference(
1807          &ctx->sampler_views[shader_type][start_slot + i],
1808          NULL);
1809       update_descriptor_state_sampler(ctx, shader_type, start_slot + i, NULL);
1810    }
1811    ctx->di.num_sampler_views[shader_type] = start_slot + num_views;
1812    if (update) {
1813       struct zink_screen *screen = zink_screen(pctx->screen);
1814       screen->context_invalidate_descriptor_state(ctx, shader_type, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, start_slot, num_views);
1815       if (!screen->info.have_EXT_non_seamless_cube_map)
1816          update_nonseamless_shader_key(ctx, shader_type);
1817    }
1818 }
1819 
1820 static uint64_t
zink_create_texture_handle(struct pipe_context * pctx,struct pipe_sampler_view * view,const struct pipe_sampler_state * state)1821 zink_create_texture_handle(struct pipe_context *pctx, struct pipe_sampler_view *view, const struct pipe_sampler_state *state)
1822 {
1823    struct zink_context *ctx = zink_context(pctx);
1824    struct zink_resource *res = zink_resource(view->texture);
1825    struct zink_sampler_view *sv = zink_sampler_view(view);
1826    struct zink_bindless_descriptor *bd;
1827    bd = calloc(1, sizeof(struct zink_bindless_descriptor));
1828    if (!bd)
1829       return 0;
1830 
1831    bd->sampler = pctx->create_sampler_state(pctx, state);
1832    if (!bd->sampler) {
1833       free(bd);
1834       return 0;
1835    }
1836 
1837    bd->ds.is_buffer = res->base.b.target == PIPE_BUFFER;
1838    if (res->base.b.target == PIPE_BUFFER)
1839       zink_buffer_view_reference(zink_screen(pctx->screen), &bd->ds.bufferview, sv->buffer_view);
1840    else
1841       zink_surface_reference(zink_screen(pctx->screen), &bd->ds.surface, sv->image_view);
1842    uint64_t handle = util_idalloc_alloc(&ctx->di.bindless[bd->ds.is_buffer].tex_slots);
1843    if (bd->ds.is_buffer)
1844       handle += ZINK_MAX_BINDLESS_HANDLES;
1845    bd->handle = handle;
1846    _mesa_hash_table_insert(&ctx->di.bindless[bd->ds.is_buffer].tex_handles, (void*)(uintptr_t)handle, bd);
1847    return handle;
1848 }
1849 
1850 static void
zink_delete_texture_handle(struct pipe_context * pctx,uint64_t handle)1851 zink_delete_texture_handle(struct pipe_context *pctx, uint64_t handle)
1852 {
1853    struct zink_context *ctx = zink_context(pctx);
1854    bool is_buffer = ZINK_BINDLESS_IS_BUFFER(handle);
1855    struct hash_entry *he = _mesa_hash_table_search(&ctx->di.bindless[is_buffer].tex_handles, (void*)(uintptr_t)handle);
1856    assert(he);
1857    struct zink_bindless_descriptor *bd = he->data;
1858    struct zink_descriptor_surface *ds = &bd->ds;
1859    _mesa_hash_table_remove(&ctx->di.bindless[is_buffer].tex_handles, he);
1860    uint32_t h = handle;
1861    util_dynarray_append(&ctx->batch.state->bindless_releases[0], uint32_t, h);
1862 
1863    struct zink_resource *res = zink_descriptor_surface_resource(ds);
1864    if (ds->is_buffer) {
1865       if (zink_resource_has_usage(res))
1866          zink_batch_reference_bufferview(&ctx->batch, ds->bufferview);
1867       zink_buffer_view_reference(zink_screen(pctx->screen), &ds->bufferview, NULL);
1868    } else {
1869       if (zink_resource_has_usage(res))
1870          zink_batch_reference_surface(&ctx->batch, ds->surface);
1871       zink_surface_reference(zink_screen(pctx->screen), &ds->surface, NULL);
1872       pctx->delete_sampler_state(pctx, bd->sampler);
1873    }
1874    free(ds);
1875 }
1876 
1877 static void
rebind_bindless_bufferview(struct zink_context * ctx,struct zink_resource * res,struct zink_descriptor_surface * ds)1878 rebind_bindless_bufferview(struct zink_context *ctx, struct zink_resource *res, struct zink_descriptor_surface *ds)
1879 {
1880    /* if this resource has been rebound while it wasn't set here,
1881     * its backing resource will have changed and thus we need to update
1882     * the bufferview
1883     */
1884    VkBufferViewCreateInfo bvci = ds->bufferview->bvci;
1885    bvci.buffer = res->obj->buffer;
1886    struct zink_buffer_view *buffer_view = get_buffer_view(ctx, res, &bvci);
1887    assert(buffer_view != ds->bufferview);
1888    if (zink_resource_has_usage(res))
1889       zink_batch_reference_bufferview(&ctx->batch, ds->bufferview);
1890    zink_buffer_view_reference(zink_screen(ctx->base.screen), &ds->bufferview, NULL);
1891    ds->bufferview = buffer_view;
1892 }
1893 
1894 static void
zero_bindless_descriptor(struct zink_context * ctx,uint32_t handle,bool is_buffer,bool is_image)1895 zero_bindless_descriptor(struct zink_context *ctx, uint32_t handle, bool is_buffer, bool is_image)
1896 {
1897    if (likely(zink_screen(ctx->base.screen)->info.rb2_feats.nullDescriptor)) {
1898       if (is_buffer) {
1899          VkBufferView *bv = &ctx->di.bindless[is_image].buffer_infos[handle];
1900          *bv = VK_NULL_HANDLE;
1901       } else {
1902          VkDescriptorImageInfo *ii = &ctx->di.bindless[is_image].img_infos[handle];
1903          memset(ii, 0, sizeof(*ii));
1904       }
1905    } else {
1906       if (is_buffer) {
1907          VkBufferView *bv = &ctx->di.bindless[is_image].buffer_infos[handle];
1908          struct zink_buffer_view *null_bufferview = ctx->dummy_bufferview;
1909          *bv = null_bufferview->buffer_view;
1910       } else {
1911          struct zink_surface *null_surface = zink_csurface(ctx->dummy_surface[is_image]);
1912          VkDescriptorImageInfo *ii = &ctx->di.bindless[is_image].img_infos[handle];
1913          ii->sampler = VK_NULL_HANDLE;
1914          ii->imageView = null_surface->image_view;
1915          ii->imageLayout = VK_IMAGE_LAYOUT_GENERAL;
1916       }
1917    }
1918 }
1919 
1920 static void
zink_make_texture_handle_resident(struct pipe_context * pctx,uint64_t handle,bool resident)1921 zink_make_texture_handle_resident(struct pipe_context *pctx, uint64_t handle, bool resident)
1922 {
1923    struct zink_context *ctx = zink_context(pctx);
1924    bool is_buffer = ZINK_BINDLESS_IS_BUFFER(handle);
1925    struct hash_entry *he = _mesa_hash_table_search(&ctx->di.bindless[is_buffer].tex_handles, (void*)(uintptr_t)handle);
1926    assert(he);
1927    struct zink_bindless_descriptor *bd = he->data;
1928    struct zink_descriptor_surface *ds = &bd->ds;
1929    struct zink_resource *res = zink_descriptor_surface_resource(ds);
1930    if (is_buffer)
1931       handle -= ZINK_MAX_BINDLESS_HANDLES;
1932    if (resident) {
1933       update_res_bind_count(ctx, res, false, false);
1934       update_res_bind_count(ctx, res, true, false);
1935       res->bindless[0]++;
1936       if (is_buffer) {
1937          if (ds->bufferview->bvci.buffer != res->obj->buffer)
1938             rebind_bindless_bufferview(ctx, res, ds);
1939          VkBufferView *bv = &ctx->di.bindless[0].buffer_infos[handle];
1940          *bv = ds->bufferview->buffer_view;
1941          zink_resource_buffer_barrier(ctx, res, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
1942       } else {
1943          VkDescriptorImageInfo *ii = &ctx->di.bindless[0].img_infos[handle];
1944          ii->sampler = bd->sampler->sampler;
1945          ii->imageView = ds->surface->image_view;
1946          ii->imageLayout = zink_descriptor_util_image_layout_eval(ctx, res, false);
1947          flush_pending_clears(ctx, res);
1948          check_for_layout_update(ctx, res, false);
1949          check_for_layout_update(ctx, res, true);
1950       }
1951       zink_batch_resource_usage_set(&ctx->batch, res, false);
1952       util_dynarray_append(&ctx->di.bindless[0].resident, struct zink_bindless_descriptor *, bd);
1953       uint32_t h = is_buffer ? handle + ZINK_MAX_BINDLESS_HANDLES : handle;
1954       util_dynarray_append(&ctx->di.bindless[0].updates, uint32_t, h);
1955       res->obj->unordered_read = false;
1956    } else {
1957       zero_bindless_descriptor(ctx, handle, is_buffer, false);
1958       util_dynarray_delete_unordered(&ctx->di.bindless[0].resident, struct zink_bindless_descriptor *, bd);
1959       update_res_bind_count(ctx, res, false, true);
1960       update_res_bind_count(ctx, res, true, true);
1961       res->bindless[0]--;
1962       for (unsigned i = 0; i < 2; i++) {
1963          if (!res->image_bind_count[i])
1964             check_for_layout_update(ctx, res, i);
1965       }
1966    }
1967    ctx->di.bindless_dirty[0] = true;
1968 }
1969 
1970 static uint64_t
zink_create_image_handle(struct pipe_context * pctx,const struct pipe_image_view * view)1971 zink_create_image_handle(struct pipe_context *pctx, const struct pipe_image_view *view)
1972 {
1973    struct zink_context *ctx = zink_context(pctx);
1974    struct zink_resource *res = zink_resource(view->resource);
1975    struct zink_bindless_descriptor *bd;
1976    if (!zink_resource_object_init_storage(ctx, res)) {
1977       debug_printf("couldn't create storage image!");
1978       return 0;
1979    }
1980    bd = malloc(sizeof(struct zink_bindless_descriptor));
1981    if (!bd)
1982       return 0;
1983    bd->sampler = NULL;
1984 
1985    bd->ds.is_buffer = res->base.b.target == PIPE_BUFFER;
1986    if (res->base.b.target == PIPE_BUFFER)
1987       bd->ds.bufferview = create_image_bufferview(ctx, view);
1988    else
1989       bd->ds.surface = create_image_surface(ctx, view, false);
1990    uint64_t handle = util_idalloc_alloc(&ctx->di.bindless[bd->ds.is_buffer].img_slots);
1991    if (bd->ds.is_buffer)
1992       handle += ZINK_MAX_BINDLESS_HANDLES;
1993    bd->handle = handle;
1994    _mesa_hash_table_insert(&ctx->di.bindless[bd->ds.is_buffer].img_handles, (void*)(uintptr_t)handle, bd);
1995    return handle;
1996 }
1997 
1998 static void
zink_delete_image_handle(struct pipe_context * pctx,uint64_t handle)1999 zink_delete_image_handle(struct pipe_context *pctx, uint64_t handle)
2000 {
2001    struct zink_context *ctx = zink_context(pctx);
2002    bool is_buffer = ZINK_BINDLESS_IS_BUFFER(handle);
2003    struct hash_entry *he = _mesa_hash_table_search(&ctx->di.bindless[is_buffer].img_handles, (void*)(uintptr_t)handle);
2004    assert(he);
2005    struct zink_descriptor_surface *ds = he->data;
2006    _mesa_hash_table_remove(&ctx->di.bindless[is_buffer].img_handles, he);
2007    uint32_t h = handle;
2008    util_dynarray_append(&ctx->batch.state->bindless_releases[1], uint32_t, h);
2009 
2010    struct zink_resource *res = zink_descriptor_surface_resource(ds);
2011    if (ds->is_buffer) {
2012       if (zink_resource_has_usage(res))
2013          zink_batch_reference_bufferview(&ctx->batch, ds->bufferview);
2014       zink_buffer_view_reference(zink_screen(pctx->screen), &ds->bufferview, NULL);
2015    } else {
2016       if (zink_resource_has_usage(res))
2017          zink_batch_reference_surface(&ctx->batch, ds->surface);
2018       zink_surface_reference(zink_screen(pctx->screen), &ds->surface, NULL);
2019    }
2020    free(ds);
2021 }
2022 
2023 static void
zink_make_image_handle_resident(struct pipe_context * pctx,uint64_t handle,unsigned paccess,bool resident)2024 zink_make_image_handle_resident(struct pipe_context *pctx, uint64_t handle, unsigned paccess, bool resident)
2025 {
2026    struct zink_context *ctx = zink_context(pctx);
2027    bool is_buffer = ZINK_BINDLESS_IS_BUFFER(handle);
2028    struct hash_entry *he = _mesa_hash_table_search(&ctx->di.bindless[is_buffer].img_handles, (void*)(uintptr_t)handle);
2029    assert(he);
2030    struct zink_bindless_descriptor *bd = he->data;
2031    struct zink_descriptor_surface *ds = &bd->ds;
2032    bd->access = paccess;
2033    struct zink_resource *res = zink_descriptor_surface_resource(ds);
2034    VkAccessFlags access = 0;
2035    if (paccess & PIPE_IMAGE_ACCESS_WRITE) {
2036       if (resident) {
2037          res->write_bind_count[0]++;
2038          res->write_bind_count[1]++;
2039       } else {
2040          res->write_bind_count[0]--;
2041          res->write_bind_count[1]--;
2042       }
2043       access |= VK_ACCESS_SHADER_WRITE_BIT;
2044    }
2045    if (paccess & PIPE_IMAGE_ACCESS_READ) {
2046       access |= VK_ACCESS_SHADER_READ_BIT;
2047    }
2048    if (is_buffer)
2049       handle -= ZINK_MAX_BINDLESS_HANDLES;
2050    if (resident) {
2051       update_res_bind_count(ctx, res, false, false);
2052       update_res_bind_count(ctx, res, true, false);
2053       res->image_bind_count[0]++;
2054       res->image_bind_count[1]++;
2055       res->bindless[1]++;
2056       if (is_buffer) {
2057          if (ds->bufferview->bvci.buffer != res->obj->buffer)
2058             rebind_bindless_bufferview(ctx, res, ds);
2059          VkBufferView *bv = &ctx->di.bindless[1].buffer_infos[handle];
2060          *bv = ds->bufferview->buffer_view;
2061          zink_resource_buffer_barrier(ctx, res, access, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
2062       } else {
2063          VkDescriptorImageInfo *ii = &ctx->di.bindless[1].img_infos[handle];
2064          ii->sampler = VK_NULL_HANDLE;
2065          ii->imageView = ds->surface->image_view;
2066          ii->imageLayout = VK_IMAGE_LAYOUT_GENERAL;
2067          finalize_image_bind(ctx, res, false);
2068          finalize_image_bind(ctx, res, true);
2069       }
2070       zink_batch_resource_usage_set(&ctx->batch, res, zink_resource_access_is_write(access));
2071       util_dynarray_append(&ctx->di.bindless[1].resident, struct zink_bindless_descriptor *, bd);
2072       uint32_t h = is_buffer ? handle + ZINK_MAX_BINDLESS_HANDLES : handle;
2073       util_dynarray_append(&ctx->di.bindless[1].updates, uint32_t, h);
2074       if (zink_resource_access_is_write(access))
2075          res->obj->unordered_read = res->obj->unordered_write = false;
2076       else
2077          res->obj->unordered_read = false;
2078    } else {
2079       zero_bindless_descriptor(ctx, handle, is_buffer, true);
2080       util_dynarray_delete_unordered(&ctx->di.bindless[1].resident, struct zink_bindless_descriptor *, bd);
2081       unbind_shader_image_counts(ctx, res, false, false);
2082       unbind_shader_image_counts(ctx, res, true, false);
2083       res->bindless[1]--;
2084       for (unsigned i = 0; i < 2; i++) {
2085          if (!res->image_bind_count[i])
2086             check_for_layout_update(ctx, res, i);
2087       }
2088    }
2089    ctx->di.bindless_dirty[1] = true;
2090 }
2091 
2092 static void
zink_set_stencil_ref(struct pipe_context * pctx,const struct pipe_stencil_ref ref)2093 zink_set_stencil_ref(struct pipe_context *pctx,
2094                      const struct pipe_stencil_ref ref)
2095 {
2096    struct zink_context *ctx = zink_context(pctx);
2097    ctx->stencil_ref = ref;
2098    ctx->stencil_ref_changed = true;
2099 }
2100 
2101 static void
zink_set_clip_state(struct pipe_context * pctx,const struct pipe_clip_state * pcs)2102 zink_set_clip_state(struct pipe_context *pctx,
2103                     const struct pipe_clip_state *pcs)
2104 {
2105 }
2106 
2107 static void
zink_set_tess_state(struct pipe_context * pctx,const float default_outer_level[4],const float default_inner_level[2])2108 zink_set_tess_state(struct pipe_context *pctx,
2109                     const float default_outer_level[4],
2110                     const float default_inner_level[2])
2111 {
2112    struct zink_context *ctx = zink_context(pctx);
2113    memcpy(&ctx->default_inner_level, default_inner_level, sizeof(ctx->default_inner_level));
2114    memcpy(&ctx->default_outer_level, default_outer_level, sizeof(ctx->default_outer_level));
2115 }
2116 
2117 static void
zink_set_patch_vertices(struct pipe_context * pctx,uint8_t patch_vertices)2118 zink_set_patch_vertices(struct pipe_context *pctx, uint8_t patch_vertices)
2119 {
2120    struct zink_context *ctx = zink_context(pctx);
2121    if (zink_set_tcs_key_patches(ctx, patch_vertices)) {
2122       ctx->gfx_pipeline_state.dyn_state2.vertices_per_patch = patch_vertices;
2123       if (zink_screen(ctx->base.screen)->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints)
2124          VKCTX(CmdSetPatchControlPointsEXT)(ctx->batch.state->cmdbuf, patch_vertices);
2125       else
2126          ctx->gfx_pipeline_state.dirty = true;
2127    }
2128 }
2129 
2130 void
zink_update_fbfetch(struct zink_context * ctx)2131 zink_update_fbfetch(struct zink_context *ctx)
2132 {
2133    const bool had_fbfetch = ctx->di.fbfetch.imageLayout == VK_IMAGE_LAYOUT_GENERAL;
2134    if (!ctx->gfx_stages[PIPE_SHADER_FRAGMENT] ||
2135        !ctx->gfx_stages[PIPE_SHADER_FRAGMENT]->nir->info.fs.uses_fbfetch_output) {
2136       if (!had_fbfetch)
2137          return;
2138       ctx->rp_changed = true;
2139       zink_batch_no_rp(ctx);
2140       ctx->di.fbfetch.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
2141       ctx->di.fbfetch.imageView = zink_screen(ctx->base.screen)->info.rb2_feats.nullDescriptor ?
2142                                   VK_NULL_HANDLE :
2143                                   zink_csurface(ctx->dummy_surface[0])->image_view;
2144       zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, PIPE_SHADER_FRAGMENT, ZINK_DESCRIPTOR_TYPE_UBO, 0, 1);
2145       return;
2146    }
2147 
2148    bool changed = !had_fbfetch;
2149    if (ctx->fb_state.cbufs[0]) {
2150       VkImageView fbfetch = zink_csurface(ctx->fb_state.cbufs[0])->image_view;
2151       if (!fbfetch)
2152          /* swapchain image: retry later */
2153          return;
2154       changed |= fbfetch != ctx->di.fbfetch.imageView;
2155       ctx->di.fbfetch.imageView = zink_csurface(ctx->fb_state.cbufs[0])->image_view;
2156 
2157       bool fbfetch_ms = ctx->fb_state.cbufs[0]->texture->nr_samples > 1;
2158       if (zink_get_fs_key(ctx)->fbfetch_ms != fbfetch_ms)
2159          zink_set_fs_key(ctx)->fbfetch_ms = fbfetch_ms;
2160    }
2161    ctx->di.fbfetch.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
2162    if (changed) {
2163       zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, PIPE_SHADER_FRAGMENT, ZINK_DESCRIPTOR_TYPE_UBO, 0, 1);
2164       if (!had_fbfetch) {
2165          ctx->rp_changed = true;
2166          zink_batch_no_rp(ctx);
2167       }
2168    }
2169 }
2170 
2171 void
zink_update_vk_sample_locations(struct zink_context * ctx)2172 zink_update_vk_sample_locations(struct zink_context *ctx)
2173 {
2174    if (ctx->gfx_pipeline_state.sample_locations_enabled && ctx->sample_locations_changed) {
2175       unsigned samples = ctx->gfx_pipeline_state.rast_samples + 1;
2176       unsigned idx = util_logbase2_ceil(MAX2(samples, 1));
2177       VkExtent2D grid_size = zink_screen(ctx->base.screen)->maxSampleLocationGridSize[idx];
2178 
2179       for (unsigned pixel = 0; pixel < grid_size.width * grid_size.height; pixel++) {
2180          for (unsigned sample = 0; sample < samples; sample++) {
2181             unsigned pixel_x = pixel % grid_size.width;
2182             unsigned pixel_y = pixel / grid_size.width;
2183             unsigned wi = pixel * samples + sample;
2184             unsigned ri = (pixel_y * grid_size.width + pixel_x % grid_size.width);
2185             ri = ri * samples + sample;
2186             ctx->vk_sample_locations[wi].x = (ctx->sample_locations[ri] & 0xf) / 16.0f;
2187             ctx->vk_sample_locations[wi].y = (16 - (ctx->sample_locations[ri] >> 4)) / 16.0f;
2188          }
2189       }
2190    }
2191 }
2192 
2193 static unsigned
find_rp_state(struct zink_context * ctx)2194 find_rp_state(struct zink_context *ctx)
2195 {
2196    bool found = false;
2197    struct set_entry *he = _mesa_set_search_or_add(&ctx->rendering_state_cache, &ctx->gfx_pipeline_state.rendering_info, &found);
2198    struct zink_rendering_info *info;
2199    if (found) {
2200       info = (void*)he->key;
2201       return info->id;
2202    }
2203    info = ralloc(ctx, struct zink_rendering_info);
2204    memcpy(info, &ctx->gfx_pipeline_state.rendering_info, sizeof(VkPipelineRenderingCreateInfo));
2205    info->id = ctx->rendering_state_cache.entries;
2206    he->key = info;
2207    return info->id;
2208 }
2209 
2210 static unsigned
begin_rendering(struct zink_context * ctx)2211 begin_rendering(struct zink_context *ctx)
2212 {
2213    unsigned clear_buffers = 0;
2214    ctx->gfx_pipeline_state.render_pass = NULL;
2215    zink_update_vk_sample_locations(ctx);
2216    zink_render_update_swapchain(ctx);
2217    bool has_depth = false;
2218    bool has_stencil = false;
2219    bool changed_layout = false;
2220    bool changed_size = false;
2221    if (ctx->rp_changed || ctx->rp_layout_changed || ctx->rp_loadop_changed) {
2222       /* init imageviews, base loadOp, formats */
2223       for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
2224          struct zink_surface *surf = zink_csurface(ctx->fb_state.cbufs[i]);
2225 
2226          if (!surf || !zink_resource(surf->base.texture)->valid || (surf->is_swapchain && ctx->new_swapchain))
2227             ctx->dynamic_fb.attachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
2228          else
2229             ctx->dynamic_fb.attachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
2230          ctx->gfx_pipeline_state.rendering_formats[i] = surf ? surf->info.format[0] : VK_FORMAT_R8G8B8A8_UNORM;
2231          /* use dummy fb size of 1024 if no surf exists */
2232          unsigned width = surf ? surf->base.texture->width0 : 1024;
2233          unsigned height = surf ? surf->base.texture->height0 : 1024;
2234          unsigned prev_width = ctx->dynamic_fb.info.renderArea.extent.width;
2235          unsigned prev_height = ctx->dynamic_fb.info.renderArea.extent.height;
2236          ctx->dynamic_fb.info.renderArea.extent.width = MIN2(ctx->dynamic_fb.info.renderArea.extent.width, width);
2237          ctx->dynamic_fb.info.renderArea.extent.height = MIN2(ctx->dynamic_fb.info.renderArea.extent.height, height);
2238          changed_size |= ctx->dynamic_fb.info.renderArea.extent.width != prev_width;
2239          changed_size |= ctx->dynamic_fb.info.renderArea.extent.height != prev_height;
2240       }
2241 
2242       /* unset depth and stencil info: reset below */
2243       VkImageLayout zlayout = ctx->dynamic_fb.info.pDepthAttachment ? ctx->dynamic_fb.info.pDepthAttachment->imageLayout : VK_IMAGE_LAYOUT_UNDEFINED;
2244       VkImageLayout slayout = ctx->dynamic_fb.info.pStencilAttachment ? ctx->dynamic_fb.info.pStencilAttachment->imageLayout : VK_IMAGE_LAYOUT_UNDEFINED;
2245       ctx->dynamic_fb.info.pDepthAttachment = NULL;
2246       ctx->gfx_pipeline_state.rendering_info.depthAttachmentFormat = VK_FORMAT_UNDEFINED;
2247       ctx->dynamic_fb.info.pStencilAttachment = NULL;
2248       ctx->gfx_pipeline_state.rendering_info.stencilAttachmentFormat = VK_FORMAT_UNDEFINED;
2249 
2250       if (ctx->fb_state.zsbuf) {
2251          struct zink_surface *surf = zink_csurface(ctx->fb_state.zsbuf);
2252          has_depth = util_format_has_depth(util_format_description(ctx->fb_state.zsbuf->format));
2253          has_stencil = util_format_has_stencil(util_format_description(ctx->fb_state.zsbuf->format));
2254 
2255          /* depth may or may not be used but init it anyway */
2256          if (zink_resource(surf->base.texture)->valid)
2257             ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
2258          else
2259             ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
2260 
2261          /* stencil may or may not be used but init it anyway */
2262          ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].loadOp = ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].loadOp;
2263 
2264          if (has_depth) {
2265             ctx->dynamic_fb.info.pDepthAttachment = &ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS];
2266             ctx->gfx_pipeline_state.rendering_info.depthAttachmentFormat = surf->info.format[0];
2267             /* stencil info only set for clears below */
2268          }
2269          if (has_stencil) {
2270             /* must be stencil-only */
2271             ctx->dynamic_fb.info.pStencilAttachment = &ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS + 1];
2272             ctx->gfx_pipeline_state.rendering_info.stencilAttachmentFormat = surf->info.format[0];
2273          }
2274       } else {
2275          ctx->dynamic_fb.info.pDepthAttachment = NULL;
2276          ctx->gfx_pipeline_state.rendering_info.depthAttachmentFormat = VK_FORMAT_UNDEFINED;
2277       }
2278       if (zlayout != (ctx->dynamic_fb.info.pDepthAttachment ? ctx->dynamic_fb.info.pDepthAttachment->imageLayout : VK_IMAGE_LAYOUT_UNDEFINED))
2279          changed_layout = true;
2280       if (slayout != (ctx->dynamic_fb.info.pStencilAttachment ? ctx->dynamic_fb.info.pStencilAttachment->imageLayout : VK_IMAGE_LAYOUT_UNDEFINED))
2281          changed_layout = true;
2282 
2283       /* similar to begin_render_pass(), but just filling in VkRenderingInfo */
2284       for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
2285          /* these are no-ops */
2286          if (!ctx->fb_state.cbufs[i] || !zink_fb_clear_enabled(ctx, i))
2287             continue;
2288          /* these need actual clear calls inside the rp */
2289          struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(&ctx->fb_clears[i], 0);
2290          if (zink_fb_clear_needs_explicit(&ctx->fb_clears[i])) {
2291             clear_buffers |= (PIPE_CLEAR_COLOR0 << i);
2292             if (zink_fb_clear_count(&ctx->fb_clears[i]) < 2 ||
2293                 zink_fb_clear_element_needs_explicit(clear))
2294                continue;
2295          }
2296          /* we now know there's one clear that can be done here */
2297          memcpy(&ctx->dynamic_fb.attachments[i].clearValue, &clear->color, sizeof(float) * 4);
2298          ctx->dynamic_fb.attachments[i].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
2299       }
2300       if (ctx->fb_state.zsbuf && zink_fb_clear_enabled(ctx, PIPE_MAX_COLOR_BUFS)) {
2301          struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[PIPE_MAX_COLOR_BUFS];
2302          struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(fb_clear, 0);
2303          if (!zink_fb_clear_element_needs_explicit(clear)) {
2304             /* base zs clear info */
2305             ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].clearValue.depthStencil.depth = clear->zs.depth;
2306             ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].clearValue.depthStencil.stencil = clear->zs.stencil;
2307             /* always init separate stencil attachment */
2308             ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].clearValue.depthStencil.stencil = clear->zs.stencil;
2309             if ((zink_fb_clear_element(fb_clear, 0)->zs.bits & PIPE_CLEAR_DEPTH))
2310                /* initiate a depth clear */
2311                ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
2312             if ((zink_fb_clear_element(fb_clear, 0)->zs.bits & PIPE_CLEAR_STENCIL)) {
2313                /* use a stencil clear, also set stencil attachment */
2314                ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
2315             }
2316          }
2317          if (zink_fb_clear_needs_explicit(fb_clear)) {
2318             for (int j = !zink_fb_clear_element_needs_explicit(clear);
2319                  (clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL && j < zink_fb_clear_count(fb_clear);
2320                  j++)
2321                clear_buffers |= zink_fb_clear_element(fb_clear, j)->zs.bits;
2322          }
2323       }
2324       if (changed_size || changed_layout)
2325          ctx->rp_changed = true;
2326       ctx->rp_loadop_changed = false;
2327       ctx->rp_layout_changed = false;
2328    }
2329    /* validate zs VUs: attachment must be null or format must be valid */
2330    assert(!ctx->dynamic_fb.info.pDepthAttachment || ctx->gfx_pipeline_state.rendering_info.depthAttachmentFormat);
2331    assert(!ctx->dynamic_fb.info.pStencilAttachment || ctx->gfx_pipeline_state.rendering_info.stencilAttachmentFormat);
2332 
2333    if (!ctx->rp_changed && ctx->batch.in_rp)
2334       return 0;
2335    ctx->rp_changed = false;
2336    /* update pipeline info id for compatibility VUs */
2337    unsigned rp_state = find_rp_state(ctx);
2338    bool rp_changed = ctx->gfx_pipeline_state.rp_state != rp_state;
2339    if (!rp_changed && ctx->batch.in_rp)
2340       return 0;
2341    zink_batch_no_rp(ctx);
2342    for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
2343       struct zink_surface *surf = zink_csurface(ctx->fb_state.cbufs[i]);
2344       VkImageView iv = zink_prep_fb_attachment(ctx, surf, i);
2345       if (!iv)
2346          /* dead swapchain */
2347          return 0;
2348       ctx->dynamic_fb.attachments[i].imageView = iv;
2349    }
2350    if (ctx->fb_state.zsbuf) {
2351       struct zink_surface *surf = zink_csurface(ctx->fb_state.zsbuf);
2352       VkImageView iv = zink_prep_fb_attachment(ctx, surf, ctx->fb_state.nr_cbufs);
2353       ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].imageView = iv;
2354       ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS].imageLayout = zink_resource(surf->base.texture)->layout;
2355       ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].imageView = iv;
2356       ctx->dynamic_fb.attachments[PIPE_MAX_COLOR_BUFS+1].imageLayout = zink_resource(surf->base.texture)->layout;
2357    }
2358    ctx->gfx_pipeline_state.dirty |= rp_changed;
2359    ctx->gfx_pipeline_state.rp_state = rp_state;
2360 
2361    VKCTX(CmdBeginRendering)(ctx->batch.state->cmdbuf, &ctx->dynamic_fb.info);
2362    ctx->batch.in_rp = true;
2363    ctx->new_swapchain = false;
2364    return clear_buffers;
2365 }
2366 
2367 void
zink_batch_rp(struct zink_context * ctx)2368 zink_batch_rp(struct zink_context *ctx)
2369 {
2370    assert(!(ctx->batch.in_rp && ctx->rp_changed));
2371    if (ctx->batch.in_rp && !ctx->rp_layout_changed)
2372       return;
2373    bool in_rp = ctx->batch.in_rp;
2374    if (!in_rp && ctx->void_clears) {
2375       union pipe_color_union color;
2376       color.f[0] = color.f[1] = color.f[2] = 0;
2377       color.f[3] = 1.0;
2378       ctx->base.clear(&ctx->base, ctx->void_clears, NULL, &color, 0, 0);
2379       ctx->void_clears = 0;
2380    }
2381    unsigned clear_buffers;
2382    /* use renderpass for multisample-to-singlesample or fbfetch:
2383     * - msrtss is TODO
2384     * - dynamic rendering doesn't have input attachments
2385     */
2386    if (!zink_screen(ctx->base.screen)->info.have_KHR_dynamic_rendering || ctx->transient_attachments || ctx->fbfetch_outputs)
2387       clear_buffers = zink_begin_render_pass(ctx);
2388    else
2389       clear_buffers = begin_rendering(ctx);
2390    assert(!ctx->rp_changed);
2391    if (in_rp || !ctx->batch.in_rp)
2392       return; //dead swapchain or continued renderpass
2393    if (ctx->render_condition.query)
2394       zink_start_conditional_render(ctx);
2395    zink_clear_framebuffer(ctx, clear_buffers);
2396 }
2397 
2398 void
zink_batch_no_rp(struct zink_context * ctx)2399 zink_batch_no_rp(struct zink_context *ctx)
2400 {
2401    if (!ctx->batch.in_rp)
2402       return;
2403    if (ctx->render_condition.query)
2404       zink_stop_conditional_render(ctx);
2405    if (ctx->gfx_pipeline_state.render_pass)
2406       zink_end_render_pass(ctx);
2407    else {
2408       VKCTX(CmdEndRendering)(ctx->batch.state->cmdbuf);
2409       ctx->batch.in_rp = false;
2410    }
2411    assert(!ctx->batch.in_rp);
2412 }
2413 
2414 ALWAYS_INLINE static void
update_res_sampler_layouts(struct zink_context * ctx,struct zink_resource * res)2415 update_res_sampler_layouts(struct zink_context *ctx, struct zink_resource *res)
2416 {
2417    unsigned find = res->sampler_bind_count[0];
2418    for (unsigned i = 0; find && i < PIPE_SHADER_COMPUTE; i++) {
2419       u_foreach_bit(slot, res->sampler_binds[i]) {
2420          /* only set layout, skip rest of update */
2421          if (ctx->di.descriptor_res[ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW][i][slot] == res)
2422             ctx->di.textures[i][slot].imageLayout = zink_descriptor_util_image_layout_eval(ctx, res, false);
2423          find--;
2424          if (!find) break;
2425       }
2426    }
2427 }
2428 
2429 VkImageView
zink_prep_fb_attachment(struct zink_context * ctx,struct zink_surface * surf,unsigned i)2430 zink_prep_fb_attachment(struct zink_context *ctx, struct zink_surface *surf, unsigned i)
2431 {
2432    struct zink_resource *res;
2433    if (!surf || (i < ctx->fb_state.nr_cbufs && zink_use_dummy_attachments(ctx))) {
2434       surf = zink_csurface(ctx->dummy_surface[util_logbase2_ceil(ctx->fb_state.samples)]);
2435       res = zink_resource(surf->base.texture);
2436    } else {
2437       res = zink_resource(surf->base.texture);
2438       zink_batch_resource_usage_set(&ctx->batch, res, true);
2439       zink_batch_usage_set(&surf->batch_uses, ctx->batch.state);
2440    }
2441 
2442    VkAccessFlags access;
2443    VkPipelineStageFlags pipeline;
2444    if (zink_is_swapchain(res)) {
2445       if (!zink_kopper_acquire(ctx, res, UINT64_MAX))
2446          return VK_NULL_HANDLE;
2447       zink_surface_swapchain_update(ctx, surf);
2448       if (!i)
2449          zink_update_fbfetch(ctx);
2450    }
2451    VkImageLayout layout;
2452    if (ctx->gfx_pipeline_state.render_pass) {
2453       layout = zink_render_pass_attachment_get_barrier_info(&ctx->gfx_pipeline_state.render_pass->state.rts[i],
2454                                                             i < ctx->fb_state.nr_cbufs, &pipeline, &access);
2455    } else {
2456       struct zink_rt_attrib rt;
2457       if (i < ctx->fb_state.nr_cbufs)
2458          zink_init_color_attachment(ctx, i, &rt);
2459       else
2460          zink_init_zs_attachment(ctx, &rt);
2461       layout = zink_render_pass_attachment_get_barrier_info(&rt, i < ctx->fb_state.nr_cbufs, &pipeline, &access);
2462    }
2463    zink_resource_image_barrier(ctx, res, layout, access, pipeline);
2464    res->obj->unordered_read = res->obj->unordered_write = false;
2465    if (i == ctx->fb_state.nr_cbufs && res->sampler_bind_count[0])
2466       update_res_sampler_layouts(ctx, res);
2467    return surf->image_view;
2468 }
2469 
2470 static uint32_t
hash_rendering_state(const void * key)2471 hash_rendering_state(const void *key)
2472 {
2473    const VkPipelineRenderingCreateInfo *info = key;
2474    uint32_t hash = 0;
2475    /*
2476     uint32_t           colorAttachmentCount;
2477     const VkFormat*    pColorAttachmentFormats;
2478     VkFormat           depthAttachmentFormat;
2479     VkFormat           stencilAttachmentFormat;
2480     * this data is not optimally arranged, so it must be manually hashed
2481     */
2482    hash = XXH32(&info->colorAttachmentCount, sizeof(uint32_t), hash);
2483    hash = XXH32(&info->depthAttachmentFormat, sizeof(uint32_t), hash);
2484    hash = XXH32(&info->stencilAttachmentFormat, sizeof(VkFormat), hash);
2485    return XXH32(info->pColorAttachmentFormats, sizeof(VkFormat) * info->colorAttachmentCount, hash);
2486 }
2487 
2488 static bool
equals_rendering_state(const void * a,const void * b)2489 equals_rendering_state(const void *a, const void *b)
2490 {
2491    const VkPipelineRenderingCreateInfo *ai = a;
2492    const VkPipelineRenderingCreateInfo *bi = b;
2493    return ai->colorAttachmentCount == bi->colorAttachmentCount &&
2494           ai->depthAttachmentFormat == bi->depthAttachmentFormat &&
2495           ai->stencilAttachmentFormat == bi->stencilAttachmentFormat &&
2496           !memcmp(ai->pColorAttachmentFormats, bi->pColorAttachmentFormats, sizeof(VkFormat) * ai->colorAttachmentCount);
2497 }
2498 
2499 static uint32_t
hash_framebuffer_imageless(const void * key)2500 hash_framebuffer_imageless(const void *key)
2501 {
2502    struct zink_framebuffer_state* s = (struct zink_framebuffer_state*)key;
2503    return _mesa_hash_data(key, offsetof(struct zink_framebuffer_state, infos) + sizeof(s->infos[0]) * s->num_attachments);
2504 }
2505 
2506 static bool
equals_framebuffer_imageless(const void * a,const void * b)2507 equals_framebuffer_imageless(const void *a, const void *b)
2508 {
2509    struct zink_framebuffer_state *s = (struct zink_framebuffer_state*)a;
2510    return memcmp(a, b, offsetof(struct zink_framebuffer_state, infos) + sizeof(s->infos[0]) * s->num_attachments) == 0;
2511 }
2512 
2513 void
zink_init_vk_sample_locations(struct zink_context * ctx,VkSampleLocationsInfoEXT * loc)2514 zink_init_vk_sample_locations(struct zink_context *ctx, VkSampleLocationsInfoEXT *loc)
2515 {
2516    struct zink_screen *screen = zink_screen(ctx->base.screen);
2517    unsigned idx = util_logbase2_ceil(MAX2(ctx->gfx_pipeline_state.rast_samples + 1, 1));
2518    loc->sType = VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT;
2519    loc->pNext = NULL;
2520    loc->sampleLocationsPerPixel = 1 << idx;
2521    loc->sampleLocationsCount = ctx->gfx_pipeline_state.rast_samples + 1;
2522    loc->sampleLocationGridSize = screen->maxSampleLocationGridSize[idx];
2523    loc->pSampleLocations = ctx->vk_sample_locations;
2524 }
2525 
2526 static void
zink_evaluate_depth_buffer(struct pipe_context * pctx)2527 zink_evaluate_depth_buffer(struct pipe_context *pctx)
2528 {
2529    struct zink_context *ctx = zink_context(pctx);
2530 
2531    if (!ctx->fb_state.zsbuf)
2532       return;
2533 
2534    struct zink_resource *res = zink_resource(ctx->fb_state.zsbuf->texture);
2535    res->obj->needs_zs_evaluate = true;
2536    zink_init_vk_sample_locations(ctx, &res->obj->zs_evaluate);
2537    zink_batch_no_rp(ctx);
2538 }
2539 
2540 static void
sync_flush(struct zink_context * ctx,struct zink_batch_state * bs)2541 sync_flush(struct zink_context *ctx, struct zink_batch_state *bs)
2542 {
2543    if (zink_screen(ctx->base.screen)->threaded)
2544       util_queue_fence_wait(&bs->flush_completed);
2545 }
2546 
2547 static inline VkAccessFlags
get_access_flags_for_binding(struct zink_context * ctx,enum zink_descriptor_type type,enum pipe_shader_type stage,unsigned idx)2548 get_access_flags_for_binding(struct zink_context *ctx, enum zink_descriptor_type type, enum pipe_shader_type stage, unsigned idx)
2549 {
2550    VkAccessFlags flags = 0;
2551    switch (type) {
2552    case ZINK_DESCRIPTOR_TYPE_UBO:
2553       return VK_ACCESS_UNIFORM_READ_BIT;
2554    case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
2555       return VK_ACCESS_SHADER_READ_BIT;
2556    case ZINK_DESCRIPTOR_TYPE_SSBO: {
2557       flags = VK_ACCESS_SHADER_READ_BIT;
2558       if (ctx->writable_ssbos[stage] & (1 << idx))
2559          flags |= VK_ACCESS_SHADER_WRITE_BIT;
2560       return flags;
2561    }
2562    case ZINK_DESCRIPTOR_TYPE_IMAGE: {
2563       struct zink_image_view *image_view = &ctx->image_views[stage][idx];
2564       if (image_view->base.access & PIPE_IMAGE_ACCESS_READ)
2565          flags |= VK_ACCESS_SHADER_READ_BIT;
2566       if (image_view->base.access & PIPE_IMAGE_ACCESS_WRITE)
2567          flags |= VK_ACCESS_SHADER_WRITE_BIT;
2568       return flags;
2569    }
2570    default:
2571       break;
2572    }
2573    unreachable("ACK");
2574    return 0;
2575 }
2576 
2577 static void
update_resource_refs_for_stage(struct zink_context * ctx,enum pipe_shader_type stage)2578 update_resource_refs_for_stage(struct zink_context *ctx, enum pipe_shader_type stage)
2579 {
2580    struct zink_batch *batch = &ctx->batch;
2581    unsigned max_slot[] = {
2582       [ZINK_DESCRIPTOR_TYPE_UBO] = ctx->di.num_ubos[stage],
2583       [ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW] = ctx->di.num_samplers[stage],
2584       [ZINK_DESCRIPTOR_TYPE_SSBO] = ctx->di.num_ssbos[stage],
2585       [ZINK_DESCRIPTOR_TYPE_IMAGE] = ctx->di.num_images[stage]
2586    };
2587    for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) {
2588       for (unsigned j = 0; j < max_slot[i]; j++) {
2589          if (ctx->di.descriptor_res[i][stage][j]) {
2590             struct zink_resource *res = ctx->di.descriptor_res[i][stage][j];
2591             if (!res)
2592                continue;
2593             bool is_write = zink_resource_access_is_write(get_access_flags_for_binding(ctx, i, stage, j));
2594             zink_batch_resource_usage_set(batch, res, is_write);
2595             if (is_write)
2596                res->obj->unordered_read = res->obj->unordered_write = false;
2597             else
2598                res->obj->unordered_read = false;
2599 
2600             struct zink_sampler_view *sv = zink_sampler_view(ctx->sampler_views[stage][j]);
2601             struct zink_sampler_state *sampler_state = ctx->sampler_states[stage][j];
2602             struct zink_image_view *iv = &ctx->image_views[stage][j];
2603             if (sampler_state && i == ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW && j <= ctx->di.num_samplers[stage])
2604                zink_batch_usage_set(&sampler_state->batch_uses, ctx->batch.state);
2605             if (sv && i == ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW && j <= ctx->di.num_sampler_views[stage]) {
2606                if (res->obj->is_buffer) {
2607                   zink_batch_usage_set(&sv->buffer_view->batch_uses, ctx->batch.state);
2608                } else {
2609                   zink_batch_usage_set(&sv->image_view->batch_uses, ctx->batch.state);
2610                   if (sv->cube_array)
2611                      zink_batch_usage_set(&sv->cube_array->batch_uses, ctx->batch.state);
2612                }
2613                zink_batch_reference_sampler_view(batch, sv);
2614             } else if (i == ZINK_DESCRIPTOR_TYPE_IMAGE && j <= ctx->di.num_images[stage]) {
2615                if (res->obj->is_buffer)
2616                   zink_batch_usage_set(&iv->buffer_view->batch_uses, ctx->batch.state);
2617                else
2618                   zink_batch_usage_set(&iv->surface->batch_uses, ctx->batch.state);
2619                zink_batch_reference_image_view(batch, iv);
2620             }
2621          }
2622       }
2623    }
2624 }
2625 
2626 void
zink_update_descriptor_refs(struct zink_context * ctx,bool compute)2627 zink_update_descriptor_refs(struct zink_context *ctx, bool compute)
2628 {
2629    struct zink_batch *batch = &ctx->batch;
2630    if (compute) {
2631       update_resource_refs_for_stage(ctx, PIPE_SHADER_COMPUTE);
2632       if (ctx->curr_compute)
2633          zink_batch_reference_program(batch, &ctx->curr_compute->base);
2634    } else {
2635       for (unsigned i = 0; i < ZINK_SHADER_COUNT; i++)
2636          update_resource_refs_for_stage(ctx, i);
2637       unsigned vertex_buffers_enabled_mask = ctx->gfx_pipeline_state.vertex_buffers_enabled_mask;
2638       unsigned last_vbo = util_last_bit(vertex_buffers_enabled_mask);
2639       for (unsigned i = 0; i < last_vbo + 1; i++) {
2640          struct zink_resource *res = zink_resource(ctx->vertex_buffers[i].buffer.resource);
2641          if (res) {
2642             zink_batch_resource_usage_set(batch, res, false);
2643             res->obj->unordered_read = false;
2644          }
2645       }
2646       if (ctx->curr_program)
2647          zink_batch_reference_program(batch, &ctx->curr_program->base);
2648    }
2649    if (ctx->di.bindless_refs_dirty) {
2650       ctx->di.bindless_refs_dirty = false;
2651       for (unsigned i = 0; i < 2; i++) {
2652          util_dynarray_foreach(&ctx->di.bindless[i].resident, struct zink_bindless_descriptor*, bd) {
2653             struct zink_resource *res = zink_descriptor_surface_resource(&(*bd)->ds);
2654             zink_batch_resource_usage_set(&ctx->batch, res, (*bd)->access & PIPE_IMAGE_ACCESS_WRITE);
2655             if ((*bd)->access & PIPE_IMAGE_ACCESS_WRITE)
2656                res->obj->unordered_read = res->obj->unordered_write = false;
2657             else
2658                res->obj->unordered_read = false;
2659          }
2660       }
2661    }
2662 }
2663 
2664 static void
reapply_color_write(struct zink_context * ctx)2665 reapply_color_write(struct zink_context *ctx)
2666 {
2667    struct zink_screen *screen = zink_screen(ctx->base.screen);
2668    if (!screen->driver_workarounds.color_write_missing) {
2669       const VkBool32 enables[PIPE_MAX_COLOR_BUFS] = {1, 1, 1, 1, 1, 1, 1, 1};
2670       const VkBool32 disables[PIPE_MAX_COLOR_BUFS] = {0};
2671       const unsigned max_att = MIN2(PIPE_MAX_COLOR_BUFS, screen->info.props.limits.maxColorAttachments);
2672       VKCTX(CmdSetColorWriteEnableEXT)(ctx->batch.state->cmdbuf, max_att, ctx->disable_color_writes ? disables : enables);
2673    }
2674    if (screen->info.have_EXT_extended_dynamic_state && ctx->dsa_state)
2675       VKCTX(CmdSetDepthWriteEnableEXT)(ctx->batch.state->cmdbuf, ctx->disable_color_writes ? VK_FALSE : ctx->dsa_state->hw_state.depth_write);
2676 }
2677 
2678 static void
stall(struct zink_context * ctx)2679 stall(struct zink_context *ctx)
2680 {
2681    struct zink_screen *screen = zink_screen(ctx->base.screen);
2682    sync_flush(ctx, zink_batch_state(ctx->last_fence));
2683    zink_screen_timeline_wait(screen, ctx->last_fence->batch_id, PIPE_TIMEOUT_INFINITE);
2684    zink_batch_reset_all(ctx);
2685 }
2686 
2687 static void
flush_batch(struct zink_context * ctx,bool sync)2688 flush_batch(struct zink_context *ctx, bool sync)
2689 {
2690    struct zink_batch *batch = &ctx->batch;
2691    if (ctx->clears_enabled)
2692       /* start rp to do all the clears */
2693       zink_batch_rp(ctx);
2694    bool conditional_render_active = ctx->render_condition.active;
2695    zink_stop_conditional_render(ctx);
2696    zink_batch_no_rp(ctx);
2697    zink_end_batch(ctx, batch);
2698    ctx->deferred_fence = NULL;
2699 
2700    if (sync)
2701       sync_flush(ctx, ctx->batch.state);
2702 
2703    if (ctx->batch.state->is_device_lost) {
2704       check_device_lost(ctx);
2705    } else {
2706       zink_start_batch(ctx, batch);
2707       if (zink_screen(ctx->base.screen)->info.have_EXT_transform_feedback && ctx->num_so_targets)
2708          ctx->dirty_so_targets = true;
2709       ctx->pipeline_changed[0] = ctx->pipeline_changed[1] = true;
2710       zink_select_draw_vbo(ctx);
2711       zink_select_launch_grid(ctx);
2712 
2713       if (ctx->oom_stall)
2714          stall(ctx);
2715       ctx->oom_flush = false;
2716       ctx->oom_stall = false;
2717       if (ctx->dd) //copy context
2718          ctx->dd->bindless_bound = false;
2719       ctx->di.bindless_refs_dirty = true;
2720       ctx->sample_locations_changed = ctx->gfx_pipeline_state.sample_locations_enabled;
2721       if (zink_screen(ctx->base.screen)->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints)
2722          VKCTX(CmdSetPatchControlPointsEXT)(ctx->batch.state->cmdbuf, ctx->gfx_pipeline_state.dyn_state2.vertices_per_patch);
2723       if (conditional_render_active)
2724          zink_start_conditional_render(ctx);
2725       reapply_color_write(ctx);
2726    }
2727 }
2728 
2729 void
zink_flush_queue(struct zink_context * ctx)2730 zink_flush_queue(struct zink_context *ctx)
2731 {
2732    flush_batch(ctx, true);
2733 }
2734 
2735 static bool
rebind_fb_surface(struct zink_context * ctx,struct pipe_surface ** surf,struct zink_resource * match_res)2736 rebind_fb_surface(struct zink_context *ctx, struct pipe_surface **surf, struct zink_resource *match_res)
2737 {
2738    if (!*surf)
2739       return false;
2740    struct zink_resource *surf_res = zink_resource((*surf)->texture);
2741    if ((match_res == surf_res) || surf_res->obj != zink_csurface(*surf)->obj)
2742       return zink_rebind_ctx_surface(ctx, surf);
2743    return false;
2744 }
2745 
2746 static bool
rebind_fb_state(struct zink_context * ctx,struct zink_resource * match_res,bool from_set_fb)2747 rebind_fb_state(struct zink_context *ctx, struct zink_resource *match_res, bool from_set_fb)
2748 {
2749    bool rebind = false;
2750    for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
2751       rebind |= rebind_fb_surface(ctx, &ctx->fb_state.cbufs[i], match_res);
2752       if (from_set_fb && ctx->fb_state.cbufs[i] && ctx->fb_state.cbufs[i]->texture->bind & PIPE_BIND_SCANOUT)
2753          ctx->new_swapchain = true;
2754    }
2755    rebind |= rebind_fb_surface(ctx, &ctx->fb_state.zsbuf, match_res);
2756    return rebind;
2757 }
2758 
2759 static void
unbind_fb_surface(struct zink_context * ctx,struct pipe_surface * surf,unsigned idx,bool changed)2760 unbind_fb_surface(struct zink_context *ctx, struct pipe_surface *surf, unsigned idx, bool changed)
2761 {
2762    ctx->dynamic_fb.attachments[idx].imageView = VK_NULL_HANDLE;
2763    if (!surf)
2764       return;
2765    struct zink_surface *transient = zink_transient_surface(surf);
2766    struct zink_resource *res = zink_resource(surf->texture);
2767    if (changed) {
2768       if (zink_batch_usage_exists(zink_csurface(surf)->batch_uses)) {
2769          zink_batch_reference_surface(&ctx->batch, zink_csurface(surf));
2770          if (transient)
2771             zink_batch_reference_surface(&ctx->batch, transient);
2772       }
2773       ctx->rp_changed = true;
2774    }
2775    res->fb_binds--;
2776    if (!res->fb_binds) {
2777       check_resource_for_batch_ref(ctx, res);
2778       if (res->sampler_bind_count[0]) {
2779          update_res_sampler_layouts(ctx, res);
2780          _mesa_set_add(ctx->need_barriers[0], res);
2781       }
2782    }
2783 }
2784 
2785 void
zink_set_color_write_enables(struct zink_context * ctx)2786 zink_set_color_write_enables(struct zink_context *ctx)
2787 {
2788    bool disable_color_writes = ctx->rast_state && ctx->rast_state->base.rasterizer_discard && ctx->primitives_generated_active;
2789    if (ctx->disable_color_writes == disable_color_writes)
2790       return;
2791    /* flush all pending clears: these have already occurred */
2792    if (disable_color_writes && ctx->clears_enabled)
2793       zink_batch_rp(ctx);
2794    ctx->disable_color_writes = disable_color_writes;
2795    if (zink_screen(ctx->base.screen)->driver_workarounds.color_write_missing) {
2796       /* use dummy color buffers instead of the more sane option */
2797       zink_batch_no_rp(ctx);
2798       ctx->rp_changed = true;
2799       zink_update_framebuffer_state(ctx);
2800    } else {
2801       reapply_color_write(ctx);
2802    }
2803 }
2804 
2805 static void
zink_set_framebuffer_state(struct pipe_context * pctx,const struct pipe_framebuffer_state * state)2806 zink_set_framebuffer_state(struct pipe_context *pctx,
2807                            const struct pipe_framebuffer_state *state)
2808 {
2809    struct zink_context *ctx = zink_context(pctx);
2810    unsigned samples = state->nr_cbufs || state->zsbuf ? 0 : state->samples;
2811    unsigned w = ctx->fb_state.width;
2812    unsigned h = ctx->fb_state.height;
2813    unsigned layers = MAX2(zink_framebuffer_get_num_layers(state), 1);
2814 
2815    bool flush_clears = ctx->clears_enabled &&
2816                        (ctx->dynamic_fb.info.layerCount != layers ||
2817                         state->width != w || state->height != h);
2818    for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
2819       if (i >= state->nr_cbufs || ctx->fb_state.cbufs[i] != state->cbufs[i])
2820          flush_clears |= zink_fb_clear_enabled(ctx, i);
2821    }
2822    if (ctx->fb_state.zsbuf != state->zsbuf)
2823       flush_clears |= zink_fb_clear_enabled(ctx, PIPE_MAX_COLOR_BUFS);
2824    if (flush_clears)
2825       zink_batch_rp(ctx);
2826    for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
2827       struct pipe_surface *psurf = ctx->fb_state.cbufs[i];
2828       if (i < state->nr_cbufs)
2829          ctx->rp_changed |= !!zink_transient_surface(psurf) != !!zink_transient_surface(state->cbufs[i]);
2830       unbind_fb_surface(ctx, psurf, i, i >= state->nr_cbufs || psurf != state->cbufs[i]);
2831       if (psurf && ctx->needs_present == zink_resource(psurf->texture))
2832          ctx->needs_present = NULL;
2833    }
2834    if (ctx->fb_state.zsbuf) {
2835       struct pipe_surface *psurf = ctx->fb_state.zsbuf;
2836       struct zink_resource *res = zink_resource(psurf->texture);
2837       bool changed = psurf != state->zsbuf;
2838       unbind_fb_surface(ctx, psurf, PIPE_MAX_COLOR_BUFS, changed);
2839       if (!changed)
2840          ctx->rp_changed |= !!zink_transient_surface(psurf) != !!zink_transient_surface(state->zsbuf);
2841       if (changed && unlikely(res->obj->needs_zs_evaluate))
2842          /* have to flush zs eval while the sample location data still exists,
2843           * so just throw some random barrier */
2844          zink_resource_image_barrier(ctx, res, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
2845                                      VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
2846    }
2847    /* renderpass changes if the number or types of attachments change */
2848    ctx->rp_changed |= ctx->fb_state.nr_cbufs != state->nr_cbufs;
2849    ctx->rp_changed |= !!ctx->fb_state.zsbuf != !!state->zsbuf;
2850 
2851    util_copy_framebuffer_state(&ctx->fb_state, state);
2852    zink_update_fbfetch(ctx);
2853    unsigned prev_void_alpha_attachments = ctx->gfx_pipeline_state.void_alpha_attachments;
2854    ctx->gfx_pipeline_state.void_alpha_attachments = 0;
2855    ctx->transient_attachments = 0;
2856    ctx->fb_layer_mismatch = 0;
2857 
2858    ctx->dynamic_fb.info.renderArea.offset.x = 0;
2859    ctx->dynamic_fb.info.renderArea.offset.y = 0;
2860    ctx->dynamic_fb.info.renderArea.extent.width = state->width;
2861    ctx->dynamic_fb.info.renderArea.extent.height = state->height;
2862    ctx->dynamic_fb.info.colorAttachmentCount = ctx->fb_state.nr_cbufs;
2863    ctx->rp_changed |= ctx->dynamic_fb.info.layerCount != layers;
2864    ctx->dynamic_fb.info.layerCount = layers;
2865    ctx->gfx_pipeline_state.rendering_info.colorAttachmentCount = ctx->fb_state.nr_cbufs;
2866 
2867    ctx->void_clears = 0;
2868    for (int i = 0; i < ctx->fb_state.nr_cbufs; i++) {
2869       struct pipe_surface *psurf = ctx->fb_state.cbufs[i];
2870       if (psurf) {
2871          struct zink_surface *transient = zink_transient_surface(psurf);
2872          if (transient)
2873             ctx->transient_attachments |= BITFIELD_BIT(i);
2874          if (!samples)
2875             samples = MAX3(transient ? transient->base.nr_samples : 1, psurf->texture->nr_samples, 1);
2876          struct zink_resource *res = zink_resource(psurf->texture);
2877          if (zink_csurface(psurf)->info.layerCount > layers)
2878             ctx->fb_layer_mismatch |= BITFIELD_BIT(i);
2879          if (res->modifiers) {
2880             assert(!ctx->needs_present || ctx->needs_present == res);
2881             ctx->needs_present = res;
2882          }
2883          if (res->obj->dt) {
2884             /* #6274 */
2885             if (!zink_screen(ctx->base.screen)->info.have_KHR_swapchain_mutable_format &&
2886                 psurf->format != res->base.b.format) {
2887                static bool warned = false;
2888                if (!warned) {
2889                   mesa_loge("zink: SRGB framebuffer unsupported without KHR_swapchain_mutable_format");
2890                   warned = true;
2891                }
2892             }
2893          }
2894          res->fb_binds++;
2895          if (util_format_has_alpha1(psurf->format)) {
2896             ctx->gfx_pipeline_state.void_alpha_attachments |= BITFIELD_BIT(i);
2897             if (!res->valid)
2898                ctx->void_clears |= (PIPE_CLEAR_COLOR0 << i);
2899          }
2900       }
2901    }
2902    if (ctx->gfx_pipeline_state.void_alpha_attachments != prev_void_alpha_attachments)
2903       ctx->gfx_pipeline_state.dirty = true;
2904    unsigned depth_bias_scale_factor = ctx->depth_bias_scale_factor;
2905    if (ctx->fb_state.zsbuf) {
2906       struct pipe_surface *psurf = ctx->fb_state.zsbuf;
2907       struct zink_surface *transient = zink_transient_surface(psurf);
2908       if (transient)
2909          ctx->transient_attachments |= BITFIELD_BIT(PIPE_MAX_COLOR_BUFS);
2910       if (!samples)
2911          samples = MAX3(transient ? transient->base.nr_samples : 1, psurf->texture->nr_samples, 1);
2912       if (zink_csurface(psurf)->info.layerCount > layers)
2913          ctx->fb_layer_mismatch |= BITFIELD_BIT(PIPE_MAX_COLOR_BUFS);
2914       zink_resource(psurf->texture)->fb_binds++;
2915       switch (psurf->format) {
2916       case PIPE_FORMAT_Z16_UNORM:
2917       case PIPE_FORMAT_Z16_UNORM_S8_UINT:
2918          ctx->depth_bias_scale_factor = zink_screen(ctx->base.screen)->driver_workarounds.z16_unscaled_bias;
2919          break;
2920       case PIPE_FORMAT_Z24X8_UNORM:
2921       case PIPE_FORMAT_Z24_UNORM_S8_UINT:
2922       case PIPE_FORMAT_X24S8_UINT:
2923       case PIPE_FORMAT_X8Z24_UNORM:
2924          ctx->depth_bias_scale_factor = zink_screen(ctx->base.screen)->driver_workarounds.z24_unscaled_bias;
2925          break;
2926       case PIPE_FORMAT_Z32_FLOAT:
2927       case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
2928       case PIPE_FORMAT_Z32_UNORM:
2929          ctx->depth_bias_scale_factor = 1<<23;
2930          break;
2931       default:
2932          ctx->depth_bias_scale_factor = 0;
2933       }
2934    } else {
2935       ctx->depth_bias_scale_factor = 0;
2936    }
2937    if (depth_bias_scale_factor != ctx->depth_bias_scale_factor &&
2938        ctx->rast_state && ctx->rast_state->base.offset_units_unscaled)
2939       ctx->rast_state_changed = true;
2940    rebind_fb_state(ctx, NULL, true);
2941    ctx->fb_state.samples = MAX2(samples, 1);
2942    zink_update_framebuffer_state(ctx);
2943    if (ctx->fb_state.width != w || ctx->fb_state.height != h)
2944       ctx->scissor_changed = true;
2945 
2946    uint8_t rast_samples = ctx->fb_state.samples - 1;
2947    if (rast_samples != ctx->gfx_pipeline_state.rast_samples)
2948       zink_update_fs_key_samples(ctx);
2949    if (ctx->gfx_pipeline_state.rast_samples != rast_samples) {
2950       ctx->sample_locations_changed |= ctx->gfx_pipeline_state.sample_locations_enabled;
2951       ctx->gfx_pipeline_state.dirty = true;
2952    }
2953    ctx->gfx_pipeline_state.rast_samples = rast_samples;
2954 
2955    /* need to ensure we start a new rp on next draw */
2956    zink_batch_no_rp(ctx);
2957    /* this is an ideal time to oom flush since it won't split a renderpass */
2958    if (ctx->oom_flush)
2959       flush_batch(ctx, false);
2960 }
2961 
2962 static void
zink_set_blend_color(struct pipe_context * pctx,const struct pipe_blend_color * color)2963 zink_set_blend_color(struct pipe_context *pctx,
2964                      const struct pipe_blend_color *color)
2965 {
2966    struct zink_context *ctx = zink_context(pctx);
2967    memcpy(ctx->blend_constants, color->color, sizeof(float) * 4);
2968 }
2969 
2970 static void
zink_set_sample_mask(struct pipe_context * pctx,unsigned sample_mask)2971 zink_set_sample_mask(struct pipe_context *pctx, unsigned sample_mask)
2972 {
2973    struct zink_context *ctx = zink_context(pctx);
2974    ctx->gfx_pipeline_state.sample_mask = sample_mask;
2975    ctx->gfx_pipeline_state.dirty = true;
2976 }
2977 
2978 static void
zink_set_sample_locations(struct pipe_context * pctx,size_t size,const uint8_t * locations)2979 zink_set_sample_locations(struct pipe_context *pctx, size_t size, const uint8_t *locations)
2980 {
2981    struct zink_context *ctx = zink_context(pctx);
2982 
2983    ctx->gfx_pipeline_state.sample_locations_enabled = size && locations;
2984    ctx->sample_locations_changed = ctx->gfx_pipeline_state.sample_locations_enabled;
2985    if (size > sizeof(ctx->sample_locations))
2986       size = sizeof(ctx->sample_locations);
2987 
2988    if (locations)
2989       memcpy(ctx->sample_locations, locations, size);
2990 }
2991 
2992 static VkAccessFlags
access_src_flags(VkImageLayout layout)2993 access_src_flags(VkImageLayout layout)
2994 {
2995    switch (layout) {
2996    case VK_IMAGE_LAYOUT_UNDEFINED:
2997       return 0;
2998 
2999    case VK_IMAGE_LAYOUT_GENERAL:
3000       return VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
3001 
3002    case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
3003       return VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
3004    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
3005       return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
3006 
3007    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
3008    case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
3009       return VK_ACCESS_SHADER_READ_BIT;
3010 
3011    case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
3012       return VK_ACCESS_TRANSFER_READ_BIT;
3013 
3014    case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
3015       return VK_ACCESS_TRANSFER_WRITE_BIT;
3016 
3017    case VK_IMAGE_LAYOUT_PREINITIALIZED:
3018       return VK_ACCESS_HOST_WRITE_BIT;
3019 
3020    case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
3021       return 0;
3022 
3023    default:
3024       unreachable("unexpected layout");
3025    }
3026 }
3027 
3028 static VkAccessFlags
access_dst_flags(VkImageLayout layout)3029 access_dst_flags(VkImageLayout layout)
3030 {
3031    switch (layout) {
3032    case VK_IMAGE_LAYOUT_UNDEFINED:
3033       return 0;
3034 
3035    case VK_IMAGE_LAYOUT_GENERAL:
3036       return VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
3037 
3038    case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
3039       return VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
3040    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
3041       return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
3042 
3043    case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
3044       return VK_ACCESS_SHADER_READ_BIT;
3045 
3046    case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
3047       return VK_ACCESS_TRANSFER_READ_BIT;
3048 
3049    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
3050       return VK_ACCESS_SHADER_READ_BIT;
3051 
3052    case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
3053       return VK_ACCESS_TRANSFER_WRITE_BIT;
3054 
3055    case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
3056       return 0;
3057 
3058    default:
3059       unreachable("unexpected layout");
3060    }
3061 }
3062 
3063 static VkPipelineStageFlags
pipeline_dst_stage(VkImageLayout layout)3064 pipeline_dst_stage(VkImageLayout layout)
3065 {
3066    switch (layout) {
3067    case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
3068       return VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
3069    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
3070       return VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
3071 
3072    case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
3073       return VK_PIPELINE_STAGE_TRANSFER_BIT;
3074    case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
3075       return VK_PIPELINE_STAGE_TRANSFER_BIT;
3076 
3077    case VK_IMAGE_LAYOUT_GENERAL:
3078       return VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
3079 
3080    case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
3081    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
3082       return VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
3083 
3084    default:
3085       return VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
3086    }
3087 }
3088 
3089 #define ALL_READ_ACCESS_FLAGS \
3090     (VK_ACCESS_INDIRECT_COMMAND_READ_BIT | \
3091     VK_ACCESS_INDEX_READ_BIT | \
3092     VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT | \
3093     VK_ACCESS_UNIFORM_READ_BIT | \
3094     VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | \
3095     VK_ACCESS_SHADER_READ_BIT | \
3096     VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | \
3097     VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | \
3098     VK_ACCESS_TRANSFER_READ_BIT |\
3099     VK_ACCESS_HOST_READ_BIT |\
3100     VK_ACCESS_MEMORY_READ_BIT |\
3101     VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT |\
3102     VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT |\
3103     VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT |\
3104     VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR |\
3105     VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR |\
3106     VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT |\
3107     VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_NV |\
3108     VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR |\
3109     VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR)
3110 
3111 
3112 bool
zink_resource_access_is_write(VkAccessFlags flags)3113 zink_resource_access_is_write(VkAccessFlags flags)
3114 {
3115    return (flags & ALL_READ_ACCESS_FLAGS) != flags;
3116 }
3117 
3118 bool
zink_resource_image_needs_barrier(struct zink_resource * res,VkImageLayout new_layout,VkAccessFlags flags,VkPipelineStageFlags pipeline)3119 zink_resource_image_needs_barrier(struct zink_resource *res, VkImageLayout new_layout, VkAccessFlags flags, VkPipelineStageFlags pipeline)
3120 {
3121    if (!pipeline)
3122       pipeline = pipeline_dst_stage(new_layout);
3123    if (!flags)
3124       flags = access_dst_flags(new_layout);
3125    return res->layout != new_layout || (res->obj->access_stage & pipeline) != pipeline ||
3126           (res->obj->access & flags) != flags ||
3127           zink_resource_access_is_write(res->obj->access) ||
3128           zink_resource_access_is_write(flags);
3129 }
3130 
3131 bool
zink_resource_image_barrier_init(VkImageMemoryBarrier * imb,struct zink_resource * res,VkImageLayout new_layout,VkAccessFlags flags,VkPipelineStageFlags pipeline)3132 zink_resource_image_barrier_init(VkImageMemoryBarrier *imb, struct zink_resource *res, VkImageLayout new_layout, VkAccessFlags flags, VkPipelineStageFlags pipeline)
3133 {
3134    if (!pipeline)
3135       pipeline = pipeline_dst_stage(new_layout);
3136    if (!flags)
3137       flags = access_dst_flags(new_layout);
3138 
3139    VkImageSubresourceRange isr = {
3140       res->aspect,
3141       0, VK_REMAINING_MIP_LEVELS,
3142       0, VK_REMAINING_ARRAY_LAYERS
3143    };
3144    *imb = (VkImageMemoryBarrier){
3145       VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
3146       NULL,
3147       res->obj->access ? res->obj->access : access_src_flags(res->layout),
3148       flags,
3149       res->layout,
3150       new_layout,
3151       VK_QUEUE_FAMILY_IGNORED,
3152       VK_QUEUE_FAMILY_IGNORED,
3153       res->obj->image,
3154       isr
3155    };
3156    return res->obj->needs_zs_evaluate || zink_resource_image_needs_barrier(res, new_layout, flags, pipeline);
3157 }
3158 
3159 static inline bool
is_shader_pipline_stage(VkPipelineStageFlags pipeline)3160 is_shader_pipline_stage(VkPipelineStageFlags pipeline)
3161 {
3162    return pipeline & GFX_SHADER_BITS;
3163 }
3164 
3165 static void
resource_check_defer_buffer_barrier(struct zink_context * ctx,struct zink_resource * res,VkPipelineStageFlags pipeline)3166 resource_check_defer_buffer_barrier(struct zink_context *ctx, struct zink_resource *res, VkPipelineStageFlags pipeline)
3167 {
3168    assert(res->obj->is_buffer);
3169    if (res->bind_count[0] - res->so_bind_count > 0) {
3170       if ((res->obj->is_buffer && res->vbo_bind_mask && !(pipeline & VK_PIPELINE_STAGE_VERTEX_INPUT_BIT)) ||
3171           ((!res->obj->is_buffer || util_bitcount(res->vbo_bind_mask) != res->bind_count[0]) && !is_shader_pipline_stage(pipeline)))
3172          /* gfx rebind */
3173          _mesa_set_add(ctx->need_barriers[0], res);
3174    }
3175    if (res->bind_count[1] && !(pipeline & VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT))
3176       /* compute rebind */
3177       _mesa_set_add(ctx->need_barriers[1], res);
3178 }
3179 
3180 static inline bool
unordered_res_exec(const struct zink_context * ctx,const struct zink_resource * res,bool is_write)3181 unordered_res_exec(const struct zink_context *ctx, const struct zink_resource *res, bool is_write)
3182 {
3183    /* if all usage is unordered, keep unordered */
3184    if (res->obj->unordered_read && res->obj->unordered_write)
3185       return true;
3186    /* if testing write access but have any ordered read access, cannot promote */
3187    if (is_write && zink_batch_usage_matches(res->obj->bo->reads, ctx->batch.state) && !res->obj->unordered_read)
3188       return false;
3189    /* if write access is unordered or nonexistent, always promote */
3190    return res->obj->unordered_write || !zink_batch_usage_matches(res->obj->bo->writes, ctx->batch.state);
3191 }
3192 
3193 VkCommandBuffer
zink_get_cmdbuf(struct zink_context * ctx,struct zink_resource * src,struct zink_resource * dst)3194 zink_get_cmdbuf(struct zink_context *ctx, struct zink_resource *src, struct zink_resource *dst)
3195 {
3196    bool unordered_exec = (zink_debug & ZINK_DEBUG_NOREORDER) == 0;
3197    if (src)
3198       unordered_exec &= unordered_res_exec(ctx, src, false);
3199    if (dst)
3200       unordered_exec &= unordered_res_exec(ctx, dst, true);
3201    if (src)
3202       src->obj->unordered_read = unordered_exec;
3203    if (dst)
3204       dst->obj->unordered_write = unordered_exec;
3205    if (unordered_exec) {
3206       ctx->batch.state->has_barriers = true;
3207       return ctx->batch.state->barrier_cmdbuf;
3208    }
3209    zink_batch_no_rp(ctx);
3210    return ctx->batch.state->cmdbuf;
3211 }
3212 
3213 static void
resource_check_defer_image_barrier(struct zink_context * ctx,struct zink_resource * res,VkImageLayout layout,VkPipelineStageFlags pipeline)3214 resource_check_defer_image_barrier(struct zink_context *ctx, struct zink_resource *res, VkImageLayout layout, VkPipelineStageFlags pipeline)
3215 {
3216    assert(!res->obj->is_buffer);
3217 
3218    bool is_compute = pipeline == VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
3219    /* if this is a non-shader barrier and there are binds, always queue a shader barrier */
3220    bool is_shader = is_shader_pipline_stage(pipeline);
3221    if ((is_shader || !res->bind_count[is_compute]) &&
3222        /* if no layout change is needed between gfx and compute, do nothing */
3223        !res->bind_count[!is_compute] && (!is_compute || !res->fb_binds))
3224       return;
3225 
3226    if (res->bind_count[!is_compute] && is_shader) {
3227       /* if the layout is the same between gfx and compute, do nothing */
3228       if (layout == zink_descriptor_util_image_layout_eval(ctx, res, !is_compute))
3229          return;
3230    }
3231    /* queue a layout change if a layout change will be needed */
3232    if (res->bind_count[!is_compute])
3233       _mesa_set_add(ctx->need_barriers[!is_compute], res);
3234    /* also queue a layout change if this is a non-shader layout */
3235    if (res->bind_count[is_compute] && !is_shader)
3236       _mesa_set_add(ctx->need_barriers[is_compute], res);
3237 }
3238 
3239 void
zink_resource_image_barrier(struct zink_context * ctx,struct zink_resource * res,VkImageLayout new_layout,VkAccessFlags flags,VkPipelineStageFlags pipeline)3240 zink_resource_image_barrier(struct zink_context *ctx, struct zink_resource *res,
3241                       VkImageLayout new_layout, VkAccessFlags flags, VkPipelineStageFlags pipeline)
3242 {
3243    VkImageMemoryBarrier imb;
3244    if (!pipeline)
3245       pipeline = pipeline_dst_stage(new_layout);
3246 
3247    if (!zink_resource_image_barrier_init(&imb, res, new_layout, flags, pipeline))
3248       return;
3249    /* only barrier if we're changing layout or doing something besides read -> read */
3250    bool is_write = zink_resource_access_is_write(imb.dstAccessMask);
3251    VkCommandBuffer cmdbuf = is_write ? zink_get_cmdbuf(ctx, NULL, res) : zink_get_cmdbuf(ctx, res, NULL);
3252    assert(new_layout);
3253    if (!res->obj->access_stage)
3254       imb.srcAccessMask = 0;
3255    if (res->obj->needs_zs_evaluate)
3256       imb.pNext = &res->obj->zs_evaluate;
3257    res->obj->needs_zs_evaluate = false;
3258    if (res->dmabuf_acquire) {
3259       imb.srcQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT;
3260       imb.dstQueueFamilyIndex = zink_screen(ctx->base.screen)->gfx_queue;
3261       res->dmabuf_acquire = false;
3262    }
3263    VKCTX(CmdPipelineBarrier)(
3264       cmdbuf,
3265       res->obj->access_stage ? res->obj->access_stage : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
3266       pipeline,
3267       0,
3268       0, NULL,
3269       0, NULL,
3270       1, &imb
3271    );
3272 
3273    resource_check_defer_image_barrier(ctx, res, new_layout, pipeline);
3274 
3275    res->obj->access = imb.dstAccessMask;
3276    res->obj->access_stage = pipeline;
3277    res->layout = new_layout;
3278 }
3279 
3280 
3281 VkPipelineStageFlags
zink_pipeline_flags_from_stage(VkShaderStageFlagBits stage)3282 zink_pipeline_flags_from_stage(VkShaderStageFlagBits stage)
3283 {
3284    switch (stage) {
3285    case VK_SHADER_STAGE_VERTEX_BIT:
3286       return VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
3287    case VK_SHADER_STAGE_FRAGMENT_BIT:
3288       return VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
3289    case VK_SHADER_STAGE_GEOMETRY_BIT:
3290       return VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT;
3291    case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
3292       return VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT;
3293    case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
3294       return VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT;
3295    case VK_SHADER_STAGE_COMPUTE_BIT:
3296       return VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
3297    default:
3298       unreachable("unknown shader stage bit");
3299    }
3300 }
3301 
3302 ALWAYS_INLINE static VkPipelineStageFlags
pipeline_access_stage(VkAccessFlags flags)3303 pipeline_access_stage(VkAccessFlags flags)
3304 {
3305    if (flags & (VK_ACCESS_UNIFORM_READ_BIT |
3306                 VK_ACCESS_SHADER_READ_BIT |
3307                 VK_ACCESS_SHADER_WRITE_BIT))
3308       return VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV |
3309              VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV |
3310              VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR |
3311              VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
3312              VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
3313              VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT |
3314              VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT |
3315              VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
3316              VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
3317    return VK_PIPELINE_STAGE_TRANSFER_BIT;
3318 }
3319 
3320 ALWAYS_INLINE static bool
zink_resource_buffer_needs_barrier(struct zink_resource * res,VkAccessFlags flags,VkPipelineStageFlags pipeline)3321 zink_resource_buffer_needs_barrier(struct zink_resource *res, VkAccessFlags flags, VkPipelineStageFlags pipeline)
3322 {
3323    if (!res->obj->access || !res->obj->access_stage)
3324       return true;
3325    if (!pipeline)
3326       pipeline = pipeline_access_stage(flags);
3327    return zink_resource_access_is_write(res->obj->access) ||
3328           zink_resource_access_is_write(flags) ||
3329           (res->obj->access_stage & pipeline) != pipeline ||
3330           (res->obj->access & flags) != flags;
3331 }
3332 
3333 void
zink_resource_buffer_barrier(struct zink_context * ctx,struct zink_resource * res,VkAccessFlags flags,VkPipelineStageFlags pipeline)3334 zink_resource_buffer_barrier(struct zink_context *ctx, struct zink_resource *res, VkAccessFlags flags, VkPipelineStageFlags pipeline)
3335 {
3336    VkMemoryBarrier bmb;
3337    if (!pipeline)
3338       pipeline = pipeline_access_stage(flags);
3339    if (!zink_resource_buffer_needs_barrier(res, flags, pipeline))
3340       return;
3341 
3342    bmb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
3343    bmb.pNext = NULL;
3344    bmb.srcAccessMask = res->obj->access;
3345    bmb.dstAccessMask = flags;
3346    if (!res->obj->access_stage)
3347       bmb.srcAccessMask = 0;
3348    bool is_write = zink_resource_access_is_write(flags);
3349    VkCommandBuffer cmdbuf = is_write ? zink_get_cmdbuf(ctx, NULL, res) : zink_get_cmdbuf(ctx, res, NULL);
3350    /* only barrier if we're changing layout or doing something besides read -> read */
3351    VKCTX(CmdPipelineBarrier)(
3352       cmdbuf,
3353       res->obj->access_stage ? res->obj->access_stage : pipeline_access_stage(res->obj->access),
3354       pipeline,
3355       0,
3356       1, &bmb,
3357       0, NULL,
3358       0, NULL
3359    );
3360 
3361    resource_check_defer_buffer_barrier(ctx, res, pipeline);
3362 
3363    res->obj->access = bmb.dstAccessMask;
3364    res->obj->access_stage = pipeline;
3365 }
3366 
3367 bool
zink_resource_needs_barrier(struct zink_resource * res,VkImageLayout layout,VkAccessFlags flags,VkPipelineStageFlags pipeline)3368 zink_resource_needs_barrier(struct zink_resource *res, VkImageLayout layout, VkAccessFlags flags, VkPipelineStageFlags pipeline)
3369 {
3370    if (res->base.b.target == PIPE_BUFFER)
3371       return zink_resource_buffer_needs_barrier(res, flags, pipeline);
3372    return zink_resource_image_needs_barrier(res, layout, flags, pipeline);
3373 }
3374 
3375 VkShaderStageFlagBits
zink_shader_stage(enum pipe_shader_type type)3376 zink_shader_stage(enum pipe_shader_type type)
3377 {
3378    VkShaderStageFlagBits stages[] = {
3379       [PIPE_SHADER_VERTEX] = VK_SHADER_STAGE_VERTEX_BIT,
3380       [PIPE_SHADER_FRAGMENT] = VK_SHADER_STAGE_FRAGMENT_BIT,
3381       [PIPE_SHADER_GEOMETRY] = VK_SHADER_STAGE_GEOMETRY_BIT,
3382       [PIPE_SHADER_TESS_CTRL] = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
3383       [PIPE_SHADER_TESS_EVAL] = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
3384       [PIPE_SHADER_COMPUTE] = VK_SHADER_STAGE_COMPUTE_BIT,
3385    };
3386    return stages[type];
3387 }
3388 
3389 static void
zink_flush(struct pipe_context * pctx,struct pipe_fence_handle ** pfence,unsigned flags)3390 zink_flush(struct pipe_context *pctx,
3391            struct pipe_fence_handle **pfence,
3392            unsigned flags)
3393 {
3394    struct zink_context *ctx = zink_context(pctx);
3395    bool deferred = flags & PIPE_FLUSH_DEFERRED;
3396    bool deferred_fence = false;
3397    struct zink_batch *batch = &ctx->batch;
3398    struct zink_fence *fence = NULL;
3399    struct zink_screen *screen = zink_screen(ctx->base.screen);
3400    unsigned submit_count = 0;
3401 
3402    /* triggering clears will force has_work */
3403    if (!deferred && ctx->clears_enabled) {
3404       /* if fbfetch outputs are active, disable them when flushing clears */
3405       unsigned fbfetch_outputs = ctx->fbfetch_outputs;
3406       if (fbfetch_outputs) {
3407          ctx->fbfetch_outputs = 0;
3408          ctx->rp_changed = true;
3409       }
3410       /* start rp to do all the clears */
3411       zink_batch_rp(ctx);
3412       ctx->fbfetch_outputs = fbfetch_outputs;
3413       ctx->rp_changed |= fbfetch_outputs > 0;
3414    }
3415 
3416    if (ctx->needs_present && (flags & PIPE_FLUSH_END_OF_FRAME)) {
3417       if (ctx->needs_present->obj->image)
3418          zink_resource_image_barrier(ctx, ctx->needs_present, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, 0, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
3419       ctx->needs_present = NULL;
3420    }
3421 
3422    if (!batch->has_work) {
3423        if (pfence) {
3424           /* reuse last fence */
3425           fence = ctx->last_fence;
3426        }
3427        if (!deferred) {
3428           struct zink_batch_state *last = zink_batch_state(ctx->last_fence);
3429           if (last) {
3430              sync_flush(ctx, last);
3431              if (last->is_device_lost)
3432                 check_device_lost(ctx);
3433           }
3434        }
3435        tc_driver_internal_flush_notify(ctx->tc);
3436    } else {
3437       fence = &batch->state->fence;
3438       submit_count = batch->state->submit_count;
3439       if (deferred && !(flags & PIPE_FLUSH_FENCE_FD) && pfence)
3440          deferred_fence = true;
3441       else
3442          flush_batch(ctx, true);
3443    }
3444 
3445    if (pfence) {
3446       struct zink_tc_fence *mfence;
3447 
3448       if (flags & TC_FLUSH_ASYNC) {
3449          mfence = zink_tc_fence(*pfence);
3450          assert(mfence);
3451       } else {
3452          mfence = zink_create_tc_fence();
3453 
3454          screen->base.fence_reference(&screen->base, pfence, NULL);
3455          *pfence = (struct pipe_fence_handle *)mfence;
3456       }
3457 
3458       mfence->fence = fence;
3459       if (fence)
3460          mfence->submit_count = submit_count;
3461 
3462       if (deferred_fence) {
3463          assert(fence);
3464          mfence->deferred_ctx = pctx;
3465          assert(!ctx->deferred_fence || ctx->deferred_fence == fence);
3466          ctx->deferred_fence = fence;
3467       }
3468 
3469       if (!fence || flags & TC_FLUSH_ASYNC) {
3470          if (!util_queue_fence_is_signalled(&mfence->ready))
3471             util_queue_fence_signal(&mfence->ready);
3472       }
3473    }
3474    if (fence) {
3475       if (!(flags & (PIPE_FLUSH_DEFERRED | PIPE_FLUSH_ASYNC)))
3476          sync_flush(ctx, zink_batch_state(fence));
3477    }
3478 }
3479 
3480 void
zink_fence_wait(struct pipe_context * pctx)3481 zink_fence_wait(struct pipe_context *pctx)
3482 {
3483    struct zink_context *ctx = zink_context(pctx);
3484 
3485    if (ctx->batch.has_work)
3486       pctx->flush(pctx, NULL, PIPE_FLUSH_HINT_FINISH);
3487    if (ctx->last_fence)
3488       stall(ctx);
3489 }
3490 
3491 void
zink_wait_on_batch(struct zink_context * ctx,uint64_t batch_id)3492 zink_wait_on_batch(struct zink_context *ctx, uint64_t batch_id)
3493 {
3494    struct zink_batch_state *bs;
3495    if (!batch_id) {
3496       /* not submitted yet */
3497       flush_batch(ctx, true);
3498       bs = zink_batch_state(ctx->last_fence);
3499       assert(bs);
3500       batch_id = bs->fence.batch_id;
3501    }
3502    assert(batch_id);
3503    if (!zink_screen_timeline_wait(zink_screen(ctx->base.screen), batch_id, UINT64_MAX))
3504       check_device_lost(ctx);
3505 }
3506 
3507 bool
zink_check_batch_completion(struct zink_context * ctx,uint64_t batch_id)3508 zink_check_batch_completion(struct zink_context *ctx, uint64_t batch_id)
3509 {
3510    assert(ctx->batch.state);
3511    if (!batch_id)
3512       /* not submitted yet */
3513       return false;
3514 
3515    if (zink_screen_check_last_finished(zink_screen(ctx->base.screen), batch_id))
3516       return true;
3517 
3518    bool success = zink_screen_timeline_wait(zink_screen(ctx->base.screen), batch_id, 0);
3519    if (!success)
3520       check_device_lost(ctx);
3521    return success;
3522 }
3523 
3524 static void
zink_texture_barrier(struct pipe_context * pctx,unsigned flags)3525 zink_texture_barrier(struct pipe_context *pctx, unsigned flags)
3526 {
3527    struct zink_context *ctx = zink_context(pctx);
3528    VkAccessFlags dst = flags == PIPE_TEXTURE_BARRIER_FRAMEBUFFER ?
3529                        VK_ACCESS_INPUT_ATTACHMENT_READ_BIT :
3530                        VK_ACCESS_SHADER_READ_BIT;
3531 
3532    if (!ctx->framebuffer || !ctx->framebuffer->state.num_attachments)
3533       return;
3534 
3535    /* if this is a fb barrier, flush all pending clears */
3536    if (ctx->rp_clears_enabled && dst == VK_ACCESS_INPUT_ATTACHMENT_READ_BIT)
3537       zink_batch_rp(ctx);
3538 
3539    /* this is not an in-renderpass barrier */
3540    if (!ctx->fbfetch_outputs)
3541       zink_batch_no_rp(ctx);
3542 
3543    if (zink_screen(ctx->base.screen)->info.have_KHR_synchronization2) {
3544       VkDependencyInfo dep = {0};
3545       dep.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
3546       dep.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
3547       dep.memoryBarrierCount = 1;
3548 
3549       VkMemoryBarrier2 dmb = {0};
3550       dmb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2;
3551       dmb.pNext = NULL;
3552       dmb.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
3553       dmb.dstAccessMask = dst;
3554       dmb.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
3555       dmb.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT;
3556       dep.pMemoryBarriers = &dmb;
3557 
3558       /* if zs fbfetch is a thing?
3559       if (ctx->fb_state.zsbuf) {
3560          const VkPipelineStageFlagBits2 depth_flags = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT;
3561          dmb.dstAccessMask |= VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
3562          dmb.srcStageMask |= depth_flags;
3563          dmb.dstStageMask |= depth_flags;
3564       }
3565       */
3566       VKCTX(CmdPipelineBarrier2)(ctx->batch.state->cmdbuf, &dep);
3567    } else {
3568       VkMemoryBarrier bmb = {0};
3569       bmb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
3570       bmb.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
3571       bmb.dstAccessMask = dst;
3572       VKCTX(CmdPipelineBarrier)(
3573          ctx->batch.state->cmdbuf,
3574          VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
3575          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
3576          0,
3577          1, &bmb,
3578          0, NULL,
3579          0, NULL
3580       );
3581    }
3582 }
3583 
3584 static inline void
mem_barrier(struct zink_context * ctx,VkPipelineStageFlags src_stage,VkPipelineStageFlags dst_stage,VkAccessFlags src,VkAccessFlags dst)3585 mem_barrier(struct zink_context *ctx, VkPipelineStageFlags src_stage, VkPipelineStageFlags dst_stage, VkAccessFlags src, VkAccessFlags dst)
3586 {
3587    struct zink_batch *batch = &ctx->batch;
3588    VkMemoryBarrier mb;
3589    mb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
3590    mb.pNext = NULL;
3591    mb.srcAccessMask = src;
3592    mb.dstAccessMask = dst;
3593    zink_batch_no_rp(ctx);
3594    VKCTX(CmdPipelineBarrier)(batch->state->cmdbuf, src_stage, dst_stage, 0, 1, &mb, 0, NULL, 0, NULL);
3595 }
3596 
3597 void
zink_flush_memory_barrier(struct zink_context * ctx,bool is_compute)3598 zink_flush_memory_barrier(struct zink_context *ctx, bool is_compute)
3599 {
3600    const VkPipelineStageFlags gfx_flags = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
3601                                           VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
3602                                           VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT |
3603                                           VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT |
3604                                           VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
3605    const VkPipelineStageFlags cs_flags = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
3606    VkPipelineStageFlags src = ctx->batch.last_was_compute ? cs_flags : gfx_flags;
3607    VkPipelineStageFlags dst = is_compute ? cs_flags : gfx_flags;
3608 
3609    if (ctx->memory_barrier & (PIPE_BARRIER_TEXTURE | PIPE_BARRIER_SHADER_BUFFER | PIPE_BARRIER_IMAGE))
3610       mem_barrier(ctx, src, dst, VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT);
3611 
3612    if (ctx->memory_barrier & PIPE_BARRIER_CONSTANT_BUFFER)
3613       mem_barrier(ctx, src, dst,
3614                   VK_ACCESS_SHADER_WRITE_BIT,
3615                   VK_ACCESS_UNIFORM_READ_BIT);
3616 
3617    if (!is_compute) {
3618       if (ctx->memory_barrier & PIPE_BARRIER_INDIRECT_BUFFER)
3619          mem_barrier(ctx, src, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
3620                      VK_ACCESS_SHADER_WRITE_BIT,
3621                      VK_ACCESS_INDIRECT_COMMAND_READ_BIT);
3622       if (ctx->memory_barrier & PIPE_BARRIER_VERTEX_BUFFER)
3623          mem_barrier(ctx, gfx_flags, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
3624                      VK_ACCESS_SHADER_WRITE_BIT,
3625                      VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT);
3626 
3627       if (ctx->memory_barrier & PIPE_BARRIER_INDEX_BUFFER)
3628          mem_barrier(ctx, gfx_flags, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
3629                      VK_ACCESS_SHADER_WRITE_BIT,
3630                      VK_ACCESS_INDEX_READ_BIT);
3631       if (ctx->memory_barrier & PIPE_BARRIER_FRAMEBUFFER)
3632          zink_texture_barrier(&ctx->base, 0);
3633       if (ctx->memory_barrier & PIPE_BARRIER_STREAMOUT_BUFFER)
3634          mem_barrier(ctx, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
3635                             VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT |
3636                             VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT,
3637                      VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT,
3638                      VK_ACCESS_SHADER_READ_BIT,
3639                      VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT |
3640                      VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT);
3641    }
3642    ctx->memory_barrier = 0;
3643 }
3644 
3645 static void
zink_memory_barrier(struct pipe_context * pctx,unsigned flags)3646 zink_memory_barrier(struct pipe_context *pctx, unsigned flags)
3647 {
3648    struct zink_context *ctx = zink_context(pctx);
3649 
3650    flags &= ~PIPE_BARRIER_UPDATE;
3651    if (!flags)
3652       return;
3653 
3654    if (flags & PIPE_BARRIER_MAPPED_BUFFER) {
3655       /* TODO: this should flush all persistent buffers in use as I think */
3656       flags &= ~PIPE_BARRIER_MAPPED_BUFFER;
3657    }
3658    ctx->memory_barrier = flags;
3659 }
3660 
3661 static void
zink_flush_resource(struct pipe_context * pctx,struct pipe_resource * pres)3662 zink_flush_resource(struct pipe_context *pctx,
3663                     struct pipe_resource *pres)
3664 {
3665    struct zink_context *ctx = zink_context(pctx);
3666    struct zink_resource *res = zink_resource(pres);
3667    if (res->obj->dt) {
3668       if (zink_kopper_acquired(res->obj->dt, res->obj->dt_idx)) {
3669          zink_resource_image_barrier(ctx, res, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, 0, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
3670          zink_batch_reference_resource_rw(&ctx->batch, res, true);
3671       } else {
3672          ctx->needs_present = res;
3673       }
3674       ctx->batch.swapchain = res;
3675    } else if (res->dmabuf)
3676       res->dmabuf_acquire = true;
3677 }
3678 
3679 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)3680 zink_create_stream_output_target(struct pipe_context *pctx,
3681                                  struct pipe_resource *pres,
3682                                  unsigned buffer_offset,
3683                                  unsigned buffer_size)
3684 {
3685    struct zink_so_target *t;
3686    t = CALLOC_STRUCT(zink_so_target);
3687    if (!t)
3688       return NULL;
3689 
3690    /* using PIPE_BIND_CUSTOM here lets us create a custom pipe buffer resource,
3691     * which allows us to differentiate and use VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT
3692     * as we must for this case
3693     */
3694    t->counter_buffer = pipe_buffer_create(pctx->screen, PIPE_BIND_STREAM_OUTPUT | PIPE_BIND_CUSTOM, PIPE_USAGE_DEFAULT, 4);
3695    if (!t->counter_buffer) {
3696       FREE(t);
3697       return NULL;
3698    }
3699 
3700    t->base.reference.count = 1;
3701    t->base.context = pctx;
3702    pipe_resource_reference(&t->base.buffer, pres);
3703    t->base.buffer_offset = buffer_offset;
3704    t->base.buffer_size = buffer_size;
3705 
3706    zink_resource(t->base.buffer)->so_valid = true;
3707 
3708    return &t->base;
3709 }
3710 
3711 static void
zink_stream_output_target_destroy(struct pipe_context * pctx,struct pipe_stream_output_target * psot)3712 zink_stream_output_target_destroy(struct pipe_context *pctx,
3713                                   struct pipe_stream_output_target *psot)
3714 {
3715    struct zink_so_target *t = (struct zink_so_target *)psot;
3716    pipe_resource_reference(&t->counter_buffer, NULL);
3717    pipe_resource_reference(&t->base.buffer, NULL);
3718    FREE(t);
3719 }
3720 
3721 static void
zink_set_stream_output_targets(struct pipe_context * pctx,unsigned num_targets,struct pipe_stream_output_target ** targets,const unsigned * offsets)3722 zink_set_stream_output_targets(struct pipe_context *pctx,
3723                                unsigned num_targets,
3724                                struct pipe_stream_output_target **targets,
3725                                const unsigned *offsets)
3726 {
3727    struct zink_context *ctx = zink_context(pctx);
3728 
3729    /* always set counter_buffer_valid=false on unbind:
3730     * - on resume (indicated by offset==-1), set counter_buffer_valid=true
3731     * - otherwise the counter buffer is invalidated
3732     */
3733 
3734    if (num_targets == 0) {
3735       for (unsigned i = 0; i < ctx->num_so_targets; i++) {
3736          if (ctx->so_targets[i]) {
3737             struct zink_resource *so = zink_resource(ctx->so_targets[i]->buffer);
3738             if (so) {
3739                so->so_bind_count--;
3740                update_res_bind_count(ctx, so, false, true);
3741             }
3742          }
3743          pipe_so_target_reference(&ctx->so_targets[i], NULL);
3744       }
3745       ctx->num_so_targets = 0;
3746    } else {
3747       for (unsigned i = 0; i < num_targets; i++) {
3748          struct zink_so_target *t = zink_so_target(targets[i]);
3749          pipe_so_target_reference(&ctx->so_targets[i], targets[i]);
3750          if (!t)
3751             continue;
3752          if (offsets[0] != (unsigned)-1)
3753             t->counter_buffer_valid = false;
3754          struct zink_resource *so = zink_resource(ctx->so_targets[i]->buffer);
3755          if (so) {
3756             so->so_bind_count++;
3757             update_res_bind_count(ctx, so, false, false);
3758          }
3759       }
3760       for (unsigned i = num_targets; i < ctx->num_so_targets; i++) {
3761          if (ctx->so_targets[i]) {
3762             struct zink_resource *so = zink_resource(ctx->so_targets[i]->buffer);
3763             if (so) {
3764                so->so_bind_count--;
3765                update_res_bind_count(ctx, so, false, true);
3766             }
3767          }
3768          pipe_so_target_reference(&ctx->so_targets[i], NULL);
3769       }
3770       ctx->num_so_targets = num_targets;
3771 
3772       /* TODO: possibly avoid rebinding on resume if resuming from same buffers? */
3773       ctx->dirty_so_targets = true;
3774    }
3775 }
3776 
3777 void
zink_rebind_framebuffer(struct zink_context * ctx,struct zink_resource * res)3778 zink_rebind_framebuffer(struct zink_context *ctx, struct zink_resource *res)
3779 {
3780    if (!ctx->framebuffer)
3781       return;
3782    bool did_rebind = false;
3783    if (res->aspect & VK_IMAGE_ASPECT_COLOR_BIT) {
3784       for (unsigned i = 0; i < ctx->fb_state.nr_cbufs; i++) {
3785          if (!ctx->fb_state.cbufs[i] ||
3786              zink_resource(ctx->fb_state.cbufs[i]->texture) != res)
3787             continue;
3788          zink_rebind_ctx_surface(ctx, &ctx->fb_state.cbufs[i]);
3789          did_rebind = true;
3790       }
3791    } else {
3792       if (ctx->fb_state.zsbuf && zink_resource(ctx->fb_state.zsbuf->texture) != res) {
3793          zink_rebind_ctx_surface(ctx, &ctx->fb_state.zsbuf);
3794          did_rebind = true;
3795       }
3796    }
3797 
3798    did_rebind |= rebind_fb_state(ctx, res, false);
3799 
3800    if (!did_rebind)
3801       return;
3802 
3803    zink_batch_no_rp(ctx);
3804    struct zink_framebuffer *fb = zink_get_framebuffer(ctx);
3805    ctx->fb_changed |= ctx->framebuffer != fb;
3806    ctx->framebuffer = fb;
3807 }
3808 
3809 ALWAYS_INLINE static struct zink_resource *
rebind_ubo(struct zink_context * ctx,enum pipe_shader_type shader,unsigned slot)3810 rebind_ubo(struct zink_context *ctx, enum pipe_shader_type shader, unsigned slot)
3811 {
3812    struct zink_resource *res = update_descriptor_state_ubo(ctx, shader, slot,
3813                                                            ctx->di.descriptor_res[ZINK_DESCRIPTOR_TYPE_UBO][shader][slot]);
3814    zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_UBO, slot, 1);
3815    return res;
3816 }
3817 
3818 ALWAYS_INLINE static struct zink_resource *
rebind_ssbo(struct zink_context * ctx,enum pipe_shader_type shader,unsigned slot)3819 rebind_ssbo(struct zink_context *ctx, enum pipe_shader_type shader, unsigned slot)
3820 {
3821    const struct pipe_shader_buffer *ssbo = &ctx->ssbos[shader][slot];
3822    struct zink_resource *res = zink_resource(ssbo->buffer);
3823    if (!res)
3824       return NULL;
3825    util_range_add(&res->base.b, &res->valid_buffer_range, ssbo->buffer_offset,
3826                   ssbo->buffer_offset + ssbo->buffer_size);
3827    update_descriptor_state_ssbo(ctx, shader, slot, res);
3828    zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SSBO, slot, 1);
3829    return res;
3830 }
3831 
3832 ALWAYS_INLINE static struct zink_resource *
rebind_tbo(struct zink_context * ctx,enum pipe_shader_type shader,unsigned slot)3833 rebind_tbo(struct zink_context *ctx, enum pipe_shader_type shader, unsigned slot)
3834 {
3835    struct zink_sampler_view *sampler_view = zink_sampler_view(ctx->sampler_views[shader][slot]);
3836    if (!sampler_view || sampler_view->base.texture->target != PIPE_BUFFER)
3837       return NULL;
3838    struct zink_resource *res = zink_resource(sampler_view->base.texture);
3839    if (zink_batch_usage_exists(sampler_view->buffer_view->batch_uses))
3840       zink_batch_reference_bufferview(&ctx->batch, sampler_view->buffer_view);
3841    VkBufferViewCreateInfo bvci = sampler_view->buffer_view->bvci;
3842    bvci.buffer = res->obj->buffer;
3843    zink_buffer_view_reference(zink_screen(ctx->base.screen), &sampler_view->buffer_view, NULL);
3844    sampler_view->buffer_view = get_buffer_view(ctx, res, &bvci);
3845    update_descriptor_state_sampler(ctx, shader, slot, res);
3846    zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, slot, 1);
3847    return res;
3848 }
3849 
3850 ALWAYS_INLINE static struct zink_resource *
rebind_ibo(struct zink_context * ctx,enum pipe_shader_type shader,unsigned slot)3851 rebind_ibo(struct zink_context *ctx, enum pipe_shader_type shader, unsigned slot)
3852 {
3853    struct zink_image_view *image_view = &ctx->image_views[shader][slot];
3854    struct zink_resource *res = zink_resource(image_view->base.resource);
3855    if (!res || res->base.b.target != PIPE_BUFFER)
3856       return NULL;
3857    zink_descriptor_set_refs_clear(&image_view->buffer_view->desc_set_refs, image_view->buffer_view);
3858    if (zink_batch_usage_exists(image_view->buffer_view->batch_uses))
3859       zink_batch_reference_bufferview(&ctx->batch, image_view->buffer_view);
3860    VkBufferViewCreateInfo bvci = image_view->buffer_view->bvci;
3861    bvci.buffer = res->obj->buffer;
3862    zink_buffer_view_reference(zink_screen(ctx->base.screen), &image_view->buffer_view, NULL);
3863    if (!zink_resource_object_init_storage(ctx, res)) {
3864       debug_printf("couldn't create storage image!");
3865       return NULL;
3866    }
3867    image_view->buffer_view = get_buffer_view(ctx, res, &bvci);
3868    assert(image_view->buffer_view);
3869    util_range_add(&res->base.b, &res->valid_buffer_range, image_view->base.u.buf.offset,
3870                   image_view->base.u.buf.offset + image_view->base.u.buf.size);
3871    update_descriptor_state_image(ctx, shader, slot, res);
3872    zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_IMAGE, slot, 1);
3873    return res;
3874 }
3875 
3876 static unsigned
rebind_buffer(struct zink_context * ctx,struct zink_resource * res,uint32_t rebind_mask,const unsigned expected_num_rebinds)3877 rebind_buffer(struct zink_context *ctx, struct zink_resource *res, uint32_t rebind_mask, const unsigned expected_num_rebinds)
3878 {
3879    unsigned num_rebinds = 0;
3880    bool has_write = false;
3881 
3882    if (!zink_resource_has_binds(res))
3883       return 0;
3884 
3885    assert(!res->bindless[1]); //TODO
3886    if ((rebind_mask & BITFIELD_BIT(TC_BINDING_STREAMOUT_BUFFER)) || (!rebind_mask && res->so_bind_count && ctx->num_so_targets)) {
3887       for (unsigned i = 0; i < ctx->num_so_targets; i++) {
3888          if (ctx->so_targets[i]) {
3889             struct zink_resource *so = zink_resource(ctx->so_targets[i]->buffer);
3890             if (so && so == res) {
3891                ctx->dirty_so_targets = true;
3892                num_rebinds++;
3893             }
3894          }
3895       }
3896       rebind_mask &= ~BITFIELD_BIT(TC_BINDING_STREAMOUT_BUFFER);
3897    }
3898    if (num_rebinds && expected_num_rebinds >= num_rebinds && !rebind_mask)
3899       goto end;
3900 
3901    if ((rebind_mask & BITFIELD_BIT(TC_BINDING_VERTEX_BUFFER)) || (!rebind_mask && res->vbo_bind_mask)) {
3902       u_foreach_bit(slot, res->vbo_bind_mask) {
3903          if (ctx->vertex_buffers[slot].buffer.resource != &res->base.b) //wrong context
3904             goto end;
3905          num_rebinds++;
3906       }
3907       rebind_mask &= ~BITFIELD_BIT(TC_BINDING_VERTEX_BUFFER);
3908       ctx->vertex_buffers_dirty = true;
3909    }
3910    if (num_rebinds && expected_num_rebinds >= num_rebinds && !rebind_mask)
3911       goto end;
3912 
3913    const uint32_t ubo_mask = rebind_mask ?
3914                              rebind_mask & BITFIELD_RANGE(TC_BINDING_UBO_VS, PIPE_SHADER_TYPES) :
3915                              ((res->ubo_bind_count[0] ? BITFIELD_RANGE(TC_BINDING_UBO_VS, (PIPE_SHADER_TYPES - 1)) : 0) |
3916                               (res->ubo_bind_count[1] ? BITFIELD_BIT(TC_BINDING_UBO_CS) : 0));
3917    u_foreach_bit(shader, ubo_mask >> TC_BINDING_UBO_VS) {
3918       u_foreach_bit(slot, res->ubo_bind_mask[shader]) {
3919          if (&res->base.b != ctx->ubos[shader][slot].buffer) //wrong context
3920             goto end;
3921          rebind_ubo(ctx, shader, slot);
3922          num_rebinds++;
3923       }
3924    }
3925    rebind_mask &= ~BITFIELD_RANGE(TC_BINDING_UBO_VS, PIPE_SHADER_TYPES);
3926    if (num_rebinds && expected_num_rebinds >= num_rebinds && !rebind_mask)
3927       goto end;
3928 
3929    const unsigned ssbo_mask = rebind_mask ?
3930                               rebind_mask & BITFIELD_RANGE(TC_BINDING_SSBO_VS, PIPE_SHADER_TYPES) :
3931                               BITFIELD_RANGE(TC_BINDING_SSBO_VS, PIPE_SHADER_TYPES);
3932    u_foreach_bit(shader, ssbo_mask >> TC_BINDING_SSBO_VS) {
3933       u_foreach_bit(slot, res->ssbo_bind_mask[shader]) {
3934          struct pipe_shader_buffer *ssbo = &ctx->ssbos[shader][slot];
3935          if (&res->base.b != ssbo->buffer) //wrong context
3936             goto end;
3937          rebind_ssbo(ctx, shader, slot);
3938          has_write |= (ctx->writable_ssbos[shader] & BITFIELD64_BIT(slot)) != 0;
3939          num_rebinds++;
3940       }
3941    }
3942    rebind_mask &= ~BITFIELD_RANGE(TC_BINDING_SSBO_VS, PIPE_SHADER_TYPES);
3943    if (num_rebinds && expected_num_rebinds >= num_rebinds && !rebind_mask)
3944       goto end;
3945    const unsigned sampler_mask = rebind_mask ?
3946                                  rebind_mask & BITFIELD_RANGE(TC_BINDING_SAMPLERVIEW_VS, PIPE_SHADER_TYPES) :
3947                                  BITFIELD_RANGE(TC_BINDING_SAMPLERVIEW_VS, PIPE_SHADER_TYPES);
3948    u_foreach_bit(shader, sampler_mask >> TC_BINDING_SAMPLERVIEW_VS) {
3949       u_foreach_bit(slot, res->sampler_binds[shader]) {
3950          struct zink_sampler_view *sampler_view = zink_sampler_view(ctx->sampler_views[shader][slot]);
3951          if (&res->base.b != sampler_view->base.texture) //wrong context
3952             goto end;
3953          rebind_tbo(ctx, shader, slot);
3954          num_rebinds++;
3955       }
3956    }
3957    rebind_mask &= ~BITFIELD_RANGE(TC_BINDING_SAMPLERVIEW_VS, PIPE_SHADER_TYPES);
3958    if (num_rebinds && expected_num_rebinds >= num_rebinds && !rebind_mask)
3959       goto end;
3960 
3961    const unsigned image_mask = rebind_mask ?
3962                                rebind_mask & BITFIELD_RANGE(TC_BINDING_IMAGE_VS, PIPE_SHADER_TYPES) :
3963                                BITFIELD_RANGE(TC_BINDING_IMAGE_VS, PIPE_SHADER_TYPES);
3964    unsigned num_image_rebinds_remaining = rebind_mask ? expected_num_rebinds - num_rebinds : res->image_bind_count[0] + res->image_bind_count[1];
3965    u_foreach_bit(shader, image_mask >> TC_BINDING_IMAGE_VS) {
3966       for (unsigned slot = 0; num_image_rebinds_remaining && slot < ctx->di.num_images[shader]; slot++) {
3967          struct zink_resource *cres = ctx->di.descriptor_res[ZINK_DESCRIPTOR_TYPE_IMAGE][shader][slot];
3968          if (res != cres)
3969             continue;
3970 
3971          rebind_ibo(ctx, shader, slot);
3972          const struct zink_image_view *image_view = &ctx->image_views[shader][slot];
3973          has_write |= (image_view->base.access & PIPE_IMAGE_ACCESS_WRITE) != 0;
3974          num_image_rebinds_remaining--;
3975          num_rebinds++;
3976       }
3977    }
3978 end:
3979    if (num_rebinds)
3980       zink_batch_resource_usage_set(&ctx->batch, res, has_write);
3981    return num_rebinds;
3982 }
3983 
3984 void
zink_copy_buffer(struct zink_context * ctx,struct zink_resource * dst,struct zink_resource * src,unsigned dst_offset,unsigned src_offset,unsigned size)3985 zink_copy_buffer(struct zink_context *ctx, struct zink_resource *dst, struct zink_resource *src,
3986                  unsigned dst_offset, unsigned src_offset, unsigned size)
3987 {
3988    VkBufferCopy region;
3989    region.srcOffset = src_offset;
3990    region.dstOffset = dst_offset;
3991    region.size = size;
3992 
3993    struct zink_batch *batch = &ctx->batch;
3994    util_range_add(&dst->base.b, &dst->valid_buffer_range, dst_offset, dst_offset + size);
3995    zink_resource_buffer_barrier(ctx, src, VK_ACCESS_TRANSFER_READ_BIT, 0);
3996    zink_resource_buffer_barrier(ctx, dst, VK_ACCESS_TRANSFER_WRITE_BIT, 0);
3997    VkCommandBuffer cmdbuf = zink_get_cmdbuf(ctx, src, dst);
3998    zink_batch_reference_resource_rw(batch, src, false);
3999    zink_batch_reference_resource_rw(batch, dst, true);
4000    VKCTX(CmdCopyBuffer)(cmdbuf, src->obj->buffer, dst->obj->buffer, 1, &region);
4001 }
4002 
4003 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)4004 zink_copy_image_buffer(struct zink_context *ctx, struct zink_resource *dst, struct zink_resource *src,
4005                        unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz,
4006                        unsigned src_level, const struct pipe_box *src_box, enum pipe_map_flags map_flags)
4007 {
4008    struct zink_resource *img = dst->base.b.target == PIPE_BUFFER ? src : dst;
4009    struct zink_resource *buf = dst->base.b.target == PIPE_BUFFER ? dst : src;
4010    struct zink_batch *batch = &ctx->batch;
4011    bool needs_present_readback = false;
4012 
4013    bool buf2img = buf == src;
4014 
4015    if (buf2img) {
4016       if (zink_is_swapchain(img)) {
4017          if (!zink_kopper_acquire(ctx, img, UINT64_MAX))
4018             return;
4019       }
4020       zink_resource_image_barrier(ctx, img, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, 0);
4021       zink_resource_buffer_barrier(ctx, buf, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
4022    } else {
4023       if (zink_is_swapchain(img))
4024          needs_present_readback = zink_kopper_acquire_readback(ctx, img);
4025       zink_resource_image_barrier(ctx, img, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 0, 0);
4026       zink_resource_buffer_barrier(ctx, buf, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
4027       util_range_add(&dst->base.b, &dst->valid_buffer_range, dstx, dstx + src_box->width);
4028    }
4029 
4030    VkBufferImageCopy region = {0};
4031    region.bufferOffset = buf2img ? src_box->x : dstx;
4032    region.bufferRowLength = 0;
4033    region.bufferImageHeight = 0;
4034    region.imageSubresource.mipLevel = buf2img ? dst_level : src_level;
4035    enum pipe_texture_target img_target = img->base.b.target;
4036    if (img->need_2D)
4037       img_target = img_target == PIPE_TEXTURE_1D ? PIPE_TEXTURE_2D : PIPE_TEXTURE_2D_ARRAY;
4038    switch (img_target) {
4039    case PIPE_TEXTURE_CUBE:
4040    case PIPE_TEXTURE_CUBE_ARRAY:
4041    case PIPE_TEXTURE_2D_ARRAY:
4042    case PIPE_TEXTURE_1D_ARRAY:
4043       /* these use layer */
4044       region.imageSubresource.baseArrayLayer = buf2img ? dstz : src_box->z;
4045       region.imageSubresource.layerCount = src_box->depth;
4046       region.imageOffset.z = 0;
4047       region.imageExtent.depth = 1;
4048       break;
4049    case PIPE_TEXTURE_3D:
4050       /* this uses depth */
4051       region.imageSubresource.baseArrayLayer = 0;
4052       region.imageSubresource.layerCount = 1;
4053       region.imageOffset.z = buf2img ? dstz : src_box->z;
4054       region.imageExtent.depth = src_box->depth;
4055       break;
4056    default:
4057       /* these must only copy one layer */
4058       region.imageSubresource.baseArrayLayer = 0;
4059       region.imageSubresource.layerCount = 1;
4060       region.imageOffset.z = 0;
4061       region.imageExtent.depth = 1;
4062    }
4063    region.imageOffset.x = buf2img ? dstx : src_box->x;
4064    region.imageOffset.y = buf2img ? dsty : src_box->y;
4065 
4066    region.imageExtent.width = src_box->width;
4067    region.imageExtent.height = src_box->height;
4068 
4069    /* never promote to unordered if swapchain was acquired */
4070    VkCommandBuffer cmdbuf = needs_present_readback ?
4071                             ctx->batch.state->cmdbuf :
4072                             buf2img ? zink_get_cmdbuf(ctx, buf, img) : zink_get_cmdbuf(ctx, img, buf);
4073    zink_batch_reference_resource_rw(batch, img, buf2img);
4074    zink_batch_reference_resource_rw(batch, buf, !buf2img);
4075 
4076    /* we're using u_transfer_helper_deinterleave, which means we'll be getting PIPE_MAP_* usage
4077     * to indicate whether to copy either the depth or stencil aspects
4078     */
4079    unsigned aspects = 0;
4080    if (map_flags) {
4081       assert((map_flags & (PIPE_MAP_DEPTH_ONLY | PIPE_MAP_STENCIL_ONLY)) !=
4082              (PIPE_MAP_DEPTH_ONLY | PIPE_MAP_STENCIL_ONLY));
4083       if (map_flags & PIPE_MAP_DEPTH_ONLY)
4084          aspects = VK_IMAGE_ASPECT_DEPTH_BIT;
4085       else if (map_flags & PIPE_MAP_STENCIL_ONLY)
4086          aspects = VK_IMAGE_ASPECT_STENCIL_BIT;
4087    }
4088    if (!aspects)
4089       aspects = img->aspect;
4090    while (aspects) {
4091       int aspect = 1 << u_bit_scan(&aspects);
4092       region.imageSubresource.aspectMask = aspect;
4093 
4094       /* this may or may not work with multisampled depth/stencil buffers depending on the driver implementation:
4095        *
4096        * srcImage must have a sample count equal to VK_SAMPLE_COUNT_1_BIT
4097        * - vkCmdCopyImageToBuffer spec
4098        *
4099        * dstImage must have a sample count equal to VK_SAMPLE_COUNT_1_BIT
4100        * - vkCmdCopyBufferToImage spec
4101        */
4102       if (buf2img)
4103          VKCTX(CmdCopyBufferToImage)(cmdbuf, buf->obj->buffer, img->obj->image, img->layout, 1, &region);
4104       else
4105          VKCTX(CmdCopyImageToBuffer)(cmdbuf, img->obj->image, img->layout, buf->obj->buffer, 1, &region);
4106    }
4107    if (needs_present_readback)
4108       zink_kopper_present_readback(ctx, img);
4109 }
4110 
4111 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)4112 zink_resource_copy_region(struct pipe_context *pctx,
4113                           struct pipe_resource *pdst,
4114                           unsigned dst_level, unsigned dstx, unsigned dsty, unsigned dstz,
4115                           struct pipe_resource *psrc,
4116                           unsigned src_level, const struct pipe_box *src_box)
4117 {
4118    struct zink_resource *dst = zink_resource(pdst);
4119    struct zink_resource *src = zink_resource(psrc);
4120    struct zink_context *ctx = zink_context(pctx);
4121    if (dst->base.b.target != PIPE_BUFFER && src->base.b.target != PIPE_BUFFER) {
4122       VkImageCopy region = {0};
4123       if (util_format_get_num_planes(src->base.b.format) == 1 &&
4124           util_format_get_num_planes(dst->base.b.format) == 1) {
4125       /* If neither the calling command’s srcImage nor the calling command’s dstImage
4126        * has a multi-planar image format then the aspectMask member of srcSubresource
4127        * and dstSubresource must match
4128        *
4129        * -VkImageCopy spec
4130        */
4131          assert(src->aspect == dst->aspect);
4132       } else
4133          unreachable("planar formats not yet handled");
4134 
4135       zink_fb_clears_apply_or_discard(ctx, pdst, (struct u_rect){dstx, dstx + src_box->width, dsty, dsty + src_box->height}, false);
4136       zink_fb_clears_apply_region(ctx, psrc, zink_rect_from_box(src_box));
4137 
4138       region.srcSubresource.aspectMask = src->aspect;
4139       region.srcSubresource.mipLevel = src_level;
4140       enum pipe_texture_target src_target = src->base.b.target;
4141       if (src->need_2D)
4142          src_target = src_target == PIPE_TEXTURE_1D ? PIPE_TEXTURE_2D : PIPE_TEXTURE_2D_ARRAY;
4143       switch (src_target) {
4144       case PIPE_TEXTURE_CUBE:
4145       case PIPE_TEXTURE_CUBE_ARRAY:
4146       case PIPE_TEXTURE_2D_ARRAY:
4147       case PIPE_TEXTURE_1D_ARRAY:
4148          /* these use layer */
4149          region.srcSubresource.baseArrayLayer = src_box->z;
4150          region.srcSubresource.layerCount = src_box->depth;
4151          region.srcOffset.z = 0;
4152          region.extent.depth = 1;
4153          break;
4154       case PIPE_TEXTURE_3D:
4155          /* this uses depth */
4156          region.srcSubresource.baseArrayLayer = 0;
4157          region.srcSubresource.layerCount = 1;
4158          region.srcOffset.z = src_box->z;
4159          region.extent.depth = src_box->depth;
4160          break;
4161       default:
4162          /* these must only copy one layer */
4163          region.srcSubresource.baseArrayLayer = 0;
4164          region.srcSubresource.layerCount = 1;
4165          region.srcOffset.z = 0;
4166          region.extent.depth = 1;
4167       }
4168 
4169       region.srcOffset.x = src_box->x;
4170       region.srcOffset.y = src_box->y;
4171 
4172       region.dstSubresource.aspectMask = dst->aspect;
4173       region.dstSubresource.mipLevel = dst_level;
4174       enum pipe_texture_target dst_target = dst->base.b.target;
4175       if (dst->need_2D)
4176          dst_target = dst_target == PIPE_TEXTURE_1D ? PIPE_TEXTURE_2D : PIPE_TEXTURE_2D_ARRAY;
4177       switch (dst_target) {
4178       case PIPE_TEXTURE_CUBE:
4179       case PIPE_TEXTURE_CUBE_ARRAY:
4180       case PIPE_TEXTURE_2D_ARRAY:
4181       case PIPE_TEXTURE_1D_ARRAY:
4182          /* these use layer */
4183          region.dstSubresource.baseArrayLayer = dstz;
4184          region.dstSubresource.layerCount = src_box->depth;
4185          region.dstOffset.z = 0;
4186          break;
4187       case PIPE_TEXTURE_3D:
4188          /* this uses depth */
4189          region.dstSubresource.baseArrayLayer = 0;
4190          region.dstSubresource.layerCount = 1;
4191          region.dstOffset.z = dstz;
4192          break;
4193       default:
4194          /* these must only copy one layer */
4195          region.dstSubresource.baseArrayLayer = 0;
4196          region.dstSubresource.layerCount = 1;
4197          region.dstOffset.z = 0;
4198       }
4199 
4200       region.dstOffset.x = dstx;
4201       region.dstOffset.y = dsty;
4202       region.extent.width = src_box->width;
4203       region.extent.height = src_box->height;
4204 
4205       struct zink_batch *batch = &ctx->batch;
4206       zink_resource_setup_transfer_layouts(ctx, src, dst);
4207       VkCommandBuffer cmdbuf = zink_get_cmdbuf(ctx, src, dst);
4208       zink_batch_reference_resource_rw(batch, src, false);
4209       zink_batch_reference_resource_rw(batch, dst, true);
4210 
4211       VKCTX(CmdCopyImage)(cmdbuf, src->obj->image, src->layout,
4212                      dst->obj->image, dst->layout,
4213                      1, &region);
4214    } else if (dst->base.b.target == PIPE_BUFFER &&
4215               src->base.b.target == PIPE_BUFFER) {
4216       zink_copy_buffer(ctx, dst, src, dstx, src_box->x, src_box->width);
4217    } else
4218       zink_copy_image_buffer(ctx, dst, src, dst_level, dstx, dsty, dstz, src_level, src_box, 0);
4219 }
4220 
4221 static bool
zink_resource_commit(struct pipe_context * pctx,struct pipe_resource * pres,unsigned level,struct pipe_box * box,bool commit)4222 zink_resource_commit(struct pipe_context *pctx, struct pipe_resource *pres, unsigned level, struct pipe_box *box, bool commit)
4223 {
4224    struct zink_context *ctx = zink_context(pctx);
4225    struct zink_resource *res = zink_resource(pres);
4226    struct zink_screen *screen = zink_screen(pctx->screen);
4227 
4228    /* if any current usage exists, flush the queue */
4229    if (zink_resource_has_unflushed_usage(res))
4230       zink_flush_queue(ctx);
4231 
4232    VkSemaphore sem = VK_NULL_HANDLE;
4233    bool ret = zink_bo_commit(screen, res, level, box, commit, &sem);
4234    if (ret) {
4235       if (sem)
4236          zink_batch_add_wait_semaphore(&ctx->batch, sem);
4237    } else {
4238       check_device_lost(ctx);
4239    }
4240 
4241    return ret;
4242 }
4243 
4244 static void
rebind_image(struct zink_context * ctx,struct zink_resource * res)4245 rebind_image(struct zink_context *ctx, struct zink_resource *res)
4246 {
4247     zink_rebind_framebuffer(ctx, res);
4248     if (!zink_resource_has_binds(res))
4249        return;
4250     for (unsigned i = 0; i < PIPE_SHADER_TYPES; i++) {
4251        if (res->sampler_binds[i]) {
4252           for (unsigned j = 0; j < ctx->di.num_sampler_views[i]; j++) {
4253              struct zink_sampler_view *sv = zink_sampler_view(ctx->sampler_views[i][j]);
4254              if (sv && sv->base.texture == &res->base.b) {
4255                  struct pipe_surface *psurf = &sv->image_view->base;
4256                  zink_rebind_surface(ctx, &psurf);
4257                  sv->image_view = zink_surface(psurf);
4258                  zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, j, 1);
4259                  update_descriptor_state_sampler(ctx, i, j, res);
4260              }
4261           }
4262        }
4263        if (!res->image_bind_count[i == PIPE_SHADER_COMPUTE])
4264           continue;
4265        for (unsigned j = 0; j < ctx->di.num_images[i]; j++) {
4266           if (zink_resource(ctx->image_views[i][j].base.resource) == res) {
4267              zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_IMAGE, j, 1);
4268              update_descriptor_state_image(ctx, i, j, res);
4269              _mesa_set_add(ctx->need_barriers[i == PIPE_SHADER_COMPUTE], res);
4270           }
4271        }
4272     }
4273 }
4274 
4275 bool
zink_resource_rebind(struct zink_context * ctx,struct zink_resource * res)4276 zink_resource_rebind(struct zink_context *ctx, struct zink_resource *res)
4277 {
4278    if (res->base.b.target == PIPE_BUFFER) {
4279       /* force counter buffer reset */
4280       res->so_valid = false;
4281       return rebind_buffer(ctx, res, 0, 0) == res->bind_count[0] + res->bind_count[1];
4282    }
4283    rebind_image(ctx, res);
4284    return false;
4285 }
4286 
4287 void
zink_rebind_all_buffers(struct zink_context * ctx)4288 zink_rebind_all_buffers(struct zink_context *ctx)
4289 {
4290    struct zink_batch *batch = &ctx->batch;
4291    ctx->vertex_buffers_dirty = ctx->gfx_pipeline_state.vertex_buffers_enabled_mask > 0;
4292    ctx->dirty_so_targets = ctx->num_so_targets > 0;
4293    if (ctx->num_so_targets)
4294       zink_resource_buffer_barrier(ctx, zink_resource(ctx->dummy_xfb_buffer),
4295                                    VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT);
4296    for (unsigned shader = PIPE_SHADER_VERTEX; shader < PIPE_SHADER_TYPES; shader++) {
4297       for (unsigned slot = 0; slot < ctx->di.num_ubos[shader]; slot++) {
4298          struct zink_resource *res = rebind_ubo(ctx, shader, slot);
4299          if (res)
4300             zink_batch_resource_usage_set(batch, res, false);
4301       }
4302       for (unsigned slot = 0; slot < ctx->di.num_sampler_views[shader]; slot++) {
4303          struct zink_resource *res = rebind_tbo(ctx, shader, slot);
4304          if (res)
4305             zink_batch_resource_usage_set(batch, res, false);
4306       }
4307       for (unsigned slot = 0; slot < ctx->di.num_ssbos[shader]; slot++) {
4308          struct zink_resource *res = rebind_ssbo(ctx, shader, slot);
4309          if (res)
4310             zink_batch_resource_usage_set(batch, res, (ctx->writable_ssbos[shader] & BITFIELD64_BIT(slot)) != 0);
4311       }
4312       for (unsigned slot = 0; slot < ctx->di.num_images[shader]; slot++) {
4313          struct zink_resource *res = rebind_ibo(ctx, shader, slot);
4314          if (res)
4315             zink_batch_resource_usage_set(batch, res, (ctx->image_views[shader][slot].base.access & PIPE_IMAGE_ACCESS_WRITE) != 0);
4316       }
4317    }
4318 }
4319 
4320 void
zink_rebind_all_images(struct zink_context * ctx)4321 zink_rebind_all_images(struct zink_context *ctx)
4322 {
4323    rebind_fb_state(ctx, NULL, false);
4324     for (unsigned i = 0; i < PIPE_SHADER_TYPES; i++) {
4325       for (unsigned j = 0; j < ctx->di.num_sampler_views[i]; j++) {
4326          struct zink_sampler_view *sv = zink_sampler_view(ctx->sampler_views[i][j]);
4327          if (!sv)
4328             continue;
4329          struct zink_resource *res = zink_resource(sv->image_view->base.texture);
4330          if (res->obj != sv->image_view->obj) {
4331              struct pipe_surface *psurf = &sv->image_view->base;
4332              zink_rebind_surface(ctx, &psurf);
4333              sv->image_view = zink_surface(psurf);
4334              zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, j, 1);
4335              update_descriptor_state_sampler(ctx, i, j, res);
4336          }
4337       }
4338       for (unsigned j = 0; j < ctx->di.num_images[i]; j++) {
4339          struct zink_image_view *image_view = &ctx->image_views[i][j];
4340          struct zink_resource *res = zink_resource(image_view->base.resource);
4341          if (!res)
4342             continue;
4343          if (ctx->image_views[i][j].surface->obj != res->obj) {
4344             zink_surface_reference(zink_screen(ctx->base.screen), &image_view->surface, NULL);
4345             image_view->surface = create_image_surface(ctx, &image_view->base, i == PIPE_SHADER_COMPUTE);
4346             zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, i, ZINK_DESCRIPTOR_TYPE_IMAGE, j, 1);
4347             update_descriptor_state_image(ctx, i, j, res);
4348             _mesa_set_add(ctx->need_barriers[i == PIPE_SHADER_COMPUTE], res);
4349          }
4350       }
4351    }
4352 }
4353 
4354 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)4355 zink_context_replace_buffer_storage(struct pipe_context *pctx, struct pipe_resource *dst,
4356                                     struct pipe_resource *src, unsigned num_rebinds,
4357                                     uint32_t rebind_mask, uint32_t delete_buffer_id)
4358 {
4359    struct zink_resource *d = zink_resource(dst);
4360    struct zink_resource *s = zink_resource(src);
4361    struct zink_context *ctx = zink_context(pctx);
4362    struct zink_screen *screen = zink_screen(pctx->screen);
4363 
4364    assert(d->internal_format == s->internal_format);
4365    assert(d->obj);
4366    assert(s->obj);
4367    util_idalloc_mt_free(&screen->buffer_ids, delete_buffer_id);
4368    zink_descriptor_set_refs_clear(&d->obj->desc_set_refs, d->obj);
4369    /* add a ref just like check_resource_for_batch_ref() would've */
4370    if (zink_resource_has_binds(d) && zink_resource_has_usage(d))
4371       zink_batch_reference_resource(&ctx->batch, d);
4372    /* don't be too creative */
4373    zink_resource_object_reference(screen, &d->obj, s->obj);
4374    /* force counter buffer reset */
4375    d->so_valid = false;
4376    if (num_rebinds && rebind_buffer(ctx, d, rebind_mask, num_rebinds) < num_rebinds)
4377       ctx->buffer_rebind_counter = p_atomic_inc_return(&screen->buffer_rebind_counter);
4378 }
4379 
4380 static bool
zink_context_is_resource_busy(struct pipe_screen * pscreen,struct pipe_resource * pres,unsigned usage)4381 zink_context_is_resource_busy(struct pipe_screen *pscreen, struct pipe_resource *pres, unsigned usage)
4382 {
4383    struct zink_screen *screen = zink_screen(pscreen);
4384    struct zink_resource *res = zink_resource(pres);
4385    uint32_t check_usage = 0;
4386    if (usage & PIPE_MAP_READ)
4387       check_usage |= ZINK_RESOURCE_ACCESS_WRITE;
4388    if (usage & PIPE_MAP_WRITE)
4389       check_usage |= ZINK_RESOURCE_ACCESS_RW;
4390    return !zink_resource_usage_check_completion(screen, res, check_usage);
4391 }
4392 
4393 static void
zink_emit_string_marker(struct pipe_context * pctx,const char * string,int len)4394 zink_emit_string_marker(struct pipe_context *pctx,
4395                         const char *string, int len)
4396 {
4397    struct zink_screen *screen = zink_screen(pctx->screen);
4398    struct zink_batch *batch = &zink_context(pctx)->batch;
4399 
4400    /* make sure string is nul-terminated */
4401    char buf[512], *temp = NULL;
4402    if (len < ARRAY_SIZE(buf)) {
4403       memcpy(buf, string, len);
4404       buf[len] = '\0';
4405       string = buf;
4406    } else
4407       string = temp = strndup(string, len);
4408 
4409    VkDebugUtilsLabelEXT label = {
4410       VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, NULL,
4411       string,
4412       { 0 }
4413    };
4414    screen->vk.CmdInsertDebugUtilsLabelEXT(batch->state->cmdbuf, &label);
4415    free(temp);
4416 }
4417 
4418 struct pipe_context *
zink_context_create(struct pipe_screen * pscreen,void * priv,unsigned flags)4419 zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
4420 {
4421    struct zink_screen *screen = zink_screen(pscreen);
4422    struct zink_context *ctx = rzalloc(NULL, struct zink_context);
4423    bool is_copy_only = (flags & ZINK_CONTEXT_COPY_ONLY) > 0;
4424    if (!ctx)
4425       goto fail;
4426 
4427    ctx->flags = flags;
4428    ctx->pipeline_changed[0] = ctx->pipeline_changed[1] = true;
4429    ctx->gfx_pipeline_state.dirty = true;
4430    ctx->gfx_pipeline_state.dyn_state2.vertices_per_patch = 1;
4431    ctx->gfx_pipeline_state.uses_dynamic_stride = screen->info.have_EXT_extended_dynamic_state ||
4432                                                  screen->info.have_EXT_vertex_input_dynamic_state;
4433    ctx->compute_pipeline_state.dirty = true;
4434    ctx->fb_changed = ctx->rp_changed = true;
4435    ctx->gfx_pipeline_state.gfx_prim_mode = PIPE_PRIM_MAX;
4436 
4437    zink_init_draw_functions(ctx, screen);
4438    zink_init_grid_functions(ctx);
4439 
4440    ctx->base.screen = pscreen;
4441    ctx->base.priv = priv;
4442 
4443    ctx->base.destroy = zink_context_destroy;
4444    ctx->base.get_device_reset_status = zink_get_device_reset_status;
4445    ctx->base.set_device_reset_callback = zink_set_device_reset_callback;
4446 
4447    zink_context_state_init(&ctx->base);
4448 
4449    ctx->base.create_sampler_state = zink_create_sampler_state;
4450    ctx->base.bind_sampler_states = zink_bind_sampler_states;
4451    ctx->base.delete_sampler_state = zink_delete_sampler_state;
4452 
4453    ctx->base.create_sampler_view = zink_create_sampler_view;
4454    ctx->base.set_sampler_views = zink_set_sampler_views;
4455    ctx->base.sampler_view_destroy = zink_sampler_view_destroy;
4456    ctx->base.get_sample_position = zink_get_sample_position;
4457    ctx->base.set_sample_locations = zink_set_sample_locations;
4458 
4459    zink_program_init(ctx);
4460 
4461    ctx->base.set_polygon_stipple = zink_set_polygon_stipple;
4462    ctx->base.set_vertex_buffers = zink_set_vertex_buffers;
4463    ctx->base.set_viewport_states = zink_set_viewport_states;
4464    ctx->base.set_scissor_states = zink_set_scissor_states;
4465    ctx->base.set_inlinable_constants = zink_set_inlinable_constants;
4466    ctx->base.set_constant_buffer = zink_set_constant_buffer;
4467    ctx->base.set_shader_buffers = zink_set_shader_buffers;
4468    ctx->base.set_shader_images = zink_set_shader_images;
4469    ctx->base.set_framebuffer_state = zink_set_framebuffer_state;
4470    ctx->base.set_stencil_ref = zink_set_stencil_ref;
4471    ctx->base.set_clip_state = zink_set_clip_state;
4472    ctx->base.set_blend_color = zink_set_blend_color;
4473    ctx->base.set_tess_state = zink_set_tess_state;
4474    ctx->base.set_patch_vertices = zink_set_patch_vertices;
4475 
4476    ctx->base.set_sample_mask = zink_set_sample_mask;
4477    ctx->gfx_pipeline_state.sample_mask = UINT32_MAX;
4478 
4479    ctx->base.clear = zink_clear;
4480    ctx->base.clear_texture = zink_clear_texture;
4481    ctx->base.clear_buffer = zink_clear_buffer;
4482    ctx->base.clear_render_target = zink_clear_render_target;
4483    ctx->base.clear_depth_stencil = zink_clear_depth_stencil;
4484 
4485    ctx->base.create_fence_fd = zink_create_fence_fd;
4486    ctx->base.fence_server_sync = zink_fence_server_sync;
4487    ctx->base.fence_server_signal = zink_fence_server_signal;
4488    ctx->base.flush = zink_flush;
4489    ctx->base.memory_barrier = zink_memory_barrier;
4490    ctx->base.texture_barrier = zink_texture_barrier;
4491    ctx->base.evaluate_depth_buffer = zink_evaluate_depth_buffer;
4492 
4493    ctx->base.resource_commit = zink_resource_commit;
4494    ctx->base.resource_copy_region = zink_resource_copy_region;
4495    ctx->base.blit = zink_blit;
4496    ctx->base.create_stream_output_target = zink_create_stream_output_target;
4497    ctx->base.stream_output_target_destroy = zink_stream_output_target_destroy;
4498 
4499    ctx->base.set_stream_output_targets = zink_set_stream_output_targets;
4500    ctx->base.flush_resource = zink_flush_resource;
4501 
4502    ctx->base.emit_string_marker = zink_emit_string_marker;
4503 
4504    zink_context_surface_init(&ctx->base);
4505    zink_context_resource_init(&ctx->base);
4506    zink_context_query_init(&ctx->base);
4507 
4508    list_inithead(&ctx->query_pools);
4509    _mesa_set_init(&ctx->update_barriers[0][0], ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);
4510    _mesa_set_init(&ctx->update_barriers[1][0], ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);
4511    _mesa_set_init(&ctx->update_barriers[0][1], ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);
4512    _mesa_set_init(&ctx->update_barriers[1][1], ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);
4513    ctx->need_barriers[0] = &ctx->update_barriers[0][0];
4514    ctx->need_barriers[1] = &ctx->update_barriers[1][0];
4515 
4516    util_dynarray_init(&ctx->free_batch_states, ctx);
4517 
4518    ctx->gfx_pipeline_state.have_EXT_extended_dynamic_state = screen->info.have_EXT_extended_dynamic_state;
4519    ctx->gfx_pipeline_state.have_EXT_extended_dynamic_state2 = screen->info.have_EXT_extended_dynamic_state2;
4520    ctx->gfx_pipeline_state.extendedDynamicState2PatchControlPoints = screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints;
4521 
4522    slab_create_child(&ctx->transfer_pool, &screen->transfer_pool);
4523    slab_create_child(&ctx->transfer_pool_unsync, &screen->transfer_pool);
4524 
4525    ctx->base.stream_uploader = u_upload_create_default(&ctx->base);
4526    ctx->base.const_uploader = u_upload_create_default(&ctx->base);
4527    for (int i = 0; i < ARRAY_SIZE(ctx->fb_clears); i++)
4528       util_dynarray_init(&ctx->fb_clears[i].clears, ctx);
4529 
4530    if (!is_copy_only) {
4531       ctx->blitter = util_blitter_create(&ctx->base);
4532       if (!ctx->blitter)
4533          goto fail;
4534    }
4535 
4536    ctx->gfx_pipeline_state.shader_keys.last_vertex.key.vs_base.last_vertex_stage = true;
4537    ctx->last_vertex_stage_dirty = true;
4538    ctx->gfx_pipeline_state.shader_keys.key[PIPE_SHADER_TESS_CTRL].key.tcs.patch_vertices = 1;
4539    ctx->gfx_pipeline_state.shader_keys.key[PIPE_SHADER_VERTEX].size = sizeof(struct zink_vs_key_base);
4540    ctx->gfx_pipeline_state.shader_keys.key[PIPE_SHADER_TESS_EVAL].size = sizeof(struct zink_vs_key_base);
4541    ctx->gfx_pipeline_state.shader_keys.key[PIPE_SHADER_TESS_CTRL].size = sizeof(struct zink_tcs_key);
4542    ctx->gfx_pipeline_state.shader_keys.key[PIPE_SHADER_GEOMETRY].size = sizeof(struct zink_vs_key_base);
4543    ctx->gfx_pipeline_state.shader_keys.key[PIPE_SHADER_FRAGMENT].size = sizeof(struct zink_fs_key);
4544    _mesa_hash_table_init(&ctx->compute_program_cache, ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);
4545    _mesa_hash_table_init(&ctx->framebuffer_cache, ctx, hash_framebuffer_imageless, equals_framebuffer_imageless);
4546    if (!zink_init_render_pass(ctx))
4547       goto fail;
4548    _mesa_set_init(&ctx->rendering_state_cache, ctx, hash_rendering_state, equals_rendering_state);
4549    ctx->dynamic_fb.info.pColorAttachments = ctx->dynamic_fb.attachments;
4550    ctx->dynamic_fb.info.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
4551    for (unsigned i = 0; i < ARRAY_SIZE(ctx->dynamic_fb.attachments); i++) {
4552       VkRenderingAttachmentInfo *att = &ctx->dynamic_fb.attachments[i];
4553       att->sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
4554       att->imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
4555       att->storeOp = VK_ATTACHMENT_STORE_OP_STORE;
4556    }
4557    ctx->gfx_pipeline_state.rendering_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
4558    ctx->gfx_pipeline_state.rendering_info.pColorAttachmentFormats = ctx->gfx_pipeline_state.rendering_formats;
4559 
4560    const uint32_t data[] = {0};
4561    if (!is_copy_only) {
4562       ctx->dummy_vertex_buffer = pipe_buffer_create(&screen->base,
4563          PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_SHADER_IMAGE, PIPE_USAGE_IMMUTABLE, sizeof(data));
4564       if (!ctx->dummy_vertex_buffer)
4565          goto fail;
4566       ctx->dummy_xfb_buffer = pipe_buffer_create(&screen->base,
4567          PIPE_BIND_STREAM_OUTPUT, PIPE_USAGE_IMMUTABLE, sizeof(data));
4568       if (!ctx->dummy_xfb_buffer)
4569          goto fail;
4570       for (unsigned i = 0; i < ARRAY_SIZE(ctx->dummy_surface); i++) {
4571          if (!(screen->info.props.limits.framebufferDepthSampleCounts & BITFIELD_BIT(i)))
4572             continue;
4573          ctx->dummy_surface[i] = zink_surface_create_null(ctx, PIPE_TEXTURE_2D, 1024, 1024, BITFIELD_BIT(i));
4574          if (!ctx->dummy_surface[i])
4575             goto fail;
4576       }
4577       VkBufferViewCreateInfo bvci = create_bvci(ctx, zink_resource(ctx->dummy_vertex_buffer), PIPE_FORMAT_R8G8B8A8_UNORM, 0, sizeof(data));
4578       ctx->dummy_bufferview = get_buffer_view(ctx, zink_resource(ctx->dummy_vertex_buffer), &bvci);
4579       if (!ctx->dummy_bufferview)
4580          goto fail;
4581 
4582       if (!zink_descriptor_layouts_init(ctx))
4583          goto fail;
4584 
4585       if (!screen->descriptors_init(ctx)) {
4586          zink_screen_init_descriptor_funcs(screen, true);
4587          if (!screen->descriptors_init(ctx))
4588             goto fail;
4589       }
4590 
4591       ctx->base.create_texture_handle = zink_create_texture_handle;
4592       ctx->base.delete_texture_handle = zink_delete_texture_handle;
4593       ctx->base.make_texture_handle_resident = zink_make_texture_handle_resident;
4594       ctx->base.create_image_handle = zink_create_image_handle;
4595       ctx->base.delete_image_handle = zink_delete_image_handle;
4596       ctx->base.make_image_handle_resident = zink_make_image_handle_resident;
4597       for (unsigned i = 0; i < 2; i++) {
4598          _mesa_hash_table_init(&ctx->di.bindless[i].img_handles, ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);
4599          _mesa_hash_table_init(&ctx->di.bindless[i].tex_handles, ctx, _mesa_hash_pointer, _mesa_key_pointer_equal);
4600 
4601          /* allocate 1024 slots and reserve slot 0 */
4602          util_idalloc_init(&ctx->di.bindless[i].tex_slots, ZINK_MAX_BINDLESS_HANDLES);
4603          util_idalloc_alloc(&ctx->di.bindless[i].tex_slots);
4604          util_idalloc_init(&ctx->di.bindless[i].img_slots, ZINK_MAX_BINDLESS_HANDLES);
4605          util_idalloc_alloc(&ctx->di.bindless[i].img_slots);
4606          ctx->di.bindless[i].buffer_infos = malloc(sizeof(VkBufferView) * ZINK_MAX_BINDLESS_HANDLES);
4607          ctx->di.bindless[i].img_infos = malloc(sizeof(VkDescriptorImageInfo) * ZINK_MAX_BINDLESS_HANDLES);
4608          util_dynarray_init(&ctx->di.bindless[i].updates, NULL);
4609          util_dynarray_init(&ctx->di.bindless[i].resident, NULL);
4610       }
4611    }
4612 
4613    zink_start_batch(ctx, &ctx->batch);
4614    if (!ctx->batch.state)
4615       goto fail;
4616 
4617    if (!is_copy_only) {
4618       pipe_buffer_write_nooverlap(&ctx->base, ctx->dummy_vertex_buffer, 0, sizeof(data), data);
4619       pipe_buffer_write_nooverlap(&ctx->base, ctx->dummy_xfb_buffer, 0, sizeof(data), data);
4620 
4621       for (unsigned i = 0; i < PIPE_SHADER_TYPES; i++) {
4622          /* need to update these based on screen config for null descriptors */
4623          for (unsigned j = 0; j < 32; j++) {
4624             update_descriptor_state_ubo(ctx, i, j, NULL);
4625             update_descriptor_state_sampler(ctx, i, j, NULL);
4626             update_descriptor_state_ssbo(ctx, i, j, NULL);
4627             update_descriptor_state_image(ctx, i, j, NULL);
4628          }
4629       }
4630       if (!screen->info.rb2_feats.nullDescriptor)
4631          ctx->di.fbfetch.imageView = zink_csurface(ctx->dummy_surface[0])->image_view;
4632 
4633       reapply_color_write(ctx);
4634       p_atomic_inc(&screen->base.num_contexts);
4635    }
4636 
4637    zink_select_draw_vbo(ctx);
4638    zink_select_launch_grid(ctx);
4639 
4640    /* set on startup just to avoid validation errors if a draw comes through without
4641     * a tess shader later
4642     */
4643    if (screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints)
4644       VKCTX(CmdSetPatchControlPointsEXT)(ctx->batch.state->cmdbuf, 1);
4645 
4646    if (!(flags & PIPE_CONTEXT_PREFER_THREADED) || flags & PIPE_CONTEXT_COMPUTE_ONLY) {
4647       return &ctx->base;
4648    }
4649 
4650    struct threaded_context *tc = (struct threaded_context*)threaded_context_create(&ctx->base, &screen->transfer_pool,
4651                                                      zink_context_replace_buffer_storage,
4652                                                      &(struct threaded_context_options){
4653                                                         .create_fence = zink_create_tc_fence_for_tc,
4654                                                         .is_resource_busy = zink_context_is_resource_busy,
4655                                                         .driver_calls_flush_notify = true,
4656                                                         .unsynchronized_get_device_reset_status = true,
4657                                                      },
4658                                                      &ctx->tc);
4659 
4660    if (tc && (struct zink_context*)tc != ctx) {
4661       threaded_context_init_bytes_mapped_limit(tc, 4);
4662       ctx->base.set_context_param = zink_set_context_param;
4663    }
4664 
4665    return (struct pipe_context*)tc;
4666 
4667 fail:
4668    if (ctx)
4669       zink_context_destroy(&ctx->base);
4670    return NULL;
4671 }
4672 
4673 struct zink_context *
zink_tc_context_unwrap(struct pipe_context * pctx)4674 zink_tc_context_unwrap(struct pipe_context *pctx)
4675 {
4676    struct zink_context *ctx = zink_context(pctx);
4677    struct zink_screen *screen = zink_screen(ctx->base.screen);
4678    /* need to get the actual zink_context, not the threaded context */
4679    if (screen->threaded)
4680       pctx = threaded_context_unwrap_sync(pctx);
4681    pctx = trace_get_possibly_threaded_context(pctx);
4682    return zink_context(pctx);
4683 }
4684