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