poly: Make all heap allocations atomic

All non-atomic allocations are on pretty slow paths where we only have a
single invocation running.  This means they're technically thread-safe
(assuming only a single queue) but it also means the perf of a single
allocation doesn't matter much.  However, as a bunch of things are
becoming helpers that may or may not be run in parallel for things like
multi-draw, it becomes harder to know when non-atomic is safe.  We're
probably better off using atomic allocations everywhere.

Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>
Reviewed-by: Mary Guillemard <mary@mary.zone>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38404>
This commit is contained in:
Faith Ekstrand
2025-11-24 12:02:48 -05:00
committed by Marge Bot
parent ed0998ca98
commit 3aa4be52f3
6 changed files with 13 additions and 31 deletions
+1 -1
View File
@@ -149,7 +149,7 @@ poly_setup_unroll_for_draw(global struct poly_heap *heap,
* TODO: For multidraw, should be atomic. But multidraw+unroll isn't
* currently wired up in any driver.
*/
uint old_heap_bottom_B = poly_heap_alloc_nonatomic_offs(heap, alloc_size);
uint old_heap_bottom_B = poly_heap_alloc_offs(heap, alloc_size);
/* Setup most of the descriptor. Count will be determined after unroll. */
out_draw[1] = in_draw[1]; /* instance count */
+1 -1
View File
@@ -193,7 +193,7 @@ poly_heap_alloc_points(constant struct poly_tess_params *p, uint patch,
}
uint32_t elsize_B = sizeof(struct poly_tess_point);
uint32_t alloc_B = poly_heap_alloc_atomic_offs(p->heap, elsize_B * count);
uint32_t alloc_B = poly_heap_alloc_offs(p->heap, elsize_B * count);
uint32_t alloc_el = alloc_B / elsize_B;
p->coord_allocs[patch] = alloc_el;
+8 -26
View File
@@ -116,17 +116,12 @@ static_assert(sizeof(struct poly_heap) == 4 * 4);
#ifdef __OPENCL_VERSION__
static inline uint
_poly_heap_alloc_offs(global struct poly_heap *heap, uint size_B, bool atomic)
poly_heap_alloc_offs(global struct poly_heap *heap, uint size_B)
{
size_B = align(size_B, 16);
uint offs;
if (atomic) {
offs = atomic_fetch_add((volatile atomic_uint *)(&heap->bottom), size_B);
} else {
offs = heap->bottom;
heap->bottom = offs + size_B;
}
uint offs =
atomic_fetch_add((volatile atomic_uint *)(&heap->bottom), size_B);
/* Use printf+abort because assert is stripped from release builds. */
if (heap->bottom >= heap->size) {
@@ -140,22 +135,10 @@ _poly_heap_alloc_offs(global struct poly_heap *heap, uint size_B, bool atomic)
return offs;
}
static inline uint
poly_heap_alloc_nonatomic_offs(global struct poly_heap *heap, uint size_B)
{
return _poly_heap_alloc_offs(heap, size_B, false);
}
static inline uint
poly_heap_alloc_atomic_offs(global struct poly_heap *heap, uint size_B)
{
return _poly_heap_alloc_offs(heap, size_B, true);
}
static inline global void *
poly_heap_alloc_nonatomic(global struct poly_heap *heap, uint size_B)
poly_heap_alloc(global struct poly_heap *heap, uint size_B)
{
return heap->base + poly_heap_alloc_nonatomic_offs(heap, size_B);
return heap->base + poly_heap_alloc_offs(heap, size_B);
}
uint64_t nir_load_ro_sink_address_poly(void);
@@ -648,18 +631,17 @@ poly_gs_setup_indirect(uint64_t index_buffer, constant uint *draw,
poly_tcs_in_size(vertex_count * instance_count, vs_outputs);
if (is_prefix_summing) {
p->count_buffer = poly_heap_alloc_nonatomic(
p->count_buffer = poly_heap_alloc(
heap, p->input_primitives * p->count_buffer_stride);
}
vp->output_buffer =
(uintptr_t)poly_heap_alloc_nonatomic(heap, vertex_buffer_size);
vp->output_buffer = (uintptr_t)poly_heap_alloc(heap, vertex_buffer_size);
vp->outputs = vs_outputs;
if (shape == POLY_GS_SHAPE_DYNAMIC_INDEXED) {
const uint32_t index_offset =
poly_heap_alloc_nonatomic_offs(heap, p->draw.index_count * 4);
poly_heap_alloc_offs(heap, p->draw.index_count * 4);
p->draw.first_index = index_offset / 4;
p->output_index_buffer = (global uint *)(heap->base + index_offset);
}