diff --git a/src/asahi/compiler/agx_compile.c b/src/asahi/compiler/agx_compile.c index b4dc80f0d37..4127984616a 100644 --- a/src/asahi/compiler/agx_compile.c +++ b/src/asahi/compiler/agx_compile.c @@ -628,6 +628,10 @@ agx_emit_intrinsic(agx_builder *b, nir_intrinsic_instr *instr) case nir_intrinsic_load_back_face_agx: return agx_get_sr_to(b, dst, AGX_SR_BACKFACING); + case nir_intrinsic_load_texture_base_agx: + return agx_mov_to(b, dst, agx_indexed_sysval(b->shader, + AGX_PUSH_TEXTURE_BASE, AGX_SIZE_64, 0, 4)); + case nir_intrinsic_load_vertex_id: return agx_mov_to(b, dst, agx_abs(agx_register(10, AGX_SIZE_32))); diff --git a/src/asahi/compiler/agx_compile.h b/src/asahi/compiler/agx_compile.h index 20068664541..b0199524b47 100644 --- a/src/asahi/compiler/agx_compile.h +++ b/src/asahi/compiler/agx_compile.h @@ -54,6 +54,8 @@ enum agx_push_type { */ AGX_PUSH_ARRAY_SIZE_MINUS_1, + AGX_PUSH_TEXTURE_BASE, + /* Keep last */ AGX_PUSH_NUM_TYPES }; diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c index 140c7494342..bb31397a1f3 100644 --- a/src/gallium/drivers/asahi/agx_state.c +++ b/src/gallium/drivers/asahi/agx_state.c @@ -1193,18 +1193,6 @@ agx_build_pipeline(struct agx_context *ctx, struct agx_compiled_shader *cs, enum uint8_t *record = ptr.cpu; - for (unsigned i = 0; i < cs->info.push_ranges; ++i) { - struct agx_push push = cs->info.push[i]; - - agx_pack(record, BIND_UNIFORM, cfg) { - cfg.start_halfs = push.base; - cfg.size_halfs = push.length; - cfg.buffer = agx_push_location(ctx, push, stage); - } - - record += AGX_BIND_UNIFORM_LENGTH; - } - unsigned nr_textures = ctx->stage[stage].texture_count; unsigned nr_samplers = ctx->stage[stage].sampler_count; @@ -1240,6 +1228,7 @@ agx_build_pipeline(struct agx_context *ctx, struct agx_compiled_shader *cs, enum cfg.buffer = T_tex.gpu; } + ctx->batch->textures = T_tex.gpu; record += AGX_BIND_TEXTURE_LENGTH; } @@ -1253,6 +1242,21 @@ agx_build_pipeline(struct agx_context *ctx, struct agx_compiled_shader *cs, enum record += AGX_BIND_SAMPLER_LENGTH; } + /* Must only upload uniforms after uploading textures so we can implement the + * AGX_PUSH_TEXTURE_BASE sysval correctly. + */ + for (unsigned i = 0; i < cs->info.push_ranges; ++i) { + struct agx_push push = cs->info.push[i]; + + agx_pack(record, BIND_UNIFORM, cfg) { + cfg.start_halfs = push.base; + cfg.size_halfs = push.length; + cfg.buffer = agx_push_location(ctx, push, stage); + } + + record += AGX_BIND_UNIFORM_LENGTH; + } + /* TODO: Can we prepack this? */ if (stage == PIPE_SHADER_FRAGMENT) { bool writes_sample_mask = ctx->fs->info.writes_sample_mask; diff --git a/src/gallium/drivers/asahi/agx_state.h b/src/gallium/drivers/asahi/agx_state.h index 157473077aa..862f069f070 100644 --- a/src/gallium/drivers/asahi/agx_state.h +++ b/src/gallium/drivers/asahi/agx_state.h @@ -100,6 +100,9 @@ struct agx_batch { /* PIPE_CLEAR_* bitmask */ uint32_t clear, draw, load; + /* Base of uploaded texture descriptors */ + uint64_t textures; + float clear_color[4]; double clear_depth; unsigned clear_stencil; diff --git a/src/gallium/drivers/asahi/agx_uniforms.c b/src/gallium/drivers/asahi/agx_uniforms.c index f406a799d6b..e8165bc244a 100644 --- a/src/gallium/drivers/asahi/agx_uniforms.c +++ b/src/gallium/drivers/asahi/agx_uniforms.c @@ -106,6 +106,13 @@ agx_push_location_direct(struct agx_context *ctx, struct agx_push push, return ptr.gpu; } + case AGX_PUSH_TEXTURE_BASE: { + struct agx_ptr ptr = agx_pool_alloc_aligned(&batch->pool, sizeof(uint64_t), 8); + uint64_t *address = ptr.cpu; + *address = batch->textures; + return ptr.gpu; + } + default: unreachable("todo: push more"); }