#include "zink_cmdbuf.h" #include "zink_context.h" #include "zink_fence.h" #include "zink_framebuffer.h" #include "zink_render_pass.h" #include "zink_resource.h" #include "zink_screen.h" #include "util/u_debug.h" #include "util/set.h" static void reset_cmdbuf(struct zink_screen *screen, struct zink_cmdbuf *cmdbuf) { // cmdbuf hasn't been submitted before if (!cmdbuf->fence) return; zink_fence_finish(screen, cmdbuf->fence, PIPE_TIMEOUT_INFINITE); zink_fence_reference(screen, &cmdbuf->fence, NULL); zink_render_pass_reference(screen, &cmdbuf->rp, NULL); zink_framebuffer_reference(screen, &cmdbuf->fb, NULL); /* unref all used resources */ set_foreach(cmdbuf->resources, entry) { struct pipe_resource *pres = (struct pipe_resource *)entry->key; pipe_resource_reference(&pres, NULL); } _mesa_set_clear(cmdbuf->resources, NULL); util_dynarray_foreach(&cmdbuf->zombie_samplers, VkSampler, samp) { vkDestroySampler(screen->dev, *samp, NULL); } util_dynarray_clear(&cmdbuf->zombie_samplers); } struct zink_cmdbuf * zink_start_cmdbuf(struct zink_context *ctx) { struct zink_cmdbuf *cmdbuf = &ctx->cmdbufs[0]; reset_cmdbuf(zink_screen(ctx->base.screen), cmdbuf); VkCommandBufferBeginInfo cbbi = {}; cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; if (vkBeginCommandBuffer(cmdbuf->cmdbuf, &cbbi) != VK_SUCCESS) { debug_printf("vkBeginCommandBuffer failed\n"); return NULL; } return cmdbuf; } static bool submit_cmdbuf(struct zink_context *ctx, VkCommandBuffer cmdbuf, VkFence fence) { VkPipelineStageFlags wait = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; VkSubmitInfo si = {}; si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; si.waitSemaphoreCount = 0; si.pWaitSemaphores = NULL; si.signalSemaphoreCount = 0; si.pSignalSemaphores = NULL; si.pWaitDstStageMask = &wait; si.commandBufferCount = 1; si.pCommandBuffers = &cmdbuf; if (vkQueueSubmit(ctx->queue, 1, &si, fence) != VK_SUCCESS) { debug_printf("vkQueueSubmit failed\n"); return false; } return true; } void zink_end_cmdbuf(struct zink_context *ctx, struct zink_cmdbuf *cmdbuf) { if (vkEndCommandBuffer(cmdbuf->cmdbuf) != VK_SUCCESS) { debug_printf("vkEndCommandBuffer failed\n"); return; } assert(cmdbuf->fence == NULL); cmdbuf->fence = zink_create_fence(ctx->base.screen); if (!cmdbuf->fence || !submit_cmdbuf(ctx, cmdbuf->cmdbuf, cmdbuf->fence->fence)) return; if (vkQueueWaitIdle(ctx->queue) != VK_SUCCESS) debug_printf("vkQueueWaitIdle failed\n"); } void zink_cmdbuf_reference_resoure(struct zink_cmdbuf *cmdbuf, struct zink_resource *res) { struct set_entry *entry = _mesa_set_search(cmdbuf->resources, res); if (!entry) { struct pipe_resource *tmp = NULL; entry = _mesa_set_add(cmdbuf->resources, res); pipe_resource_reference(&tmp, &res->base); } }