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