diff --git a/src/gallium/drivers/asahi/agx_batch.c b/src/gallium/drivers/asahi/agx_batch.c index 717e2006065..0ed90d002cc 100644 --- a/src/gallium/drivers/asahi/agx_batch.c +++ b/src/gallium/drivers/asahi/agx_batch.c @@ -120,6 +120,9 @@ agx_batch_init(struct agx_context *ctx, batch->any_draws = false; batch->initialized = false; batch->draws = 0; + agx_bo_unreference(batch->sampler_heap.bo); + batch->sampler_heap.bo = NULL; + batch->sampler_heap.count = 0; /* We need to emit prim state at the start. Max collides with all. */ batch->reduced_prim = MESA_PRIM_COUNT; diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c index ebd88c4b38c..19a2d0f710c 100644 --- a/src/gallium/drivers/asahi/agx_state.c +++ b/src/gallium/drivers/asahi/agx_state.c @@ -2242,6 +2242,28 @@ agx_upload_textures(struct agx_batch *batch, struct agx_compiled_shader *cs, batch->textures[stage] = T_tex.gpu; } +uint16_t +agx_sampler_heap_add(struct agx_device *dev, struct agx_sampler_heap *heap, + struct agx_sampler_packed *sampler) +{ + /* Allocate (maximally sized) BO if we haven't already */ + if (!heap->bo) { + heap->bo = agx_bo_create(dev, AGX_SAMPLER_HEAP_SIZE * AGX_SAMPLER_LENGTH, + AGX_BO_WRITEBACK, "Sampler heap"); + + assert(heap->count == 0); + } + + /* TODO search */ + + /* Precondition: there is room in the heap */ + assert(heap->count < AGX_SAMPLER_HEAP_SIZE); + struct agx_sampler_packed *samplers = heap->bo->ptr.cpu; + memcpy(samplers + heap->count, sampler, sizeof(*sampler)); + + return heap->count++; +} + static void agx_upload_samplers(struct agx_batch *batch, struct agx_compiled_shader *cs, enum pipe_shader_type stage) @@ -3320,6 +3342,9 @@ agx_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info, } else if (unlikely(batch->draws > 100000)) { /* Mostly so drawoverhead doesn't OOM */ agx_flush_batch_for_reason(ctx, batch, "Absurd number of draws"); + } else if (unlikely(batch->sampler_heap.count > + (AGX_SAMPLER_HEAP_SIZE - (PIPE_MAX_SAMPLERS * 6)))) { + agx_flush_batch_for_reason(ctx, batch, "Sampler heap overflow"); } } diff --git a/src/gallium/drivers/asahi/agx_state.h b/src/gallium/drivers/asahi/agx_state.h index c34a83b67ea..554dcdf1586 100644 --- a/src/gallium/drivers/asahi/agx_state.h +++ b/src/gallium/drivers/asahi/agx_state.h @@ -247,6 +247,20 @@ struct agx_stage { union agx_batch_result { }; +/* This is a firmware limit. It should be possible to raise to 2048 in the + * future... still not good enough for VK though :-( + */ +#define AGX_SAMPLER_HEAP_SIZE (1024) + +struct agx_sampler_heap { + struct agx_bo *bo; + uint16_t count; +}; + +uint16_t agx_sampler_heap_add(struct agx_device *dev, + struct agx_sampler_heap *heap, + struct agx_sampler_packed *sampler); + struct agx_batch { struct agx_context *ctx; struct pipe_framebuffer_state key; @@ -280,6 +294,8 @@ struct agx_batch { uint64_t samplers[PIPE_SHADER_TYPES]; uint32_t sampler_count[PIPE_SHADER_TYPES]; + struct agx_sampler_heap sampler_heap; + /* Resource list requirements, represented as a bit set indexed by BO * handles (GEM handles on Linux, or IOGPU's equivalent on macOS) */