1bf215546Sopenharmony_ci#include "zink_batch.h" 2bf215546Sopenharmony_ci 3bf215546Sopenharmony_ci#include "zink_context.h" 4bf215546Sopenharmony_ci#include "zink_kopper.h" 5bf215546Sopenharmony_ci#include "zink_fence.h" 6bf215546Sopenharmony_ci#include "zink_framebuffer.h" 7bf215546Sopenharmony_ci#include "zink_query.h" 8bf215546Sopenharmony_ci#include "zink_program.h" 9bf215546Sopenharmony_ci#include "zink_render_pass.h" 10bf215546Sopenharmony_ci#include "zink_resource.h" 11bf215546Sopenharmony_ci#include "zink_screen.h" 12bf215546Sopenharmony_ci#include "zink_surface.h" 13bf215546Sopenharmony_ci 14bf215546Sopenharmony_ci#include "util/hash_table.h" 15bf215546Sopenharmony_ci#include "util/u_debug.h" 16bf215546Sopenharmony_ci#include "util/set.h" 17bf215546Sopenharmony_ci 18bf215546Sopenharmony_ci#ifdef VK_USE_PLATFORM_METAL_EXT 19bf215546Sopenharmony_ci#include "QuartzCore/CAMetalLayer.h" 20bf215546Sopenharmony_ci#endif 21bf215546Sopenharmony_ci#include "wsi_common.h" 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_civoid 24bf215546Sopenharmony_cidebug_describe_zink_batch_state(char *buf, const struct zink_batch_state *ptr) 25bf215546Sopenharmony_ci{ 26bf215546Sopenharmony_ci sprintf(buf, "zink_batch_state"); 27bf215546Sopenharmony_ci} 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_civoid 30bf215546Sopenharmony_cizink_reset_batch_state(struct zink_context *ctx, struct zink_batch_state *bs) 31bf215546Sopenharmony_ci{ 32bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(ctx->base.screen); 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci VkResult result = VKSCR(ResetCommandPool)(screen->dev, bs->cmdpool, 0); 35bf215546Sopenharmony_ci if (result != VK_SUCCESS) 36bf215546Sopenharmony_ci mesa_loge("ZINK: vkResetCommandPool failed (%s)", vk_Result_to_str(result)); 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci /* unref all used resources */ 39bf215546Sopenharmony_ci set_foreach_remove(bs->resources, entry) { 40bf215546Sopenharmony_ci struct zink_resource_object *obj = (struct zink_resource_object *)entry->key; 41bf215546Sopenharmony_ci if (!zink_resource_object_usage_unset(obj, bs)) { 42bf215546Sopenharmony_ci obj->unordered_read = obj->unordered_write = false; 43bf215546Sopenharmony_ci obj->access = 0; 44bf215546Sopenharmony_ci obj->access_stage = 0; 45bf215546Sopenharmony_ci } 46bf215546Sopenharmony_ci util_dynarray_append(&bs->unref_resources, struct zink_resource_object*, obj); 47bf215546Sopenharmony_ci } 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci for (unsigned i = 0; i < 2; i++) { 50bf215546Sopenharmony_ci while (util_dynarray_contains(&bs->bindless_releases[i], uint32_t)) { 51bf215546Sopenharmony_ci uint32_t handle = util_dynarray_pop(&bs->bindless_releases[i], uint32_t); 52bf215546Sopenharmony_ci bool is_buffer = ZINK_BINDLESS_IS_BUFFER(handle); 53bf215546Sopenharmony_ci struct util_idalloc *ids = i ? &ctx->di.bindless[is_buffer].img_slots : &ctx->di.bindless[is_buffer].tex_slots; 54bf215546Sopenharmony_ci util_idalloc_free(ids, is_buffer ? handle - ZINK_MAX_BINDLESS_HANDLES : handle); 55bf215546Sopenharmony_ci } 56bf215546Sopenharmony_ci } 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci set_foreach_remove(bs->active_queries, entry) { 59bf215546Sopenharmony_ci struct zink_query *query = (void*)entry->key; 60bf215546Sopenharmony_ci zink_prune_query(screen, bs, query); 61bf215546Sopenharmony_ci } 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci set_foreach_remove(bs->surfaces, entry) { 64bf215546Sopenharmony_ci struct zink_surface *surf = (struct zink_surface *)entry->key; 65bf215546Sopenharmony_ci zink_batch_usage_unset(&surf->batch_uses, bs); 66bf215546Sopenharmony_ci zink_surface_reference(screen, &surf, NULL); 67bf215546Sopenharmony_ci } 68bf215546Sopenharmony_ci set_foreach_remove(bs->bufferviews, entry) { 69bf215546Sopenharmony_ci struct zink_buffer_view *buffer_view = (struct zink_buffer_view *)entry->key; 70bf215546Sopenharmony_ci zink_batch_usage_unset(&buffer_view->batch_uses, bs); 71bf215546Sopenharmony_ci zink_buffer_view_reference(screen, &buffer_view, NULL); 72bf215546Sopenharmony_ci } 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci util_dynarray_foreach(&bs->dead_framebuffers, struct zink_framebuffer*, fb) { 75bf215546Sopenharmony_ci zink_framebuffer_reference(screen, fb, NULL); 76bf215546Sopenharmony_ci } 77bf215546Sopenharmony_ci util_dynarray_clear(&bs->dead_framebuffers); 78bf215546Sopenharmony_ci util_dynarray_foreach(&bs->zombie_samplers, VkSampler, samp) { 79bf215546Sopenharmony_ci VKSCR(DestroySampler)(screen->dev, *samp, NULL); 80bf215546Sopenharmony_ci } 81bf215546Sopenharmony_ci util_dynarray_clear(&bs->zombie_samplers); 82bf215546Sopenharmony_ci util_dynarray_clear(&bs->persistent_resources); 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci screen->batch_descriptor_reset(screen, bs); 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci set_foreach_remove(bs->programs, entry) { 87bf215546Sopenharmony_ci struct zink_program *pg = (struct zink_program*)entry->key; 88bf215546Sopenharmony_ci zink_batch_usage_unset(&pg->batch_uses, bs); 89bf215546Sopenharmony_ci zink_program_reference(ctx, &pg, NULL); 90bf215546Sopenharmony_ci } 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci bs->resource_size = 0; 93bf215546Sopenharmony_ci bs->signal_semaphore = VK_NULL_HANDLE; 94bf215546Sopenharmony_ci while (util_dynarray_contains(&bs->wait_semaphores, VkSemaphore)) 95bf215546Sopenharmony_ci VKSCR(DestroySemaphore)(screen->dev, util_dynarray_pop(&bs->wait_semaphores, VkSemaphore), NULL); 96bf215546Sopenharmony_ci util_dynarray_clear(&bs->wait_semaphore_stages); 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci bs->present = VK_NULL_HANDLE; 99bf215546Sopenharmony_ci while (util_dynarray_contains(&bs->acquires, VkSemaphore)) 100bf215546Sopenharmony_ci VKSCR(DestroySemaphore)(screen->dev, util_dynarray_pop(&bs->acquires, VkSemaphore), NULL); 101bf215546Sopenharmony_ci bs->swapchain = NULL; 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci while (util_dynarray_contains(&bs->dead_swapchains, VkImageView)) 104bf215546Sopenharmony_ci VKSCR(DestroyImageView)(screen->dev, util_dynarray_pop(&bs->dead_swapchains, VkImageView), NULL); 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci /* only reset submitted here so that tc fence desync can pick up the 'completed' flag 107bf215546Sopenharmony_ci * before the state is reused 108bf215546Sopenharmony_ci */ 109bf215546Sopenharmony_ci bs->fence.submitted = false; 110bf215546Sopenharmony_ci bs->has_barriers = false; 111bf215546Sopenharmony_ci if (bs->fence.batch_id) 112bf215546Sopenharmony_ci zink_screen_update_last_finished(screen, bs->fence.batch_id); 113bf215546Sopenharmony_ci bs->submit_count++; 114bf215546Sopenharmony_ci bs->fence.batch_id = 0; 115bf215546Sopenharmony_ci bs->usage.usage = 0; 116bf215546Sopenharmony_ci bs->next = NULL; 117bf215546Sopenharmony_ci} 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_cistatic void 120bf215546Sopenharmony_ciunref_resources(struct zink_screen *screen, struct zink_batch_state *bs) 121bf215546Sopenharmony_ci{ 122bf215546Sopenharmony_ci while (util_dynarray_contains(&bs->unref_resources, struct zink_resource_object*)) { 123bf215546Sopenharmony_ci struct zink_resource_object *obj = util_dynarray_pop(&bs->unref_resources, struct zink_resource_object*); 124bf215546Sopenharmony_ci zink_resource_object_reference(screen, &obj, NULL); 125bf215546Sopenharmony_ci } 126bf215546Sopenharmony_ci} 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_civoid 129bf215546Sopenharmony_cizink_clear_batch_state(struct zink_context *ctx, struct zink_batch_state *bs) 130bf215546Sopenharmony_ci{ 131bf215546Sopenharmony_ci bs->fence.completed = true; 132bf215546Sopenharmony_ci zink_reset_batch_state(ctx, bs); 133bf215546Sopenharmony_ci unref_resources(zink_screen(ctx->base.screen), bs); 134bf215546Sopenharmony_ci} 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_cistatic void 137bf215546Sopenharmony_cipop_batch_state(struct zink_context *ctx) 138bf215546Sopenharmony_ci{ 139bf215546Sopenharmony_ci const struct zink_batch_state *bs = ctx->batch_states; 140bf215546Sopenharmony_ci ctx->batch_states = bs->next; 141bf215546Sopenharmony_ci ctx->batch_states_count--; 142bf215546Sopenharmony_ci if (ctx->last_fence == &bs->fence) 143bf215546Sopenharmony_ci ctx->last_fence = NULL; 144bf215546Sopenharmony_ci} 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_civoid 147bf215546Sopenharmony_cizink_batch_reset_all(struct zink_context *ctx) 148bf215546Sopenharmony_ci{ 149bf215546Sopenharmony_ci while (ctx->batch_states) { 150bf215546Sopenharmony_ci struct zink_batch_state *bs = ctx->batch_states; 151bf215546Sopenharmony_ci bs->fence.completed = true; 152bf215546Sopenharmony_ci pop_batch_state(ctx); 153bf215546Sopenharmony_ci zink_reset_batch_state(ctx, bs); 154bf215546Sopenharmony_ci util_dynarray_append(&ctx->free_batch_states, struct zink_batch_state *, bs); 155bf215546Sopenharmony_ci } 156bf215546Sopenharmony_ci} 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_civoid 159bf215546Sopenharmony_cizink_batch_state_destroy(struct zink_screen *screen, struct zink_batch_state *bs) 160bf215546Sopenharmony_ci{ 161bf215546Sopenharmony_ci if (!bs) 162bf215546Sopenharmony_ci return; 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci util_queue_fence_destroy(&bs->flush_completed); 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci cnd_destroy(&bs->usage.flush); 167bf215546Sopenharmony_ci mtx_destroy(&bs->usage.mtx); 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci if (bs->cmdbuf) 170bf215546Sopenharmony_ci VKSCR(FreeCommandBuffers)(screen->dev, bs->cmdpool, 1, &bs->cmdbuf); 171bf215546Sopenharmony_ci if (bs->barrier_cmdbuf) 172bf215546Sopenharmony_ci VKSCR(FreeCommandBuffers)(screen->dev, bs->cmdpool, 1, &bs->barrier_cmdbuf); 173bf215546Sopenharmony_ci if (bs->cmdpool) 174bf215546Sopenharmony_ci VKSCR(DestroyCommandPool)(screen->dev, bs->cmdpool, NULL); 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci util_dynarray_fini(&bs->zombie_samplers); 177bf215546Sopenharmony_ci util_dynarray_fini(&bs->dead_framebuffers); 178bf215546Sopenharmony_ci util_dynarray_fini(&bs->unref_resources); 179bf215546Sopenharmony_ci util_dynarray_fini(&bs->bindless_releases[0]); 180bf215546Sopenharmony_ci util_dynarray_fini(&bs->bindless_releases[1]); 181bf215546Sopenharmony_ci util_dynarray_fini(&bs->acquires); 182bf215546Sopenharmony_ci util_dynarray_fini(&bs->acquire_flags); 183bf215546Sopenharmony_ci util_dynarray_fini(&bs->dead_swapchains); 184bf215546Sopenharmony_ci _mesa_set_destroy(bs->surfaces, NULL); 185bf215546Sopenharmony_ci _mesa_set_destroy(bs->bufferviews, NULL); 186bf215546Sopenharmony_ci _mesa_set_destroy(bs->programs, NULL); 187bf215546Sopenharmony_ci _mesa_set_destroy(bs->active_queries, NULL); 188bf215546Sopenharmony_ci screen->batch_descriptor_deinit(screen, bs); 189bf215546Sopenharmony_ci ralloc_free(bs); 190bf215546Sopenharmony_ci} 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_cistatic struct zink_batch_state * 193bf215546Sopenharmony_cicreate_batch_state(struct zink_context *ctx) 194bf215546Sopenharmony_ci{ 195bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(ctx->base.screen); 196bf215546Sopenharmony_ci struct zink_batch_state *bs = rzalloc(NULL, struct zink_batch_state); 197bf215546Sopenharmony_ci VkCommandPoolCreateInfo cpci = {0}; 198bf215546Sopenharmony_ci cpci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 199bf215546Sopenharmony_ci cpci.queueFamilyIndex = screen->gfx_queue; 200bf215546Sopenharmony_ci VkResult result = VKSCR(CreateCommandPool)(screen->dev, &cpci, NULL, &bs->cmdpool); 201bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 202bf215546Sopenharmony_ci mesa_loge("ZINK: vkCreateCommandPool failed (%s)", vk_Result_to_str(result)); 203bf215546Sopenharmony_ci goto fail; 204bf215546Sopenharmony_ci } 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci VkCommandBufferAllocateInfo cbai = {0}; 207bf215546Sopenharmony_ci cbai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 208bf215546Sopenharmony_ci cbai.commandPool = bs->cmdpool; 209bf215546Sopenharmony_ci cbai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 210bf215546Sopenharmony_ci cbai.commandBufferCount = 1; 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_ci result = VKSCR(AllocateCommandBuffers)(screen->dev, &cbai, &bs->cmdbuf); 213bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 214bf215546Sopenharmony_ci mesa_loge("ZINK: vkAllocateCommandBuffers failed (%s)", vk_Result_to_str(result)); 215bf215546Sopenharmony_ci goto fail; 216bf215546Sopenharmony_ci } 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci result = VKSCR(AllocateCommandBuffers)(screen->dev, &cbai, &bs->barrier_cmdbuf); 219bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 220bf215546Sopenharmony_ci mesa_loge("ZINK: vkAllocateCommandBuffers failed (%s)", vk_Result_to_str(result)); 221bf215546Sopenharmony_ci goto fail; 222bf215546Sopenharmony_ci } 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci#define SET_CREATE_OR_FAIL(ptr) \ 225bf215546Sopenharmony_ci ptr = _mesa_pointer_set_create(bs); \ 226bf215546Sopenharmony_ci if (!ptr) \ 227bf215546Sopenharmony_ci goto fail 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ci bs->ctx = ctx; 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci SET_CREATE_OR_FAIL(bs->resources); 232bf215546Sopenharmony_ci SET_CREATE_OR_FAIL(bs->surfaces); 233bf215546Sopenharmony_ci SET_CREATE_OR_FAIL(bs->bufferviews); 234bf215546Sopenharmony_ci SET_CREATE_OR_FAIL(bs->programs); 235bf215546Sopenharmony_ci SET_CREATE_OR_FAIL(bs->active_queries); 236bf215546Sopenharmony_ci util_dynarray_init(&bs->wait_semaphores, NULL); 237bf215546Sopenharmony_ci util_dynarray_init(&bs->wait_semaphore_stages, NULL); 238bf215546Sopenharmony_ci util_dynarray_init(&bs->zombie_samplers, NULL); 239bf215546Sopenharmony_ci util_dynarray_init(&bs->dead_framebuffers, NULL); 240bf215546Sopenharmony_ci util_dynarray_init(&bs->persistent_resources, NULL); 241bf215546Sopenharmony_ci util_dynarray_init(&bs->unref_resources, NULL); 242bf215546Sopenharmony_ci util_dynarray_init(&bs->acquires, NULL); 243bf215546Sopenharmony_ci util_dynarray_init(&bs->acquire_flags, NULL); 244bf215546Sopenharmony_ci util_dynarray_init(&bs->dead_swapchains, NULL); 245bf215546Sopenharmony_ci util_dynarray_init(&bs->bindless_releases[0], NULL); 246bf215546Sopenharmony_ci util_dynarray_init(&bs->bindless_releases[1], NULL); 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci cnd_init(&bs->usage.flush); 249bf215546Sopenharmony_ci mtx_init(&bs->usage.mtx, mtx_plain); 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci if (!screen->batch_descriptor_init(screen, bs)) 252bf215546Sopenharmony_ci goto fail; 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci util_queue_fence_init(&bs->flush_completed); 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci return bs; 257bf215546Sopenharmony_cifail: 258bf215546Sopenharmony_ci zink_batch_state_destroy(screen, bs); 259bf215546Sopenharmony_ci return NULL; 260bf215546Sopenharmony_ci} 261bf215546Sopenharmony_ci 262bf215546Sopenharmony_cistatic inline bool 263bf215546Sopenharmony_cifind_unused_state(struct zink_batch_state *bs) 264bf215546Sopenharmony_ci{ 265bf215546Sopenharmony_ci struct zink_fence *fence = &bs->fence; 266bf215546Sopenharmony_ci /* we can't reset these from fence_finish because threads */ 267bf215546Sopenharmony_ci bool completed = p_atomic_read(&fence->completed); 268bf215546Sopenharmony_ci bool submitted = p_atomic_read(&fence->submitted); 269bf215546Sopenharmony_ci return submitted && completed; 270bf215546Sopenharmony_ci} 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_cistatic struct zink_batch_state * 273bf215546Sopenharmony_ciget_batch_state(struct zink_context *ctx, struct zink_batch *batch) 274bf215546Sopenharmony_ci{ 275bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(ctx->base.screen); 276bf215546Sopenharmony_ci struct zink_batch_state *bs = NULL; 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci if (util_dynarray_num_elements(&ctx->free_batch_states, struct zink_batch_state*)) 279bf215546Sopenharmony_ci bs = util_dynarray_pop(&ctx->free_batch_states, struct zink_batch_state*); 280bf215546Sopenharmony_ci if (!bs && ctx->batch_states) { 281bf215546Sopenharmony_ci /* states are stored sequentially, so if the first one doesn't work, none of them will */ 282bf215546Sopenharmony_ci if (zink_screen_check_last_finished(screen, ctx->batch_states->fence.batch_id) || 283bf215546Sopenharmony_ci find_unused_state(ctx->batch_states)) { 284bf215546Sopenharmony_ci bs = ctx->batch_states; 285bf215546Sopenharmony_ci pop_batch_state(ctx); 286bf215546Sopenharmony_ci } 287bf215546Sopenharmony_ci } 288bf215546Sopenharmony_ci if (bs) { 289bf215546Sopenharmony_ci zink_reset_batch_state(ctx, bs); 290bf215546Sopenharmony_ci } else { 291bf215546Sopenharmony_ci if (!batch->state) { 292bf215546Sopenharmony_ci /* this is batch init, so create a few more states for later use */ 293bf215546Sopenharmony_ci for (int i = 0; i < 3; i++) { 294bf215546Sopenharmony_ci struct zink_batch_state *state = create_batch_state(ctx); 295bf215546Sopenharmony_ci util_dynarray_append(&ctx->free_batch_states, struct zink_batch_state *, state); 296bf215546Sopenharmony_ci } 297bf215546Sopenharmony_ci } 298bf215546Sopenharmony_ci bs = create_batch_state(ctx); 299bf215546Sopenharmony_ci } 300bf215546Sopenharmony_ci return bs; 301bf215546Sopenharmony_ci} 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_civoid 304bf215546Sopenharmony_cizink_reset_batch(struct zink_context *ctx, struct zink_batch *batch) 305bf215546Sopenharmony_ci{ 306bf215546Sopenharmony_ci batch->state = get_batch_state(ctx, batch); 307bf215546Sopenharmony_ci assert(batch->state); 308bf215546Sopenharmony_ci 309bf215546Sopenharmony_ci batch->has_work = false; 310bf215546Sopenharmony_ci} 311bf215546Sopenharmony_ci 312bf215546Sopenharmony_civoid 313bf215546Sopenharmony_cizink_start_batch(struct zink_context *ctx, struct zink_batch *batch) 314bf215546Sopenharmony_ci{ 315bf215546Sopenharmony_ci zink_reset_batch(ctx, batch); 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci batch->state->usage.unflushed = true; 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci VkCommandBufferBeginInfo cbbi = {0}; 320bf215546Sopenharmony_ci cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 321bf215546Sopenharmony_ci cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci VkResult result = VKCTX(BeginCommandBuffer)(batch->state->cmdbuf, &cbbi); 324bf215546Sopenharmony_ci if (result != VK_SUCCESS) 325bf215546Sopenharmony_ci mesa_loge("ZINK: vkBeginCommandBuffer failed (%s)", vk_Result_to_str(result)); 326bf215546Sopenharmony_ci 327bf215546Sopenharmony_ci result = VKCTX(BeginCommandBuffer)(batch->state->barrier_cmdbuf, &cbbi); 328bf215546Sopenharmony_ci if (result != VK_SUCCESS) 329bf215546Sopenharmony_ci mesa_loge("ZINK: vkBeginCommandBuffer failed (%s)", vk_Result_to_str(result)); 330bf215546Sopenharmony_ci 331bf215546Sopenharmony_ci batch->state->fence.completed = false; 332bf215546Sopenharmony_ci if (ctx->last_fence) { 333bf215546Sopenharmony_ci struct zink_batch_state *last_state = zink_batch_state(ctx->last_fence); 334bf215546Sopenharmony_ci batch->last_batch_usage = &last_state->usage; 335bf215546Sopenharmony_ci } 336bf215546Sopenharmony_ci 337bf215546Sopenharmony_ci if (!ctx->queries_disabled) 338bf215546Sopenharmony_ci zink_resume_queries(ctx, batch); 339bf215546Sopenharmony_ci} 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_cistatic void 342bf215546Sopenharmony_cipost_submit(void *data, void *gdata, int thread_index) 343bf215546Sopenharmony_ci{ 344bf215546Sopenharmony_ci struct zink_batch_state *bs = data; 345bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(bs->ctx->base.screen); 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci if (bs->is_device_lost) { 348bf215546Sopenharmony_ci if (bs->ctx->reset.reset) 349bf215546Sopenharmony_ci bs->ctx->reset.reset(bs->ctx->reset.data, PIPE_GUILTY_CONTEXT_RESET); 350bf215546Sopenharmony_ci else if (screen->abort_on_hang && !screen->robust_ctx_count) 351bf215546Sopenharmony_ci /* if nothing can save us, abort */ 352bf215546Sopenharmony_ci abort(); 353bf215546Sopenharmony_ci screen->device_lost = true; 354bf215546Sopenharmony_ci } else if (bs->ctx->batch_states_count > 5000) { 355bf215546Sopenharmony_ci zink_screen_timeline_wait(screen, bs->fence.batch_id - 2500, PIPE_TIMEOUT_INFINITE); 356bf215546Sopenharmony_ci } 357bf215546Sopenharmony_ci} 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_cistatic void 360bf215546Sopenharmony_cisubmit_queue(void *data, void *gdata, int thread_index) 361bf215546Sopenharmony_ci{ 362bf215546Sopenharmony_ci struct zink_batch_state *bs = data; 363bf215546Sopenharmony_ci struct zink_context *ctx = bs->ctx; 364bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(ctx->base.screen); 365bf215546Sopenharmony_ci VkSubmitInfo si[2] = {0}; 366bf215546Sopenharmony_ci int num_si = 2; 367bf215546Sopenharmony_ci while (!bs->fence.batch_id) 368bf215546Sopenharmony_ci bs->fence.batch_id = (uint32_t)p_atomic_inc_return(&screen->curr_batch); 369bf215546Sopenharmony_ci bs->usage.usage = bs->fence.batch_id; 370bf215546Sopenharmony_ci bs->usage.unflushed = false; 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_ci uint64_t batch_id = bs->fence.batch_id; 373bf215546Sopenharmony_ci /* first submit is just for acquire waits since they have a separate array */ 374bf215546Sopenharmony_ci si[0].sType = si[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 375bf215546Sopenharmony_ci si[0].waitSemaphoreCount = util_dynarray_num_elements(&bs->acquires, VkSemaphore); 376bf215546Sopenharmony_ci si[0].pWaitSemaphores = bs->acquires.data; 377bf215546Sopenharmony_ci while (util_dynarray_num_elements(&bs->acquire_flags, VkPipelineStageFlags) < si[0].waitSemaphoreCount) { 378bf215546Sopenharmony_ci VkPipelineStageFlags mask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; 379bf215546Sopenharmony_ci util_dynarray_append(&bs->acquire_flags, VkPipelineStageFlags, mask); 380bf215546Sopenharmony_ci } 381bf215546Sopenharmony_ci assert(util_dynarray_num_elements(&bs->acquires, VkSemaphore) <= util_dynarray_num_elements(&bs->acquire_flags, VkPipelineStageFlags)); 382bf215546Sopenharmony_ci si[0].pWaitDstStageMask = bs->acquire_flags.data; 383bf215546Sopenharmony_ci 384bf215546Sopenharmony_ci if (si[0].waitSemaphoreCount == 0) 385bf215546Sopenharmony_ci num_si--; 386bf215546Sopenharmony_ci 387bf215546Sopenharmony_ci /* then the real submit */ 388bf215546Sopenharmony_ci si[1].waitSemaphoreCount = util_dynarray_num_elements(&bs->wait_semaphores, VkSemaphore); 389bf215546Sopenharmony_ci si[1].pWaitSemaphores = bs->wait_semaphores.data; 390bf215546Sopenharmony_ci si[1].pWaitDstStageMask = bs->wait_semaphore_stages.data; 391bf215546Sopenharmony_ci si[1].commandBufferCount = bs->has_barriers ? 2 : 1; 392bf215546Sopenharmony_ci VkCommandBuffer cmdbufs[2] = { 393bf215546Sopenharmony_ci bs->barrier_cmdbuf, 394bf215546Sopenharmony_ci bs->cmdbuf, 395bf215546Sopenharmony_ci }; 396bf215546Sopenharmony_ci si[1].pCommandBuffers = bs->has_barriers ? cmdbufs : &cmdbufs[1]; 397bf215546Sopenharmony_ci 398bf215546Sopenharmony_ci VkSemaphore signals[3]; 399bf215546Sopenharmony_ci si[1].signalSemaphoreCount = !!bs->signal_semaphore; 400bf215546Sopenharmony_ci signals[0] = bs->signal_semaphore; 401bf215546Sopenharmony_ci si[1].pSignalSemaphores = signals; 402bf215546Sopenharmony_ci VkTimelineSemaphoreSubmitInfo tsi = {0}; 403bf215546Sopenharmony_ci uint64_t signal_values[2] = {0}; 404bf215546Sopenharmony_ci tsi.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO; 405bf215546Sopenharmony_ci si[1].pNext = &tsi; 406bf215546Sopenharmony_ci tsi.pSignalSemaphoreValues = signal_values; 407bf215546Sopenharmony_ci signal_values[si[1].signalSemaphoreCount] = batch_id; 408bf215546Sopenharmony_ci signals[si[1].signalSemaphoreCount++] = screen->sem; 409bf215546Sopenharmony_ci tsi.signalSemaphoreValueCount = si[1].signalSemaphoreCount; 410bf215546Sopenharmony_ci 411bf215546Sopenharmony_ci if (bs->present) 412bf215546Sopenharmony_ci signals[si[1].signalSemaphoreCount++] = bs->present; 413bf215546Sopenharmony_ci tsi.signalSemaphoreValueCount = si[1].signalSemaphoreCount; 414bf215546Sopenharmony_ci 415bf215546Sopenharmony_ci VkResult result = VKSCR(EndCommandBuffer)(bs->cmdbuf); 416bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 417bf215546Sopenharmony_ci mesa_loge("ZINK: vkEndCommandBuffer failed (%s)", vk_Result_to_str(result)); 418bf215546Sopenharmony_ci bs->is_device_lost = true; 419bf215546Sopenharmony_ci goto end; 420bf215546Sopenharmony_ci } 421bf215546Sopenharmony_ci if (bs->has_barriers) { 422bf215546Sopenharmony_ci result = VKSCR(EndCommandBuffer)(bs->barrier_cmdbuf); 423bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 424bf215546Sopenharmony_ci mesa_loge("ZINK: vkEndCommandBuffer failed (%s)", vk_Result_to_str(result)); 425bf215546Sopenharmony_ci bs->is_device_lost = true; 426bf215546Sopenharmony_ci goto end; 427bf215546Sopenharmony_ci } 428bf215546Sopenharmony_ci } 429bf215546Sopenharmony_ci 430bf215546Sopenharmony_ci while (util_dynarray_contains(&bs->persistent_resources, struct zink_resource_object*)) { 431bf215546Sopenharmony_ci struct zink_resource_object *obj = util_dynarray_pop(&bs->persistent_resources, struct zink_resource_object*); 432bf215546Sopenharmony_ci VkMappedMemoryRange range = zink_resource_init_mem_range(screen, obj, 0, obj->size); 433bf215546Sopenharmony_ci 434bf215546Sopenharmony_ci result = VKSCR(FlushMappedMemoryRanges)(screen->dev, 1, &range); 435bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 436bf215546Sopenharmony_ci mesa_loge("ZINK: vkFlushMappedMemoryRanges failed (%s)", vk_Result_to_str(result)); 437bf215546Sopenharmony_ci } 438bf215546Sopenharmony_ci } 439bf215546Sopenharmony_ci 440bf215546Sopenharmony_ci simple_mtx_lock(&screen->queue_lock); 441bf215546Sopenharmony_ci result = VKSCR(QueueSubmit)(screen->queue, num_si, num_si == 2 ? si : &si[1], VK_NULL_HANDLE); 442bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 443bf215546Sopenharmony_ci mesa_loge("ZINK: vkQueueSubmit failed (%s)", vk_Result_to_str(result)); 444bf215546Sopenharmony_ci bs->is_device_lost = true; 445bf215546Sopenharmony_ci } 446bf215546Sopenharmony_ci simple_mtx_unlock(&screen->queue_lock); 447bf215546Sopenharmony_ci bs->submit_count++; 448bf215546Sopenharmony_ciend: 449bf215546Sopenharmony_ci cnd_broadcast(&bs->usage.flush); 450bf215546Sopenharmony_ci 451bf215546Sopenharmony_ci p_atomic_set(&bs->fence.submitted, true); 452bf215546Sopenharmony_ci unref_resources(screen, bs); 453bf215546Sopenharmony_ci} 454bf215546Sopenharmony_ci 455bf215546Sopenharmony_civoid 456bf215546Sopenharmony_cizink_end_batch(struct zink_context *ctx, struct zink_batch *batch) 457bf215546Sopenharmony_ci{ 458bf215546Sopenharmony_ci if (!ctx->queries_disabled) 459bf215546Sopenharmony_ci zink_suspend_queries(ctx, batch); 460bf215546Sopenharmony_ci 461bf215546Sopenharmony_ci tc_driver_internal_flush_notify(ctx->tc); 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_ci struct zink_screen *screen = zink_screen(ctx->base.screen); 464bf215546Sopenharmony_ci struct zink_batch_state *bs; 465bf215546Sopenharmony_ci 466bf215546Sopenharmony_ci if (ctx->oom_flush || ctx->batch_states_count > 10) { 467bf215546Sopenharmony_ci assert(!ctx->batch_states_count || ctx->batch_states); 468bf215546Sopenharmony_ci while (ctx->batch_states) { 469bf215546Sopenharmony_ci bs = ctx->batch_states; 470bf215546Sopenharmony_ci struct zink_fence *fence = &bs->fence; 471bf215546Sopenharmony_ci /* once an incomplete state is reached, no more will be complete */ 472bf215546Sopenharmony_ci if (!zink_check_batch_completion(ctx, fence->batch_id)) 473bf215546Sopenharmony_ci break; 474bf215546Sopenharmony_ci 475bf215546Sopenharmony_ci pop_batch_state(ctx); 476bf215546Sopenharmony_ci zink_reset_batch_state(ctx, bs); 477bf215546Sopenharmony_ci util_dynarray_append(&ctx->free_batch_states, struct zink_batch_state *, bs); 478bf215546Sopenharmony_ci } 479bf215546Sopenharmony_ci if (ctx->batch_states_count > 50) 480bf215546Sopenharmony_ci ctx->oom_flush = true; 481bf215546Sopenharmony_ci } 482bf215546Sopenharmony_ci 483bf215546Sopenharmony_ci bs = batch->state; 484bf215546Sopenharmony_ci if (ctx->last_fence) 485bf215546Sopenharmony_ci zink_batch_state(ctx->last_fence)->next = bs; 486bf215546Sopenharmony_ci else { 487bf215546Sopenharmony_ci assert(!ctx->batch_states); 488bf215546Sopenharmony_ci ctx->batch_states = bs; 489bf215546Sopenharmony_ci } 490bf215546Sopenharmony_ci ctx->last_fence = &bs->fence; 491bf215546Sopenharmony_ci ctx->batch_states_count++; 492bf215546Sopenharmony_ci batch->work_count = 0; 493bf215546Sopenharmony_ci 494bf215546Sopenharmony_ci if (batch->swapchain) { 495bf215546Sopenharmony_ci if (zink_kopper_acquired(batch->swapchain->obj->dt, batch->swapchain->obj->dt_idx) && !batch->swapchain->obj->present) { 496bf215546Sopenharmony_ci batch->state->present = zink_kopper_present(screen, batch->swapchain); 497bf215546Sopenharmony_ci batch->state->swapchain = batch->swapchain; 498bf215546Sopenharmony_ci } 499bf215546Sopenharmony_ci batch->swapchain = NULL; 500bf215546Sopenharmony_ci } 501bf215546Sopenharmony_ci 502bf215546Sopenharmony_ci if (screen->device_lost) 503bf215546Sopenharmony_ci return; 504bf215546Sopenharmony_ci 505bf215546Sopenharmony_ci if (screen->threaded) { 506bf215546Sopenharmony_ci util_queue_add_job(&screen->flush_queue, bs, &bs->flush_completed, 507bf215546Sopenharmony_ci submit_queue, post_submit, 0); 508bf215546Sopenharmony_ci } else { 509bf215546Sopenharmony_ci submit_queue(bs, NULL, 0); 510bf215546Sopenharmony_ci post_submit(bs, NULL, 0); 511bf215546Sopenharmony_ci } 512bf215546Sopenharmony_ci} 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_civoid 515bf215546Sopenharmony_cizink_batch_resource_usage_set(struct zink_batch *batch, struct zink_resource *res, bool write) 516bf215546Sopenharmony_ci{ 517bf215546Sopenharmony_ci if (res->obj->dt) { 518bf215546Sopenharmony_ci VkSemaphore acquire = zink_kopper_acquire_submit(zink_screen(batch->state->ctx->base.screen), res); 519bf215546Sopenharmony_ci if (acquire) 520bf215546Sopenharmony_ci util_dynarray_append(&batch->state->acquires, VkSemaphore, acquire); 521bf215546Sopenharmony_ci } 522bf215546Sopenharmony_ci if (write && !res->obj->is_buffer) { 523bf215546Sopenharmony_ci if (!res->valid && res->fb_binds) 524bf215546Sopenharmony_ci batch->state->ctx->rp_loadop_changed = true; 525bf215546Sopenharmony_ci res->valid = true; 526bf215546Sopenharmony_ci } 527bf215546Sopenharmony_ci zink_resource_usage_set(res, batch->state, write); 528bf215546Sopenharmony_ci /* multiple array entries are fine */ 529bf215546Sopenharmony_ci if (!res->obj->coherent && res->obj->persistent_maps) 530bf215546Sopenharmony_ci util_dynarray_append(&batch->state->persistent_resources, struct zink_resource_object*, res->obj); 531bf215546Sopenharmony_ci 532bf215546Sopenharmony_ci batch->has_work = true; 533bf215546Sopenharmony_ci} 534bf215546Sopenharmony_ci 535bf215546Sopenharmony_civoid 536bf215546Sopenharmony_cizink_batch_reference_resource_rw(struct zink_batch *batch, struct zink_resource *res, bool write) 537bf215546Sopenharmony_ci{ 538bf215546Sopenharmony_ci /* if the resource already has usage of any sort set for this batch, */ 539bf215546Sopenharmony_ci if (!zink_resource_usage_matches(res, batch->state) || 540bf215546Sopenharmony_ci /* or if it's bound somewhere */ 541bf215546Sopenharmony_ci !zink_resource_has_binds(res)) 542bf215546Sopenharmony_ci /* then it already has a batch ref and doesn't need one here */ 543bf215546Sopenharmony_ci zink_batch_reference_resource(batch, res); 544bf215546Sopenharmony_ci zink_batch_resource_usage_set(batch, res, write); 545bf215546Sopenharmony_ci} 546bf215546Sopenharmony_ci 547bf215546Sopenharmony_civoid 548bf215546Sopenharmony_cizink_batch_add_wait_semaphore(struct zink_batch *batch, VkSemaphore sem) 549bf215546Sopenharmony_ci{ 550bf215546Sopenharmony_ci util_dynarray_append(&batch->state->acquires, VkSemaphore, sem); 551bf215546Sopenharmony_ci} 552bf215546Sopenharmony_ci 553bf215546Sopenharmony_cibool 554bf215546Sopenharmony_cibatch_ptr_add_usage(struct zink_batch *batch, struct set *s, void *ptr) 555bf215546Sopenharmony_ci{ 556bf215546Sopenharmony_ci bool found = false; 557bf215546Sopenharmony_ci _mesa_set_search_or_add(s, ptr, &found); 558bf215546Sopenharmony_ci return !found; 559bf215546Sopenharmony_ci} 560bf215546Sopenharmony_ci 561bf215546Sopenharmony_ciALWAYS_INLINE static void 562bf215546Sopenharmony_cicheck_oom_flush(struct zink_context *ctx, const struct zink_batch *batch) 563bf215546Sopenharmony_ci{ 564bf215546Sopenharmony_ci const VkDeviceSize resource_size = batch->state->resource_size; 565bf215546Sopenharmony_ci if (resource_size >= zink_screen(ctx->base.screen)->clamp_video_mem) { 566bf215546Sopenharmony_ci ctx->oom_flush = true; 567bf215546Sopenharmony_ci ctx->oom_stall = true; 568bf215546Sopenharmony_ci } 569bf215546Sopenharmony_ci} 570bf215546Sopenharmony_ci 571bf215546Sopenharmony_civoid 572bf215546Sopenharmony_cizink_batch_reference_resource(struct zink_batch *batch, struct zink_resource *res) 573bf215546Sopenharmony_ci{ 574bf215546Sopenharmony_ci if (!batch_ptr_add_usage(batch, batch->state->resources, res->obj)) 575bf215546Sopenharmony_ci return; 576bf215546Sopenharmony_ci pipe_reference(NULL, &res->obj->reference); 577bf215546Sopenharmony_ci batch->state->resource_size += res->obj->size; 578bf215546Sopenharmony_ci check_oom_flush(batch->state->ctx, batch); 579bf215546Sopenharmony_ci batch->has_work = true; 580bf215546Sopenharmony_ci} 581bf215546Sopenharmony_ci 582bf215546Sopenharmony_civoid 583bf215546Sopenharmony_cizink_batch_reference_resource_move(struct zink_batch *batch, struct zink_resource *res) 584bf215546Sopenharmony_ci{ 585bf215546Sopenharmony_ci if (!batch_ptr_add_usage(batch, batch->state->resources, res->obj)) 586bf215546Sopenharmony_ci return; 587bf215546Sopenharmony_ci batch->state->resource_size += res->obj->size; 588bf215546Sopenharmony_ci check_oom_flush(batch->state->ctx, batch); 589bf215546Sopenharmony_ci batch->has_work = true; 590bf215546Sopenharmony_ci} 591bf215546Sopenharmony_ci 592bf215546Sopenharmony_civoid 593bf215546Sopenharmony_cizink_batch_reference_bufferview(struct zink_batch *batch, struct zink_buffer_view *buffer_view) 594bf215546Sopenharmony_ci{ 595bf215546Sopenharmony_ci if (!batch_ptr_add_usage(batch, batch->state->bufferviews, buffer_view)) 596bf215546Sopenharmony_ci return; 597bf215546Sopenharmony_ci pipe_reference(NULL, &buffer_view->reference); 598bf215546Sopenharmony_ci batch->has_work = true; 599bf215546Sopenharmony_ci} 600bf215546Sopenharmony_ci 601bf215546Sopenharmony_civoid 602bf215546Sopenharmony_cizink_batch_reference_surface(struct zink_batch *batch, struct zink_surface *surface) 603bf215546Sopenharmony_ci{ 604bf215546Sopenharmony_ci if (!batch_ptr_add_usage(batch, batch->state->surfaces, surface)) 605bf215546Sopenharmony_ci return; 606bf215546Sopenharmony_ci struct pipe_surface *surf = NULL; 607bf215546Sopenharmony_ci pipe_surface_reference(&surf, &surface->base); 608bf215546Sopenharmony_ci batch->has_work = true; 609bf215546Sopenharmony_ci} 610bf215546Sopenharmony_ci 611bf215546Sopenharmony_civoid 612bf215546Sopenharmony_cizink_batch_reference_sampler_view(struct zink_batch *batch, 613bf215546Sopenharmony_ci struct zink_sampler_view *sv) 614bf215546Sopenharmony_ci{ 615bf215546Sopenharmony_ci if (sv->base.target == PIPE_BUFFER) 616bf215546Sopenharmony_ci zink_batch_reference_bufferview(batch, sv->buffer_view); 617bf215546Sopenharmony_ci else { 618bf215546Sopenharmony_ci zink_batch_reference_surface(batch, sv->image_view); 619bf215546Sopenharmony_ci if (sv->cube_array) 620bf215546Sopenharmony_ci zink_batch_reference_surface(batch, sv->cube_array); 621bf215546Sopenharmony_ci } 622bf215546Sopenharmony_ci} 623bf215546Sopenharmony_ci 624bf215546Sopenharmony_civoid 625bf215546Sopenharmony_cizink_batch_reference_program(struct zink_batch *batch, 626bf215546Sopenharmony_ci struct zink_program *pg) 627bf215546Sopenharmony_ci{ 628bf215546Sopenharmony_ci if (zink_batch_usage_matches(pg->batch_uses, batch->state) || 629bf215546Sopenharmony_ci !batch_ptr_add_usage(batch, batch->state->programs, pg)) 630bf215546Sopenharmony_ci return; 631bf215546Sopenharmony_ci pipe_reference(NULL, &pg->reference); 632bf215546Sopenharmony_ci zink_batch_usage_set(&pg->batch_uses, batch->state); 633bf215546Sopenharmony_ci batch->has_work = true; 634bf215546Sopenharmony_ci} 635bf215546Sopenharmony_ci 636bf215546Sopenharmony_civoid 637bf215546Sopenharmony_cizink_batch_reference_image_view(struct zink_batch *batch, 638bf215546Sopenharmony_ci struct zink_image_view *image_view) 639bf215546Sopenharmony_ci{ 640bf215546Sopenharmony_ci if (image_view->base.resource->target == PIPE_BUFFER) 641bf215546Sopenharmony_ci zink_batch_reference_bufferview(batch, image_view->buffer_view); 642bf215546Sopenharmony_ci else 643bf215546Sopenharmony_ci zink_batch_reference_surface(batch, image_view->surface); 644bf215546Sopenharmony_ci} 645bf215546Sopenharmony_ci 646bf215546Sopenharmony_cibool 647bf215546Sopenharmony_cizink_screen_usage_check_completion(struct zink_screen *screen, const struct zink_batch_usage *u) 648bf215546Sopenharmony_ci{ 649bf215546Sopenharmony_ci if (!zink_batch_usage_exists(u)) 650bf215546Sopenharmony_ci return true; 651bf215546Sopenharmony_ci if (zink_batch_usage_is_unflushed(u)) 652bf215546Sopenharmony_ci return false; 653bf215546Sopenharmony_ci 654bf215546Sopenharmony_ci return zink_screen_timeline_wait(screen, u->usage, 0); 655bf215546Sopenharmony_ci} 656bf215546Sopenharmony_ci 657bf215546Sopenharmony_cibool 658bf215546Sopenharmony_cizink_batch_usage_check_completion(struct zink_context *ctx, const struct zink_batch_usage *u) 659bf215546Sopenharmony_ci{ 660bf215546Sopenharmony_ci if (!zink_batch_usage_exists(u)) 661bf215546Sopenharmony_ci return true; 662bf215546Sopenharmony_ci if (zink_batch_usage_is_unflushed(u)) 663bf215546Sopenharmony_ci return false; 664bf215546Sopenharmony_ci return zink_check_batch_completion(ctx, u->usage); 665bf215546Sopenharmony_ci} 666bf215546Sopenharmony_ci 667bf215546Sopenharmony_civoid 668bf215546Sopenharmony_cizink_batch_usage_wait(struct zink_context *ctx, struct zink_batch_usage *u) 669bf215546Sopenharmony_ci{ 670bf215546Sopenharmony_ci if (!zink_batch_usage_exists(u)) 671bf215546Sopenharmony_ci return; 672bf215546Sopenharmony_ci if (zink_batch_usage_is_unflushed(u)) { 673bf215546Sopenharmony_ci if (likely(u == &ctx->batch.state->usage)) 674bf215546Sopenharmony_ci ctx->base.flush(&ctx->base, NULL, PIPE_FLUSH_HINT_FINISH); 675bf215546Sopenharmony_ci else { //multi-context 676bf215546Sopenharmony_ci mtx_lock(&u->mtx); 677bf215546Sopenharmony_ci cnd_wait(&u->flush, &u->mtx); 678bf215546Sopenharmony_ci mtx_unlock(&u->mtx); 679bf215546Sopenharmony_ci } 680bf215546Sopenharmony_ci } 681bf215546Sopenharmony_ci zink_wait_on_batch(ctx, u->usage); 682bf215546Sopenharmony_ci} 683