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