xref: /aosp_15_r20/external/mesa3d/src/asahi/lib/agx_usc.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright 2022 Alyssa Rosenzweig
3*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker  */
5*61046927SAndroid Build Coastguard Worker 
6*61046927SAndroid Build Coastguard Worker #pragma once
7*61046927SAndroid Build Coastguard Worker 
8*61046927SAndroid Build Coastguard Worker #include "asahi/genxml/agx_pack.h"
9*61046927SAndroid Build Coastguard Worker #include "agx_compile.h"
10*61046927SAndroid Build Coastguard Worker 
11*61046927SAndroid Build Coastguard Worker /* Opaque structure representing a USC program being constructed */
12*61046927SAndroid Build Coastguard Worker struct agx_usc_builder {
13*61046927SAndroid Build Coastguard Worker    uint8_t *head;
14*61046927SAndroid Build Coastguard Worker 
15*61046927SAndroid Build Coastguard Worker #ifndef NDEBUG
16*61046927SAndroid Build Coastguard Worker    uint8_t *begin;
17*61046927SAndroid Build Coastguard Worker    size_t size;
18*61046927SAndroid Build Coastguard Worker #endif
19*61046927SAndroid Build Coastguard Worker };
20*61046927SAndroid Build Coastguard Worker 
21*61046927SAndroid Build Coastguard Worker static inline unsigned
agx_usc_size(unsigned num_reg_bindings)22*61046927SAndroid Build Coastguard Worker agx_usc_size(unsigned num_reg_bindings)
23*61046927SAndroid Build Coastguard Worker {
24*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT(AGX_USC_UNIFORM_HIGH_LENGTH == AGX_USC_UNIFORM_LENGTH);
25*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT(AGX_USC_TEXTURE_LENGTH == AGX_USC_UNIFORM_LENGTH);
26*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT(AGX_USC_SAMPLER_LENGTH == AGX_USC_UNIFORM_LENGTH);
27*61046927SAndroid Build Coastguard Worker 
28*61046927SAndroid Build Coastguard Worker    size_t size = AGX_USC_UNIFORM_LENGTH * num_reg_bindings;
29*61046927SAndroid Build Coastguard Worker 
30*61046927SAndroid Build Coastguard Worker    size += AGX_USC_SHARED_LENGTH;
31*61046927SAndroid Build Coastguard Worker    size += AGX_USC_SHADER_LENGTH;
32*61046927SAndroid Build Coastguard Worker    size += AGX_USC_REGISTERS_LENGTH;
33*61046927SAndroid Build Coastguard Worker    size += MAX2(AGX_USC_NO_PRESHADER_LENGTH, AGX_USC_PRESHADER_LENGTH);
34*61046927SAndroid Build Coastguard Worker    size += AGX_USC_FRAGMENT_PROPERTIES_LENGTH;
35*61046927SAndroid Build Coastguard Worker 
36*61046927SAndroid Build Coastguard Worker    return size;
37*61046927SAndroid Build Coastguard Worker }
38*61046927SAndroid Build Coastguard Worker 
39*61046927SAndroid Build Coastguard Worker static struct agx_usc_builder
agx_usc_builder(void * out,ASSERTED size_t size)40*61046927SAndroid Build Coastguard Worker agx_usc_builder(void *out, ASSERTED size_t size)
41*61046927SAndroid Build Coastguard Worker {
42*61046927SAndroid Build Coastguard Worker    return (struct agx_usc_builder){
43*61046927SAndroid Build Coastguard Worker       .head = out,
44*61046927SAndroid Build Coastguard Worker 
45*61046927SAndroid Build Coastguard Worker #ifndef NDEBUG
46*61046927SAndroid Build Coastguard Worker       .begin = out,
47*61046927SAndroid Build Coastguard Worker       .size = size,
48*61046927SAndroid Build Coastguard Worker #endif
49*61046927SAndroid Build Coastguard Worker    };
50*61046927SAndroid Build Coastguard Worker }
51*61046927SAndroid Build Coastguard Worker 
52*61046927SAndroid Build Coastguard Worker static bool
agx_usc_builder_validate(struct agx_usc_builder * b,size_t size)53*61046927SAndroid Build Coastguard Worker agx_usc_builder_validate(struct agx_usc_builder *b, size_t size)
54*61046927SAndroid Build Coastguard Worker {
55*61046927SAndroid Build Coastguard Worker #ifndef NDEBUG
56*61046927SAndroid Build Coastguard Worker    assert(((b->head - b->begin) + size) <= b->size);
57*61046927SAndroid Build Coastguard Worker #endif
58*61046927SAndroid Build Coastguard Worker 
59*61046927SAndroid Build Coastguard Worker    return true;
60*61046927SAndroid Build Coastguard Worker }
61*61046927SAndroid Build Coastguard Worker 
62*61046927SAndroid Build Coastguard Worker #define agx_usc_pack(b, struct_name, template)                                 \
63*61046927SAndroid Build Coastguard Worker    for (bool it =                                                              \
64*61046927SAndroid Build Coastguard Worker            agx_usc_builder_validate((b), AGX_USC_##struct_name##_LENGTH);      \
65*61046927SAndroid Build Coastguard Worker         it; it = false, (b)->head += AGX_USC_##struct_name##_LENGTH)           \
66*61046927SAndroid Build Coastguard Worker       agx_pack((b)->head, USC_##struct_name, template)
67*61046927SAndroid Build Coastguard Worker 
68*61046927SAndroid Build Coastguard Worker #define agx_usc_push_blob(b, blob, length)                                     \
69*61046927SAndroid Build Coastguard Worker    for (bool it = agx_usc_builder_validate((b), length); it;                   \
70*61046927SAndroid Build Coastguard Worker         it = false, (b)->head += length)                                       \
71*61046927SAndroid Build Coastguard Worker       memcpy((b)->head, blob, length);
72*61046927SAndroid Build Coastguard Worker 
73*61046927SAndroid Build Coastguard Worker #define agx_usc_push_packed(b, struct_name, packed)                            \
74*61046927SAndroid Build Coastguard Worker    agx_usc_push_blob(b, packed.opaque, AGX_USC_##struct_name##_LENGTH);
75*61046927SAndroid Build Coastguard Worker 
76*61046927SAndroid Build Coastguard Worker static void
agx_usc_uniform(struct agx_usc_builder * b,unsigned start_halfs,unsigned size_halfs,uint64_t buffer)77*61046927SAndroid Build Coastguard Worker agx_usc_uniform(struct agx_usc_builder *b, unsigned start_halfs,
78*61046927SAndroid Build Coastguard Worker                 unsigned size_halfs, uint64_t buffer)
79*61046927SAndroid Build Coastguard Worker {
80*61046927SAndroid Build Coastguard Worker    assert((start_halfs + size_halfs) <= (1 << 9) && "uniform file overflow");
81*61046927SAndroid Build Coastguard Worker    assert(size_halfs <= 64 && "caller's responsibility to split");
82*61046927SAndroid Build Coastguard Worker    assert(size_halfs > 0 && "no empty uniforms");
83*61046927SAndroid Build Coastguard Worker 
84*61046927SAndroid Build Coastguard Worker    if (start_halfs & BITFIELD_BIT(8)) {
85*61046927SAndroid Build Coastguard Worker       agx_usc_pack(b, UNIFORM_HIGH, cfg) {
86*61046927SAndroid Build Coastguard Worker          cfg.start_halfs = start_halfs & BITFIELD_MASK(8);
87*61046927SAndroid Build Coastguard Worker          cfg.size_halfs = size_halfs;
88*61046927SAndroid Build Coastguard Worker          cfg.buffer = buffer;
89*61046927SAndroid Build Coastguard Worker       }
90*61046927SAndroid Build Coastguard Worker    } else {
91*61046927SAndroid Build Coastguard Worker       agx_usc_pack(b, UNIFORM, cfg) {
92*61046927SAndroid Build Coastguard Worker          cfg.start_halfs = start_halfs;
93*61046927SAndroid Build Coastguard Worker          cfg.size_halfs = size_halfs;
94*61046927SAndroid Build Coastguard Worker          cfg.buffer = buffer;
95*61046927SAndroid Build Coastguard Worker       }
96*61046927SAndroid Build Coastguard Worker    }
97*61046927SAndroid Build Coastguard Worker }
98*61046927SAndroid Build Coastguard Worker 
99*61046927SAndroid Build Coastguard Worker static void
agx_usc_shared_none(struct agx_usc_builder * b)100*61046927SAndroid Build Coastguard Worker agx_usc_shared_none(struct agx_usc_builder *b)
101*61046927SAndroid Build Coastguard Worker {
102*61046927SAndroid Build Coastguard Worker    agx_usc_pack(b, SHARED, cfg) {
103*61046927SAndroid Build Coastguard Worker       cfg.layout = AGX_SHARED_LAYOUT_VERTEX_COMPUTE;
104*61046927SAndroid Build Coastguard Worker       cfg.bytes_per_threadgroup = 65536;
105*61046927SAndroid Build Coastguard Worker    }
106*61046927SAndroid Build Coastguard Worker }
107*61046927SAndroid Build Coastguard Worker 
108*61046927SAndroid Build Coastguard Worker static void
agx_usc_shared_non_fragment(struct agx_usc_builder * b,struct agx_shader_info * info,unsigned variable_shared_mem)109*61046927SAndroid Build Coastguard Worker agx_usc_shared_non_fragment(struct agx_usc_builder *b,
110*61046927SAndroid Build Coastguard Worker                             struct agx_shader_info *info,
111*61046927SAndroid Build Coastguard Worker                             unsigned variable_shared_mem)
112*61046927SAndroid Build Coastguard Worker {
113*61046927SAndroid Build Coastguard Worker    if (info->stage == PIPE_SHADER_FRAGMENT) {
114*61046927SAndroid Build Coastguard Worker       return;
115*61046927SAndroid Build Coastguard Worker    } else if (info->stage == PIPE_SHADER_COMPUTE && info->imageblock_stride) {
116*61046927SAndroid Build Coastguard Worker       assert(info->local_size == 0 && "we don't handle this interaction");
117*61046927SAndroid Build Coastguard Worker       assert(variable_shared_mem == 0 && "we don't handle this interaction");
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker       agx_usc_pack(b, SHARED, cfg) {
120*61046927SAndroid Build Coastguard Worker          cfg.layout = AGX_SHARED_LAYOUT_32X32;
121*61046927SAndroid Build Coastguard Worker          cfg.uses_shared_memory = true;
122*61046927SAndroid Build Coastguard Worker          cfg.sample_count = 1;
123*61046927SAndroid Build Coastguard Worker          cfg.sample_stride_in_8_bytes =
124*61046927SAndroid Build Coastguard Worker             DIV_ROUND_UP(info->imageblock_stride, 8);
125*61046927SAndroid Build Coastguard Worker          cfg.bytes_per_threadgroup = cfg.sample_stride_in_8_bytes * 8 * 32 * 32;
126*61046927SAndroid Build Coastguard Worker       }
127*61046927SAndroid Build Coastguard Worker    } else if (info->stage == PIPE_SHADER_COMPUTE ||
128*61046927SAndroid Build Coastguard Worker               info->stage == PIPE_SHADER_TESS_CTRL) {
129*61046927SAndroid Build Coastguard Worker       unsigned size = info->local_size + variable_shared_mem;
130*61046927SAndroid Build Coastguard Worker 
131*61046927SAndroid Build Coastguard Worker       agx_usc_pack(b, SHARED, cfg) {
132*61046927SAndroid Build Coastguard Worker          cfg.layout = AGX_SHARED_LAYOUT_VERTEX_COMPUTE;
133*61046927SAndroid Build Coastguard Worker          cfg.bytes_per_threadgroup = size > 0 ? size : 65536;
134*61046927SAndroid Build Coastguard Worker          cfg.uses_shared_memory = size > 0;
135*61046927SAndroid Build Coastguard Worker       }
136*61046927SAndroid Build Coastguard Worker    } else {
137*61046927SAndroid Build Coastguard Worker       agx_usc_shared_none(b);
138*61046927SAndroid Build Coastguard Worker    }
139*61046927SAndroid Build Coastguard Worker }
140