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;
}
}