From d466ccc6bd975c9ba3b270974780bb7f75ab7ffa Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Sat, 2 Nov 2024 09:03:26 -0400 Subject: [PATCH] libagx: promote math to use AGX address mode we want to fit into the 64 + ext() << #n pattern to let us fuse address arithmetic into our loads, so rework some libagx addressing to better match that Signed-off-by: Alyssa Rosenzweig Part-of: --- src/asahi/lib/shaders/geometry.cl | 3 +- src/asahi/lib/shaders/geometry.h | 47 ++++++++++++++++++++------- src/asahi/lib/shaders/tessellation.cl | 13 +++++--- src/asahi/lib/shaders/texture.cl | 7 +++- 4 files changed, 51 insertions(+), 19 deletions(-) diff --git a/src/asahi/lib/shaders/geometry.cl b/src/asahi/lib/shaders/geometry.cl index 9fe6a992273..4522f2c9355 100644 --- a/src/asahi/lib/shaders/geometry.cl +++ b/src/asahi/lib/shaders/geometry.cl @@ -665,7 +665,8 @@ uintptr_t libagx_vertex_output_address(uintptr_t buffer, uint64_t mask, uint vtx, gl_varying_slot location) { - return buffer + libagx_tcs_in_offs(vtx, location, mask); + /* Written like this to let address arithmetic work */ + return buffer + ((uintptr_t)libagx_tcs_in_offs_el(vtx, location, mask)) * 16; } uintptr_t diff --git a/src/asahi/lib/shaders/geometry.h b/src/asahi/lib/shaders/geometry.h index a700166988e..fb432fe16bd 100644 --- a/src/asahi/lib/shaders/geometry.h +++ b/src/asahi/lib/shaders/geometry.h @@ -217,14 +217,21 @@ AGX_STATIC_ASSERT(sizeof(struct agx_geometry_params) == 82 * 4); * TODO: compact. */ static inline uint -libagx_tcs_in_offs(uint vtx, gl_varying_slot location, - uint64_t crosslane_vs_out_mask) +libagx_tcs_in_offs_el(uint vtx, gl_varying_slot location, + uint64_t crosslane_vs_out_mask) { uint base = vtx * libagx_popcount(crosslane_vs_out_mask); uint offs = libagx_popcount(crosslane_vs_out_mask & (((uint64_t)(1) << location) - 1)); - return (base + offs) * 16; + return base + offs; +} + +static inline uint +libagx_tcs_in_offs(uint vtx, gl_varying_slot location, + uint64_t crosslane_vs_out_mask) +{ + return libagx_tcs_in_offs_el(vtx, location, crosslane_vs_out_mask) * 16; } static inline uint @@ -247,34 +254,50 @@ libagx_tcs_in_size(uint32_t vertices_in_patch, uint64_t crosslane_vs_out_mask) * Bounding boxes are ignored. */ static inline uint -libagx_tcs_out_offs(uint vtx_id, gl_varying_slot location, uint nr_patch_out, - uint64_t vtx_out_mask) +libagx_tcs_out_offs_el(uint vtx_id, gl_varying_slot location, uint nr_patch_out, + uint64_t vtx_out_mask) { uint off = 0; if (location == VARYING_SLOT_TESS_LEVEL_OUTER) return off; - off += 4 * sizeof(float); + off += 4; if (location == VARYING_SLOT_TESS_LEVEL_INNER) return off; - off += 2 * sizeof(float); + off += 2; if (location >= VARYING_SLOT_PATCH0) - return off + (16 * (location - VARYING_SLOT_PATCH0)); + return off + (4 * (location - VARYING_SLOT_PATCH0)); /* Anything else is a per-vtx output */ - off += 16 * nr_patch_out; - off += 16 * vtx_id * libagx_popcount(vtx_out_mask); + off += 4 * nr_patch_out; + off += 4 * vtx_id * libagx_popcount(vtx_out_mask); uint idx = libagx_popcount(vtx_out_mask & (((uint64_t)(1) << location) - 1)); - return off + (16 * idx); + return off + (4 * idx); +} + +static inline uint +libagx_tcs_out_offs(uint vtx_id, gl_varying_slot location, uint nr_patch_out, + uint64_t vtx_out_mask) +{ + return libagx_tcs_out_offs_el(vtx_id, location, nr_patch_out, vtx_out_mask) * + 4; +} + +static inline uint +libagx_tcs_out_stride_el(uint nr_patch_out, uint out_patch_size, + uint64_t vtx_out_mask) +{ + return libagx_tcs_out_offs_el(out_patch_size, 0, nr_patch_out, vtx_out_mask); } static inline uint libagx_tcs_out_stride(uint nr_patch_out, uint out_patch_size, uint64_t vtx_out_mask) { - return libagx_tcs_out_offs(out_patch_size, 0, nr_patch_out, vtx_out_mask); + return libagx_tcs_out_stride_el(nr_patch_out, out_patch_size, vtx_out_mask) * + 4; } /* In a tess eval shader, stride for hw vertex ID */ diff --git a/src/asahi/lib/shaders/tessellation.cl b/src/asahi/lib/shaders/tessellation.cl index c5b71b4e968..bc9910d0fae 100644 --- a/src/asahi/lib/shaders/tessellation.cl +++ b/src/asahi/lib/shaders/tessellation.cl @@ -71,13 +71,16 @@ libagx_tcs_out_address(constant struct libagx_tess_args *p, uint patch_id, uint vtx_id, gl_varying_slot location, uint nr_patch_out, uint out_patch_size, uint64_t vtx_out_mask) { - uint stride = - libagx_tcs_out_stride(nr_patch_out, out_patch_size, vtx_out_mask); + uint stride_el = + libagx_tcs_out_stride_el(nr_patch_out, out_patch_size, vtx_out_mask); - uint offs = - libagx_tcs_out_offs(vtx_id, location, nr_patch_out, vtx_out_mask); + uint offs_el = + libagx_tcs_out_offs_el(vtx_id, location, nr_patch_out, vtx_out_mask); - return (uintptr_t)(p->tcs_buffer) + (patch_id * stride) + offs; + offs_el += patch_id * stride_el; + + /* Written to match the AGX addressing mode */ + return (uintptr_t)(p->tcs_buffer) + (((uintptr_t)offs_el) << 2); } static uint diff --git a/src/asahi/lib/shaders/texture.cl b/src/asahi/lib/shaders/texture.cl index b56b7e31c69..c4fee794743 100644 --- a/src/asahi/lib/shaders/texture.cl +++ b/src/asahi/lib/shaders/texture.cl @@ -222,7 +222,12 @@ libagx_texture_load_rgb32(constant struct agx_texture_packed *ptr, uint coord, bool is_float) { agx_unpack(NULL, ptr, TEXTURE, d); - constant uint3 *data = (constant uint3 *)(d.address + 12 * coord); + + /* This is carefully written to let us do the * 3 with a 32-bit operation but + * still use the free 64-bit add-extend-shift for the rest. + */ + uint64_t addr = d.address + ((uint64_t)(coord * 3)) * 4; + constant uint3 *data = (constant uint3 *)addr; return (uint4)(*data, is_float ? as_uint(1.0f) : 1); }