xref: /aosp_15_r20/external/mesa3d/src/freedreno/decode/script.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
2*61046927SAndroid Build Coastguard Worker 
3*61046927SAndroid Build Coastguard Worker /*
4*61046927SAndroid Build Coastguard Worker  * Copyright © 2014 Rob Clark <[email protected]>
5*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
6*61046927SAndroid Build Coastguard Worker  *
7*61046927SAndroid Build Coastguard Worker  * Authors:
8*61046927SAndroid Build Coastguard Worker  *    Rob Clark <[email protected]>
9*61046927SAndroid Build Coastguard Worker  */
10*61046927SAndroid Build Coastguard Worker 
11*61046927SAndroid Build Coastguard Worker #define LUA_COMPAT_APIINTCASTS
12*61046927SAndroid Build Coastguard Worker 
13*61046927SAndroid Build Coastguard Worker #include <assert.h>
14*61046927SAndroid Build Coastguard Worker #include <lauxlib.h>
15*61046927SAndroid Build Coastguard Worker #include <lua.h>
16*61046927SAndroid Build Coastguard Worker #include <lualib.h>
17*61046927SAndroid Build Coastguard Worker #include <stdio.h>
18*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
19*61046927SAndroid Build Coastguard Worker #include <string.h>
20*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
21*61046927SAndroid Build Coastguard Worker 
22*61046927SAndroid Build Coastguard Worker #include "cffdec.h"
23*61046927SAndroid Build Coastguard Worker #include "rnnutil.h"
24*61046927SAndroid Build Coastguard Worker #include "script.h"
25*61046927SAndroid Build Coastguard Worker 
26*61046927SAndroid Build Coastguard Worker static lua_State *L;
27*61046927SAndroid Build Coastguard Worker 
28*61046927SAndroid Build Coastguard Worker #if 0
29*61046927SAndroid Build Coastguard Worker #define DBG(fmt, ...)                                                          \
30*61046927SAndroid Build Coastguard Worker    do {                                                                        \
31*61046927SAndroid Build Coastguard Worker       printf(" ** %s:%d ** " fmt "\n", __func__, __LINE__, ##__VA_ARGS__);     \
32*61046927SAndroid Build Coastguard Worker    } while (0)
33*61046927SAndroid Build Coastguard Worker #else
34*61046927SAndroid Build Coastguard Worker #define DBG(fmt, ...)                                                          \
35*61046927SAndroid Build Coastguard Worker    do {                                                                        \
36*61046927SAndroid Build Coastguard Worker    } while (0)
37*61046927SAndroid Build Coastguard Worker #endif
38*61046927SAndroid Build Coastguard Worker 
39*61046927SAndroid Build Coastguard Worker /* An rnn based decoder, which can either be decoding current register
40*61046927SAndroid Build Coastguard Worker  * values, or domain based decoding of a pm4 packet.
41*61046927SAndroid Build Coastguard Worker  *
42*61046927SAndroid Build Coastguard Worker  */
43*61046927SAndroid Build Coastguard Worker struct rnndec {
44*61046927SAndroid Build Coastguard Worker    struct rnn base;
45*61046927SAndroid Build Coastguard Worker 
46*61046927SAndroid Build Coastguard Worker    /* for pm4 packet decoding: */
47*61046927SAndroid Build Coastguard Worker    uint32_t sizedwords;
48*61046927SAndroid Build Coastguard Worker    uint32_t *dwords;
49*61046927SAndroid Build Coastguard Worker };
50*61046927SAndroid Build Coastguard Worker 
51*61046927SAndroid Build Coastguard Worker static inline struct rnndec *
to_rnndec(struct rnn * rnn)52*61046927SAndroid Build Coastguard Worker to_rnndec(struct rnn *rnn)
53*61046927SAndroid Build Coastguard Worker {
54*61046927SAndroid Build Coastguard Worker    return (struct rnndec *)rnn;
55*61046927SAndroid Build Coastguard Worker }
56*61046927SAndroid Build Coastguard Worker 
57*61046927SAndroid Build Coastguard Worker static uint32_t
rnn_val(struct rnn * rnn,uint32_t regbase)58*61046927SAndroid Build Coastguard Worker rnn_val(struct rnn *rnn, uint32_t regbase)
59*61046927SAndroid Build Coastguard Worker {
60*61046927SAndroid Build Coastguard Worker    struct rnndec *rnndec = to_rnndec(rnn);
61*61046927SAndroid Build Coastguard Worker 
62*61046927SAndroid Build Coastguard Worker    if (!rnndec->sizedwords) {
63*61046927SAndroid Build Coastguard Worker       return reg_val(regbase);
64*61046927SAndroid Build Coastguard Worker    } else if (regbase < rnndec->sizedwords) {
65*61046927SAndroid Build Coastguard Worker       return rnndec->dwords[regbase];
66*61046927SAndroid Build Coastguard Worker    } else {
67*61046927SAndroid Build Coastguard Worker       // XXX throw an error
68*61046927SAndroid Build Coastguard Worker       return -1;
69*61046927SAndroid Build Coastguard Worker    }
70*61046927SAndroid Build Coastguard Worker }
71*61046927SAndroid Build Coastguard Worker 
72*61046927SAndroid Build Coastguard Worker /* does not return */
73*61046927SAndroid Build Coastguard Worker static void
error(const char * fmt)74*61046927SAndroid Build Coastguard Worker error(const char *fmt)
75*61046927SAndroid Build Coastguard Worker {
76*61046927SAndroid Build Coastguard Worker    fprintf(stderr, fmt, lua_tostring(L, -1));
77*61046927SAndroid Build Coastguard Worker    exit(1);
78*61046927SAndroid Build Coastguard Worker }
79*61046927SAndroid Build Coastguard Worker 
80*61046927SAndroid Build Coastguard Worker /*
81*61046927SAndroid Build Coastguard Worker  * An enum type that can be used as string or number:
82*61046927SAndroid Build Coastguard Worker  */
83*61046927SAndroid Build Coastguard Worker 
84*61046927SAndroid Build Coastguard Worker struct rnndenum {
85*61046927SAndroid Build Coastguard Worker    const char *str;
86*61046927SAndroid Build Coastguard Worker    int val;
87*61046927SAndroid Build Coastguard Worker };
88*61046927SAndroid Build Coastguard Worker 
89*61046927SAndroid Build Coastguard Worker static int
l_meta_rnn_enum_tostring(lua_State * L)90*61046927SAndroid Build Coastguard Worker l_meta_rnn_enum_tostring(lua_State *L)
91*61046927SAndroid Build Coastguard Worker {
92*61046927SAndroid Build Coastguard Worker    struct rnndenum *e = lua_touserdata(L, 1);
93*61046927SAndroid Build Coastguard Worker    if (e->str) {
94*61046927SAndroid Build Coastguard Worker       lua_pushstring(L, e->str);
95*61046927SAndroid Build Coastguard Worker    } else {
96*61046927SAndroid Build Coastguard Worker       char buf[32];
97*61046927SAndroid Build Coastguard Worker       sprintf(buf, "%u", e->val);
98*61046927SAndroid Build Coastguard Worker       lua_pushstring(L, buf);
99*61046927SAndroid Build Coastguard Worker    }
100*61046927SAndroid Build Coastguard Worker    return 1;
101*61046927SAndroid Build Coastguard Worker }
102*61046927SAndroid Build Coastguard Worker 
103*61046927SAndroid Build Coastguard Worker /* so, this doesn't actually seem to be implemented yet, but hopefully
104*61046927SAndroid Build Coastguard Worker  * some day lua comes to it's senses
105*61046927SAndroid Build Coastguard Worker  */
106*61046927SAndroid Build Coastguard Worker static int
l_meta_rnn_enum_tonumber(lua_State * L)107*61046927SAndroid Build Coastguard Worker l_meta_rnn_enum_tonumber(lua_State *L)
108*61046927SAndroid Build Coastguard Worker {
109*61046927SAndroid Build Coastguard Worker    struct rnndenum *e = lua_touserdata(L, 1);
110*61046927SAndroid Build Coastguard Worker    lua_pushinteger(L, e->val);
111*61046927SAndroid Build Coastguard Worker    return 1;
112*61046927SAndroid Build Coastguard Worker }
113*61046927SAndroid Build Coastguard Worker 
114*61046927SAndroid Build Coastguard Worker static const struct luaL_Reg l_meta_rnn_enum[] = {
115*61046927SAndroid Build Coastguard Worker    {"__tostring", l_meta_rnn_enum_tostring},
116*61046927SAndroid Build Coastguard Worker    {"__tonumber", l_meta_rnn_enum_tonumber},
117*61046927SAndroid Build Coastguard Worker    {NULL, NULL} /* sentinel */
118*61046927SAndroid Build Coastguard Worker };
119*61046927SAndroid Build Coastguard Worker 
120*61046927SAndroid Build Coastguard Worker static void
pushenum(struct lua_State * L,int val,struct rnnenum * info)121*61046927SAndroid Build Coastguard Worker pushenum(struct lua_State *L, int val, struct rnnenum *info)
122*61046927SAndroid Build Coastguard Worker {
123*61046927SAndroid Build Coastguard Worker    struct rnndenum *e = lua_newuserdata(L, sizeof(*e));
124*61046927SAndroid Build Coastguard Worker 
125*61046927SAndroid Build Coastguard Worker    e->val = val;
126*61046927SAndroid Build Coastguard Worker    e->str = NULL;
127*61046927SAndroid Build Coastguard Worker 
128*61046927SAndroid Build Coastguard Worker    for (int i = 0; i < info->valsnum; i++) {
129*61046927SAndroid Build Coastguard Worker       if (info->vals[i]->valvalid && (info->vals[i]->value == val)) {
130*61046927SAndroid Build Coastguard Worker          e->str = info->vals[i]->name;
131*61046927SAndroid Build Coastguard Worker          break;
132*61046927SAndroid Build Coastguard Worker       }
133*61046927SAndroid Build Coastguard Worker    }
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker    luaL_newmetatable(L, "rnnmetaenum");
136*61046927SAndroid Build Coastguard Worker    luaL_setfuncs(L, l_meta_rnn_enum, 0);
137*61046927SAndroid Build Coastguard Worker    lua_pop(L, 1);
138*61046927SAndroid Build Coastguard Worker 
139*61046927SAndroid Build Coastguard Worker    luaL_setmetatable(L, "rnnmetaenum");
140*61046927SAndroid Build Coastguard Worker }
141*61046927SAndroid Build Coastguard Worker 
142*61046927SAndroid Build Coastguard Worker /* Expose rnn decode to script environment as "rnn" library:
143*61046927SAndroid Build Coastguard Worker  */
144*61046927SAndroid Build Coastguard Worker 
145*61046927SAndroid Build Coastguard Worker struct rnndoff {
146*61046927SAndroid Build Coastguard Worker    struct rnn *rnn;
147*61046927SAndroid Build Coastguard Worker    struct rnndelem *elem;
148*61046927SAndroid Build Coastguard Worker    uint64_t offset;
149*61046927SAndroid Build Coastguard Worker };
150*61046927SAndroid Build Coastguard Worker 
151*61046927SAndroid Build Coastguard Worker static void
push_rnndoff(lua_State * L,struct rnn * rnn,struct rnndelem * elem,uint64_t offset)152*61046927SAndroid Build Coastguard Worker push_rnndoff(lua_State *L, struct rnn *rnn, struct rnndelem *elem,
153*61046927SAndroid Build Coastguard Worker              uint64_t offset)
154*61046927SAndroid Build Coastguard Worker {
155*61046927SAndroid Build Coastguard Worker    struct rnndoff *rnndoff = lua_newuserdata(L, sizeof(*rnndoff));
156*61046927SAndroid Build Coastguard Worker    rnndoff->rnn = rnn;
157*61046927SAndroid Build Coastguard Worker    rnndoff->elem = elem;
158*61046927SAndroid Build Coastguard Worker    rnndoff->offset = offset;
159*61046927SAndroid Build Coastguard Worker }
160*61046927SAndroid Build Coastguard Worker 
161*61046927SAndroid Build Coastguard Worker static int l_rnn_etype_array(lua_State *L, struct rnn *rnn,
162*61046927SAndroid Build Coastguard Worker                              struct rnndelem *elem, uint64_t offset);
163*61046927SAndroid Build Coastguard Worker static int l_rnn_etype_reg(lua_State *L, struct rnn *rnn, struct rnndelem *elem,
164*61046927SAndroid Build Coastguard Worker                            uint64_t offset);
165*61046927SAndroid Build Coastguard Worker 
166*61046927SAndroid Build Coastguard Worker static int
pushdecval(struct lua_State * L,struct rnn * rnn,uint64_t regval,struct rnntypeinfo * info)167*61046927SAndroid Build Coastguard Worker pushdecval(struct lua_State *L, struct rnn *rnn, uint64_t regval,
168*61046927SAndroid Build Coastguard Worker            struct rnntypeinfo *info)
169*61046927SAndroid Build Coastguard Worker {
170*61046927SAndroid Build Coastguard Worker    union rnndecval val;
171*61046927SAndroid Build Coastguard Worker    switch (rnn_decodelem(rnn, info, regval, &val)) {
172*61046927SAndroid Build Coastguard Worker    case RNN_TTYPE_ENUM:
173*61046927SAndroid Build Coastguard Worker    case RNN_TTYPE_INLINE_ENUM:
174*61046927SAndroid Build Coastguard Worker       pushenum(L, val.i, info->eenum);
175*61046927SAndroid Build Coastguard Worker       return 1;
176*61046927SAndroid Build Coastguard Worker    case RNN_TTYPE_INT:
177*61046927SAndroid Build Coastguard Worker       lua_pushinteger(L, val.i);
178*61046927SAndroid Build Coastguard Worker       return 1;
179*61046927SAndroid Build Coastguard Worker    case RNN_TTYPE_UINT:
180*61046927SAndroid Build Coastguard Worker    case RNN_TTYPE_HEX:
181*61046927SAndroid Build Coastguard Worker       lua_pushunsigned(L, val.u);
182*61046927SAndroid Build Coastguard Worker       return 1;
183*61046927SAndroid Build Coastguard Worker    case RNN_TTYPE_FLOAT:
184*61046927SAndroid Build Coastguard Worker       lua_pushnumber(L, uif(val.u));
185*61046927SAndroid Build Coastguard Worker       return 1;
186*61046927SAndroid Build Coastguard Worker    case RNN_TTYPE_BOOLEAN:
187*61046927SAndroid Build Coastguard Worker       lua_pushboolean(L, val.u);
188*61046927SAndroid Build Coastguard Worker       return 1;
189*61046927SAndroid Build Coastguard Worker    case RNN_TTYPE_INVALID:
190*61046927SAndroid Build Coastguard Worker    default:
191*61046927SAndroid Build Coastguard Worker       return 0;
192*61046927SAndroid Build Coastguard Worker    }
193*61046927SAndroid Build Coastguard Worker }
194*61046927SAndroid Build Coastguard Worker 
195*61046927SAndroid Build Coastguard Worker static int
l_rnn_etype(lua_State * L,struct rnn * rnn,struct rnndelem * elem,uint64_t offset)196*61046927SAndroid Build Coastguard Worker l_rnn_etype(lua_State *L, struct rnn *rnn, struct rnndelem *elem,
197*61046927SAndroid Build Coastguard Worker             uint64_t offset)
198*61046927SAndroid Build Coastguard Worker {
199*61046927SAndroid Build Coastguard Worker    int ret;
200*61046927SAndroid Build Coastguard Worker    uint64_t regval;
201*61046927SAndroid Build Coastguard Worker    DBG("elem=%p (%d), offset=%lu", elem, elem->type, offset);
202*61046927SAndroid Build Coastguard Worker    switch (elem->type) {
203*61046927SAndroid Build Coastguard Worker    case RNN_ETYPE_REG:
204*61046927SAndroid Build Coastguard Worker       /* if a register has no bitfields, just return
205*61046927SAndroid Build Coastguard Worker        * the raw value:
206*61046927SAndroid Build Coastguard Worker        */
207*61046927SAndroid Build Coastguard Worker       regval = rnn_val(rnn, offset);
208*61046927SAndroid Build Coastguard Worker       if (elem->width == 64)
209*61046927SAndroid Build Coastguard Worker          regval |= (uint64_t)rnn_val(rnn, offset + 1) << 32;
210*61046927SAndroid Build Coastguard Worker       regval <<= elem->typeinfo.shr;
211*61046927SAndroid Build Coastguard Worker       ret = pushdecval(L, rnn, regval, &elem->typeinfo);
212*61046927SAndroid Build Coastguard Worker       if (ret)
213*61046927SAndroid Build Coastguard Worker          return ret;
214*61046927SAndroid Build Coastguard Worker       return l_rnn_etype_reg(L, rnn, elem, offset);
215*61046927SAndroid Build Coastguard Worker    case RNN_ETYPE_ARRAY:
216*61046927SAndroid Build Coastguard Worker       return l_rnn_etype_array(L, rnn, elem, offset);
217*61046927SAndroid Build Coastguard Worker    default:
218*61046927SAndroid Build Coastguard Worker       /* hmm.. */
219*61046927SAndroid Build Coastguard Worker       printf("unhandled type: %d\n", elem->type);
220*61046927SAndroid Build Coastguard Worker       return 0;
221*61046927SAndroid Build Coastguard Worker    }
222*61046927SAndroid Build Coastguard Worker }
223*61046927SAndroid Build Coastguard Worker 
224*61046927SAndroid Build Coastguard Worker /*
225*61046927SAndroid Build Coastguard Worker  * Struct Object:
226*61046927SAndroid Build Coastguard Worker  * To implement stuff like 'RB_MRT[n].CONTROL' we need a struct-object
227*61046927SAndroid Build Coastguard Worker  * to represent the current array index (ie. 'RB_MRT[n]')
228*61046927SAndroid Build Coastguard Worker  */
229*61046927SAndroid Build Coastguard Worker 
230*61046927SAndroid Build Coastguard Worker static int
l_rnn_struct_meta_index(lua_State * L)231*61046927SAndroid Build Coastguard Worker l_rnn_struct_meta_index(lua_State *L)
232*61046927SAndroid Build Coastguard Worker {
233*61046927SAndroid Build Coastguard Worker    struct rnndoff *rnndoff = lua_touserdata(L, 1);
234*61046927SAndroid Build Coastguard Worker    const char *name = lua_tostring(L, 2);
235*61046927SAndroid Build Coastguard Worker    struct rnndelem *elem = rnndoff->elem;
236*61046927SAndroid Build Coastguard Worker    int i;
237*61046927SAndroid Build Coastguard Worker 
238*61046927SAndroid Build Coastguard Worker    for (i = 0; i < elem->subelemsnum; i++) {
239*61046927SAndroid Build Coastguard Worker       struct rnndelem *subelem = elem->subelems[i];
240*61046927SAndroid Build Coastguard Worker       if (!strcmp(name, subelem->name)) {
241*61046927SAndroid Build Coastguard Worker          return l_rnn_etype(L, rnndoff->rnn, subelem,
242*61046927SAndroid Build Coastguard Worker                             rnndoff->offset + subelem->offset);
243*61046927SAndroid Build Coastguard Worker       }
244*61046927SAndroid Build Coastguard Worker    }
245*61046927SAndroid Build Coastguard Worker 
246*61046927SAndroid Build Coastguard Worker    return 0;
247*61046927SAndroid Build Coastguard Worker }
248*61046927SAndroid Build Coastguard Worker 
249*61046927SAndroid Build Coastguard Worker static const struct luaL_Reg l_meta_rnn_struct[] = {
250*61046927SAndroid Build Coastguard Worker    {"__index", l_rnn_struct_meta_index}, {NULL, NULL} /* sentinel */
251*61046927SAndroid Build Coastguard Worker };
252*61046927SAndroid Build Coastguard Worker 
253*61046927SAndroid Build Coastguard Worker static int
l_rnn_etype_struct(lua_State * L,struct rnn * rnn,struct rnndelem * elem,uint64_t offset)254*61046927SAndroid Build Coastguard Worker l_rnn_etype_struct(lua_State *L, struct rnn *rnn, struct rnndelem *elem,
255*61046927SAndroid Build Coastguard Worker                    uint64_t offset)
256*61046927SAndroid Build Coastguard Worker {
257*61046927SAndroid Build Coastguard Worker    push_rnndoff(L, rnn, elem, offset);
258*61046927SAndroid Build Coastguard Worker 
259*61046927SAndroid Build Coastguard Worker    luaL_newmetatable(L, "rnnmetastruct");
260*61046927SAndroid Build Coastguard Worker    luaL_setfuncs(L, l_meta_rnn_struct, 0);
261*61046927SAndroid Build Coastguard Worker    lua_pop(L, 1);
262*61046927SAndroid Build Coastguard Worker 
263*61046927SAndroid Build Coastguard Worker    luaL_setmetatable(L, "rnnmetastruct");
264*61046927SAndroid Build Coastguard Worker 
265*61046927SAndroid Build Coastguard Worker    return 1;
266*61046927SAndroid Build Coastguard Worker }
267*61046927SAndroid Build Coastguard Worker 
268*61046927SAndroid Build Coastguard Worker /*
269*61046927SAndroid Build Coastguard Worker  * Array Object:
270*61046927SAndroid Build Coastguard Worker  */
271*61046927SAndroid Build Coastguard Worker 
272*61046927SAndroid Build Coastguard Worker static int
l_rnn_array_meta_index(lua_State * L)273*61046927SAndroid Build Coastguard Worker l_rnn_array_meta_index(lua_State *L)
274*61046927SAndroid Build Coastguard Worker {
275*61046927SAndroid Build Coastguard Worker    struct rnndoff *rnndoff = lua_touserdata(L, 1);
276*61046927SAndroid Build Coastguard Worker    int idx = lua_tointeger(L, 2);
277*61046927SAndroid Build Coastguard Worker    struct rnndelem *elem = rnndoff->elem;
278*61046927SAndroid Build Coastguard Worker    uint64_t offset = rnndoff->offset + (elem->stride * idx);
279*61046927SAndroid Build Coastguard Worker 
280*61046927SAndroid Build Coastguard Worker    DBG("rnndoff=%p, idx=%d, numsubelems=%d", rnndoff, idx,
281*61046927SAndroid Build Coastguard Worker        rnndoff->elem->subelemsnum);
282*61046927SAndroid Build Coastguard Worker 
283*61046927SAndroid Build Coastguard Worker    /* if just a single sub-element, it is directly a register,
284*61046927SAndroid Build Coastguard Worker     * otherwise we need to accumulate the array index while
285*61046927SAndroid Build Coastguard Worker     * we wait for the register name within the array..
286*61046927SAndroid Build Coastguard Worker     */
287*61046927SAndroid Build Coastguard Worker    if (elem->subelemsnum == 1) {
288*61046927SAndroid Build Coastguard Worker       return l_rnn_etype(L, rnndoff->rnn, elem->subelems[0], offset);
289*61046927SAndroid Build Coastguard Worker    } else {
290*61046927SAndroid Build Coastguard Worker       return l_rnn_etype_struct(L, rnndoff->rnn, elem, offset);
291*61046927SAndroid Build Coastguard Worker    }
292*61046927SAndroid Build Coastguard Worker 
293*61046927SAndroid Build Coastguard Worker    return 0;
294*61046927SAndroid Build Coastguard Worker }
295*61046927SAndroid Build Coastguard Worker 
296*61046927SAndroid Build Coastguard Worker static const struct luaL_Reg l_meta_rnn_array[] = {
297*61046927SAndroid Build Coastguard Worker    {"__index", l_rnn_array_meta_index}, {NULL, NULL} /* sentinel */
298*61046927SAndroid Build Coastguard Worker };
299*61046927SAndroid Build Coastguard Worker 
300*61046927SAndroid Build Coastguard Worker static int
l_rnn_etype_array(lua_State * L,struct rnn * rnn,struct rnndelem * elem,uint64_t offset)301*61046927SAndroid Build Coastguard Worker l_rnn_etype_array(lua_State *L, struct rnn *rnn, struct rnndelem *elem,
302*61046927SAndroid Build Coastguard Worker                   uint64_t offset)
303*61046927SAndroid Build Coastguard Worker {
304*61046927SAndroid Build Coastguard Worker    push_rnndoff(L, rnn, elem, offset);
305*61046927SAndroid Build Coastguard Worker 
306*61046927SAndroid Build Coastguard Worker    luaL_newmetatable(L, "rnnmetaarray");
307*61046927SAndroid Build Coastguard Worker    luaL_setfuncs(L, l_meta_rnn_array, 0);
308*61046927SAndroid Build Coastguard Worker    lua_pop(L, 1);
309*61046927SAndroid Build Coastguard Worker 
310*61046927SAndroid Build Coastguard Worker    luaL_setmetatable(L, "rnnmetaarray");
311*61046927SAndroid Build Coastguard Worker 
312*61046927SAndroid Build Coastguard Worker    return 1;
313*61046927SAndroid Build Coastguard Worker }
314*61046927SAndroid Build Coastguard Worker 
315*61046927SAndroid Build Coastguard Worker /*
316*61046927SAndroid Build Coastguard Worker  * Register element:
317*61046927SAndroid Build Coastguard Worker  */
318*61046927SAndroid Build Coastguard Worker 
319*61046927SAndroid Build Coastguard Worker static int
l_rnn_reg_meta_index(lua_State * L)320*61046927SAndroid Build Coastguard Worker l_rnn_reg_meta_index(lua_State *L)
321*61046927SAndroid Build Coastguard Worker {
322*61046927SAndroid Build Coastguard Worker    struct rnndoff *rnndoff = lua_touserdata(L, 1);
323*61046927SAndroid Build Coastguard Worker    const char *name = lua_tostring(L, 2);
324*61046927SAndroid Build Coastguard Worker    struct rnndelem *elem = rnndoff->elem;
325*61046927SAndroid Build Coastguard Worker    struct rnntypeinfo *info = &elem->typeinfo;
326*61046927SAndroid Build Coastguard Worker    struct rnnbitfield **bitfields;
327*61046927SAndroid Build Coastguard Worker    int bitfieldsnum;
328*61046927SAndroid Build Coastguard Worker    int i;
329*61046927SAndroid Build Coastguard Worker 
330*61046927SAndroid Build Coastguard Worker    switch (info->type) {
331*61046927SAndroid Build Coastguard Worker    case RNN_TTYPE_BITSET:
332*61046927SAndroid Build Coastguard Worker       bitfields = info->ebitset->bitfields;
333*61046927SAndroid Build Coastguard Worker       bitfieldsnum = info->ebitset->bitfieldsnum;
334*61046927SAndroid Build Coastguard Worker       break;
335*61046927SAndroid Build Coastguard Worker    case RNN_TTYPE_INLINE_BITSET:
336*61046927SAndroid Build Coastguard Worker       bitfields = info->bitfields;
337*61046927SAndroid Build Coastguard Worker       bitfieldsnum = info->bitfieldsnum;
338*61046927SAndroid Build Coastguard Worker       break;
339*61046927SAndroid Build Coastguard Worker    default:
340*61046927SAndroid Build Coastguard Worker       printf("invalid register type: %d\n", info->type);
341*61046927SAndroid Build Coastguard Worker       return 0;
342*61046927SAndroid Build Coastguard Worker    }
343*61046927SAndroid Build Coastguard Worker 
344*61046927SAndroid Build Coastguard Worker    for (i = 0; i < bitfieldsnum; i++) {
345*61046927SAndroid Build Coastguard Worker       struct rnnbitfield *bf = bitfields[i];
346*61046927SAndroid Build Coastguard Worker       if (!strcmp(name, bf->name)) {
347*61046927SAndroid Build Coastguard Worker          uint32_t regval = rnn_val(rnndoff->rnn, rnndoff->offset);
348*61046927SAndroid Build Coastguard Worker 
349*61046927SAndroid Build Coastguard Worker          regval &= typeinfo_mask(&bf->typeinfo);
350*61046927SAndroid Build Coastguard Worker          regval >>= bf->typeinfo.low;
351*61046927SAndroid Build Coastguard Worker          regval <<= bf->typeinfo.shr;
352*61046927SAndroid Build Coastguard Worker 
353*61046927SAndroid Build Coastguard Worker          DBG("name=%s, info=%p, subelemsnum=%d, type=%d, regval=%x", name, info,
354*61046927SAndroid Build Coastguard Worker              rnndoff->elem->subelemsnum, bf->typeinfo.type, regval);
355*61046927SAndroid Build Coastguard Worker 
356*61046927SAndroid Build Coastguard Worker          return pushdecval(L, rnndoff->rnn, regval, &bf->typeinfo);
357*61046927SAndroid Build Coastguard Worker       }
358*61046927SAndroid Build Coastguard Worker    }
359*61046927SAndroid Build Coastguard Worker 
360*61046927SAndroid Build Coastguard Worker    printf("invalid member: %s\n", name);
361*61046927SAndroid Build Coastguard Worker    return 0;
362*61046927SAndroid Build Coastguard Worker }
363*61046927SAndroid Build Coastguard Worker 
364*61046927SAndroid Build Coastguard Worker static int
l_rnn_reg_meta_tostring(lua_State * L)365*61046927SAndroid Build Coastguard Worker l_rnn_reg_meta_tostring(lua_State *L)
366*61046927SAndroid Build Coastguard Worker {
367*61046927SAndroid Build Coastguard Worker    struct rnndoff *rnndoff = lua_touserdata(L, 1);
368*61046927SAndroid Build Coastguard Worker    uint32_t regval = rnn_val(rnndoff->rnn, rnndoff->offset);
369*61046927SAndroid Build Coastguard Worker    struct rnndecaddrinfo *info = rnn_reginfo(rnndoff->rnn, rnndoff->offset);
370*61046927SAndroid Build Coastguard Worker    char *decoded;
371*61046927SAndroid Build Coastguard Worker    if (info && info->typeinfo) {
372*61046927SAndroid Build Coastguard Worker       decoded = rnndec_decodeval(rnndoff->rnn->vc, info->typeinfo, regval);
373*61046927SAndroid Build Coastguard Worker    } else {
374*61046927SAndroid Build Coastguard Worker       asprintf(&decoded, "%08x", regval);
375*61046927SAndroid Build Coastguard Worker    }
376*61046927SAndroid Build Coastguard Worker    lua_pushstring(L, decoded);
377*61046927SAndroid Build Coastguard Worker    free(decoded);
378*61046927SAndroid Build Coastguard Worker    rnn_reginfo_free(info);
379*61046927SAndroid Build Coastguard Worker    return 1;
380*61046927SAndroid Build Coastguard Worker }
381*61046927SAndroid Build Coastguard Worker 
382*61046927SAndroid Build Coastguard Worker static int
l_rnn_reg_meta_tonumber(lua_State * L)383*61046927SAndroid Build Coastguard Worker l_rnn_reg_meta_tonumber(lua_State *L)
384*61046927SAndroid Build Coastguard Worker {
385*61046927SAndroid Build Coastguard Worker    struct rnndoff *rnndoff = lua_touserdata(L, 1);
386*61046927SAndroid Build Coastguard Worker    uint32_t regval = rnn_val(rnndoff->rnn, rnndoff->offset);
387*61046927SAndroid Build Coastguard Worker 
388*61046927SAndroid Build Coastguard Worker    regval <<= rnndoff->elem->typeinfo.shr;
389*61046927SAndroid Build Coastguard Worker 
390*61046927SAndroid Build Coastguard Worker    lua_pushnumber(L, regval);
391*61046927SAndroid Build Coastguard Worker    return 1;
392*61046927SAndroid Build Coastguard Worker }
393*61046927SAndroid Build Coastguard Worker 
394*61046927SAndroid Build Coastguard Worker static const struct luaL_Reg l_meta_rnn_reg[] = {
395*61046927SAndroid Build Coastguard Worker    {"__index", l_rnn_reg_meta_index},
396*61046927SAndroid Build Coastguard Worker    {"__tostring", l_rnn_reg_meta_tostring},
397*61046927SAndroid Build Coastguard Worker    {"__tonumber", l_rnn_reg_meta_tonumber},
398*61046927SAndroid Build Coastguard Worker    {NULL, NULL} /* sentinel */
399*61046927SAndroid Build Coastguard Worker };
400*61046927SAndroid Build Coastguard Worker 
401*61046927SAndroid Build Coastguard Worker static int
l_rnn_etype_reg(lua_State * L,struct rnn * rnn,struct rnndelem * elem,uint64_t offset)402*61046927SAndroid Build Coastguard Worker l_rnn_etype_reg(lua_State *L, struct rnn *rnn, struct rnndelem *elem,
403*61046927SAndroid Build Coastguard Worker                 uint64_t offset)
404*61046927SAndroid Build Coastguard Worker {
405*61046927SAndroid Build Coastguard Worker    push_rnndoff(L, rnn, elem, offset);
406*61046927SAndroid Build Coastguard Worker 
407*61046927SAndroid Build Coastguard Worker    luaL_newmetatable(L, "rnnmetareg");
408*61046927SAndroid Build Coastguard Worker    luaL_setfuncs(L, l_meta_rnn_reg, 0);
409*61046927SAndroid Build Coastguard Worker    lua_pop(L, 1);
410*61046927SAndroid Build Coastguard Worker 
411*61046927SAndroid Build Coastguard Worker    luaL_setmetatable(L, "rnnmetareg");
412*61046927SAndroid Build Coastguard Worker 
413*61046927SAndroid Build Coastguard Worker    return 1;
414*61046927SAndroid Build Coastguard Worker }
415*61046927SAndroid Build Coastguard Worker 
416*61046927SAndroid Build Coastguard Worker /*
417*61046927SAndroid Build Coastguard Worker  *
418*61046927SAndroid Build Coastguard Worker  */
419*61046927SAndroid Build Coastguard Worker 
420*61046927SAndroid Build Coastguard Worker static int
l_rnn_meta_index(lua_State * L)421*61046927SAndroid Build Coastguard Worker l_rnn_meta_index(lua_State *L)
422*61046927SAndroid Build Coastguard Worker {
423*61046927SAndroid Build Coastguard Worker    struct rnn *rnn = lua_touserdata(L, 1);
424*61046927SAndroid Build Coastguard Worker    const char *name = lua_tostring(L, 2);
425*61046927SAndroid Build Coastguard Worker    struct rnndelem *elem;
426*61046927SAndroid Build Coastguard Worker 
427*61046927SAndroid Build Coastguard Worker    elem = rnn_regelem(rnn, name);
428*61046927SAndroid Build Coastguard Worker    if (!elem)
429*61046927SAndroid Build Coastguard Worker       return 0;
430*61046927SAndroid Build Coastguard Worker 
431*61046927SAndroid Build Coastguard Worker    return l_rnn_etype(L, rnn, elem, elem->offset);
432*61046927SAndroid Build Coastguard Worker }
433*61046927SAndroid Build Coastguard Worker 
434*61046927SAndroid Build Coastguard Worker static int
l_rnn_meta_gc(lua_State * L)435*61046927SAndroid Build Coastguard Worker l_rnn_meta_gc(lua_State *L)
436*61046927SAndroid Build Coastguard Worker {
437*61046927SAndroid Build Coastguard Worker    // TODO
438*61046927SAndroid Build Coastguard Worker    // struct rnn *rnn = lua_touserdata(L, 1);
439*61046927SAndroid Build Coastguard Worker    // rnn_deinit(rnn);
440*61046927SAndroid Build Coastguard Worker    return 0;
441*61046927SAndroid Build Coastguard Worker }
442*61046927SAndroid Build Coastguard Worker 
443*61046927SAndroid Build Coastguard Worker static const struct luaL_Reg l_meta_rnn[] = {
444*61046927SAndroid Build Coastguard Worker    {"__index", l_rnn_meta_index},
445*61046927SAndroid Build Coastguard Worker    {"__gc", l_rnn_meta_gc},
446*61046927SAndroid Build Coastguard Worker    {NULL, NULL} /* sentinel */
447*61046927SAndroid Build Coastguard Worker };
448*61046927SAndroid Build Coastguard Worker 
449*61046927SAndroid Build Coastguard Worker static int
l_rnn_init(lua_State * L)450*61046927SAndroid Build Coastguard Worker l_rnn_init(lua_State *L)
451*61046927SAndroid Build Coastguard Worker {
452*61046927SAndroid Build Coastguard Worker    const char *gpuname = lua_tostring(L, 1);
453*61046927SAndroid Build Coastguard Worker    struct rnndec *rnndec = lua_newuserdata(L, sizeof(*rnndec));
454*61046927SAndroid Build Coastguard Worker    _rnn_init(&rnndec->base, 0);
455*61046927SAndroid Build Coastguard Worker    rnn_load(&rnndec->base, gpuname);
456*61046927SAndroid Build Coastguard Worker    rnndec->sizedwords = 0;
457*61046927SAndroid Build Coastguard Worker 
458*61046927SAndroid Build Coastguard Worker    luaL_newmetatable(L, "rnnmeta");
459*61046927SAndroid Build Coastguard Worker    luaL_setfuncs(L, l_meta_rnn, 0);
460*61046927SAndroid Build Coastguard Worker    lua_pop(L, 1);
461*61046927SAndroid Build Coastguard Worker 
462*61046927SAndroid Build Coastguard Worker    luaL_setmetatable(L, "rnnmeta");
463*61046927SAndroid Build Coastguard Worker 
464*61046927SAndroid Build Coastguard Worker    return 1;
465*61046927SAndroid Build Coastguard Worker }
466*61046927SAndroid Build Coastguard Worker 
467*61046927SAndroid Build Coastguard Worker static int
l_rnn_enumname(lua_State * L)468*61046927SAndroid Build Coastguard Worker l_rnn_enumname(lua_State *L)
469*61046927SAndroid Build Coastguard Worker {
470*61046927SAndroid Build Coastguard Worker    struct rnn *rnn = lua_touserdata(L, 1);
471*61046927SAndroid Build Coastguard Worker    const char *name = lua_tostring(L, 2);
472*61046927SAndroid Build Coastguard Worker    uint32_t val = (uint32_t)lua_tonumber(L, 3);
473*61046927SAndroid Build Coastguard Worker    lua_pushstring(L, rnn_enumname(rnn, name, val));
474*61046927SAndroid Build Coastguard Worker    return 1;
475*61046927SAndroid Build Coastguard Worker }
476*61046927SAndroid Build Coastguard Worker 
477*61046927SAndroid Build Coastguard Worker static int
l_rnn_regname(lua_State * L)478*61046927SAndroid Build Coastguard Worker l_rnn_regname(lua_State *L)
479*61046927SAndroid Build Coastguard Worker {
480*61046927SAndroid Build Coastguard Worker    struct rnn *rnn = lua_touserdata(L, 1);
481*61046927SAndroid Build Coastguard Worker    uint32_t regbase = (uint32_t)lua_tonumber(L, 2);
482*61046927SAndroid Build Coastguard Worker    lua_pushstring(L, rnn_regname(rnn, regbase, 1));
483*61046927SAndroid Build Coastguard Worker    return 1;
484*61046927SAndroid Build Coastguard Worker }
485*61046927SAndroid Build Coastguard Worker 
486*61046927SAndroid Build Coastguard Worker static int
l_rnn_regval(lua_State * L)487*61046927SAndroid Build Coastguard Worker l_rnn_regval(lua_State *L)
488*61046927SAndroid Build Coastguard Worker {
489*61046927SAndroid Build Coastguard Worker    struct rnn *rnn = lua_touserdata(L, 1);
490*61046927SAndroid Build Coastguard Worker    uint32_t regbase = (uint32_t)lua_tonumber(L, 2);
491*61046927SAndroid Build Coastguard Worker    uint32_t regval = (uint32_t)lua_tonumber(L, 3);
492*61046927SAndroid Build Coastguard Worker    struct rnndecaddrinfo *info = rnn_reginfo(rnn, regbase);
493*61046927SAndroid Build Coastguard Worker    char *decoded;
494*61046927SAndroid Build Coastguard Worker    if (info && info->typeinfo) {
495*61046927SAndroid Build Coastguard Worker       decoded = rnndec_decodeval(rnn->vc, info->typeinfo, regval);
496*61046927SAndroid Build Coastguard Worker    } else {
497*61046927SAndroid Build Coastguard Worker       asprintf(&decoded, "%08x", regval);
498*61046927SAndroid Build Coastguard Worker    }
499*61046927SAndroid Build Coastguard Worker    lua_pushstring(L, decoded);
500*61046927SAndroid Build Coastguard Worker    free(decoded);
501*61046927SAndroid Build Coastguard Worker    rnn_reginfo_free(info);
502*61046927SAndroid Build Coastguard Worker    return 1;
503*61046927SAndroid Build Coastguard Worker }
504*61046927SAndroid Build Coastguard Worker 
505*61046927SAndroid Build Coastguard Worker static const struct luaL_Reg l_rnn[] = {
506*61046927SAndroid Build Coastguard Worker    {"init", l_rnn_init},
507*61046927SAndroid Build Coastguard Worker    {"enumname", l_rnn_enumname},
508*61046927SAndroid Build Coastguard Worker    {"regname", l_rnn_regname},
509*61046927SAndroid Build Coastguard Worker    {"regval", l_rnn_regval},
510*61046927SAndroid Build Coastguard Worker    {NULL, NULL} /* sentinel */
511*61046927SAndroid Build Coastguard Worker };
512*61046927SAndroid Build Coastguard Worker 
513*61046927SAndroid Build Coastguard Worker /* Expose the register state to script enviroment as a "regs" library:
514*61046927SAndroid Build Coastguard Worker  */
515*61046927SAndroid Build Coastguard Worker 
516*61046927SAndroid Build Coastguard Worker static int
l_reg_written(lua_State * L)517*61046927SAndroid Build Coastguard Worker l_reg_written(lua_State *L)
518*61046927SAndroid Build Coastguard Worker {
519*61046927SAndroid Build Coastguard Worker    uint32_t regbase = (uint32_t)lua_tonumber(L, 1);
520*61046927SAndroid Build Coastguard Worker    lua_pushnumber(L, reg_written(regbase));
521*61046927SAndroid Build Coastguard Worker    return 1;
522*61046927SAndroid Build Coastguard Worker }
523*61046927SAndroid Build Coastguard Worker 
524*61046927SAndroid Build Coastguard Worker static int
l_reg_lastval(lua_State * L)525*61046927SAndroid Build Coastguard Worker l_reg_lastval(lua_State *L)
526*61046927SAndroid Build Coastguard Worker {
527*61046927SAndroid Build Coastguard Worker    uint32_t regbase = (uint32_t)lua_tonumber(L, 1);
528*61046927SAndroid Build Coastguard Worker    lua_pushnumber(L, reg_lastval(regbase));
529*61046927SAndroid Build Coastguard Worker    return 1;
530*61046927SAndroid Build Coastguard Worker }
531*61046927SAndroid Build Coastguard Worker 
532*61046927SAndroid Build Coastguard Worker static int
l_reg_val(lua_State * L)533*61046927SAndroid Build Coastguard Worker l_reg_val(lua_State *L)
534*61046927SAndroid Build Coastguard Worker {
535*61046927SAndroid Build Coastguard Worker    uint32_t regbase = (uint32_t)lua_tonumber(L, 1);
536*61046927SAndroid Build Coastguard Worker    lua_pushnumber(L, reg_val(regbase));
537*61046927SAndroid Build Coastguard Worker    return 1;
538*61046927SAndroid Build Coastguard Worker }
539*61046927SAndroid Build Coastguard Worker 
540*61046927SAndroid Build Coastguard Worker static const struct luaL_Reg l_regs[] = {
541*61046927SAndroid Build Coastguard Worker    {"written", l_reg_written},
542*61046927SAndroid Build Coastguard Worker    {"lastval", l_reg_lastval},
543*61046927SAndroid Build Coastguard Worker    {"val", l_reg_val},
544*61046927SAndroid Build Coastguard Worker    {NULL, NULL} /* sentinel */
545*61046927SAndroid Build Coastguard Worker };
546*61046927SAndroid Build Coastguard Worker 
547*61046927SAndroid Build Coastguard Worker /* Expose API to lookup snapshot buffers:
548*61046927SAndroid Build Coastguard Worker  */
549*61046927SAndroid Build Coastguard Worker 
550*61046927SAndroid Build Coastguard Worker uint64_t gpubaseaddr(uint64_t gpuaddr);
551*61046927SAndroid Build Coastguard Worker unsigned hostlen(uint64_t gpuaddr);
552*61046927SAndroid Build Coastguard Worker 
553*61046927SAndroid Build Coastguard Worker /* given address, return base-address of buffer: */
554*61046927SAndroid Build Coastguard Worker static int
l_bo_base(lua_State * L)555*61046927SAndroid Build Coastguard Worker l_bo_base(lua_State *L)
556*61046927SAndroid Build Coastguard Worker {
557*61046927SAndroid Build Coastguard Worker    uint64_t addr = (uint64_t)lua_tonumber(L, 1);
558*61046927SAndroid Build Coastguard Worker    lua_pushnumber(L, gpubaseaddr(addr));
559*61046927SAndroid Build Coastguard Worker    return 1;
560*61046927SAndroid Build Coastguard Worker }
561*61046927SAndroid Build Coastguard Worker 
562*61046927SAndroid Build Coastguard Worker /* given address, return the remaining size of the buffer: */
563*61046927SAndroid Build Coastguard Worker static int
l_bo_size(lua_State * L)564*61046927SAndroid Build Coastguard Worker l_bo_size(lua_State *L)
565*61046927SAndroid Build Coastguard Worker {
566*61046927SAndroid Build Coastguard Worker    uint64_t addr = (uint64_t)lua_tonumber(L, 1);
567*61046927SAndroid Build Coastguard Worker    lua_pushnumber(L, hostlen(addr));
568*61046927SAndroid Build Coastguard Worker    return 1;
569*61046927SAndroid Build Coastguard Worker }
570*61046927SAndroid Build Coastguard Worker 
571*61046927SAndroid Build Coastguard Worker static const struct luaL_Reg l_bos[] = {
572*61046927SAndroid Build Coastguard Worker    {"base", l_bo_base}, {"size", l_bo_size}, {NULL, NULL} /* sentinel */
573*61046927SAndroid Build Coastguard Worker };
574*61046927SAndroid Build Coastguard Worker 
575*61046927SAndroid Build Coastguard Worker static void
openlib(const char * lib,const luaL_Reg * reg)576*61046927SAndroid Build Coastguard Worker openlib(const char *lib, const luaL_Reg *reg)
577*61046927SAndroid Build Coastguard Worker {
578*61046927SAndroid Build Coastguard Worker    lua_newtable(L);
579*61046927SAndroid Build Coastguard Worker    luaL_setfuncs(L, reg, 0);
580*61046927SAndroid Build Coastguard Worker    lua_setglobal(L, lib);
581*61046927SAndroid Build Coastguard Worker }
582*61046927SAndroid Build Coastguard Worker 
583*61046927SAndroid Build Coastguard Worker /* called at start to load the script: */
584*61046927SAndroid Build Coastguard Worker int
script_load(const char * file)585*61046927SAndroid Build Coastguard Worker script_load(const char *file)
586*61046927SAndroid Build Coastguard Worker {
587*61046927SAndroid Build Coastguard Worker    int ret;
588*61046927SAndroid Build Coastguard Worker 
589*61046927SAndroid Build Coastguard Worker    assert(!L);
590*61046927SAndroid Build Coastguard Worker 
591*61046927SAndroid Build Coastguard Worker    L = luaL_newstate();
592*61046927SAndroid Build Coastguard Worker    luaL_openlibs(L);
593*61046927SAndroid Build Coastguard Worker    openlib("bos", l_bos);
594*61046927SAndroid Build Coastguard Worker    openlib("regs", l_regs);
595*61046927SAndroid Build Coastguard Worker    openlib("rnn", l_rnn);
596*61046927SAndroid Build Coastguard Worker 
597*61046927SAndroid Build Coastguard Worker    ret = luaL_loadfile(L, file);
598*61046927SAndroid Build Coastguard Worker    if (ret)
599*61046927SAndroid Build Coastguard Worker       error("%s\n");
600*61046927SAndroid Build Coastguard Worker 
601*61046927SAndroid Build Coastguard Worker    ret = lua_pcall(L, 0, LUA_MULTRET, 0);
602*61046927SAndroid Build Coastguard Worker    if (ret)
603*61046927SAndroid Build Coastguard Worker       error("%s\n");
604*61046927SAndroid Build Coastguard Worker 
605*61046927SAndroid Build Coastguard Worker    return 0;
606*61046927SAndroid Build Coastguard Worker }
607*61046927SAndroid Build Coastguard Worker 
608*61046927SAndroid Build Coastguard Worker /* called at start of each cmdstream file: */
609*61046927SAndroid Build Coastguard Worker void
script_start_cmdstream(const char * name)610*61046927SAndroid Build Coastguard Worker script_start_cmdstream(const char *name)
611*61046927SAndroid Build Coastguard Worker {
612*61046927SAndroid Build Coastguard Worker    if (!L)
613*61046927SAndroid Build Coastguard Worker       return;
614*61046927SAndroid Build Coastguard Worker 
615*61046927SAndroid Build Coastguard Worker    lua_getglobal(L, "start_cmdstream");
616*61046927SAndroid Build Coastguard Worker 
617*61046927SAndroid Build Coastguard Worker    /* if no handler just ignore it: */
618*61046927SAndroid Build Coastguard Worker    if (!lua_isfunction(L, -1)) {
619*61046927SAndroid Build Coastguard Worker       lua_pop(L, 1);
620*61046927SAndroid Build Coastguard Worker       return;
621*61046927SAndroid Build Coastguard Worker    }
622*61046927SAndroid Build Coastguard Worker 
623*61046927SAndroid Build Coastguard Worker    lua_pushstring(L, name);
624*61046927SAndroid Build Coastguard Worker 
625*61046927SAndroid Build Coastguard Worker    /* do the call (1 arguments, 0 result) */
626*61046927SAndroid Build Coastguard Worker    if (lua_pcall(L, 1, 0, 0) != 0)
627*61046927SAndroid Build Coastguard Worker       error("error running function `f': %s\n");
628*61046927SAndroid Build Coastguard Worker }
629*61046927SAndroid Build Coastguard Worker 
630*61046927SAndroid Build Coastguard Worker /* called at each DRAW_INDX, calls script drawidx fxn to process
631*61046927SAndroid Build Coastguard Worker  * the current state
632*61046927SAndroid Build Coastguard Worker  */
633*61046927SAndroid Build Coastguard Worker void
script_draw(const char * primtype,uint32_t nindx)634*61046927SAndroid Build Coastguard Worker script_draw(const char *primtype, uint32_t nindx)
635*61046927SAndroid Build Coastguard Worker {
636*61046927SAndroid Build Coastguard Worker    if (!L)
637*61046927SAndroid Build Coastguard Worker       return;
638*61046927SAndroid Build Coastguard Worker 
639*61046927SAndroid Build Coastguard Worker    lua_getglobal(L, "draw");
640*61046927SAndroid Build Coastguard Worker 
641*61046927SAndroid Build Coastguard Worker    /* if no handler just ignore it: */
642*61046927SAndroid Build Coastguard Worker    if (!lua_isfunction(L, -1)) {
643*61046927SAndroid Build Coastguard Worker       lua_pop(L, 1);
644*61046927SAndroid Build Coastguard Worker       return;
645*61046927SAndroid Build Coastguard Worker    }
646*61046927SAndroid Build Coastguard Worker 
647*61046927SAndroid Build Coastguard Worker    lua_pushstring(L, primtype);
648*61046927SAndroid Build Coastguard Worker    lua_pushnumber(L, nindx);
649*61046927SAndroid Build Coastguard Worker 
650*61046927SAndroid Build Coastguard Worker    /* do the call (2 arguments, 0 result) */
651*61046927SAndroid Build Coastguard Worker    if (lua_pcall(L, 2, 0, 0) != 0)
652*61046927SAndroid Build Coastguard Worker       error("error running function `f': %s\n");
653*61046927SAndroid Build Coastguard Worker }
654*61046927SAndroid Build Coastguard Worker 
655*61046927SAndroid Build Coastguard Worker static int
l_rnn_meta_dom_index(lua_State * L)656*61046927SAndroid Build Coastguard Worker l_rnn_meta_dom_index(lua_State *L)
657*61046927SAndroid Build Coastguard Worker {
658*61046927SAndroid Build Coastguard Worker    struct rnn *rnn = lua_touserdata(L, 1);
659*61046927SAndroid Build Coastguard Worker    uint32_t offset = (uint32_t)lua_tonumber(L, 2);
660*61046927SAndroid Build Coastguard Worker    struct rnndelem *elem;
661*61046927SAndroid Build Coastguard Worker 
662*61046927SAndroid Build Coastguard Worker    /* TODO might be nicer if the arg isn't a number, to search the domain
663*61046927SAndroid Build Coastguard Worker     * for matching bitfields.. so that the script could do something like
664*61046927SAndroid Build Coastguard Worker     * 'pkt.WIDTH' insteadl of 'pkt[1].WIDTH', ie. not have to remember the
665*61046927SAndroid Build Coastguard Worker     * offset of the dword containing the bitfield..
666*61046927SAndroid Build Coastguard Worker     */
667*61046927SAndroid Build Coastguard Worker 
668*61046927SAndroid Build Coastguard Worker    elem = rnn_regoff(rnn, offset);
669*61046927SAndroid Build Coastguard Worker    if (!elem)
670*61046927SAndroid Build Coastguard Worker       return 0;
671*61046927SAndroid Build Coastguard Worker 
672*61046927SAndroid Build Coastguard Worker    return l_rnn_etype(L, rnn, elem, elem->offset);
673*61046927SAndroid Build Coastguard Worker }
674*61046927SAndroid Build Coastguard Worker 
675*61046927SAndroid Build Coastguard Worker /*
676*61046927SAndroid Build Coastguard Worker  * A wrapper object for rnndomain based decoding of an array of dwords
677*61046927SAndroid Build Coastguard Worker  * (ie. for pm4 packet decoding).  Mostly re-uses the register-value
678*61046927SAndroid Build Coastguard Worker  * decoding for the individual dwords and bitfields.
679*61046927SAndroid Build Coastguard Worker  */
680*61046927SAndroid Build Coastguard Worker 
681*61046927SAndroid Build Coastguard Worker static int
l_rnn_meta_dom_gc(lua_State * L)682*61046927SAndroid Build Coastguard Worker l_rnn_meta_dom_gc(lua_State *L)
683*61046927SAndroid Build Coastguard Worker {
684*61046927SAndroid Build Coastguard Worker    // TODO
685*61046927SAndroid Build Coastguard Worker    // struct rnn *rnn = lua_touserdata(L, 1);
686*61046927SAndroid Build Coastguard Worker    // rnn_deinit(rnn);
687*61046927SAndroid Build Coastguard Worker    return 0;
688*61046927SAndroid Build Coastguard Worker }
689*61046927SAndroid Build Coastguard Worker 
690*61046927SAndroid Build Coastguard Worker static const struct luaL_Reg l_meta_rnn_dom[] = {
691*61046927SAndroid Build Coastguard Worker    {"__index", l_rnn_meta_dom_index},
692*61046927SAndroid Build Coastguard Worker    {"__gc", l_rnn_meta_dom_gc},
693*61046927SAndroid Build Coastguard Worker    {NULL, NULL} /* sentinel */
694*61046927SAndroid Build Coastguard Worker };
695*61046927SAndroid Build Coastguard Worker 
696*61046927SAndroid Build Coastguard Worker /* called to general pm4 packet decoding, such as texture/sampler state
697*61046927SAndroid Build Coastguard Worker  */
698*61046927SAndroid Build Coastguard Worker void
script_packet(uint32_t * dwords,uint32_t sizedwords,struct rnn * rnn,struct rnndomain * dom)699*61046927SAndroid Build Coastguard Worker script_packet(uint32_t *dwords, uint32_t sizedwords, struct rnn *rnn,
700*61046927SAndroid Build Coastguard Worker               struct rnndomain *dom)
701*61046927SAndroid Build Coastguard Worker {
702*61046927SAndroid Build Coastguard Worker    if (!L)
703*61046927SAndroid Build Coastguard Worker       return;
704*61046927SAndroid Build Coastguard Worker 
705*61046927SAndroid Build Coastguard Worker    lua_getglobal(L, dom->name);
706*61046927SAndroid Build Coastguard Worker 
707*61046927SAndroid Build Coastguard Worker    /* if no handler for the packet, just ignore it: */
708*61046927SAndroid Build Coastguard Worker    if (!lua_isfunction(L, -1)) {
709*61046927SAndroid Build Coastguard Worker       lua_pop(L, 1);
710*61046927SAndroid Build Coastguard Worker       return;
711*61046927SAndroid Build Coastguard Worker    }
712*61046927SAndroid Build Coastguard Worker 
713*61046927SAndroid Build Coastguard Worker    struct rnndec *rnndec = lua_newuserdata(L, sizeof(*rnndec));
714*61046927SAndroid Build Coastguard Worker 
715*61046927SAndroid Build Coastguard Worker    rnndec->base = *rnn;
716*61046927SAndroid Build Coastguard Worker    rnndec->base.dom[0] = dom;
717*61046927SAndroid Build Coastguard Worker    rnndec->base.dom[1] = NULL;
718*61046927SAndroid Build Coastguard Worker    rnndec->dwords = dwords;
719*61046927SAndroid Build Coastguard Worker    rnndec->sizedwords = sizedwords;
720*61046927SAndroid Build Coastguard Worker 
721*61046927SAndroid Build Coastguard Worker    luaL_newmetatable(L, "rnnmetadom");
722*61046927SAndroid Build Coastguard Worker    luaL_setfuncs(L, l_meta_rnn_dom, 0);
723*61046927SAndroid Build Coastguard Worker    lua_pop(L, 1);
724*61046927SAndroid Build Coastguard Worker 
725*61046927SAndroid Build Coastguard Worker    luaL_setmetatable(L, "rnnmetadom");
726*61046927SAndroid Build Coastguard Worker 
727*61046927SAndroid Build Coastguard Worker    lua_pushnumber(L, sizedwords);
728*61046927SAndroid Build Coastguard Worker 
729*61046927SAndroid Build Coastguard Worker    if (lua_pcall(L, 2, 0, 0) != 0)
730*61046927SAndroid Build Coastguard Worker       error("error running function `f': %s\n");
731*61046927SAndroid Build Coastguard Worker }
732*61046927SAndroid Build Coastguard Worker 
733*61046927SAndroid Build Coastguard Worker /* helper to call fxn that takes and returns void: */
734*61046927SAndroid Build Coastguard Worker static void
simple_call(const char * name)735*61046927SAndroid Build Coastguard Worker simple_call(const char *name)
736*61046927SAndroid Build Coastguard Worker {
737*61046927SAndroid Build Coastguard Worker    if (!L)
738*61046927SAndroid Build Coastguard Worker       return;
739*61046927SAndroid Build Coastguard Worker 
740*61046927SAndroid Build Coastguard Worker    lua_getglobal(L, name);
741*61046927SAndroid Build Coastguard Worker 
742*61046927SAndroid Build Coastguard Worker    /* if no handler just ignore it: */
743*61046927SAndroid Build Coastguard Worker    if (!lua_isfunction(L, -1)) {
744*61046927SAndroid Build Coastguard Worker       lua_pop(L, 1);
745*61046927SAndroid Build Coastguard Worker       return;
746*61046927SAndroid Build Coastguard Worker    }
747*61046927SAndroid Build Coastguard Worker 
748*61046927SAndroid Build Coastguard Worker    /* do the call (0 arguments, 0 result) */
749*61046927SAndroid Build Coastguard Worker    if (lua_pcall(L, 0, 0, 0) != 0)
750*61046927SAndroid Build Coastguard Worker       error("error running function `f': %s\n");
751*61046927SAndroid Build Coastguard Worker }
752*61046927SAndroid Build Coastguard Worker 
753*61046927SAndroid Build Coastguard Worker /* called at end of each cmdstream file: */
754*61046927SAndroid Build Coastguard Worker void
script_end_cmdstream(void)755*61046927SAndroid Build Coastguard Worker script_end_cmdstream(void)
756*61046927SAndroid Build Coastguard Worker {
757*61046927SAndroid Build Coastguard Worker    simple_call("end_cmdstream");
758*61046927SAndroid Build Coastguard Worker }
759*61046927SAndroid Build Coastguard Worker 
760*61046927SAndroid Build Coastguard Worker /* called at start of submit/issueibcmds: */
761*61046927SAndroid Build Coastguard Worker void
script_start_submit(void)762*61046927SAndroid Build Coastguard Worker script_start_submit(void)
763*61046927SAndroid Build Coastguard Worker {
764*61046927SAndroid Build Coastguard Worker    simple_call("start_submit");
765*61046927SAndroid Build Coastguard Worker }
766*61046927SAndroid Build Coastguard Worker 
767*61046927SAndroid Build Coastguard Worker /* called at end of submit/issueibcmds: */
768*61046927SAndroid Build Coastguard Worker void
script_end_submit(void)769*61046927SAndroid Build Coastguard Worker script_end_submit(void)
770*61046927SAndroid Build Coastguard Worker {
771*61046927SAndroid Build Coastguard Worker    simple_call("end_submit");
772*61046927SAndroid Build Coastguard Worker }
773*61046927SAndroid Build Coastguard Worker 
774*61046927SAndroid Build Coastguard Worker /* called after last cmdstream file: */
775*61046927SAndroid Build Coastguard Worker void
script_finish(void)776*61046927SAndroid Build Coastguard Worker script_finish(void)
777*61046927SAndroid Build Coastguard Worker {
778*61046927SAndroid Build Coastguard Worker    if (!L)
779*61046927SAndroid Build Coastguard Worker       return;
780*61046927SAndroid Build Coastguard Worker 
781*61046927SAndroid Build Coastguard Worker    simple_call("finish");
782*61046927SAndroid Build Coastguard Worker 
783*61046927SAndroid Build Coastguard Worker    lua_close(L);
784*61046927SAndroid Build Coastguard Worker    L = NULL;
785*61046927SAndroid Build Coastguard Worker }
786