diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c index f2d8d5d7f28..3f53a0d741c 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.c +++ b/src/gallium/auxiliary/util/u_threaded_context.c @@ -312,8 +312,7 @@ tc_set_resource_batch_usage(struct threaded_context *tc, struct pipe_resource *p { /* ignore batch usage when persistent */ if (threaded_resource(pres)->last_batch_usage != INT8_MAX) - threaded_resource(pres)->last_batch_usage = tc->next; - threaded_resource(pres)->batch_generation = tc->batch_generation; + threaded_resource(pres)->last_batch_usage = tc->batch_generation; } ALWAYS_INLINE static void @@ -322,8 +321,7 @@ tc_set_resource_batch_usage_persistent(struct threaded_context *tc, struct pipe_ if (!pres) return; /* mark with special value to block any unsynchronized access */ - threaded_resource(pres)->last_batch_usage = enable ? INT8_MAX : tc->next; - threaded_resource(pres)->batch_generation = tc->batch_generation; + threaded_resource(pres)->last_batch_usage = enable ? INT8_MAX : tc->batch_generation; } /* this can ONLY be used to check against the currently recording batch */ @@ -347,31 +345,15 @@ tc_resource_batch_usage_test_busy(const struct threaded_context *tc, const struc if (tc->last_completed == -1) return true; - /* begin comparisons checking number of times batches have cycled */ - unsigned diff = tc->batch_generation - tbuf->batch_generation; - /* resource has been seen, batches have fully cycled at least once */ - if (diff > 1) - return false; + int diff; + if (tbuf->last_batch_usage < tc->last_completed) + /* account for wrapping */ + diff = (tbuf->last_batch_usage + (INT8_MAX - 1)) - tc->last_completed; + else + diff = tbuf->last_batch_usage - tc->last_completed; - /* resource has been seen in current batch cycle: return whether batch has definitely completed */ - if (diff == 0) - return tc->last_completed >= tbuf->last_batch_usage; - - /* resource has been seen within one batch cycle: check for batch wrapping */ - if (tc->last_completed >= tbuf->last_batch_usage) - /* this or a subsequent pre-wrap batch was the last to definitely complete: resource is idle */ - return false; - - /* batch execution has not definitely wrapped: resource is definitely not idle */ - if (tc->last_completed > tc->next) - return true; - - /* resource was seen pre-wrap, batch execution has definitely wrapped: idle */ - if (tbuf->last_batch_usage > tc->last_completed) - return false; - - /* tc->last_completed is not an exact measurement, so anything else is considered busy */ - return true; + /* if diff is positive, then batch usage has completed: resource is not busy */ + return diff > 0; } /* Assign src to dst while dst is uninitialized. */ @@ -479,6 +461,15 @@ tc_add_call_end(struct tc_batch *next) #endif } +static void +tc_update_batch_generation(struct threaded_context *tc, struct tc_batch *next) +{ + /* -1 and INT8_MAX are special values */ + next->batch_idx = tc->batch_generation; + tc->batch_generation = (tc->batch_generation + 1) % INT8_MAX; + assert(next->batch_idx >= 0 && next->batch_idx < INT8_MAX); +} + static void tc_batch_flush(struct threaded_context *tc, bool full_copy) { @@ -509,12 +500,11 @@ tc_batch_flush(struct threaded_context *tc, bool full_copy) tc_batch_increment_renderpass_info(tc, next_id, full_copy); } + tc_update_batch_generation(tc, next); util_queue_add_job(&tc->queue, next, &next->fence, tc_batch_execute, NULL, 0); tc->last = tc->next; tc->next = next_id; - if (next_id == 0) - tc->batch_generation++; tc_begin_next_buffer_list(tc); } @@ -673,6 +663,7 @@ _tc_sync(struct threaded_context *tc, UNUSED const char *info, UNUSED const char tc->bytes_mapped_estimate = 0; tc->bytes_replaced_estimate = 0; tc_add_call_end(next); + tc_update_batch_generation(tc, next); tc_batch_execute(next, NULL, 0); tc_begin_next_buffer_list(tc); synced = true; @@ -5339,7 +5330,6 @@ threaded_context_create(struct pipe_context *pipe, tc->batch_slots[i].sentinel = TC_SENTINEL; #endif tc->batch_slots[i].tc = tc; - tc->batch_slots[i].batch_idx = i; util_queue_fence_init(&tc->batch_slots[i].fence); tc->batch_slots[i].renderpass_info_idx = -1; if (tc->options.parse_renderpass_info) { diff --git a/src/gallium/auxiliary/util/u_threaded_context.h b/src/gallium/auxiliary/util/u_threaded_context.h index 3d2f5a93eab..25312f3ce4a 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.h +++ b/src/gallium/auxiliary/util/u_threaded_context.h @@ -354,8 +354,6 @@ struct threaded_resource { /* internal tag for tc indicating which batch last touched this resource */ int8_t last_batch_usage; - /* for disambiguating last_batch_usage across batch cycles */ - uint32_t batch_generation; /* Unique buffer ID. Drivers must set it to non-zero for buffers and it must * be unique. Textures must set 0. Low bits are used as a hash of the ID. @@ -517,7 +515,7 @@ struct tc_batch { struct util_queue_fence fence; /* whether the first set_framebuffer_state call has been seen by this batch */ bool first_set_fb; - uint8_t batch_idx; + int8_t batch_idx; struct tc_unflushed_batch_token *token; uint64_t slots[TC_SLOTS_PER_BATCH]; struct util_dynarray renderpass_infos; @@ -632,6 +630,7 @@ struct threaded_context { bool seen_sampler_buffers[PIPE_SHADER_TYPES]; int8_t last_completed; + int8_t batch_generation; uint8_t num_vertex_buffers; unsigned max_const_buffers; @@ -640,7 +639,7 @@ struct threaded_context { unsigned max_samplers; unsigned nr_cbufs; - unsigned last, next, next_buf_list, batch_generation; + unsigned last, next, next_buf_list; /* The list fences that the driver should signal after the next flush. * If this is empty, all driver command buffers have been flushed. diff --git a/src/gallium/drivers/zink/ci/zink-lvp-fails.txt b/src/gallium/drivers/zink/ci/zink-lvp-fails.txt index 129e9e8eed8..be9b1031896 100644 --- a/src/gallium/drivers/zink/ci/zink-lvp-fails.txt +++ b/src/gallium/drivers/zink/ci/zink-lvp-fails.txt @@ -129,17 +129,6 @@ spec@!opengl 1.0@gl-1.0-dlist-beginend,Crash spec@arb_viewport_array@display-list,Fail -# passes locally -KHR-GL46.texture_view.coherency,Fail - # uprev Piglit in Mesa spec@arb_sparse_buffer@buffer-data,Crash spec@arb_sparse_buffer@commit,Crash -spec@nv_copy_image@nv_copy_image-formats --samples=4,Fail -spec@nv_copy_image@nv_copy_image-formats --samples=4@Source: GL_RG32F/Destination: GL_RG32F,Fail -spec@nv_copy_image@nv_copy_image-formats --samples=4@Source: GL_RG32I/Destination: GL_RG32I,Fail -spec@nv_copy_image@nv_copy_image-formats --samples=4@Source: GL_RG32UI/Destination: GL_RG32UI,Fail -spec@nv_copy_image@nv_copy_image-formats --samples=4@Source: GL_RGBA16/Destination: GL_RGBA16,Fail -spec@nv_copy_image@nv_copy_image-formats --samples=4@Source: GL_RGBA16I/Destination: GL_RGBA16I,Fail -spec@nv_copy_image@nv_copy_image-formats --samples=4@Source: GL_RGBA16_SNORM/Destination: GL_RGBA16_SNORM,Fail - diff --git a/src/gallium/drivers/zink/ci/zink-venus-lvp-fails.txt b/src/gallium/drivers/zink/ci/zink-venus-lvp-fails.txt index 493c4eb6138..cb6616484d6 100644 --- a/src/gallium/drivers/zink/ci/zink-venus-lvp-fails.txt +++ b/src/gallium/drivers/zink/ci/zink-venus-lvp-fails.txt @@ -152,5 +152,3 @@ spec@arb_clip_control@arb_clip_control-depth-precision,Crash spec@nv_texture_barrier@blending-in-shader,Crash spec@arb_viewport_array@display-list,Fail -# Fails since uprev in https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33796 -KHR-GL46.texture_view.coherency,Fail