List of commits:
Subject Hash Author Date (UTC)
sync-ing asm and dis for minimal shaders a1aec48b7011a11632eb42acae562e0cee6110df Sylvain BERTRAND 2020-01-03 17:40:13
spirv: introducing asm and dis improvement 9275a362039315e40a5328743846754f47f9559f Sylvain BERTRAND 2019-12-31 03:52:33
adjust and confirm some register acronymes 1f0d098ac18f61f6d9dbc00694da84b5a7d0274e Sylvain BERTRAND 2019-12-02 14:25:44
partial and brainded pm4 disassembler 88bd38675091a9164583a05abb672c6d1962d133 Sylvain BERTRAND 2019-11-30 19:10:22
untested amd gcn gfx6 disassembler 942c2b45ce87dd3c031289acf662679933997c21 Sylvain BERTRAND 2019-11-28 18:45:56
typos 729922e37ff800683763794352533924250e8579 Sylvain BERTRAND 2019-11-17 16:33:36
braindead partial spir-v disassembler a347cbcc8284301ad6989d486373f0d2ffb9657c Sylvain BERTRAND 2019-11-16 17:48:29
Initial commit 1cd013eaa1466522d61c7b0e64d5858055fedbfa Sylvain BERTRAND 2019-10-25 18:49:16
Commit a1aec48b7011a11632eb42acae562e0cee6110df - sync-ing asm and dis for minimal shaders
Author: Sylvain BERTRAND
Author date (UTC): 2020-01-03 17:40
Committer name: Sylvain BERTRAND
Committer date (UTC): 2020-01-03 17:40
Parent(s): 9275a362039315e40a5328743846754f47f9559f
Signer:
Signing key:
Signing status: N
Tree: 67ef82825903c6b7be4f6c0edeb85f30c3ecd5f7
File Lines added Lines deleted
spirv/asm/LICENSE 2 0
spirv/asm/asm.c 530 21
spirv/dis/LICENSE 2 0
spirv/dis/dis.c 116 89
File spirv/asm/LICENSE added (mode: 100644) (index 0000000..a63046d)
1 This code is protected with a GNU Affero GPLv3 license WITH A "LESSER" EXCEPTION FOR
2 VIDEO GAMES.
File spirv/asm/asm.c changed (mode: 100644) (index 757b510..141c14c)
3 3 #include <stdlib.h> #include <stdlib.h>
4 4 #include <stdbool.h> #include <stdbool.h>
5 5 #include <string.h> #include <string.h>
6 /* see LICENSE sylvain.bertrand@legeek.net */
6 7 /* /*
7 8 * FAT WARNING: DO NOT TRY TO GENERALIZE/FACTOR THE CODE TOO EARLY * FAT WARNING: DO NOT TRY TO GENERALIZE/FACTOR THE CODE TOO EARLY
8 9 * AND EXCESSIVE GENERALIZATION/FACTORIZATION IS NOT WELCOME * AND EXCESSIVE GENERALIZATION/FACTORIZATION IS NOT WELCOME
 
... ... static u8 id_get(u32 *id, u8 *s, u8 *e, u8 **err_str)
267 268
268 269
269 270 if (*s != '%') { /* an id start with '%' */ if (*s != '%') { /* an id start with '%' */
270 *err_str = "missing '%' at the beginning af the id";
271 *err_str = "missing '%' at the beginning of the id";
271 272 return ERR; return ERR;
272 273 } }
273 274
 
... ... static u32 opd_id(u8 *op, u8 *name, u8 *desc)
336 337 u8 *opd_e; u8 *opd_e;
337 338 u8 *err_str; u8 *err_str;
338 339 u32 id; u32 id;
339
340 opd_val_reach(op, name);
340
341 if (name != 0)
342 opd_val_reach(op, name);
341 343
342 344 opd_s = b; opd_s = b;
343 345 ws_or_eol_reach(); ws_or_eol_reach();
 
... ... static void op_type_pointer(void)
1277 1279
1278 1280 } }
1279 1281
1282 /* a spirv "variable" is a pointer to some allocated storage */
1280 1283 static void op_variable(void) static void op_variable(void)
1281 1284 { {
1282 1285 u8 r; u8 r;
1283 bool have_pointer_type;
1284 u32 pointer_type;
1285 bool have_id;
1286 u32 id;
1286 bool have_type;
1287 u32 type;
1288 bool have_pointer_id;
1289 u32 pointer_id;
1287 1290 bool have_storage_class; bool have_storage_class;
1288 1291 u32 storage_class; u32 storage_class;
1289 1292 u8 *err_str; u8 *err_str;
 
... ... static void op_variable(void)
1293 1296
1294 1297 u32 word; u32 word;
1295 1298
1296 have_pointer_type = false;
1297 have_id = false;
1299 have_type = false;
1300 have_pointer_id = false;
1298 1301 have_storage_class = false; have_storage_class = false;
1299 1302 initializers_n = 0; initializers_n = 0;
1300 1303
 
... ... static void op_variable(void)
1312 1315 ws_or_eol_or_eq_reach(); ws_or_eol_or_eq_reach();
1313 1316 opd_e = b; opd_e = b;
1314 1317
1315 if (str_slice_cmp("pointer_type", opd_s, opd_e)) {
1316 pointer_type = opd_id("variable", "pointer_type",
1317 "pointer type id");
1318 have_pointer_type = true;
1319 } else if (str_slice_cmp("id", opd_s, opd_e)) {
1320 id = opd_id("variable", "id", "id");
1318 if (str_slice_cmp("type", opd_s, opd_e)) {
1319 type = opd_id("variable", "type", "type id");
1320 have_type = true;
1321 } else if (str_slice_cmp("pointer_id", opd_s, opd_e)) {
1322 pointer_id = opd_id("variable", "pointer_id", "pointer id");
1321 1323
1322 r = id_use(id, &err_str);
1324 r = id_use(pointer_id, &err_str);
1323 1325 if (r != OK) { if (r != OK) {
1324 err("ERROR:%u:variable:something is wrong with the id:%s\n", line_num, err_str);
1326 err("ERROR:%u:variable:something is wrong with the pointer id:%s\n", line_num, err_str);
1325 1327 exit(1); exit(1);
1326 1328 } }
1327 have_id = true;
1329 have_pointer_id = true;
1328 1330 } else if (str_slice_cmp("storage_class", opd_s, opd_e)) { } else if (str_slice_cmp("storage_class", opd_s, opd_e)) {
1329 1331 storage_class = opd_storage_class("variable"); storage_class = opd_storage_class("variable");
1330 1332 have_storage_class = true; have_storage_class = true;
 
... ... static void op_variable(void)
1333 1335 exit(1); exit(1);
1334 1336 } }
1335 1337
1336 if (have_pointer_type && have_id && have_storage_class)
1338 if (have_type && have_pointer_id && have_storage_class)
1337 1339 break; break;
1338 1340 } }
1339 1341
 
... ... static void op_variable(void)
1351 1353 word |= (4 + initializers_n) << 16; word |= (4 + initializers_n) << 16;
1352 1354 emit(word); emit(word);
1353 1355
1354 emit(pointer_type);
1355 emit(id);
1356 emit(type);
1357 emit(pointer_id);
1356 1358 emit(storage_class); emit(storage_class);
1357 1359
1358 1360 word = 0; word = 0;
 
... ... static void op_variable(void)
1364 1366 } }
1365 1367 } }
1366 1368
1369 static void decoration_location_opds_consume(u8 *op, u32 *opds, u32 *opds_n)
1370 {
1371 u8 r;
1372 u8 *opd_s;
1373 u8 *opd_e;
1374 u8 *err_str;
1375
1376 r = ws_skip();
1377 if (r == EOL) {
1378 err("ERROR:%u:%s:location decoration is missing its value\n", line_num, op);
1379 exit(1);
1380 }
1381
1382 opd_s = b;
1383 ws_or_eol_reach();
1384 opd_e = b;
1385
1386 r = u32_decode(opds + *opds_n, opd_s, opd_e, &err_str);
1387 if (r != OK) {
1388 err("ERROR:%u:%s:unable to decade location decoration value:%s\n", line_num, op, err_str);
1389 exit(1);
1390 }
1391 ++(*opds_n);
1392 }
1393
1367 1394 static void decoration_builtin_opds_consume(u8 *op, u32 *opds, u32 *opds_n) static void decoration_builtin_opds_consume(u8 *op, u32 *opds, u32 *opds_n)
1368 1395 { {
1369 1396 u8 r; u8 r;
 
... ... static void decoration_opds_consume(u8 * op, u32 decoration, u32 *opds,
1521 1548 case 11: case 11:
1522 1549 decoration_builtin_opds_consume(op, opds, opds_n); decoration_builtin_opds_consume(op, opds, opds_n);
1523 1550 break; break;
1551 case 30:
1552 decoration_location_opds_consume(op, opds, opds_n);
1553 break;
1524 1554 } }
1525 1555 } }
1526 1556
 
... ... static u32 opd_decoration(u8 *op)
1559 1589 return 10; return 10;
1560 1590 else if (str_slice_cmp("builtin", opd_s, opd_e)) else if (str_slice_cmp("builtin", opd_s, opd_e))
1561 1591 return 11; return 11;
1592 else if (str_slice_cmp("location", opd_s, opd_e))
1593 return 30;
1562 1594 /* TODO: more */ /* TODO: more */
1563 1595
1564 1596 err("ERROR:%u:%s:decoration operand:unknown value \"%.*s\"\n", line_num, op, opd_e - opd_s, opd_s); err("ERROR:%u:%s:decoration operand:unknown value \"%.*s\"\n", line_num, op, opd_e - opd_s, opd_s);
 
... ... static void op_label(void)
1967 1999 emit(id); emit(id);
1968 2000 } }
1969 2001
2002 /* XXX: may factor it with op_binop_x */
2003 static void op_iequal(void)
2004 {
2005 u8 r;
2006 bool have_type;
2007 u32 type;
2008 bool have_id;
2009 u32 id;
2010 bool have_opd0;
2011 u32 opd0;
2012 bool have_opd1;
2013 u32 opd1;
2014 u8 *err_str;
2015
2016 u32 word;
2017
2018 have_type = false;
2019 have_id = false;
2020 loop {
2021 u8 *opd_s;
2022 u8 *opd_e;
2023
2024 r = ws_skip();
2025 if (r == EOL) {
2026 err("ERROR:%u:iequal:missing operands\n", line_num);
2027 exit(1);
2028 }
2029
2030 opd_s = b;
2031 ws_or_eol_or_eq_reach();
2032 opd_e = b;
2033
2034 if (str_slice_cmp("type", opd_s, opd_e)) {
2035 type = opd_id("iequal", "type", "result type id");
2036 have_type = true;
2037 } else if (str_slice_cmp("id", opd_s, opd_e)) {
2038 id = opd_id("type", "id", "id");
2039
2040 r = id_use(id, &err_str);
2041 if (r != OK) {
2042 err("ERROR:%u:iequal:something is wrong with the id:%s\n", line_num, err_str);
2043 exit(1);
2044 }
2045 have_id = true;
2046 } else {
2047 err("ERROR:%u:iequal:unknown operand \"%.*s\"\n", line_num, opd_e - opd_s, opd_s);
2048 exit(1);
2049 }
2050
2051 if (have_type && have_id)
2052 break;
2053 }
2054
2055 /* now the operation operands */
2056 have_opd0 = false;
2057 have_opd1 = false;
2058 loop {
2059 r = ws_skip();
2060 if (r == EOL) {
2061 err("ERROR:%u:iequal:missing comparison operands\n", line_num);
2062 exit(1);
2063 }
2064
2065 if (!have_opd0) {
2066 opd0 = opd_id("iequal", 0, "comparison first operand");
2067 have_opd0 = true;
2068 } else if (!have_opd1) {
2069 opd1 = opd_id("iequal", 0, "comparison second operand");
2070 have_opd1 = true;
2071 }
2072
2073 if (have_opd0 && have_opd1)
2074 break;
2075 }
2076
2077 word = 170;
2078 word |= 5 << 16;
2079 emit(word);
2080
2081 emit(type);
2082 emit(id);
2083 emit(opd0);
2084 emit(opd1);
2085 }
2086
2087 static u32 opd_selection_control(u8 *op)
2088 {
2089 u8 *opd_s;
2090 u8 *opd_e;
2091
2092 opd_val_reach(op, "selection_control");
2093
2094 opd_s = b;
2095 ws_or_eol_reach();
2096 opd_e = b;
2097
2098 if (str_slice_cmp("none", opd_s, opd_e))
2099 return 0;
2100 else if (str_slice_cmp("flatten", opd_s, opd_e))
2101 return 1;
2102 else if (str_slice_cmp("dont_flatten", opd_s, opd_e))
2103 return 2;
2104 err("ERROR:%u:%s:selection_control operand:unknown value \"%.*s\"\n", line_num, op, opd_e - opd_s, opd_s);
2105 exit(1);
2106 }
2107
2108 static void op_selection_merge(void)
2109 {
2110 u8 r;
2111 bool have_block;
2112 u32 block;
2113 bool have_selection_control;
2114 u32 selection_control;
2115 u8 *err_str;
2116
2117 u32 word;
2118
2119 have_block = false;
2120 have_selection_control = false;
2121 loop {
2122 u8 *opd_s;
2123 u8 *opd_e;
2124
2125 r = ws_skip();
2126 if (r == EOL) {
2127 err("ERROR:%u:selection_merge:missing operands\n", line_num);
2128 exit(1);
2129 }
2130
2131 opd_s = b;
2132 ws_or_eol_or_eq_reach();
2133 opd_e = b;
2134
2135 if (str_slice_cmp("block", opd_s, opd_e)) {
2136 block = opd_id("selection_merge", "block", "block label id");
2137 have_block = true;
2138 } else if (str_slice_cmp("selection_control", opd_s, opd_e)) {
2139 selection_control = opd_selection_control("selection_merge");
2140 have_selection_control = true;
2141 } else {
2142 err("ERROR:%u:selection_merge:unknown operand \"%.*s\"\n", line_num, opd_e - opd_s, opd_s);
2143 exit(1);
2144 }
2145
2146 if (have_block && have_selection_control)
2147 break;
2148 }
2149
2150 word = 247;
2151 word |= 3 << 16;
2152 emit(word);
2153
2154 emit(block);
2155 emit(selection_control);
2156 }
2157
2158 /* expect b to point on the first valid char */
2159 static u8 targets_collect(u32 *opds, u32 *opds_n, u8 **err_str)
2160 {
2161 static u8 err_str_buf[BUFSIZ];
2162
2163 *err_str = err_str_buf;
2164 loop {
2165 u8 r;
2166 u8 *u32_s;
2167 u8 *u32_e;
2168 u8 *id_s;
2169 u8 *id_e;
2170 u8 *err_str_next;
2171
2172 if ((*opds_n + 2) > VAR_OPDS_N_MAX) {
2173 snprintf(err_str_buf, BUFSIZ, "target[%u]:no room for target in operand storage", *opds_n / 2);
2174 return ERR;
2175 }
2176
2177 u32_s = b;
2178 ws_or_eol_reach();
2179 u32_e = b;
2180
2181 r = u32_decode(opds + *opds_n, u32_s, u32_e, &err_str_next);
2182 if (r != OK) {
2183 snprintf(err_str_buf, BUFSIZ, "target[%u]:literal number:%s", *opds_n / 2, err_str_next);
2184 return r;
2185 }
2186
2187 r = ws_skip();
2188 if (r == EOL) {
2189 snprintf(err_str_buf, BUFSIZ, "target[%u]:missing label id", *opds_n / 2);
2190 return ERR;
2191 }
2192
2193 id_s = b;
2194 ws_or_eol_reach();
2195 id_e = b;
2196
2197 r = id_get(opds + *opds_n + 1, id_s, id_e, &err_str_next);
2198 if (r != OK) {
2199 snprintf(err_str_buf, BUFSIZ, "target[%u]:label id:%s", *opds_n / 2, err_str_next);
2200 return r;
2201 }
2202
2203 (*opds_n) += 2;
2204
2205 r = ws_skip();
2206 if (r == EOL)
2207 return OK;
2208 }
2209 }
2210
2211 static void op_switch(void)
2212 {
2213 u8 r;
2214 bool have_selector;
2215 u32 selector;
2216 bool have_default_id;
2217 u32 default_id;
2218 u8 *err_str;
2219
2220 u32 targets_opds[VAR_OPDS_N_MAX];
2221 u32 targets_opds_n;
2222
2223 u32 word;
2224
2225 have_selector = false;
2226 have_default_id = false;
2227 targets_opds_n = 0;
2228 loop {
2229 u8 *opd_s;
2230 u8 *opd_e;
2231
2232 r = ws_skip();
2233 if (r == EOL) {
2234 err("ERROR:%u:switch:missing operands\n", line_num);
2235 exit(1);
2236 }
2237
2238 opd_s = b;
2239 ws_or_eol_or_eq_reach();
2240 opd_e = b;
2241
2242 if (str_slice_cmp("selector", opd_s, opd_e)) {
2243 selector = opd_id("switch", "selector", "selector id");
2244 have_selector = true;
2245 } else if (str_slice_cmp("default", opd_s, opd_e)) {
2246 default_id = opd_id("switch", "default", "default id");
2247 have_default_id = true;
2248 } else {
2249 err("ERROR:%u:switch:unknown operand \"%.*s\"\n", line_num, opd_e - opd_s, opd_s);
2250 exit(1);
2251 }
2252
2253 if (have_selector && have_default_id)
2254 break;
2255 }
2256
2257 r = ws_skip();
2258 if (r == OK) {
2259 /* have targets */
2260 targets_collect(targets_opds, &targets_opds_n, &err_str);
2261 if (r != OK) {
2262 err("ERROR:%u:switch:collecting targets:%s\n", line_num, err_str);
2263 exit(1);
2264 }
2265 }
2266
2267 word = 251;
2268 word |= (3 + targets_opds_n) << 16;
2269 emit(word);
2270
2271 emit(selector);
2272 emit(default_id);
2273
2274 word = 0;
2275 loop {
2276 if (word == targets_opds_n)
2277 break;
2278 emit(targets_opds[word]);
2279 ++word;
2280 }
2281 }
2282
2283 static void memory_opds_alignment_get(u8 *op, u32 *alignment)
2284 {
2285 u8 r;
2286 u8 *s;
2287 u8 *e;
2288 u8 *err_str;
2289
2290 r = ws_skip();
2291 if (r != OK) {
2292 err("ERROR:%u:%s:memory operands:missing alignment literal value\n", line_num, op);
2293 exit(1);
2294 }
2295
2296 s = b;
2297 ws_or_eol_reach();
2298 e = b;
2299
2300 r = u32_decode(alignment, s, e, &err_str);
2301 if (r != OK) {
2302 err("ERROR:%u:%s:memory operands:unable to decode alignment literal value:%s\n", line_num, op, err_str);
2303 exit(1);
2304 }
2305
2306 }
2307
2308 static void memory_opds_x_scope_get(u8 *op, u8 *opd, u32 *scope)
2309 {
2310 u8 r;
2311 u8 *s;
2312 u8 *e;
2313
2314 r = ws_skip();
2315 if (r != OK) {
2316 err("ERROR:%u:%s:memory operands:missing %s scope\n", line_num, op, opd);
2317 exit(1);
2318 }
2319
2320 s = b;
2321 ws_or_eol_reach();
2322 e = b;
2323
2324 /* XXX: will probably be factor out */
2325 if (str_slice_cmp("cross_device", s, e))
2326 *scope = 0;
2327 else if (str_slice_cmp("device", s, e))
2328 *scope = 1;
2329 else if (str_slice_cmp("workgroup", s, e))
2330 *scope = 2;
2331 else if (str_slice_cmp("subgroup", s, e))
2332 *scope = 3;
2333 else if (str_slice_cmp("invocation", s, e))
2334 *scope = 4;
2335 else if (str_slice_cmp("queue_family", s, e))
2336 *scope = 5;
2337 else {
2338 err("ERROR:%u:%s:memory operands:unable to decode %s scope\n", line_num, op, opd);
2339 exit(1);
2340 }
2341 }
2342
2343 /* flag0|flag1|flag2... opds_flag_X opds_flag_Y... with X < Y*/
2344 static void memory_opds_collect(u8 *op, u32 *memory_opds, u32 *memory_opds_n)
2345 {
2346 u8 *opd_s;
2347 u8 *opd_e;
2348 u32 additional_opd_idx;
2349
2350 memory_opds[0] = 0x0;
2351
2352 loop {
2353 opd_s = b;
2354 ws_or_eol_or_bar_reach();
2355 opd_e = b;
2356
2357 if (str_slice_cmp("none", opd_s, opd_e)) {
2358 memory_opds[0] = 0x0;
2359 ws_or_eol_reach(); /* consume it all, useless */
2360 break;
2361 } else if (str_slice_cmp("volatile", opd_s, opd_e))
2362 memory_opds[0] |= 0x1;
2363 else if (str_slice_cmp("aligned", opd_s, opd_e))
2364 memory_opds[0] |= 0x2;
2365 else if (str_slice_cmp("non_temporal", opd_s, opd_e))
2366 memory_opds[0] |= 0x4;
2367 else if (str_slice_cmp("make_pointer_available", opd_s, opd_e))
2368 memory_opds[0] |= 0x8;
2369 else if (str_slice_cmp("make_pointer_visible", opd_s, opd_e))
2370 memory_opds[0] |= 0x10;
2371 else if (str_slice_cmp("non_private_pointer", opd_s, opd_e))
2372 memory_opds[0] |= 0x20;
2373 else {
2374 err("ERROR:%u:%s:memory operands:unknown operand \"%.*s\"\n", line_num, op, opd_e - opd_s, opd_s);
2375 exit(1);
2376 }
2377 if (b == eol || *b != '|')
2378 break;
2379 ++b;
2380 }
2381
2382 *memory_opds_n = 1;
2383 additional_opd_idx = 1; /* skip the flags word */
2384
2385 if ((memory_opds[0] & 0x2) != 0) {
2386 memory_opds_alignment_get(op, memory_opds + additional_opd_idx);
2387 ++(*memory_opds_n);
2388 ++additional_opd_idx;
2389 }
2390 if ((memory_opds[0] & 0x8) != 0) {
2391 memory_opds_x_scope_get(op, "make_pointer_available",
2392 memory_opds + additional_opd_idx);
2393 ++(*memory_opds_n);
2394 ++additional_opd_idx;
2395 }
2396 if ((memory_opds[0] & 0x10) != 0) {
2397 memory_opds_x_scope_get(op, "make_pointer_visible",
2398 memory_opds + additional_opd_idx);
2399 ++(*memory_opds_n);
2400 ++additional_opd_idx;
2401 }
2402 }
2403
2404 static void op_store(void)
2405 {
2406 u8 r;
2407 bool have_pointer;
2408 u32 pointer;
2409 bool have_object;
2410 u32 object;
2411 u8 *err_str;
2412
2413 u32 memory_opds[VAR_OPDS_N_MAX];
2414 u32 memory_opds_n;
2415
2416 u32 word;
2417
2418 have_pointer = false;
2419 have_object = false;
2420 memory_opds_n = 0;
2421
2422 loop {
2423 u8 *opd_s;
2424 u8 *opd_e;
2425
2426 r = ws_skip();
2427 if (r == EOL) {
2428 err("ERROR:%u:type_function:missing operands\n", line_num);
2429 exit(1);
2430 }
2431
2432 opd_s = b;
2433 ws_or_eol_or_eq_reach();
2434 opd_e = b;
2435
2436 if (str_slice_cmp("pointer", opd_s, opd_e)) {
2437 pointer = opd_id("store", "pointer", "pointer id");
2438 have_pointer = true;
2439 } else if (str_slice_cmp("object", opd_s, opd_e)) {
2440 object = opd_id("store", "object", "object id");
2441 have_object = true;
2442 } else {
2443 err("ERROR:%u:store:unknown operand \"%.*s\"\n", line_num, opd_e - opd_s, opd_s);
2444 exit(1);
2445 }
2446
2447 if (have_pointer && have_object)
2448 break;
2449 }
2450
2451 r = ws_skip();
2452 if (r == OK) /* have memory opd(s) */
2453 memory_opds_collect("store", memory_opds, &memory_opds_n);
2454
2455 word = 62;
2456 word |= (3 + memory_opds_n) << 16;
2457 emit(word);
2458
2459 emit(pointer);
2460 emit(object);
2461
2462 word = 0;
2463 loop {
2464 if (word == memory_opds_n)
2465 break;
2466 emit(memory_opds[word]);
2467 ++word;
2468 }
2469 }
2470
1970 2471 static void op_dispatch(void) static void op_dispatch(void)
1971 2472 { {
1972 2473 u8 *op_s; u8 *op_s;
 
... ... static void op_dispatch(void)
2012 2513 op_function_end(); op_function_end();
2013 2514 else if (str_slice_cmp("label", op_s, op_e)) else if (str_slice_cmp("label", op_s, op_e))
2014 2515 op_label(); op_label();
2516 else if (str_slice_cmp("iequal", op_s, op_e))
2517 op_iequal();
2518 else if (str_slice_cmp("selection_merge", op_s, op_e))
2519 op_selection_merge();
2520 else if (str_slice_cmp("switch", op_s, op_e))
2521 op_switch();
2522 else if (str_slice_cmp("store", op_s, op_e))
2523 op_store();
2015 2524 /* TODO: MORE */ /* TODO: MORE */
2016 2525 else { else {
2017 2526 err("ERROR:%u:unknown instruction \"%.*s\"\n", line_num, op_e - op_s, op_s); err("ERROR:%u:unknown instruction \"%.*s\"\n", line_num, op_e - op_s, op_s);
File spirv/dis/LICENSE added (mode: 100644) (index 0000000..a63046d)
1 This code is protected with a GNU Affero GPLv3 license WITH A "LESSER" EXCEPTION FOR
2 VIDEO GAMES.
File spirv/dis/dis.c changed (mode: 100644) (index aab4bfc..5e28deb)
4 4 #include <stdint.h> #include <stdint.h>
5 5 #include <stdlib.h> #include <stdlib.h>
6 6 #include <string.h> #include <string.h>
7 /* see LICENSE sylvain.bertrand@legeek.net */
8 /*
9 * FAT WARNING: DO NOT TRY TO GENERALIZE/FACTOR THE CODE TOO EARLY
10 * AND EXCESSIVE GENERALIZATION/FACTORIZATION IS NOT WELCOME
11 */
7 12 /* /*
8 13 * ABBREVIATIONS: * ABBREVIATIONS:
9 14 * blk(s) : BLocK(S) * blk(s) : BLocK(S)
 
... ... constant {
117 122 spirv_op_logicalor = 166, spirv_op_logicalor = 166,
118 123 spirv_op_logicaland = 167, spirv_op_logicaland = 167,
119 124 spirv_op_select = 169, spirv_op_select = 169,
125 spirv_op_iequal = 170,
120 126 spirv_op_fordequal = 180, spirv_op_fordequal = 180,
121 127 spirv_op_fordnotequal = 182, spirv_op_fordnotequal = 182,
122 128 spirv_op_fordlessthan = 184, spirv_op_fordlessthan = 184,
 
... ... constant {
128 134 spirv_op_label = 248, spirv_op_label = 248,
129 135 spirv_op_branch = 249, spirv_op_branch = 249,
130 136 spirv_op_branchconditional = 250, spirv_op_branchconditional = 250,
137 spirv_op_switch = 251,
131 138 spirv_op_return = 253, spirv_op_return = 253,
132 139 spirv_op_returnvalue = 254, spirv_op_returnvalue = 254,
133 140 spirv_op_typepipestorage = 322, spirv_op_typepipestorage = 322,
 
... ... u8 *ops_name[0xffff + 1] = {
219 226 [spirv_op_logicalor] = "logical_or", [spirv_op_logicalor] = "logical_or",
220 227 [spirv_op_logicaland] = "logical_and", [spirv_op_logicaland] = "logical_and",
221 228 [spirv_op_select] = "select", [spirv_op_select] = "select",
229 [spirv_op_iequal] = "iequal",
222 230 [spirv_op_fordequal] = "ford_equal", [spirv_op_fordequal] = "ford_equal",
223 231 [spirv_op_fordnotequal] = "ford_not_equal", [spirv_op_fordnotequal] = "ford_not_equal",
224 232 [spirv_op_fordlessthan] = "ford_less_than", [spirv_op_fordlessthan] = "ford_less_than",
 
... ... u8 *ops_name[0xffff + 1] = {
230 238 [spirv_op_label] = "label", [spirv_op_label] = "label",
231 239 [spirv_op_branch] = "branch", [spirv_op_branch] = "branch",
232 240 [spirv_op_branchconditional] = "branch_conditional", [spirv_op_branchconditional] = "branch_conditional",
241 [spirv_op_switch] = "switch",
233 242 [spirv_op_return] = "return", [spirv_op_return] = "return",
234 243 [spirv_op_returnvalue] = "return_value", [spirv_op_returnvalue] = "return_value",
235 244 [spirv_op_typepipestorage] = "type_pipe_storage", [spirv_op_typepipestorage] = "type_pipe_storage",
 
... ... static u8 *img_fmt_to_str(u32 w)
1391 1400 { {
1392 1401 switch (w) { switch (w) {
1393 1402 case 0: case 0:
1394 return "unkown";
1403 return "unknown_valid";
1395 1404 case 1: case 1:
1396 1405 return "rgba32f"; return "rgba32f";
1397 1406 case 2: case 2:
 
... ... static u8 *img_fmt_to_str(u32 w)
1471 1480 case 39: case 39:
1472 1481 return "r8ui"; return "r8ui";
1473 1482 default: default:
1474 return "unknown_image_format_code";
1483 return "unknown_invalid_image_format_code";
1475 1484 } }
1476 1485 } }
1477 1486
 
... ... static u8 *access_qualifier_to_str(u32 w)
1491 1500
1492 1501 static void op_typeimage_out(void) static void op_typeimage_out(void)
1493 1502 { {
1494 out_ind_id("%s id=%%%U sampled_type=%%%u dim=%s depth=%s arrayed=%s multisample=%s sampled=%s image_format=%s", 0, op_name, opds[0], opds[1], dim_to_str(opds[2]), depth_to_str(opds[3]), arrayed_to_str(opds[4]), multisample_to_str(opds[5]), sampled_to_str(opds[6]), img_fmt_to_str(opds[7]));
1503 out_ind_id("%s id=%%%u sampled_type=%%%u dim=%s depth=%s arrayed=%s multisample=%s sampled=%s image_format=%s", 0, op_name, opds[0], opds[1], dim_to_str(opds[2]), depth_to_str(opds[3]), arrayed_to_str(opds[4]), multisample_to_str(opds[5]), sampled_to_str(opds[6]), img_fmt_to_str(opds[7]));
1495 1504 if (op_ws_n > 9) /* have access qualifier */ if (op_ws_n > 9) /* have access qualifier */
1496 1505 out(" access_qualifier=%s\n", access_qualifier_to_str(opds[8])); out(" access_qualifier=%s\n", access_qualifier_to_str(opds[8]));
1497 1506 else else
 
... ... static void op_specconstantop_out(void)
1716 1725
1717 1726 static void op_variable_out(void) static void op_variable_out(void)
1718 1727 { {
1719 out_ind_id("%s id=%%%u pointer_type=%%%u storage_class=%s", 1, op_name, opds[1], opds[0], storage_class_to_str(opds[2]));
1728 out_ind_id("%s pointer_id=%%%u type=%%%u storage_class=%s", 1, op_name, opds[1], opds[0], storage_class_to_str(opds[2]));
1720 1729
1721 1730 if (op_ws_n > 4) { if (op_ws_n > 4) {
1722 1731 out(" initializer=%%%u", opds[3]); out(" initializer=%%%u", opds[3]);
 
... ... static void layout_nonfuncdecls_out(void)
1739 1748 break; break;
1740 1749 /* types start -----------------------------------------------*/ /* types start -----------------------------------------------*/
1741 1750 case spirv_op_typevoid: case spirv_op_typevoid:
1742 out_ind_id("%s id=%%%u\n", 0, op_name, opds[0]);
1751 out_ind_id("%s %%%u\n", 0, op_name, opds[0]);
1743 1752 break; break;
1744 1753 case spirv_op_typebool: case spirv_op_typebool:
1745 out_ind_id("%s id=%%%u\n", 0, op_name, opds[0]);
1754 out_ind_id("%s %%%u\n", 0, op_name, opds[0]);
1746 1755 break; break;
1747 1756 case spirv_op_typeint: case spirv_op_typeint:
1748 1757 out_ind_id("%s id=%%%u width=%u signedness=%s\n", 0, op_name, opds[0], opds[1], signedness_to_str(opds[2])); out_ind_id("%s id=%%%u width=%u signedness=%s\n", 0, op_name, opds[0], opds[1], signedness_to_str(opds[2]));
 
... ... static void layout_nonfuncdecls_out(void)
1845 1854 op_specconstantop_out(); op_specconstantop_out();
1846 1855 break; break;
1847 1856 /* constants end ---------------------------------------------*/ /* constants end ---------------------------------------------*/
1857 /* carefull, a spirv "variable" is a pointer */
1848 1858 case spirv_op_variable: case spirv_op_variable:
1849 1859 op_variable_out(); op_variable_out();
1850 1860 break; break;
 
... ... static u8 *scope_to_str(u32 w)
1917 1927 } }
1918 1928 } }
1919 1929
1920 #define flag_no_opd(val, str) \
1930 #define flag(val, str) \
1921 1931 if ((opds[i] & val) != 0) { \ if ((opds[i] & val) != 0) { \
1922 1932 if (!first) \ if (!first) \
1923 1933 out("|"); \ out("|"); \
1924 1934 out(str); \ out(str); \
1925 1935 first = false; \ first = false; \
1926 1936 } }
1927 #define TMP_SZ 128
1928 /* return the idx of the next mem opd */
1929 static u16 mem_opd_out(u16 i)
1937 static void mem_opds_out(u16 i)
1930 1938 { {
1931 u8 tmp[TMP_SZ];
1932 u16 additional_opds;
1933 1939 bool first; bool first;
1940 u16 additional_opds;
1934 1941
1935 additional_opds = i + 1;
1942 /*--------------------------------------------------------------------*/
1943
1944 if (opds[i] == 0)
1945 return;
1946
1947 out(" ");
1948 out_cmts("/*memory_operands=*/");
1936 1949
1937 if (opds[i] == 0) {
1938 out("none");
1939 return i + 1;
1940 }
1941 1950
1942 1951 first = true; first = true;
1943 1952
1944 1953 /* order matters */ /* order matters */
1945 flag_no_opd(0x00000001, "volatile")
1954 flag(0x00000001, "volatile")
1955 flag(0x00000002, "aligned")
1956 flag(0x00000004, "non_temporal")
1957 flag(0x00000008, "make_pointer_available");
1958 flag(0x00000010, "make_pointer_visible");
1959 flag(0x00000020, "non_private_pointer")
1960 flag(0xffffffe0, "unknown_memory_operand_flag(s)-->consider the following instruction operands as corrupted")
1961
1962 /*--------------------------------------------------------------------*/
1963
1964 additional_opds = i + 1;
1946 1965
1947 1966 if ((opds[i] & 0x00000002) != 0) { if ((opds[i] & 0x00000002) != 0) {
1948 if (!first)
1949 out("|");
1950 out("aligned");
1951 first = false;
1952 snprintf(tmp, TMP_SZ, "(%u)", opds[additional_opds]);
1953 out(tmp);
1967 if (additional_opds > opds_last) {
1968 out("\n");
1969 out_ind("error:memory operands:missing alignment\n");
1970 exit(1);
1971 }
1972 if (cmts)
1973 out(" /*alignment=*/0x%x", opds[additional_opds]);
1974 else
1975 out(" 0x%x", opds[additional_opds]);
1954 1976 ++additional_opds; ++additional_opds;
1955 1977 } }
1956
1957 flag_no_opd(0x00000004, "non_temporal")
1958
1959 1978 if ((opds[i] & 0x00000008) != 0) { if ((opds[i] & 0x00000008) != 0) {
1960 if (!first)
1961 out("|");
1962 out("make_pointer_available");
1963 first = false;
1964 snprintf(tmp, TMP_SZ, "(%s)", scope_to_str(opds[additional_opds]));
1965 out(tmp);
1979 if (additional_opds > opds_last) {
1980 out("\n");
1981 out_ind("error:memory operands:missing make_pointer_available scope\n");
1982 exit(1);
1983 }
1984 if (cmts)
1985 out(" /*make_pointer_available scope=*/%s", scope_to_str(opds[additional_opds]));
1986 else
1987 out(" %s", scope_to_str(opds[additional_opds]));
1966 1988 ++additional_opds; ++additional_opds;
1967 1989 } }
1968
1969 1990 if ((opds[i] & 0x00000010) != 0) { if ((opds[i] & 0x00000010) != 0) {
1970 if (!first)
1971 out("|");
1972 out("make_pointer_visible");
1973 first = false;
1974 snprintf(tmp, TMP_SZ, "(%s)", scope_to_str(opds[additional_opds]));
1975 out(tmp);
1991 if (additional_opds > opds_last) {
1992 out("\n");
1993 out_ind("error:memory operands:missing make_pointer_visible scope\n");
1994 exit(1);
1995 }
1996 if (cmts)
1997 out(" /*make_pointer_visible scope=*/%s", scope_to_str(opds[additional_opds]));
1998 else
1999 out(" %s", scope_to_str(opds[additional_opds]));
1976 2000 ++additional_opds; ++additional_opds;
1977 2001 } }
1978
1979 flag_no_opd(0x00000010, "non_private_pointer")
1980
1981 flag_no_opd(0xffffffe0, "unknown_memory_operand_flag(s)-->consider the following instruction operands as corrupted")
1982
1983 return additional_opds;
1984 2002 } }
1985 2003 #undef flag_no_opd #undef flag_no_opd
1986 #undef TMP_SZ
1987
1988 /* will output the mem opds till the end of the instruction */
1989 static void mem_opds_out(u16 i)
1990 {
1991 u16 mem_opd_idx;
1992
1993 mem_opd_idx = 0;
1994 out(" ");
1995 out_cmts("/*memory_operands[%u]=*/", mem_opd_idx);
1996
1997 loop {
1998 i = mem_opd_out(i);
1999 ++mem_opd_idx;
2000
2001 if (i > opds_last)
2002 break;
2003 }
2004 }
2005 2004
2006 2005 static void op_load_out(void) static void op_load_out(void)
2007 2006 { {
 
... ... static void op_load_out(void)
2011 2010 out("\n"); out("\n");
2012 2011 } }
2013 2012
2014 static void op_vectorshuffle_out_depth(void)
2013 static void op_vectorshuffle_out(void)
2015 2014 { {
2016 2015 u16 i; u16 i;
2017 2016
 
... ... static void op_vectorshuffle_out_depth(void)
2034 2033 out("\n"); out("\n");
2035 2034 } }
2036 2035
2037 static void op_compositeextract_out_depth(void)
2036 static void op_compositeextract_out(void)
2038 2037 { {
2039 2038 u16 i; u16 i;
2040 2039
 
... ... static void op_compositeextract_out_depth(void)
2053 2052 out("\n"); out("\n");
2054 2053 } }
2055 2054
2056 static void op_compositeconstruct_out_depth(void)
2055 static void op_compositeconstruct_out(void)
2057 2056 { {
2058 2057 u16 i; u16 i;
2059 2058
 
... ... static void op_compositeconstruct_out_depth(void)
2072 2071 out("\n"); out("\n");
2073 2072 } }
2074 2073
2075 static void op_store_out_depth(void)
2074 static void op_store_out(void)
2076 2075 { {
2077 2076 out_ind("%s pointer=%%%u object=%%%u", op_name, opds[0], opds[1]); out_ind("%s pointer=%%%u object=%%%u", op_name, opds[0], opds[1]);
2078 2077 if (op_ws_n > 3) if (op_ws_n > 3)
 
... ... static void op_store_out_depth(void)
2080 2079 out("\n"); out("\n");
2081 2080 } }
2082 2081
2083 static void op_imagesampleimplicitlod_out_depth(void)
2082 static void op_imagesampleimplicitlod_out(void)
2084 2083 { {
2085 2084 u16 i; u16 i;
2086 2085
 
... ... static void op_imagesampleexplicitlod_out(void)
2128 2127 out("\n"); out("\n");
2129 2128 } }
2130 2129
2131 static void op_functioncall_out_depth(void)
2130 static void op_functioncall_out(void)
2132 2131 { {
2133 2132 u16 i; u16 i;
2134 2133
 
... ... static void op_functioncall_out_depth(void)
2147 2146 out("\n"); out("\n");
2148 2147 } }
2149 2148
2150 static void op_branchconditional_out_depth(void)
2149 static void op_branchconditional_out(void)
2151 2150 { {
2152 2151 u16 i; u16 i;
2153 2152
 
... ... static void op_extinst_out(void)
2199 2198 out("\n"); out("\n");
2200 2199 } }
2201 2200
2202 static void op_accesschain_out_depth(void)
2201 static void op_accesschain_out(void)
2203 2202 { {
2204 2203 u16 i; u16 i;
2205 2204
 
... ... static void op_accesschain_out_depth(void)
2218 2217 out("\n"); out("\n");
2219 2218 } }
2220 2219
2221 static void op_compositeinsert_out_depth(void)
2220 static void op_compositeinsert_out(void)
2222 2221 { {
2223 2222 u16 i; u16 i;
2224 2223
 
... ... static void op_compositeinsert_out_depth(void)
2237 2236 out("\n"); out("\n");
2238 2237 } }
2239 2238
2240 static void op_phi_out_depth(void)
2239 static void op_phi_out(void)
2241 2240 { {
2242 2241 u16 i; u16 i;
2243 2242
 
... ... static void op_phi_out_depth(void)
2248 2247 if (i > opds_last) if (i > opds_last)
2249 2248 break; break;
2250 2249 if (cmts) if (cmts)
2251 out( "/*variables[%u]=*/%%%u /*parents[%u]=*/%%%u", (i - 2) / 2, opds[i], (i - 2) / 2, opds[i + 1]);
2250 out(" /*variables[%u]=*/%%%u /*parents[%u]=*/%%%u", (i - 2) / 2, opds[i], (i - 2) / 2, opds[i + 1]);
2252 2251 else else
2253 out( "%%%u %%%u", opds[i], opds[i + 1]);
2252 out(" %%%u %%%u", opds[i], opds[i + 1]);
2253 i += 2;
2254 }
2255 out("\n");
2256 }
2257
2258 static void op_switch_out(void)
2259 {
2260 u16 i;
2261
2262 out_ind("%s selector=%%%u default=%%%u", op_name, opds[0], opds[1]);
2263
2264 i = 2;
2265 loop {
2266 if (i > opds_last)
2267 break;
2268 if (cmts)
2269 out(" /*target[%u].literal=*/0x%08x /*target[%u].label_id=*/%%%u", (i - 2) / 2, opds[i], (i - 2) / 2, opds[i + 1]);
2270 else
2271 out(" 0x%08x %%%u", opds[i], opds[i + 1]);
2254 2272 i += 2; i += 2;
2255 2273 } }
2256 2274 out("\n"); out("\n");
 
... ... static void layout_funcs_out(void)
2278 2296 out_ind("%s %%%u line=%u column=%u\n", op_name, opds[0], opds[1], opds[2]); out_ind("%s %%%u line=%u column=%u\n", op_name, opds[0], opds[1], opds[2]);
2279 2297 break; break;
2280 2298 case spirv_op_function: case spirv_op_function:
2281 out_ind_id("%s id=%%%u return_type=%%%u function_control=%s function_type=%%%u\n", 1, op_name, opds[1], opds[0], function_control_to_str(opds[2]), opds[3]);
2299 out_ind_id("%s id=%%%u return_type=%%%u control=%s type=%%%u\n", 1, op_name, opds[1], opds[0], function_control_to_str(opds[2]), opds[3]);
2282 2300 func_has_blk = false; func_has_blk = false;
2283 2301 ++depth; /* start of a blk */ ++depth; /* start of a blk */
2284 2302 break; break;
 
... ... static void layout_funcs_out(void)
2303 2321 op_load_out(); op_load_out();
2304 2322 break; break;
2305 2323 case spirv_op_vectorshuffle: case spirv_op_vectorshuffle:
2306 op_vectorshuffle_out_depth();
2324 op_vectorshuffle_out();
2307 2325 break; break;
2308 2326 case spirv_op_compositeextract: case spirv_op_compositeextract:
2309 op_compositeextract_out_depth();
2327 op_compositeextract_out();
2310 2328 break; break;
2311 2329 case spirv_op_compositeconstruct: case spirv_op_compositeconstruct:
2312 op_compositeconstruct_out_depth();
2330 op_compositeconstruct_out();
2313 2331 break; break;
2314 2332 case spirv_op_store: case spirv_op_store:
2315 op_store_out_depth();
2333 op_store_out();
2316 2334 break; break;
2317 2335 case spirv_op_return: case spirv_op_return:
2318 2336 out_ind("%s\n", op_name); out_ind("%s\n", op_name);
2319 2337 --depth; /* end of blk */ --depth; /* end of blk */
2320 2338 break; break;
2321 2339 case spirv_op_imagesampleimplicitlod: case spirv_op_imagesampleimplicitlod:
2322 op_imagesampleimplicitlod_out_depth();
2340 op_imagesampleimplicitlod_out();
2323 2341 break; break;
2324 2342 case spirv_op_fmul: case spirv_op_fmul:
2325 2343 if (cmts) if (cmts)
 
... ... static void layout_funcs_out(void)
2331 2349 op_variable_out(); op_variable_out();
2332 2350 break; break;
2333 2351 case spirv_op_functioncall: case spirv_op_functioncall:
2334 op_functioncall_out_depth();
2352 op_functioncall_out();
2335 2353 break; break;
2336 2354 case spirv_op_fordlessthanequal: case spirv_op_fordlessthanequal:
2337 2355 if (cmts) if (cmts)
 
... ... static void layout_funcs_out(void)
2340 2358 out_ind_id("%s id=%%%u type=%%%u %%%u %%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]); out_ind_id("%s id=%%%u type=%%%u %%%u %%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]);
2341 2359 break; break;
2342 2360 case spirv_op_selectionmerge: case spirv_op_selectionmerge:
2343 out_ind("%s merge_block=%%%u section_control=%s\n", op_name, opds[0], selection_control_to_str(opds[1]));
2361 out_ind("%s block=%%%u selection_control=%s\n", op_name, opds[0], selection_control_to_str(opds[1]));
2344 2362 break; break;
2345 2363 case spirv_op_branchconditional: case spirv_op_branchconditional:
2346 op_branchconditional_out_depth();
2364 op_branchconditional_out();
2347 2365 depth--; /* end of blk */ depth--; /* end of blk */
2348 2366 break; break;
2349 2367 case spirv_op_fdiv: case spirv_op_fdiv:
 
... ... static void layout_funcs_out(void)
2370 2388 out_ind("%s value=%%%u\n", op_name, opds[0]); out_ind("%s value=%%%u\n", op_name, opds[0]);
2371 2389 break; break;
2372 2390 case spirv_op_accesschain: case spirv_op_accesschain:
2373 op_accesschain_out_depth();
2391 op_accesschain_out();
2374 2392 break; break;
2375 2393 case spirv_op_compositeinsert: case spirv_op_compositeinsert:
2376 op_compositeinsert_out_depth();
2394 op_compositeinsert_out();
2377 2395 break; break;
2378 2396 case spirv_op_sampledimage: case spirv_op_sampledimage:
2379 2397 out_ind_id("%s id=%%%u type=%%%u image=%%%u sampler=%%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]); out_ind_id("%s id=%%%u type=%%%u image=%%%u sampler=%%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]);
 
... ... static void layout_funcs_out(void)
2403 2421 out_ind_id("%s id=%%%u type=%%%u %%%u %%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]); out_ind_id("%s id=%%%u type=%%%u %%%u %%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]);
2404 2422 break; break;
2405 2423 case spirv_op_phi: case spirv_op_phi:
2406 op_phi_out_depth();
2424 op_phi_out();
2407 2425 break; break;
2408 2426 case spirv_op_fordgreaterthan: case spirv_op_fordgreaterthan:
2409 2427 if (cmts) if (cmts)
 
... ... static void layout_funcs_out(void)
2459 2477 else else
2460 2478 out_ind_id("%s id=%%%u type=%%%u %%%u %%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]); out_ind_id("%s id=%%%u type=%%%u %%%u %%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]);
2461 2479 break; break;
2480 case spirv_op_iequal:
2481 if (cmts)
2482 out_ind_id("%s id=%%%u type=%%%u /*operands[0]=*/%%%u /*operands[1]=*/%%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]);
2483 else
2484 out_ind_id("%s id=%%%u type=%%%u %%%u %%%u\n", 1, op_name, opds[1], opds[0], opds[2], opds[3]);
2485 break;
2486 case spirv_op_switch:
2487 op_switch_out();
2488 break;
2462 2489 /* TODO: MORE! */ /* TODO: MORE! */
2463 2490 default: default:
2464 2491 section_breaking_op_num = op_num; section_breaking_op_num = op_num;
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/sylware/vulkan-misc

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/sylware/vulkan-misc

Clone this repository using git:
git clone git://git.rocketgit.com/user/sylware/vulkan-misc

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main