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