zink: handle PIPE_FLUSH_DEFERRED

these flushes queue the fence to be submitted on the next finish call, so
we have to store the context to the fence to be able to handle threaded calls

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9243>
This commit is contained in:
Mike Blumenkrantz 2020-09-30 09:51:55 -04:00
parent c271ac0066
commit c5292710c4
4 changed files with 28 additions and 11 deletions

View File

@ -22,7 +22,7 @@ zink_reset_batch(struct zink_context *ctx, struct zink_batch *batch)
// cmdbuf hasn't been submitted before
if (batch->submitted)
zink_fence_finish(screen, batch->fence, PIPE_TIMEOUT_INFINITE);
zink_fence_finish(screen, &ctx->base, batch->fence, PIPE_TIMEOUT_INFINITE);
zink_framebuffer_reference(screen, &batch->fb, NULL);
set_foreach(batch->programs, entry) {

View File

@ -1349,20 +1349,26 @@ zink_flush(struct pipe_context *pctx,
enum pipe_flush_flags flags)
{
struct zink_context *ctx = zink_context(pctx);
bool deferred = flags & PIPE_FLUSH_DEFERRED;
struct zink_batch *batch = zink_curr_batch(ctx);
if (batch->has_work) {
if (deferred)
batch->fence->deferred_ctx = pctx;
else if (batch->has_work) {
flush_batch(ctx);
if (zink_screen(pctx->screen)->info.have_EXT_transform_feedback && ctx->num_so_targets)
ctx->dirty_so_targets = true;
}
if (pfence)
zink_fence_reference(zink_screen(pctx->screen),
(struct zink_fence **)pfence,
batch->fence);
if (!pfence)
return;
if (deferred && !batch->has_work) {
batch = zink_prev_batch(ctx);
}
zink_fence_reference(zink_screen(pctx->screen),
(struct zink_fence **)pfence,
batch->fence);
/* HACK:
* For some strange reason, we need to finish before presenting, or else
* we start rendering on top of the back-buffer for the next frame. This

View File

@ -22,6 +22,7 @@
*/
#include "zink_batch.h"
#include "zink_context.h"
#include "zink_fence.h"
#include "zink_query.h"
@ -84,6 +85,7 @@ zink_fence_init(struct zink_fence *fence, struct zink_batch *batch)
pipe_resource_reference(&r, pres);
util_dynarray_append(&fence->resources, struct pipe_resource*, pres);
}
fence->deferred_ctx = NULL;
fence->submitted = true;
}
@ -114,9 +116,15 @@ fence_remove_resource_access(struct zink_fence *fence, struct zink_resource *res
}
bool
zink_fence_finish(struct zink_screen *screen, struct zink_fence *fence,
zink_fence_finish(struct zink_screen *screen, struct pipe_context *pctx, struct zink_fence *fence,
uint64_t timeout_ns)
{
if (pctx && fence->deferred_ctx == pctx) {
zink_curr_batch(zink_context(pctx))->has_work = true;
/* this must be the current batch */
pctx->flush(pctx, NULL, 0);
}
if (!fence->submitted)
return true;
bool success;
@ -151,7 +159,7 @@ static bool
fence_finish(struct pipe_screen *pscreen, struct pipe_context *pctx,
struct pipe_fence_handle *pfence, uint64_t timeout_ns)
{
return zink_fence_finish(zink_screen(pscreen), zink_fence(pfence),
return zink_fence_finish(zink_screen(pscreen), pctx, zink_fence(pfence),
timeout_ns);
}

View File

@ -29,7 +29,9 @@
#include <vulkan/vulkan.h>
struct pipe_context;
struct pipe_screen;
struct zink_context;
struct zink_screen;
struct zink_fence {
@ -38,6 +40,7 @@ struct zink_fence {
VkFence fence;
struct set *active_queries; /* zink_query objects which were active at some point in this batch */
struct util_dynarray resources;
struct pipe_context *deferred_ctx;
bool submitted;
};
@ -58,7 +61,7 @@ zink_fence_reference(struct zink_screen *screen,
struct zink_fence *fence);
bool
zink_fence_finish(struct zink_screen *screen, struct zink_fence *fence,
zink_fence_finish(struct zink_screen *screen, struct pipe_context *pctx, struct zink_fence *fence,
uint64_t timeout_ns);
void