agx: Be less sloppy about high uniforms
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>
Sun, 25 Sep 2022 18:16:31 +0000 (14:16 -0400)
committerAlyssa Rosenzweig <alyssa@rosenzweig.io>
Sat, 22 Oct 2022 18:59:29 +0000 (14:59 -0400)
We need 9-bits to index into the uniform file. Fix an overflow and add
some asserts to try to catch these issues earlier.

Sigh, C.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18813>

src/asahi/compiler/agx_compiler.h
src/asahi/compiler/agx_pack.c

index 749dd2e..932c39c 100644 (file)
@@ -53,6 +53,9 @@ extern int agx_debug;
 /* r0-r127 inclusive, as pairs of 16-bits, gives 256 registers */
 #define AGX_NUM_REGS (256)
 
+/* u0-u255 inclusive, as pairs of 16-bits */
+#define AGX_NUM_UNIFORMS (512)
+
 enum agx_index_type {
    AGX_INDEX_NULL = 0,
    AGX_INDEX_NORMAL = 1,
@@ -111,8 +114,10 @@ agx_get_index(unsigned value, enum agx_size size)
 }
 
 static inline agx_index
-agx_immediate(uint16_t imm)
+agx_immediate(uint32_t imm)
 {
+   assert(imm < (1 << 16) && "overflowed immediate");
+
    return (agx_index) {
       .value = imm,
       .size = AGX_SIZE_16,
@@ -129,8 +134,10 @@ agx_immediate_f(float f)
 
 /* in half-words, specify r0h as 1, r1 as 2... */
 static inline agx_index
-agx_register(uint8_t imm, enum agx_size size)
+agx_register(uint32_t imm, enum agx_size size)
 {
+   assert(imm < AGX_NUM_REGS);
+
    return (agx_index) {
       .value = imm,
       .size = size,
@@ -140,8 +147,10 @@ agx_register(uint8_t imm, enum agx_size size)
 
 /* Also in half-words */
 static inline agx_index
-agx_uniform(uint8_t imm, enum agx_size size)
+agx_uniform(uint32_t imm, enum agx_size size)
 {
+   assert(imm < AGX_NUM_UNIFORMS);
+
    return (agx_index) {
       .value = imm,
       .size = size,
index f22206e..a4a3c75 100644 (file)
@@ -182,11 +182,11 @@ agx_pack_alu_src(agx_index src)
          ((value >> 6) << 10);
    } else if (src.type == AGX_INDEX_UNIFORM) {
       assert(size == AGX_SIZE_16 || size == AGX_SIZE_32);
-      assert(value < 0x200);
+      assert(value < AGX_NUM_UNIFORMS);
 
       return
          (value & BITFIELD_MASK(6)) |
-         ((value >> 8) << 6) |
+         ((value & BITFIELD_BIT(8)) ? (1 << 6) : 0) |
          ((size == AGX_SIZE_32) ? (1 << 7) : 0) |
          (0x1 << 8) |
          (((value >> 6) & BITFIELD_MASK(2)) << 10);