xref: /aosp_15_r20/external/mesa3d/src/nouveau/headers/nv_push.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker #ifndef NV_PUSH_H
2*61046927SAndroid Build Coastguard Worker #define NV_PUSH_H
3*61046927SAndroid Build Coastguard Worker 
4*61046927SAndroid Build Coastguard Worker #include "nvtypes.h"
5*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
6*61046927SAndroid Build Coastguard Worker 
7*61046927SAndroid Build Coastguard Worker #include <assert.h>
8*61046927SAndroid Build Coastguard Worker #include <stddef.h>
9*61046927SAndroid Build Coastguard Worker #include <string.h>
10*61046927SAndroid Build Coastguard Worker #include <stdio.h>
11*61046927SAndroid Build Coastguard Worker 
12*61046927SAndroid Build Coastguard Worker struct nv_device_info;
13*61046927SAndroid Build Coastguard Worker 
14*61046927SAndroid Build Coastguard Worker struct nv_push {
15*61046927SAndroid Build Coastguard Worker    uint32_t *start;
16*61046927SAndroid Build Coastguard Worker    uint32_t *end;
17*61046927SAndroid Build Coastguard Worker    uint32_t *limit;
18*61046927SAndroid Build Coastguard Worker 
19*61046927SAndroid Build Coastguard Worker    /* A pointer to the last method header */
20*61046927SAndroid Build Coastguard Worker    uint32_t *last_hdr;
21*61046927SAndroid Build Coastguard Worker 
22*61046927SAndroid Build Coastguard Worker    /* The value in the last method header, used to avoid read-back */
23*61046927SAndroid Build Coastguard Worker    uint32_t last_hdr_dw;
24*61046927SAndroid Build Coastguard Worker };
25*61046927SAndroid Build Coastguard Worker 
26*61046927SAndroid Build Coastguard Worker static inline void
nv_push_init(struct nv_push * push,uint32_t * start,size_t dw_count)27*61046927SAndroid Build Coastguard Worker nv_push_init(struct nv_push *push, uint32_t *start, size_t dw_count)
28*61046927SAndroid Build Coastguard Worker {
29*61046927SAndroid Build Coastguard Worker    push->start = start;
30*61046927SAndroid Build Coastguard Worker    push->end = start;
31*61046927SAndroid Build Coastguard Worker    push->limit = start + dw_count;
32*61046927SAndroid Build Coastguard Worker    push->last_hdr = NULL;
33*61046927SAndroid Build Coastguard Worker    push->last_hdr_dw = 0;
34*61046927SAndroid Build Coastguard Worker }
35*61046927SAndroid Build Coastguard Worker 
36*61046927SAndroid Build Coastguard Worker static inline size_t
nv_push_dw_count(struct nv_push * push)37*61046927SAndroid Build Coastguard Worker nv_push_dw_count(struct nv_push *push)
38*61046927SAndroid Build Coastguard Worker {
39*61046927SAndroid Build Coastguard Worker    assert(push->start <= push->end);
40*61046927SAndroid Build Coastguard Worker    assert(push->end <= push->limit);
41*61046927SAndroid Build Coastguard Worker    return push->end - push->start;
42*61046927SAndroid Build Coastguard Worker }
43*61046927SAndroid Build Coastguard Worker 
44*61046927SAndroid Build Coastguard Worker #ifndef NDEBUG
45*61046927SAndroid Build Coastguard Worker void nv_push_validate(struct nv_push *push);
46*61046927SAndroid Build Coastguard Worker #else
nv_push_validate(struct nv_push * push)47*61046927SAndroid Build Coastguard Worker static inline void nv_push_validate(struct nv_push *push) { }
48*61046927SAndroid Build Coastguard Worker #endif
49*61046927SAndroid Build Coastguard Worker 
50*61046927SAndroid Build Coastguard Worker void vk_push_print(FILE *fp, const struct nv_push *push,
51*61046927SAndroid Build Coastguard Worker                    const struct nv_device_info *devinfo);
52*61046927SAndroid Build Coastguard Worker 
53*61046927SAndroid Build Coastguard Worker #define SUBC_NV9097 0
54*61046927SAndroid Build Coastguard Worker #define SUBC_NVA097 0
55*61046927SAndroid Build Coastguard Worker #define SUBC_NVB097 0
56*61046927SAndroid Build Coastguard Worker #define SUBC_NVB197 0
57*61046927SAndroid Build Coastguard Worker #define SUBC_NVC097 0
58*61046927SAndroid Build Coastguard Worker #define SUBC_NVC397 0
59*61046927SAndroid Build Coastguard Worker #define SUBC_NVC597 0
60*61046927SAndroid Build Coastguard Worker 
61*61046927SAndroid Build Coastguard Worker #define SUBC_NV90C0 1
62*61046927SAndroid Build Coastguard Worker #define SUBC_NVA0C0 1
63*61046927SAndroid Build Coastguard Worker #define SUBC_NVB0C0 1
64*61046927SAndroid Build Coastguard Worker #define SUBC_NVB1C0 1
65*61046927SAndroid Build Coastguard Worker #define SUBC_NVC0C0 1
66*61046927SAndroid Build Coastguard Worker #define SUBC_NVC3C0 1
67*61046927SAndroid Build Coastguard Worker #define SUBC_NVC6C0 1
68*61046927SAndroid Build Coastguard Worker 
69*61046927SAndroid Build Coastguard Worker #define SUBC_NV9039 2
70*61046927SAndroid Build Coastguard Worker 
71*61046927SAndroid Build Coastguard Worker #define SUBC_NV902D 3
72*61046927SAndroid Build Coastguard Worker 
73*61046927SAndroid Build Coastguard Worker #define SUBC_NV90B5 4
74*61046927SAndroid Build Coastguard Worker #define SUBC_NVC1B5 4
75*61046927SAndroid Build Coastguard Worker 
76*61046927SAndroid Build Coastguard Worker static inline uint32_t
NVC0_FIFO_PKHDR_SQ(int subc,int mthd,unsigned size)77*61046927SAndroid Build Coastguard Worker NVC0_FIFO_PKHDR_SQ(int subc, int mthd, unsigned size)
78*61046927SAndroid Build Coastguard Worker {
79*61046927SAndroid Build Coastguard Worker    return 0x20000000 | (size << 16) | (subc << 13) | (mthd >> 2);
80*61046927SAndroid Build Coastguard Worker }
81*61046927SAndroid Build Coastguard Worker 
82*61046927SAndroid Build Coastguard Worker static inline void
__push_verify(struct nv_push * push)83*61046927SAndroid Build Coastguard Worker __push_verify(struct nv_push *push)
84*61046927SAndroid Build Coastguard Worker {
85*61046927SAndroid Build Coastguard Worker    if (push->last_hdr == NULL)
86*61046927SAndroid Build Coastguard Worker       return;
87*61046927SAndroid Build Coastguard Worker 
88*61046927SAndroid Build Coastguard Worker    /* check for immd */
89*61046927SAndroid Build Coastguard Worker    if (push->last_hdr_dw >> 29 == 4)
90*61046927SAndroid Build Coastguard Worker       return;
91*61046927SAndroid Build Coastguard Worker 
92*61046927SAndroid Build Coastguard Worker    ASSERTED uint32_t last_count = (push->last_hdr_dw & 0x1fff0000);
93*61046927SAndroid Build Coastguard Worker    assert(last_count);
94*61046927SAndroid Build Coastguard Worker }
95*61046927SAndroid Build Coastguard Worker 
96*61046927SAndroid Build Coastguard Worker static inline void
__push_hdr(struct nv_push * push,uint32_t hdr)97*61046927SAndroid Build Coastguard Worker __push_hdr(struct nv_push *push, uint32_t hdr)
98*61046927SAndroid Build Coastguard Worker {
99*61046927SAndroid Build Coastguard Worker    __push_verify(push);
100*61046927SAndroid Build Coastguard Worker 
101*61046927SAndroid Build Coastguard Worker    *push->end = hdr;
102*61046927SAndroid Build Coastguard Worker    push->last_hdr_dw = hdr;
103*61046927SAndroid Build Coastguard Worker    push->last_hdr = push->end;
104*61046927SAndroid Build Coastguard Worker    push->end++;
105*61046927SAndroid Build Coastguard Worker }
106*61046927SAndroid Build Coastguard Worker 
107*61046927SAndroid Build Coastguard Worker static inline void
__push_mthd_size(struct nv_push * push,int subc,uint32_t mthd,unsigned size)108*61046927SAndroid Build Coastguard Worker __push_mthd_size(struct nv_push *push, int subc, uint32_t mthd, unsigned size)
109*61046927SAndroid Build Coastguard Worker {
110*61046927SAndroid Build Coastguard Worker    __push_hdr(push, NVC0_FIFO_PKHDR_SQ(subc, mthd, size));
111*61046927SAndroid Build Coastguard Worker }
112*61046927SAndroid Build Coastguard Worker 
113*61046927SAndroid Build Coastguard Worker static inline void
__push_mthd(struct nv_push * push,int subc,uint32_t mthd)114*61046927SAndroid Build Coastguard Worker __push_mthd(struct nv_push *push, int subc, uint32_t mthd)
115*61046927SAndroid Build Coastguard Worker {
116*61046927SAndroid Build Coastguard Worker    __push_mthd_size(push, subc, mthd, 0);
117*61046927SAndroid Build Coastguard Worker }
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker #define P_MTHD(push, class, mthd) __push_mthd(push, SUBC_##class, class##_##mthd)
120*61046927SAndroid Build Coastguard Worker 
121*61046927SAndroid Build Coastguard Worker static inline uint32_t
NVC0_FIFO_PKHDR_IL(int subc,int mthd,uint16_t data)122*61046927SAndroid Build Coastguard Worker NVC0_FIFO_PKHDR_IL(int subc, int mthd, uint16_t data)
123*61046927SAndroid Build Coastguard Worker {
124*61046927SAndroid Build Coastguard Worker    assert(!(data & ~0x1fff));
125*61046927SAndroid Build Coastguard Worker    return 0x80000000 | (data << 16) | (subc << 13) | (mthd >> 2);
126*61046927SAndroid Build Coastguard Worker }
127*61046927SAndroid Build Coastguard Worker 
128*61046927SAndroid Build Coastguard Worker static inline void
__push_immd(struct nv_push * push,int subc,uint32_t mthd,uint32_t val)129*61046927SAndroid Build Coastguard Worker __push_immd(struct nv_push *push, int subc, uint32_t mthd, uint32_t val)
130*61046927SAndroid Build Coastguard Worker {
131*61046927SAndroid Build Coastguard Worker    __push_hdr(push, NVC0_FIFO_PKHDR_IL(subc, mthd, val));
132*61046927SAndroid Build Coastguard Worker }
133*61046927SAndroid Build Coastguard Worker 
134*61046927SAndroid Build Coastguard Worker #define P_IMMD(push, class, mthd, args...) do {                         \
135*61046927SAndroid Build Coastguard Worker    uint32_t __val;                                                      \
136*61046927SAndroid Build Coastguard Worker    VA_##class##_##mthd(__val, args);                                    \
137*61046927SAndroid Build Coastguard Worker    if (__builtin_constant_p(__val & ~0x1fff) && !(__val & ~0x1fff)) {   \
138*61046927SAndroid Build Coastguard Worker       __push_immd(push, SUBC_##class, class##_##mthd, __val);           \
139*61046927SAndroid Build Coastguard Worker    } else {                                                             \
140*61046927SAndroid Build Coastguard Worker       __push_mthd_size(push, SUBC_##class, class##_##mthd, 0);          \
141*61046927SAndroid Build Coastguard Worker       nv_push_val(push, class##_##mthd, __val);                        \
142*61046927SAndroid Build Coastguard Worker    }                                                                    \
143*61046927SAndroid Build Coastguard Worker } while(0)
144*61046927SAndroid Build Coastguard Worker 
145*61046927SAndroid Build Coastguard Worker static inline uint32_t
NVC0_FIFO_PKHDR_1I(int subc,int mthd,unsigned size)146*61046927SAndroid Build Coastguard Worker NVC0_FIFO_PKHDR_1I(int subc, int mthd, unsigned size)
147*61046927SAndroid Build Coastguard Worker {
148*61046927SAndroid Build Coastguard Worker    return 0xa0000000 | (size << 16) | (subc << 13) | (mthd >> 2);
149*61046927SAndroid Build Coastguard Worker }
150*61046927SAndroid Build Coastguard Worker 
151*61046927SAndroid Build Coastguard Worker static inline void
__push_1inc(struct nv_push * push,int subc,uint32_t mthd)152*61046927SAndroid Build Coastguard Worker __push_1inc(struct nv_push *push, int subc, uint32_t mthd)
153*61046927SAndroid Build Coastguard Worker {
154*61046927SAndroid Build Coastguard Worker    __push_hdr(push, NVC0_FIFO_PKHDR_1I(subc, mthd, 0));
155*61046927SAndroid Build Coastguard Worker }
156*61046927SAndroid Build Coastguard Worker 
157*61046927SAndroid Build Coastguard Worker #define P_1INC(push, class, mthd) __push_1inc(push, SUBC_##class, class##_##mthd)
158*61046927SAndroid Build Coastguard Worker 
159*61046927SAndroid Build Coastguard Worker static inline uint32_t
NVC0_FIFO_PKHDR_0I(int subc,int mthd,unsigned size)160*61046927SAndroid Build Coastguard Worker NVC0_FIFO_PKHDR_0I(int subc, int mthd, unsigned size)
161*61046927SAndroid Build Coastguard Worker {
162*61046927SAndroid Build Coastguard Worker    return 0x60000000 | (size << 16) | (subc << 13) | (mthd >> 2);
163*61046927SAndroid Build Coastguard Worker }
164*61046927SAndroid Build Coastguard Worker 
165*61046927SAndroid Build Coastguard Worker static inline void
__push_0inc(struct nv_push * push,int subc,uint32_t mthd)166*61046927SAndroid Build Coastguard Worker __push_0inc(struct nv_push *push, int subc, uint32_t mthd)
167*61046927SAndroid Build Coastguard Worker {
168*61046927SAndroid Build Coastguard Worker    __push_hdr(push, NVC0_FIFO_PKHDR_0I(subc, mthd, 0));
169*61046927SAndroid Build Coastguard Worker }
170*61046927SAndroid Build Coastguard Worker 
171*61046927SAndroid Build Coastguard Worker #define P_0INC(push, class, mthd) __push_0inc(push, SUBC_##class, class##_##mthd)
172*61046927SAndroid Build Coastguard Worker 
173*61046927SAndroid Build Coastguard Worker #define NV_PUSH_MAX_COUNT 0x1fff
174*61046927SAndroid Build Coastguard Worker 
175*61046927SAndroid Build Coastguard Worker static inline bool
nv_push_update_count(struct nv_push * push,uint16_t count)176*61046927SAndroid Build Coastguard Worker nv_push_update_count(struct nv_push *push, uint16_t count)
177*61046927SAndroid Build Coastguard Worker {
178*61046927SAndroid Build Coastguard Worker    assert(push->last_hdr != NULL);
179*61046927SAndroid Build Coastguard Worker 
180*61046927SAndroid Build Coastguard Worker    assert(count <= NV_PUSH_MAX_COUNT);
181*61046927SAndroid Build Coastguard Worker    if (count > NV_PUSH_MAX_COUNT)
182*61046927SAndroid Build Coastguard Worker       return false;
183*61046927SAndroid Build Coastguard Worker 
184*61046927SAndroid Build Coastguard Worker    uint32_t hdr_dw = push->last_hdr_dw;
185*61046927SAndroid Build Coastguard Worker 
186*61046927SAndroid Build Coastguard Worker    /* size is encoded at 28:16 */
187*61046927SAndroid Build Coastguard Worker    uint32_t new_count = (count + (hdr_dw >> 16)) & NV_PUSH_MAX_COUNT;
188*61046927SAndroid Build Coastguard Worker    bool overflow = new_count < count;
189*61046927SAndroid Build Coastguard Worker    /* if we would overflow, don't change anything and just let it be */
190*61046927SAndroid Build Coastguard Worker    assert(!overflow);
191*61046927SAndroid Build Coastguard Worker    if (overflow)
192*61046927SAndroid Build Coastguard Worker       return false;
193*61046927SAndroid Build Coastguard Worker 
194*61046927SAndroid Build Coastguard Worker    hdr_dw &= ~0x1fff0000;
195*61046927SAndroid Build Coastguard Worker    hdr_dw |= new_count << 16;
196*61046927SAndroid Build Coastguard Worker    push->last_hdr_dw = hdr_dw;
197*61046927SAndroid Build Coastguard Worker    *push->last_hdr = hdr_dw;
198*61046927SAndroid Build Coastguard Worker    return true;
199*61046927SAndroid Build Coastguard Worker }
200*61046927SAndroid Build Coastguard Worker 
201*61046927SAndroid Build Coastguard Worker static inline void
P_INLINE_DATA(struct nv_push * push,uint32_t value)202*61046927SAndroid Build Coastguard Worker P_INLINE_DATA(struct nv_push *push, uint32_t value)
203*61046927SAndroid Build Coastguard Worker {
204*61046927SAndroid Build Coastguard Worker    assert(push->end < push->limit);
205*61046927SAndroid Build Coastguard Worker    if (nv_push_update_count(push, 1)) {
206*61046927SAndroid Build Coastguard Worker       /* push new value */
207*61046927SAndroid Build Coastguard Worker       *push->end = value;
208*61046927SAndroid Build Coastguard Worker       push->end++;
209*61046927SAndroid Build Coastguard Worker    }
210*61046927SAndroid Build Coastguard Worker }
211*61046927SAndroid Build Coastguard Worker 
212*61046927SAndroid Build Coastguard Worker static inline void
P_INLINE_FLOAT(struct nv_push * push,float value)213*61046927SAndroid Build Coastguard Worker P_INLINE_FLOAT(struct nv_push *push, float value)
214*61046927SAndroid Build Coastguard Worker {
215*61046927SAndroid Build Coastguard Worker    assert(push->end < push->limit);
216*61046927SAndroid Build Coastguard Worker    if (nv_push_update_count(push, 1)) {
217*61046927SAndroid Build Coastguard Worker       /* push new value */
218*61046927SAndroid Build Coastguard Worker       *(float *)push->end = value;
219*61046927SAndroid Build Coastguard Worker       push->end++;
220*61046927SAndroid Build Coastguard Worker    }
221*61046927SAndroid Build Coastguard Worker }
222*61046927SAndroid Build Coastguard Worker 
223*61046927SAndroid Build Coastguard Worker static inline void
P_INLINE_ARRAY(struct nv_push * push,const uint32_t * data,int num_dw)224*61046927SAndroid Build Coastguard Worker P_INLINE_ARRAY(struct nv_push *push, const uint32_t *data, int num_dw)
225*61046927SAndroid Build Coastguard Worker {
226*61046927SAndroid Build Coastguard Worker    assert(push->end + num_dw <= push->limit);
227*61046927SAndroid Build Coastguard Worker    if (nv_push_update_count(push, num_dw)) {
228*61046927SAndroid Build Coastguard Worker       /* push new value */
229*61046927SAndroid Build Coastguard Worker       memcpy(push->end, data, num_dw * 4);
230*61046927SAndroid Build Coastguard Worker       push->end += num_dw;
231*61046927SAndroid Build Coastguard Worker    }
232*61046927SAndroid Build Coastguard Worker }
233*61046927SAndroid Build Coastguard Worker 
234*61046927SAndroid Build Coastguard Worker /* internally used by generated inlines. */
235*61046927SAndroid Build Coastguard Worker static inline void
nv_push_val(struct nv_push * push,uint32_t idx,uint32_t val)236*61046927SAndroid Build Coastguard Worker nv_push_val(struct nv_push *push, uint32_t idx, uint32_t val)
237*61046927SAndroid Build Coastguard Worker {
238*61046927SAndroid Build Coastguard Worker    ASSERTED uint32_t last_hdr_dw = push->last_hdr_dw;
239*61046927SAndroid Build Coastguard Worker    ASSERTED bool is_0inc = (last_hdr_dw & 0xe0000000) == 0x60000000;
240*61046927SAndroid Build Coastguard Worker    ASSERTED bool is_1inc = (last_hdr_dw & 0xe0000000) == 0xa0000000;
241*61046927SAndroid Build Coastguard Worker    ASSERTED bool is_immd = (last_hdr_dw & 0xe0000000) == 0x80000000;
242*61046927SAndroid Build Coastguard Worker    ASSERTED uint16_t last_method = (last_hdr_dw & 0x1fff) << 2;
243*61046927SAndroid Build Coastguard Worker 
244*61046927SAndroid Build Coastguard Worker    uint16_t distance = push->end - push->last_hdr - 1;
245*61046927SAndroid Build Coastguard Worker    if (is_0inc)
246*61046927SAndroid Build Coastguard Worker       distance = 0;
247*61046927SAndroid Build Coastguard Worker    else if (is_1inc)
248*61046927SAndroid Build Coastguard Worker       distance = MIN2(1, distance);
249*61046927SAndroid Build Coastguard Worker    last_method += distance * 4;
250*61046927SAndroid Build Coastguard Worker 
251*61046927SAndroid Build Coastguard Worker    /* can't have empty headers ever */
252*61046927SAndroid Build Coastguard Worker    assert(last_hdr_dw);
253*61046927SAndroid Build Coastguard Worker    assert(!is_immd);
254*61046927SAndroid Build Coastguard Worker    assert(last_method == idx);
255*61046927SAndroid Build Coastguard Worker    assert(push->end < push->limit);
256*61046927SAndroid Build Coastguard Worker 
257*61046927SAndroid Build Coastguard Worker    P_INLINE_DATA(push, val);
258*61046927SAndroid Build Coastguard Worker }
259*61046927SAndroid Build Coastguard Worker 
260*61046927SAndroid Build Coastguard Worker static inline void
nv_push_raw(struct nv_push * push,uint32_t * raw_dw,uint32_t dw_count)261*61046927SAndroid Build Coastguard Worker nv_push_raw(struct nv_push *push, uint32_t *raw_dw, uint32_t dw_count)
262*61046927SAndroid Build Coastguard Worker {
263*61046927SAndroid Build Coastguard Worker    assert(push->end + dw_count <= push->limit);
264*61046927SAndroid Build Coastguard Worker    memcpy(push->end, raw_dw, dw_count * 4);
265*61046927SAndroid Build Coastguard Worker    push->end += dw_count;
266*61046927SAndroid Build Coastguard Worker    push->last_hdr = NULL;
267*61046927SAndroid Build Coastguard Worker }
268*61046927SAndroid Build Coastguard Worker 
269*61046927SAndroid Build Coastguard Worker #endif /* NV_PUSH_H */
270