return zink_check_batch_completion(ctx, u->usage);
}
-void
-zink_batch_usage_wait(struct zink_context *ctx, struct zink_batch_usage *u)
+static void
+batch_usage_wait(struct zink_context *ctx, struct zink_batch_usage *u, bool trywait)
{
if (!zink_batch_usage_exists(u))
return;
ctx->base.flush(&ctx->base, NULL, PIPE_FLUSH_HINT_FINISH);
else { //multi-context
mtx_lock(&u->mtx);
- cnd_wait(&u->flush, &u->mtx);
+ if (trywait) {
+ struct timespec ts = {0, 10000};
+ cnd_timedwait(&u->flush, &u->mtx, &ts);
+ } else
+ cnd_wait(&u->flush, &u->mtx);
mtx_unlock(&u->mtx);
}
}
zink_wait_on_batch(ctx, u->usage);
}
+
+void
+zink_batch_usage_wait(struct zink_context *ctx, struct zink_batch_usage *u)
+{
+ batch_usage_wait(ctx, u, false);
+}
+
+void
+zink_batch_usage_try_wait(struct zink_context *ctx, struct zink_batch_usage *u)
+{
+ batch_usage_wait(ctx, u, true);
+}
void
zink_batch_usage_wait(struct zink_context *ctx, struct zink_batch_usage *u);
+void
+zink_batch_usage_try_wait(struct zink_context *ctx, struct zink_batch_usage *u);
+
#ifdef __cplusplus
}
#endif
}
static inline void
+zink_bo_usage_try_wait(struct zink_context *ctx, struct zink_bo *bo, enum zink_resource_access access)
+{
+ if (access & ZINK_RESOURCE_ACCESS_READ)
+ zink_batch_usage_try_wait(ctx, bo->reads);
+ if (access & ZINK_RESOURCE_ACCESS_WRITE)
+ zink_batch_usage_try_wait(ctx, bo->writes);
+}
+
+static inline void
zink_bo_usage_set(struct zink_bo *bo, struct zink_batch_state *bs, bool write)
{
if (write)
!res->obj->host_visible)) {
assert(!(usage & (TC_TRANSFER_MAP_THREADED_UNSYNC | PIPE_MAP_THREAD_SAFE)));
if (!res->obj->host_visible || !(usage & PIPE_MAP_ONCE)) {
+overwrite:
trans->offset = box->x % screen->info.props.limits.minMemoryMapAlignment;
trans->staging_res = pipe_buffer_create(&screen->base, PIPE_BIND_LINEAR, PIPE_USAGE_STAGING, box->width + trans->offset);
if (!trans->staging_res)
}
if (!(usage & PIPE_MAP_UNSYNCHRONIZED)) {
- if (usage & PIPE_MAP_WRITE)
+ if (usage & PIPE_MAP_WRITE) {
+ if (!(usage & PIPE_MAP_READ)) {
+ zink_resource_usage_try_wait(ctx, res, ZINK_RESOURCE_ACCESS_RW);
+ if (zink_resource_has_unflushed_usage(res))
+ goto overwrite;
+ }
zink_resource_usage_wait(ctx, res, ZINK_RESOURCE_ACCESS_RW);
- else
+ } else
zink_resource_usage_wait(ctx, res, ZINK_RESOURCE_ACCESS_WRITE);
res->obj->access = 0;
res->obj->access_stage = 0;
}
static inline void
+zink_resource_usage_try_wait(struct zink_context *ctx, struct zink_resource *res, enum zink_resource_access access)
+{
+ zink_bo_usage_try_wait(ctx, res->obj->bo, access);
+}
+
+static inline void
zink_resource_usage_wait(struct zink_context *ctx, struct zink_resource *res, enum zink_resource_access access)
{
zink_bo_usage_wait(ctx, res->obj->bo, access);