diff --git a/src/asahi/lib/cmdbuf.xml b/src/asahi/lib/cmdbuf.xml index e7dbfee1b1b..e1c20e43339 100644 --- a/src/asahi/lib/cmdbuf.xml +++ b/src/asahi/lib/cmdbuf.xml @@ -452,18 +452,19 @@ - - - - - - - - - - - + + + + + + + + + + + + @@ -539,7 +540,7 @@ - + @@ -605,14 +606,11 @@ - - - - - - - + + + + + @@ -626,8 +624,7 @@ - - + diff --git a/src/asahi/lib/gen_pack.py b/src/asahi/lib/gen_pack.py index a970d587064..0396672a12d 100644 --- a/src/asahi/lib/gen_pack.py +++ b/src/asahi/lib/gen_pack.py @@ -89,6 +89,32 @@ __gen_unpack_sint(const uint8_t *restrict cl, uint32_t start, uint32_t end) return util_sign_extend(val, size); } +static inline uint64_t +__gen_to_groups(uint32_t value, uint32_t group_size, uint32_t length) +{ + /* Zero is not representable, clamp to minimum */ + if (value == 0) + return 1; + + /* Round up to the nearest number of groups */ + uint32_t groups = DIV_ROUND_UP(value, group_size); + + /* The 0 encoding means "all" */ + if (groups == (1ull << length)) + return 0; + + /* Otherwise it's encoded as the identity */ + assert(groups < (1u << length) && "out of bounds"); + assert(groups >= 1 && "exhaustive"); + return groups; +} + +static inline uint64_t +__gen_from_groups(uint32_t value, uint32_t group_size, uint32_t length) +{ + return group_size * (value ? value: (1 << length)); +} + #define agx_pack(dst, T, name) \\ for (struct AGX_ ## T name = { AGX_ ## T ## _header }, \\ *_loop_terminate = (void *) (dst); \\ @@ -147,7 +173,7 @@ def prefixed_upper_name(prefix, name): def enum_name(name): return "{}_{}".format(global_prefix, safe_name(name)).lower() -MODIFIERS = ["shr", "minus", "align", "log2"] +MODIFIERS = ["shr", "minus", "align", "log2", "groups"] def parse_modifier(modifier): if modifier is None: @@ -364,6 +390,9 @@ class Group(object): value = "ALIGN_POT({}, {})".format(value, field.modifier[1]) elif field.modifier[0] == "log2": value = "util_logbase2({})".format(value) + elif field.modifier[0] == "groups": + value = "__gen_to_groups({}, {}, {})".format(value, + field.modifier[1], end - start + 1) if field.type in ["uint", "hex", "address"]: s = "util_bitpack_uint(%s, %d, %d)" % \ @@ -461,6 +490,10 @@ class Group(object): suffix = " << {}".format(field.modifier[1]) if field.modifier[0] == "log2": prefix = "1 << " + elif field.modifier[0] == "groups": + prefix = "__gen_from_groups(" + suffix = ", {}, {})".format(field.modifier[1], + fieldref.end - fieldref.start + 1) if field.type in self.parser.enums: prefix = f"(enum {enum_name(field.type)}) {prefix}" diff --git a/src/gallium/drivers/asahi/agx_state.c b/src/gallium/drivers/asahi/agx_state.c index 18336e42787..130652cf9a0 100644 --- a/src/gallium/drivers/asahi/agx_state.c +++ b/src/gallium/drivers/asahi/agx_state.c @@ -1392,7 +1392,7 @@ agx_build_pipeline(struct agx_context *ctx, struct agx_compiled_shader *cs, enum } agx_usc_pack(&b, REGISTERS, cfg) { - cfg.register_quadwords = 0; + cfg.register_count = 256; cfg.unk_1 = (stage == PIPE_SHADER_FRAGMENT); } @@ -1435,7 +1435,7 @@ agx_build_clear_pipeline(struct agx_context *ctx, uint32_t code, uint64_t clear_ cfg.unk_2 = 3; } - agx_usc_pack(&b, REGISTERS, cfg) cfg.register_quadwords = 1; + agx_usc_pack(&b, REGISTERS, cfg) cfg.register_count = 8; agx_usc_pack(&b, NO_PRESHADER, cfg); return agx_usc_fini(&b); @@ -1517,7 +1517,7 @@ agx_build_reload_pipeline(struct agx_context *ctx, uint32_t code, struct pipe_su cfg.unk_2 = 3; } - agx_usc_pack(&b, REGISTERS, cfg) cfg.register_quadwords = 0; + agx_usc_pack(&b, REGISTERS, cfg) cfg.register_count = 256; agx_usc_pack(&b, NO_PRESHADER, cfg); return agx_usc_fini(&b); @@ -1552,7 +1552,7 @@ agx_build_store_pipeline(struct agx_context *ctx, uint32_t code, } agx_usc_pack(&b, SHADER, cfg) cfg.code = code; - agx_usc_pack(&b, REGISTERS, cfg) cfg.register_quadwords = 1; + agx_usc_pack(&b, REGISTERS, cfg) cfg.register_count = 8; agx_usc_pack(&b, NO_PRESHADER, cfg); return agx_usc_fini(&b); @@ -1618,8 +1618,9 @@ agx_encode_state(struct agx_context *ctx, uint8_t *out, unsigned tex_count = ctx->stage[PIPE_SHADER_VERTEX].texture_count; agx_pack(out, VDM_STATE_VERTEX_SHADER_WORD_0, cfg) { - cfg.groups_of_8_immediate_textures = DIV_ROUND_UP(tex_count, 8); - cfg.groups_of_4_samplers = DIV_ROUND_UP(tex_count, 4); + cfg.uniform_register_count = 512; + cfg.texture_state_register_count = tex_count; + cfg.sampler_state_register_count = tex_count; } out += AGX_VDM_STATE_VERTEX_SHADER_WORD_0_LENGTH; @@ -1635,7 +1636,8 @@ agx_encode_state(struct agx_context *ctx, uint8_t *out, out += AGX_VDM_STATE_VERTEX_OUTPUTS_LENGTH; agx_pack(out, VDM_STATE_VERTEX_UNKNOWN, cfg) { - cfg.more_than_4_textures = tex_count >= 4; + /* XXX: This is probably wrong */ + cfg.unknown = tex_count >= 4; } out += AGX_VDM_STATE_VERTEX_UNKNOWN_LENGTH; @@ -1786,11 +1788,14 @@ agx_encode_state(struct agx_context *ctx, uint8_t *out, unsigned frag_tex_count = ctx->stage[PIPE_SHADER_FRAGMENT].texture_count; agx_ppp_push(&ppp, FRAGMENT_SHADER, cfg) { cfg.pipeline = agx_build_pipeline(ctx, ctx->fs, PIPE_SHADER_FRAGMENT), - cfg.groups_of_8_immediate_textures = DIV_ROUND_UP(frag_tex_count, 8); - cfg.groups_of_4_samplers = DIV_ROUND_UP(frag_tex_count, 4); - cfg.more_than_4_textures = frag_tex_count >= 4; + cfg.uniform_register_count = 512; + cfg.texture_state_register_count = frag_tex_count; + cfg.sampler_state_register_count = frag_tex_count; cfg.cf_binding_count = ctx->fs->info.varyings.fs.nr_bindings; cfg.cf_bindings = ctx->batch->varyings; + + /* XXX: This is probably wrong */ + cfg.unknown_30 = frag_tex_count >= 4; } }