ReactOS 0.4.17-dev-923-g4c9a150
dxil.c
Go to the documentation of this file.
1/*
2 * Copyright 2023 Conor McCarthy for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
20
21#define VKD3D_SM6_VERSION_MAJOR(version) (((version) >> 4) & 0xf)
22#define VKD3D_SM6_VERSION_MINOR(version) (((version) >> 0) & 0xf)
23/* Two seems to be the maximum but leave some extra room. */
24#define VKD3D_SM6_MAX_METADATA_TABLES 4
25
26#define BITCODE_MAGIC VKD3D_MAKE_TAG('B', 'C', 0xc0, 0xde)
27#define DXIL_OP_MAX_OPERANDS 17
31static const unsigned int GLOBALVAR_ADDRESS_SPACE_SHIFT = 2;
32static const uint64_t ALLOCA_FLAG_IN_ALLOCA = 0x20;
34static const uint64_t ALLOCA_ALIGNMENT_MASK = 0x1f;
35static const unsigned int SHADER_DESCRIPTOR_TYPE_COUNT = 4;
37
38static const unsigned int dx_max_thread_group_size[3] = {1024, 1024, 64};
39
40static const unsigned int MAX_GS_INSTANCE_COUNT = 32; /* kMaxGSInstanceCount */
41static const unsigned int MAX_GS_OUTPUT_TOTAL_SCALARS = 1024; /* kMaxGSOutputTotalScalars */
42static const unsigned int MAX_GS_OUTPUT_STREAMS = 4;
43
44#define VKD3D_SHADER_SWIZZLE_64_MASK \
45 (VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(0) \
46 | VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(1))
47
49{
61};
62
64{
65 SETBID = 1,
68};
69
71{
76};
77
79{
85};
86
88{
93};
94
96{
100};
101
103{
114};
115
117{
137};
138
140{
150};
151
153{
169};
170
172{
175};
176
178{
182};
183
185{
205};
206
208{
213};
214
216{
236};
237
239{
243};
244
246{
280};
281
283{
288};
289
291{
300};
301
303{
317};
318
320{
333 BINOP_XOR = 12
335
337{
343};
344
346{
347 /* Operation is known to never overflow. */
350};
351
353{
354 /* "A udiv or sdiv instruction, which can be marked as "exact", indicating that no bits are destroyed." */
356};
357
359{
367 DX_COS = 12,
368 DX_SIN = 13,
369 DX_TAN = 14,
376 DX_EXP = 21,
377 DX_FRC = 22,
378 DX_LOG = 23,
397 DX_FMA = 47,
470};
471
473{
487};
488
490{
517};
518
520{
532};
533
535{
543};
544
546{
557};
558
560{
565};
566
568{
572};
573
575{
580};
581
583{
587};
588
590{
591 const struct sm6_type *type;
593};
594
596{
597 const char *name;
598 unsigned int elem_count;
599 const struct sm6_type *elem_types[];
600};
601
603{
604 const struct sm6_type *ret_type;
605 unsigned int param_count;
606 const struct sm6_type *param_types[];
607};
608
610{
611 unsigned int count;
612 const struct sm6_type *elem_type;
613};
614
616{
627};
628
630{
631 enum sm6_type_class class;
632 union
633 {
634 unsigned int width;
639 } u;
640};
641
643{
648};
649
651{
652 const char *name;
654 unsigned int attribs_id;
655};
656
658{
659 const struct sm6_descriptor_info *d;
661};
662
664{
665 const struct sm6_type *type;
667 unsigned int structure_stride;
670 union
671 {
676 } u;
677};
678
680{
681 unsigned int code;
682 unsigned int operand_count;
683 const struct dxil_record *attachment;
685};
686
688{
689 unsigned int id;
690 const char *name;
691};
692
694{
695 const struct sm6_block *block;
697};
698
700{
705};
706
708{
713};
714
716{
717 const struct sm6_block *block;
720};
721
723{
726 const struct sm6_block *true_block;
727 const struct sm6_block *false_block;
729 unsigned int case_count;
730};
731
733{
737
738 /* A nonzero id. */
739 unsigned int id;
740
741 struct sm6_phi *phi;
743 size_t phi_count;
744
746};
747
749{
750 const struct sm6_value *declaration;
751
755
757};
758
760{
761 const struct dxil_block *parent;
763 unsigned int abbrev_len;
764 unsigned int start;
765 unsigned int length;
766 unsigned int level;
767
768 /* The abbrev, block and record structs are not relocatable. */
772 unsigned int blockinfo_bid;
774
778
782};
783
785{
790};
791
793{
795 unsigned int operand_count;
797};
798
800{
802 char *name;
803};
804
806{
808 const struct sm6_type *value_type;
809 union
810 {
812 const struct sm6_value *value;
815 } u;
816};
817
819{
821 unsigned int count;
822};
823
825{
826 char *name;
828};
829
831{
833 unsigned int id;
840};
841
843{
844 const uint32_t *ptr, *start, *end;
845 unsigned int bitpos;
846
849
853
859
862
863 const char *entry_point;
865
870
873
877
881
883 unsigned int icb_count;
884 unsigned int tgsm_count;
885
890 unsigned int ssa_next_id;
891
893};
894
896{
899};
900
902{
903 unsigned int count;
906};
907
909{
910 unsigned int block_id;
912};
913
914static const uint64_t CALL_CONV_FLAG_EXPLICIT_TYPE = 1ull << 15;
915
916static size_t size_add_with_overflow_check(size_t a, size_t b)
917{
918 size_t i = a + b;
919 return (i < a) ? SIZE_MAX : i;
920}
921
922static bool sm6_parser_is_end(struct sm6_parser *sm6)
923{
924 return sm6->ptr == sm6->end;
925}
926
928{
929 if (sm6_parser_is_end(sm6))
930 {
931 sm6->p.failed = true;
932 return 0;
933 }
934 return *sm6->ptr++;
935}
936
937static uint32_t sm6_parser_read_bits(struct sm6_parser *sm6, unsigned int length)
938{
939 unsigned int l, prev_len = 0;
941
942 if (!length)
943 return 0;
944
945 VKD3D_ASSERT(length < 32);
946
947 if (sm6_parser_is_end(sm6))
948 {
949 sm6->p.failed = true;
950 return 0;
951 }
952
953 VKD3D_ASSERT(sm6->bitpos < 32);
954 bits = *sm6->ptr >> sm6->bitpos;
955 l = 32 - sm6->bitpos;
956 if (l <= length)
957 {
958 ++sm6->ptr;
959 if (sm6_parser_is_end(sm6) && l < length)
960 {
961 sm6->p.failed = true;
962 return bits;
963 }
964 sm6->bitpos = 0;
965 bits |= *sm6->ptr << l;
966 prev_len = l;
967 }
968 sm6->bitpos += length - prev_len;
969
970 return bits & ((1 << length) - 1);
971}
972
973static uint64_t sm6_parser_read_vbr(struct sm6_parser *sm6, unsigned int length)
974{
975 unsigned int bits, flag, mask, shift = 0;
976 uint64_t result = 0;
977
978 if (!length)
979 return 0;
980
981 if (sm6_parser_is_end(sm6))
982 {
983 sm6->p.failed = true;
984 return 0;
985 }
986
987 flag = 1 << (length - 1);
988 mask = flag - 1;
989 do
990 {
992 result |= (uint64_t)(bits & mask) << shift;
993 shift += length - 1;
994 } while ((bits & flag) && !sm6->p.failed && shift < 64);
995
996 sm6->p.failed |= !!(bits & flag);
997
998 return result;
999}
1000
1001static void sm6_parser_align_32(struct sm6_parser *sm6)
1002{
1003 if (!sm6->bitpos)
1004 return;
1005
1006 if (sm6_parser_is_end(sm6))
1007 {
1008 sm6->p.failed = true;
1009 return;
1010 }
1011
1012 ++sm6->ptr;
1013 sm6->bitpos = 0;
1014}
1015
1017{
1018 /* BLOCKINFO blocks must only occur immediately below the module root block. */
1019 if (block->level > 1)
1020 {
1021 WARN("Invalid blockinfo block level %u.\n", block->level);
1022 return false;
1023 }
1024
1025 switch (record->code)
1026 {
1027 case SETBID:
1028 if (!record->operand_count)
1029 {
1030 WARN("Missing id operand.\n");
1031 return false;
1032 }
1033 if (record->operands[0] > UINT_MAX)
1034 WARN("Truncating block id %"PRIu64".\n", record->operands[0]);
1035 block->blockinfo_bid = record->operands[0];
1036 block->has_bid = true;
1037 break;
1038 case BLOCKNAME:
1039 case SETRECORDNAME:
1040 break;
1041 default:
1042 FIXME("Unhandled BLOCKINFO record type %u.\n", record->code);
1043 break;
1044 }
1045
1046 return true;
1047}
1048
1050{
1051 unsigned int reserve;
1052
1053 switch (block->id)
1054 {
1055 /* Rough initial reserve sizes for small shaders. */
1056 case CONSTANTS_BLOCK: reserve = 32; break;
1057 case FUNCTION_BLOCK: reserve = 128; break;
1058 case METADATA_BLOCK: reserve = 32; break;
1059 case TYPE_BLOCK: reserve = 32; break;
1060 default: reserve = 8; break;
1061 }
1062 reserve = max(reserve, block->record_count + 1);
1063 if (!vkd3d_array_reserve((void **)&block->records, &block->record_capacity, reserve, sizeof(*block->records)))
1064 {
1065 ERR("Failed to allocate %u records.\n", reserve);
1067 }
1068
1071
1072 block->records[block->record_count++] = record;
1073
1074 return VKD3D_OK;
1075}
1076
1078{
1079 struct dxil_block *block = sm6->current_block;
1080 enum vkd3d_result ret = VKD3D_OK;
1081 unsigned int code, count, i;
1082 struct dxil_record *record;
1083
1084 code = sm6_parser_read_vbr(sm6, 6);
1085
1086 count = sm6_parser_read_vbr(sm6, 6);
1087 if (!(record = vkd3d_malloc(sizeof(*record) + count * sizeof(record->operands[0]))))
1088 {
1089 ERR("Failed to allocate record with %u operands.\n", count);
1091 }
1092
1093 record->code = code;
1094 record->operand_count = count;
1095 record->attachment = NULL;
1096
1097 for (i = 0; i < count; ++i)
1098 record->operands[i] = sm6_parser_read_vbr(sm6, 6);
1099 if (sm6->p.failed)
1101
1102 if (ret < 0 || (ret = dxil_block_add_record(block, record)) < 0)
1104
1105 return ret;
1106}
1107
1109{
1110 *op = context;
1111 return !sm6->p.failed;
1112}
1113
1115{
1117 return !sm6->p.failed;
1118}
1119
1121{
1123 return !sm6->p.failed;
1124}
1125
1127{
1128 *op = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._"[sm6_parser_read_bits(sm6, 6)];
1129 return !sm6->p.failed;
1130}
1131
1133{
1134 int count = sm6_parser_read_vbr(sm6, 6);
1136 for (; count > 0; count -= 4)
1138 FIXME("Unhandled blob operand.\n");
1139 return false;
1140}
1141
1142static enum vkd3d_result dxil_abbrev_init(struct dxil_abbrev *abbrev, unsigned int count, struct sm6_parser *sm6)
1143{
1144 enum bitcode_abbrev_type prev_type, type;
1145 unsigned int i;
1146
1147 abbrev->is_array = false;
1148
1149 for (i = 0, prev_type = 0; i < count && !sm6->p.failed; ++i)
1150 {
1151 if (sm6_parser_read_bits(sm6, 1))
1152 {
1153 if (prev_type == ABBREV_ARRAY)
1154 {
1155 WARN("Unexpected literal abbreviation after array.\n");
1157 }
1158 abbrev->operands[i].context = sm6_parser_read_vbr(sm6, 8);
1159 abbrev->operands[i].read_operand = sm6_parser_read_literal_operand;
1160 continue;
1161 }
1162
1163 switch (type = sm6_parser_read_bits(sm6, 3))
1164 {
1165 case ABBREV_FIXED:
1166 case ABBREV_VBR:
1167 abbrev->operands[i].context = sm6_parser_read_vbr(sm6, 5);
1168 abbrev->operands[i].read_operand = (type == ABBREV_FIXED) ? sm6_parser_read_fixed_operand
1170 break;
1171
1172 case ABBREV_ARRAY:
1173 if (prev_type == ABBREV_ARRAY || i != count - 2)
1174 {
1175 WARN("Unexpected array abbreviation.\n");
1177 }
1178 abbrev->is_array = true;
1179 --i;
1180 --count;
1181 break;
1182
1183 case ABBREV_CHAR:
1184 abbrev->operands[i].read_operand = sm6_parser_read_char6_operand;
1185 break;
1186
1187 case ABBREV_BLOB:
1188 if (prev_type == ABBREV_ARRAY || i != count - 1)
1189 {
1190 WARN("Unexpected blob abbreviation.\n");
1192 }
1193 abbrev->operands[i].read_operand = sm6_parser_read_blob_operand;
1194 break;
1195 }
1196
1197 prev_type = type;
1198 }
1199
1200 abbrev->count = count;
1201
1202 return sm6->p.failed ? VKD3D_ERROR_INVALID_SHADER : VKD3D_OK;
1203}
1204
1206{
1207 struct dxil_block *block = sm6->current_block;
1208 unsigned int count = sm6_parser_read_vbr(sm6, 5);
1209 struct dxil_global_abbrev *global_abbrev;
1210 enum vkd3d_result ret;
1211
1213
1214 if (!vkd3d_array_reserve((void **)&sm6->abbrevs, &sm6->abbrev_capacity, sm6->abbrev_count + 1, sizeof(*sm6->abbrevs))
1215 || !(global_abbrev = vkd3d_malloc(sizeof(*global_abbrev) + count * sizeof(global_abbrev->abbrev.operands[0]))))
1216 {
1217 ERR("Failed to allocate global abbreviation.\n");
1219 }
1220
1221 if ((ret = dxil_abbrev_init(&global_abbrev->abbrev, count, sm6)) < 0)
1222 {
1223 vkd3d_free(global_abbrev);
1224 return ret;
1225 }
1226
1227 if (!block->has_bid)
1228 {
1229 WARN("Missing blockinfo block id.\n");
1231 }
1232 if (block->blockinfo_bid == MODULE_BLOCK)
1233 {
1234 FIXME("Unhandled global abbreviation for module block.\n");
1236 }
1237 global_abbrev->block_id = block->blockinfo_bid;
1238
1239 sm6->abbrevs[sm6->abbrev_count++] = global_abbrev;
1240
1241 return VKD3D_OK;
1242}
1243
1245{
1246 struct dxil_block *block = sm6->current_block;
1247 struct dxil_abbrev *abbrev;
1248 enum vkd3d_result ret;
1249 unsigned int count;
1250
1251 if (block->id == BLOCKINFO_BLOCK)
1252 return sm6_parser_add_global_abbrev(sm6);
1253
1254 count = sm6_parser_read_vbr(sm6, 5);
1255 if (!vkd3d_array_reserve((void **)&block->abbrevs, &block->abbrev_capacity, block->abbrev_count + 1, sizeof(*block->abbrevs))
1256 || !(abbrev = vkd3d_malloc(sizeof(*abbrev) + count * sizeof(abbrev->operands[0]))))
1257 {
1258 ERR("Failed to allocate block abbreviation.\n");
1260 }
1261
1262 if ((ret = dxil_abbrev_init(abbrev, count, sm6)) < 0)
1263 {
1264 vkd3d_free(abbrev);
1265 return ret;
1266 }
1267
1268 block->abbrevs[block->abbrev_count++] = abbrev;
1269
1270 return VKD3D_OK;
1271}
1272
1273static enum vkd3d_result sm6_parser_read_abbrev_record(struct sm6_parser *sm6, unsigned int abbrev_id)
1274{
1276 struct dxil_block *block = sm6->current_block;
1277 struct dxil_record *temp, *record;
1278 unsigned int i, count, array_len;
1279 struct dxil_abbrev *abbrev;
1280 uint64_t code;
1281
1282 if (abbrev_id >= block->abbrev_count)
1283 {
1284 WARN("Invalid abbreviation id %u.\n", abbrev_id);
1286 }
1287
1288 abbrev = block->abbrevs[abbrev_id];
1289 if (!(count = abbrev->count))
1290 return VKD3D_OK;
1291 if (count == 1 && abbrev->is_array)
1293
1294 /* First operand is the record code. The array is included in the count, but will be done separately. */
1295 count -= abbrev->is_array + 1;
1296 if (!(record = vkd3d_malloc(sizeof(*record) + count * sizeof(record->operands[0]))))
1297 {
1298 ERR("Failed to allocate record with %u operands.\n", count);
1300 }
1301
1302 if (!abbrev->operands[0].read_operand(sm6, abbrev->operands[0].context, &code))
1303 goto fail;
1304 if (code > UINT_MAX)
1305 FIXME("Truncating 64-bit record code %#"PRIx64".\n", code);
1306 record->code = code;
1307
1308 for (i = 0; i < count; ++i)
1309 if (!abbrev->operands[i + 1].read_operand(sm6, abbrev->operands[i + 1].context, &record->operands[i]))
1310 goto fail;
1311 record->operand_count = count;
1312 record->attachment = NULL;
1313
1314 /* An array can occur only as the last operand. */
1315 if (abbrev->is_array)
1316 {
1317 array_len = sm6_parser_read_vbr(sm6, 6);
1318 if (!(temp = vkd3d_realloc(record, sizeof(*record) + (count + array_len) * sizeof(record->operands[0]))))
1319 {
1320 ERR("Failed to allocate record with %u operands.\n", count + array_len);
1322 goto fail;
1323 }
1324 record = temp;
1325
1326 for (i = 0; i < array_len; ++i)
1327 {
1328 if (!abbrev->operands[count + 1].read_operand(sm6, abbrev->operands[count + 1].context,
1329 &record->operands[count + i]))
1330 {
1331 goto fail;
1332 }
1333 }
1334 record->operand_count += array_len;
1335 }
1336
1337 if ((ret = dxil_block_add_record(block, record)) < 0)
1338 goto fail;
1339
1340 return VKD3D_OK;
1341
1342fail:
1344 return ret;
1345}
1346
1347static enum vkd3d_result dxil_block_init(struct dxil_block *block, const struct dxil_block *parent,
1348 struct sm6_parser *sm6);
1349
1351{
1352 unsigned int reserve = (parent->id == MODULE_BLOCK) ? 12 : 2;
1353 struct dxil_block *block;
1354 enum vkd3d_result ret;
1355
1356 sm6->current_block = parent;
1357
1358 do
1359 {
1360 unsigned int abbrev_id = sm6_parser_read_bits(sm6, parent->abbrev_len);
1361
1362 switch (abbrev_id)
1363 {
1364 case END_BLOCK:
1366 return VKD3D_OK;
1367
1368 case ENTER_SUBBLOCK:
1369 if (parent->id != MODULE_BLOCK && parent->id != FUNCTION_BLOCK)
1370 {
1371 WARN("Invalid subblock parent id %u.\n", parent->id);
1373 }
1374
1375 if (!vkd3d_array_reserve((void **)&parent->child_blocks, &parent->child_block_capacity,
1376 max(reserve, parent->child_block_count + 1), sizeof(*parent->child_blocks))
1377 || !(block = vkd3d_calloc(1, sizeof(*block))))
1378 {
1379 ERR("Failed to allocate block.\n");
1381 }
1382
1383 if ((ret = dxil_block_init(block, parent, sm6)) < 0)
1384 {
1386 return ret;
1387 }
1388
1389 parent->child_blocks[parent->child_block_count++] = block;
1390 sm6->current_block = parent;
1391 break;
1392
1393 case DEFINE_ABBREV:
1394 if ((ret = sm6_parser_add_block_abbrev(sm6)) < 0)
1395 return ret;
1396 break;
1397
1398 case UNABBREV_RECORD:
1399 if ((ret = sm6_parser_read_unabbrev_record(sm6)) < 0)
1400 {
1401 WARN("Failed to read unabbreviated record.\n");
1402 return ret;
1403 }
1404 break;
1405
1406 default:
1407 if ((ret = sm6_parser_read_abbrev_record(sm6, abbrev_id - 4)) < 0)
1408 {
1409 WARN("Failed to read abbreviated record.\n");
1410 return ret;
1411 }
1412 break;
1413 }
1414 } while (!sm6->p.failed);
1415
1417}
1418
1420 unsigned int block_id)
1421{
1422 size_t i, count;
1423
1424 for (i = 0, count = 0; i < sm6->abbrev_count; ++i)
1425 count += sm6->abbrevs[i]->block_id == block_id;
1426
1427 return count;
1428}
1429
1431{
1432 size_t i;
1433
1434 for (i = 0; i < block->record_count; ++i)
1435 vkd3d_free(block->records[i]);
1436 vkd3d_free(block->records);
1437
1438 for (i = 0; i < block->child_block_count; ++i)
1439 {
1440 dxil_block_destroy(block->child_blocks[i]);
1441 vkd3d_free(block->child_blocks[i]);
1442 }
1443 vkd3d_free(block->child_blocks);
1444
1445 block->records = NULL;
1446 block->record_count = 0;
1447 block->child_blocks = NULL;
1448 block->child_block_count = 0;
1449}
1450
1452 struct sm6_parser *sm6)
1453{
1454 size_t i, abbrev_count = 0;
1455 enum vkd3d_result ret;
1456
1457 block->parent = parent;
1458 block->level = parent ? parent->level + 1 : 0;
1459 block->id = sm6_parser_read_vbr(sm6, 8);
1460 block->abbrev_len = sm6_parser_read_vbr(sm6, 4);
1462 block->length = sm6_parser_read_uint32(sm6);
1463 block->start = sm6->ptr - sm6->start;
1464
1465 if (sm6->p.failed)
1467
1468 if ((block->abbrev_count = sm6_parser_compute_global_abbrev_count_for_block_id(sm6, block->id)))
1469 {
1470 if (!vkd3d_array_reserve((void **)&block->abbrevs, &block->abbrev_capacity,
1471 block->abbrev_count, sizeof(*block->abbrevs)))
1472 {
1473 ERR("Failed to allocate block abbreviations.\n");
1475 }
1476
1477 for (i = 0; i < sm6->abbrev_count; ++i)
1478 if (sm6->abbrevs[i]->block_id == block->id)
1479 block->abbrevs[abbrev_count++] = &sm6->abbrevs[i]->abbrev;
1480
1481 VKD3D_ASSERT(abbrev_count == block->abbrev_count);
1482 }
1483
1484 if ((ret = dxil_block_read(block, sm6)) < 0)
1486
1487 for (i = abbrev_count; i < block->abbrev_count; ++i)
1488 vkd3d_free(block->abbrevs[i]);
1489 vkd3d_free(block->abbrevs);
1490 block->abbrevs = NULL;
1491 block->abbrev_count = 0;
1492
1493 return ret;
1494}
1495
1497{
1498 size_t i, count;
1499
1500 for (i = 0, count = 0; i < root->child_block_count; ++i)
1501 count += root->child_blocks[i]->id == FUNCTION_BLOCK;
1502
1503 return count;
1504}
1505
1507{
1508 size_t i, count;
1509
1510 for (i = 0, count = 0; i < block->record_count; ++i)
1511 count += block->records[i]->code == MODULE_CODE_FUNCTION || block->records[i]->code == MODULE_CODE_GLOBALVAR;
1512 return count;
1513}
1514
1516{
1517 size_t i, count;
1518
1519 for (i = 0, count = 0; i < block->record_count; ++i)
1520 count += block->records[i]->code != CST_CODE_SETTYPE;
1521 return count;
1522}
1523
1525{
1526 size_t i;
1527
1528 for (i = 0; i < count; ++i)
1531}
1532
1533static const struct dxil_block *sm6_parser_get_level_one_block(const struct sm6_parser *sm6,
1534 enum bitcode_block_id id, bool *is_unique)
1535{
1536 const struct dxil_block *block, *found = NULL;
1537 size_t i;
1538
1539 for (i = 0, *is_unique = true; i < sm6->root_block.child_block_count; ++i)
1540 {
1541 block = sm6->root_block.child_blocks[i];
1542 if (block->id != id)
1543 continue;
1544
1545 if (!found)
1546 found = block;
1547 else
1548 *is_unique = false;
1549 }
1550
1551 return found;
1552}
1553
1554static char *dxil_record_to_string(const struct dxil_record *record, unsigned int offset, struct sm6_parser *sm6)
1555{
1556 unsigned int i;
1557 char *str;
1558
1559 VKD3D_ASSERT(offset <= record->operand_count);
1560 if (!(str = vkd3d_calloc(record->operand_count - offset + 1, 1)))
1561 {
1563 "Out of memory allocating a string of length %u.", record->operand_count - offset);
1564 return NULL;
1565 }
1566
1567 for (i = offset; i < record->operand_count; ++i)
1568 str[i - offset] = record->operands[i];
1569
1570 return str;
1571}
1572
1573static bool dxil_record_validate_operand_min_count(const struct dxil_record *record, unsigned int min_count,
1574 struct sm6_parser *sm6)
1575{
1576 if (record->operand_count >= min_count)
1577 return true;
1578
1579 WARN("Invalid operand count %u for code %u.\n", record->operand_count, record->code);
1581 "Invalid operand count %u for record code %u.", record->operand_count, record->code);
1582 return false;
1583}
1584
1586 struct sm6_parser *sm6)
1587{
1588 if (record->operand_count <= max_count)
1589 return;
1590
1591 WARN("Ignoring %u extra operands for code %u.\n", record->operand_count - max_count, record->code);
1593 "Ignoring %u extra operands for record code %u.", record->operand_count - max_count, record->code);
1594}
1595
1596static bool dxil_record_validate_operand_count(const struct dxil_record *record, unsigned int min_count,
1597 unsigned int max_count, struct sm6_parser *sm6)
1598{
1600 return dxil_record_validate_operand_min_count(record, min_count, sm6);
1601}
1602
1604{
1605 const struct dxil_record *record;
1606 size_t i, type_count, type_index;
1607 const struct dxil_block *block;
1608 char *struct_name = NULL;
1609 unsigned int j, count;
1610 struct sm6_type *type;
1612 bool is_unique;
1613
1614 sm6->p.location.line = 0;
1615 sm6->p.location.column = 0;
1616
1617 if (!(block = sm6_parser_get_level_one_block(sm6, TYPE_BLOCK, &is_unique)))
1618 {
1619 WARN("No type definitions found.\n");
1620 return VKD3D_OK;
1621 }
1622 if (!is_unique)
1623 WARN("Ignoring invalid extra type table(s).\n");
1624
1625 sm6->p.location.line = block->id;
1626
1627 type_count = 0;
1628 for (i = 0; i < block->record_count; ++i)
1629 type_count += block->records[i]->code != TYPE_CODE_NUMENTRY && block->records[i]->code != TYPE_CODE_STRUCT_NAME;
1630
1631 /* The type array must not be relocated. */
1632 if (!(sm6->types = vkd3d_calloc(type_count, sizeof(*sm6->types))))
1633 {
1634 ERR("Failed to allocate type array.\n");
1636 }
1637
1638 for (i = 0; i < block->record_count; ++i)
1639 {
1640 sm6->p.location.column = i;
1641 record = block->records[i];
1642
1643 type = &sm6->types[sm6->type_count];
1644 type_index = sm6->type_count;
1645
1646 switch (record->code)
1647 {
1648 case TYPE_CODE_ARRAY:
1649 case TYPE_CODE_VECTOR:
1652
1654
1655 if (!(type->u.array.count = record->operands[0]))
1656 {
1657 TRACE("Setting unbounded for type %zu.\n", type_index);
1658 type->u.array.count = UINT_MAX;
1659 }
1660
1661 if ((type_id = record->operands[1]) >= type_count)
1662 {
1663 WARN("Invalid contained type id %"PRIu64" for type %zu.\n", type_id, type_index);
1665 }
1666 type->u.array.elem_type = &sm6->types[type_id];
1667 break;
1668
1669 case TYPE_CODE_DOUBLE:
1671 type->class = TYPE_CLASS_FLOAT;
1672 type->u.width = 64;
1673 break;
1674
1675 case TYPE_CODE_FLOAT:
1677 type->class = TYPE_CLASS_FLOAT;
1678 type->u.width = 32;
1679 break;
1680
1681 case TYPE_CODE_FUNCTION:
1684 if (record->operands[0])
1685 FIXME("Unhandled vararg function type %zu.\n", type_index);
1686
1687 type->class = TYPE_CLASS_FUNCTION;
1688
1689 if ((type_id = record->operands[1]) >= type_count)
1690 {
1691 WARN("Invalid return type id %"PRIu64" for type %zu.\n", type_id, type_index);
1693 }
1694
1695 count = record->operand_count - 2;
1696 if (vkd3d_object_range_overflow(sizeof(type->u.function), count, sizeof(type->u.function->param_types[0]))
1697 || !(type->u.function = vkd3d_malloc(offsetof(struct sm6_function_info, param_types[count]))))
1698 {
1699 ERR("Failed to allocate function parameter types.\n");
1701 }
1702
1703 type->u.function->ret_type = &sm6->types[type_id];
1704 type->u.function->param_count = count;
1705 for (j = 0; j < count; ++j)
1706 {
1707 if ((type_id = record->operands[j + 2]) >= type_count)
1708 {
1709 WARN("Invalid parameter type id %"PRIu64" for type %zu.\n", type_id, type_index);
1710 vkd3d_free(type->u.function);
1712 }
1713 type->u.function->param_types[j] = &sm6->types[type_id];
1714 }
1715 break;
1716
1717 case TYPE_CODE_HALF:
1719 type->class = TYPE_CLASS_FLOAT;
1720 type->u.width = 16;
1721 break;
1722
1723 case TYPE_CODE_INTEGER:
1724 {
1726
1729
1730 type->class = TYPE_CLASS_INTEGER;
1731
1732 switch ((width = record->operands[0]))
1733 {
1734 case 1:
1735 sm6->bool_type = type;
1736 break;
1737 case 8:
1738 case 16:
1739 case 32:
1740 case 64:
1741 break;
1742 default:
1743 WARN("Invalid integer width %"PRIu64" for type %zu.\n", width, type_index);
1745 }
1746 type->u.width = width;
1747 break;
1748 }
1749
1750 case TYPE_CODE_LABEL:
1751 type->class = TYPE_CLASS_LABEL;
1752 break;
1753
1754 case TYPE_CODE_METADATA:
1755 type->class = TYPE_CLASS_METADATA;
1756 sm6->metadata_type = type;
1757 break;
1758
1759 case TYPE_CODE_NUMENTRY:
1760 continue;
1761
1762 case TYPE_CODE_POINTER:
1765
1766 type->class = TYPE_CLASS_POINTER;
1767
1768 if ((type_id = record->operands[0]) >= type_count)
1769 {
1770 WARN("Invalid pointee type id %"PRIu64" for type %zu.\n", type_id, type_index);
1772 }
1773 type->u.pointer.type = &sm6->types[type_id];
1774 type->u.pointer.addr_space = (record->operand_count > 1) ? record->operands[1] : ADDRESS_SPACE_DEFAULT;
1775 break;
1776
1781 if (record->code == TYPE_CODE_STRUCT_NAMED && !struct_name)
1782 {
1783 WARN("Missing struct name before struct type %zu.\n", type_index);
1785 }
1786
1787 type->class = TYPE_CLASS_STRUCT;
1788
1789 count = record->operand_count - 1;
1790 if (vkd3d_object_range_overflow(sizeof(type->u.struc), count, sizeof(type->u.struc->elem_types[0]))
1791 || !(type->u.struc = vkd3d_malloc(offsetof(struct sm6_struct_info, elem_types[count]))))
1792 {
1793 ERR("Failed to allocate struct element types.\n");
1795 }
1796
1797 if (record->operands[0])
1798 FIXME("Ignoring struct packed attribute.\n");
1799
1800 type->u.struc->elem_count = count;
1801 for (j = 0; j < count; ++j)
1802 {
1803 if ((type_id = record->operands[j + 1]) >= type_count)
1804 {
1805 WARN("Invalid contained type id %"PRIu64" for type %zu.\n", type_id, type_index);
1806 vkd3d_free(type->u.struc);
1808 }
1809 type->u.struc->elem_types[j] = &sm6->types[type_id];
1810 }
1811
1812 if (record->code == TYPE_CODE_STRUCT_ANON)
1813 {
1814 type->u.struc->name = NULL;
1815 break;
1816 }
1817
1818 if (!strcmp(struct_name, "dx.types.Handle"))
1819 sm6->handle_type = type;
1820
1821 type->u.struc->name = struct_name;
1822 struct_name = NULL;
1823 break;
1824
1826 if (!(struct_name = dxil_record_to_string(record, 0, sm6)))
1827 {
1828 ERR("Failed to allocate struct name.\n");
1830 }
1831 if (!struct_name[0])
1832 WARN("Struct name is empty for type %zu.\n", type_index);
1833 continue;
1834
1835 case TYPE_CODE_VOID:
1837 type->class = TYPE_CLASS_VOID;
1838 break;
1839
1840 default:
1841 FIXME("Unhandled type %u at index %zu.\n", record->code, type_index);
1843 }
1844 ++sm6->type_count;
1845 }
1846
1847 VKD3D_ASSERT(sm6->type_count == type_count);
1848
1849 if (struct_name)
1850 {
1851 WARN("Unused struct name %s.\n", struct_name);
1852 vkd3d_free(struct_name);
1853 }
1854
1855 return VKD3D_OK;
1856}
1857
1858static inline bool sm6_type_is_void(const struct sm6_type *type)
1859{
1860 return type->class == TYPE_CLASS_VOID;
1861}
1862
1863static inline bool sm6_type_is_integer(const struct sm6_type *type)
1864{
1865 return type->class == TYPE_CLASS_INTEGER;
1866}
1867
1869{
1870 return type->class == TYPE_CLASS_INTEGER && (type->u.width == 1 || type->u.width >= 16);
1871}
1872
1873static bool sm6_type_is_i16_i32_i64(const struct sm6_type *type)
1874{
1875 return type->class == TYPE_CLASS_INTEGER && type->u.width >= 16;
1876}
1877
1878static bool sm6_type_is_bool(const struct sm6_type *type)
1879{
1880 return type->class == TYPE_CLASS_INTEGER && type->u.width == 1;
1881}
1882
1883static inline bool sm6_type_is_i8(const struct sm6_type *type)
1884{
1885 return type->class == TYPE_CLASS_INTEGER && type->u.width == 8;
1886}
1887
1888static inline bool sm6_type_is_i32(const struct sm6_type *type)
1889{
1890 return type->class == TYPE_CLASS_INTEGER && type->u.width == 32;
1891}
1892
1893static bool sm6_type_is_float(const struct sm6_type *type)
1894{
1895 return type->class == TYPE_CLASS_FLOAT && type->u.width == 32;
1896}
1897
1898static bool sm6_type_is_f16_f32(const struct sm6_type *type)
1899{
1900 return type->class == TYPE_CLASS_FLOAT && (type->u.width == 16 || type->u.width == 32);
1901}
1902
1903static bool sm6_type_is_double(const struct sm6_type *type)
1904{
1905 return type->class == TYPE_CLASS_FLOAT && type->u.width == 64;
1906}
1907
1908static inline bool sm6_type_is_floating_point(const struct sm6_type *type)
1909{
1910 return type->class == TYPE_CLASS_FLOAT;
1911}
1912
1913static bool sm6_type_is_scalar(const struct sm6_type *type)
1914{
1915 return type->class == TYPE_CLASS_INTEGER || type->class == TYPE_CLASS_FLOAT || type->class == TYPE_CLASS_POINTER;
1916}
1917
1918static inline bool sm6_type_is_numeric(const struct sm6_type *type)
1919{
1920 return type->class == TYPE_CLASS_INTEGER || type->class == TYPE_CLASS_FLOAT;
1921}
1922
1923static inline bool sm6_type_is_pointer(const struct sm6_type *type)
1924{
1925 return type->class == TYPE_CLASS_POINTER;
1926}
1927
1928static bool sm6_type_is_aggregate(const struct sm6_type *type)
1929{
1930 return type->class == TYPE_CLASS_STRUCT || type->class == TYPE_CLASS_VECTOR || type->class == TYPE_CLASS_ARRAY;
1931}
1932
1934{
1935 unsigned int i;
1936
1937 switch (type->class)
1938 {
1939 case TYPE_CLASS_ARRAY:
1940 case TYPE_CLASS_VECTOR:
1941 return sm6_type_is_numeric(type->u.array.elem_type);
1942
1943 case TYPE_CLASS_STRUCT:
1944 /* Do not handle nested structs. Support can be added if they show up. */
1945 for (i = 0; i < type->u.struc->elem_count; ++i)
1946 if (!sm6_type_is_numeric(type->u.struc->elem_types[i]))
1947 return false;
1948 return true;
1949
1950 default:
1951 return false;
1952 }
1953}
1954
1955static bool sm6_type_is_array(const struct sm6_type *type)
1956{
1957 return type->class == TYPE_CLASS_ARRAY;
1958}
1959
1960static inline bool sm6_type_is_struct(const struct sm6_type *type)
1961{
1962 return type->class == TYPE_CLASS_STRUCT;
1963}
1964
1965static inline bool sm6_type_is_function(const struct sm6_type *type)
1966{
1967 return type->class == TYPE_CLASS_FUNCTION;
1968}
1969
1970static inline bool sm6_type_is_function_pointer(const struct sm6_type *type)
1971{
1972 return sm6_type_is_pointer(type) && sm6_type_is_function(type->u.pointer.type);
1973}
1974
1975static inline bool sm6_type_is_handle(const struct sm6_type *type)
1976{
1977 return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.Handle");
1978}
1979
1980static inline const struct sm6_type *sm6_type_get_element_type(const struct sm6_type *type)
1981{
1982 return (type->class == TYPE_CLASS_ARRAY || type->class == TYPE_CLASS_VECTOR) ? type->u.array.elem_type : type;
1983}
1984
1985static const struct sm6_type *sm6_type_get_pointer_to_type(const struct sm6_type *type,
1986 enum bitcode_address_space addr_space, struct sm6_parser *sm6)
1987{
1988 size_t i, start = type - sm6->types;
1989 const struct sm6_type *pointer_type;
1990
1991 /* DXC seems usually to place the pointer type immediately after its pointee. */
1992 for (i = (start + 1) % sm6->type_count; i != start; i = (i + 1) % sm6->type_count)
1993 {
1994 pointer_type = &sm6->types[i];
1995 if (sm6_type_is_pointer(pointer_type) && pointer_type->u.pointer.type == type
1996 && pointer_type->u.pointer.addr_space == addr_space)
1997 return pointer_type;
1998 }
1999
2000 return NULL;
2001}
2002
2004{
2005 const struct sm6_type *type;
2006 unsigned int i;
2007
2008 for (i = 0; i < sm6->type_count; ++i)
2009 {
2010 type = &sm6->types[i];
2011 if (sm6_type_is_struct(type) && type->u.struc->elem_count == 2
2012 && sm6_type_is_i32(type->u.struc->elem_types[0])
2013 && sm6_type_is_bool(type->u.struc->elem_types[1]))
2014 {
2015 return type;
2016 }
2017 }
2018
2019 return NULL;
2020}
2021
2022/* Call for aggregate types only. */
2023static const struct sm6_type *sm6_type_get_element_type_at_index(const struct sm6_type *type, uint64_t elem_idx)
2024{
2025 switch (type->class)
2026 {
2027 case TYPE_CLASS_ARRAY:
2028 case TYPE_CLASS_VECTOR:
2029 if (elem_idx >= type->u.array.count)
2030 return NULL;
2031 return type->u.array.elem_type;
2032
2033 case TYPE_CLASS_STRUCT:
2034 if (elem_idx >= type->u.struc->elem_count)
2035 return NULL;
2036 return type->u.struc->elem_types[elem_idx];
2037
2038 default:
2040 }
2041}
2042
2043/* Never returns null for elem_idx 0. */
2044static const struct sm6_type *sm6_type_get_scalar_type(const struct sm6_type *type, unsigned int elem_idx)
2045{
2046 switch (type->class)
2047 {
2048 case TYPE_CLASS_ARRAY:
2049 case TYPE_CLASS_VECTOR:
2050 if (elem_idx >= type->u.array.count)
2051 return NULL;
2052 return sm6_type_get_scalar_type(type->u.array.elem_type, 0);
2053
2054 case TYPE_CLASS_POINTER:
2055 return sm6_type_get_scalar_type(type->u.pointer.type, 0);
2056
2057 case TYPE_CLASS_STRUCT:
2058 if (elem_idx >= type->u.struc->elem_count)
2059 return NULL;
2060 return sm6_type_get_scalar_type(type->u.struc->elem_types[elem_idx], 0);
2061
2062 default:
2063 return type;
2064 }
2065}
2066
2067static unsigned int sm6_type_max_vector_size(const struct sm6_type *type)
2068{
2069 return min((VKD3D_VEC4_SIZE * sizeof(uint32_t) * CHAR_BIT) / type->u.width, VKD3D_VEC4_SIZE);
2070}
2071
2072static const struct sm6_type *sm6_parser_get_type(struct sm6_parser *sm6, uint64_t type_id)
2073{
2074 if (type_id >= sm6->type_count)
2075 {
2076 WARN("Invalid type index %"PRIu64" at %zu.\n", type_id, sm6->value_count);
2078 "DXIL type id %"PRIu64" is invalid.", type_id);
2079 return NULL;
2080 }
2081 return &sm6->types[type_id];
2082}
2083
2085{
2087}
2088
2090{
2092}
2093
2094static int global_symbol_compare(const void *a, const void *b)
2095{
2096 return vkd3d_u32_compare(((const struct sm6_symbol *)a)->id, ((const struct sm6_symbol *)b)->id);
2097}
2098
2100{
2101 const struct dxil_record *record;
2102 const struct dxil_block *block;
2103 struct sm6_symbol *symbol;
2104 size_t i, count;
2105 bool is_unique;
2106
2107 sm6->p.location.line = 0;
2108 sm6->p.location.column = 0;
2109
2110 if (!(block = sm6_parser_get_level_one_block(sm6, VALUE_SYMTAB_BLOCK, &is_unique)))
2111 {
2112 /* There should always be at least one symbol: the name of the entry point function. */
2113 WARN("No value symtab block found.\n");
2115 }
2116 if (!is_unique)
2117 FIXME("Ignoring extra value symtab block(s).\n");
2118
2119 sm6->p.location.line = block->id;
2120
2121 for (i = 0, count = 0; i < block->record_count; ++i)
2122 count += block->records[i]->code == VST_CODE_ENTRY;
2123
2124 if (!(sm6->global_symbols = vkd3d_calloc(count, sizeof(*sm6->global_symbols))))
2125 {
2126 ERR("Failed to allocate global symbols.\n");
2128 }
2129
2130 for (i = 0; i < block->record_count; ++i)
2131 {
2132 sm6->p.location.column = i;
2133 record = block->records[i];
2134
2135 if (record->code != VST_CODE_ENTRY)
2136 {
2137 FIXME("Unhandled symtab code %u.\n", record->code);
2138 continue;
2139 }
2141 continue;
2142
2143 symbol = &sm6->global_symbols[sm6->global_symbol_count];
2144 symbol->id = record->operands[0];
2145 if (!(symbol->name = dxil_record_to_string(record, 1, sm6)))
2146 {
2147 ERR("Failed to allocate symbol name.\n");
2149 }
2150 ++sm6->global_symbol_count;
2151 }
2152
2153 sm6->p.location.column = block->record_count;
2154
2156 for (i = 1; i < sm6->global_symbol_count; ++i)
2157 {
2158 if (sm6->global_symbols[i].id == sm6->global_symbols[i - 1].id)
2159 {
2160 WARN("Invalid duplicate symbol id %u.\n", sm6->global_symbols[i].id);
2162 }
2163 }
2164
2165 return VKD3D_OK;
2166}
2167
2168static const char *sm6_parser_get_global_symbol_name(const struct sm6_parser *sm6, size_t id)
2169{
2170 size_t i, start;
2171
2172 /* id == array index is normally true */
2173 i = start = id % sm6->global_symbol_count;
2174 do
2175 {
2176 if (sm6->global_symbols[i].id == id)
2177 return sm6->global_symbols[i].name;
2178 i = (i + 1) % sm6->global_symbol_count;
2179 } while (i != start);
2180
2181 return NULL;
2182}
2183
2184static unsigned int register_get_uint_value(const struct vkd3d_shader_register *reg)
2185{
2186 if (!register_is_constant(reg) || (!data_type_is_integer(reg->data_type) && !data_type_is_bool(reg->data_type)))
2187 return UINT_MAX;
2188
2189 if (reg->dimension == VSIR_DIMENSION_VEC4)
2190 WARN("Returning vec4.x.\n");
2191
2192 if (reg->type == VKD3DSPR_IMMCONST64)
2193 {
2194 if (reg->u.immconst_u64[0] > UINT_MAX)
2195 FIXME("Truncating 64-bit value.\n");
2196 return reg->u.immconst_u64[0];
2197 }
2198
2199 return reg->u.immconst_u32[0];
2200}
2201
2203{
2204 if (!register_is_constant(reg) || !data_type_is_integer(reg->data_type))
2205 return UINT64_MAX;
2206
2207 if (reg->dimension == VSIR_DIMENSION_VEC4)
2208 WARN("Returning vec4.x.\n");
2209
2210 return (reg->type == VKD3DSPR_IMMCONST64) ? reg->u.immconst_u64[0] : reg->u.immconst_u32[0];
2211}
2212
2213static inline bool sm6_value_is_function_dcl(const struct sm6_value *value)
2214{
2215 return value->value_type == VALUE_TYPE_FUNCTION;
2216}
2217
2218static inline bool sm6_value_is_dx_intrinsic_dcl(const struct sm6_value *fn)
2219{
2221 return fn->u.function.is_prototype && !strncmp(fn->u.function.name, "dx.op.", 6);
2222}
2223
2224static inline struct sm6_value *sm6_parser_get_current_value(const struct sm6_parser *sm6)
2225{
2227 return &sm6->values[sm6->value_count];
2228}
2229
2230static inline bool sm6_value_is_register(const struct sm6_value *value)
2231{
2232 return value->value_type == VALUE_TYPE_REG;
2233}
2234
2235static bool sm6_value_is_handle(const struct sm6_value *value)
2236{
2237 return value->value_type == VALUE_TYPE_HANDLE;
2238}
2239
2240static inline bool sm6_value_is_constant(const struct sm6_value *value)
2241{
2243}
2244
2246{
2247 /* Constant vectors do not occur. */
2249}
2250
2251static inline bool sm6_value_is_undef(const struct sm6_value *value)
2252{
2253 return sm6_value_is_register(value) && value->u.reg.type == VKD3DSPR_UNDEF;
2254}
2255
2256static bool sm6_value_vector_is_constant_or_undef(const struct sm6_value **values, unsigned int count)
2257{
2258 unsigned int i;
2259 for (i = 0; i < count; ++i)
2261 return false;
2262 return true;
2263}
2264
2265static bool sm6_value_is_icb(const struct sm6_value *value)
2266{
2267 return value->value_type == VALUE_TYPE_ICB;
2268}
2269
2270static bool sm6_value_is_ssa(const struct sm6_value *value)
2271{
2273}
2274
2276{
2278}
2279
2280static inline unsigned int sm6_value_get_constant_uint(const struct sm6_value *value)
2281{
2283 return UINT_MAX;
2284 return register_get_uint_value(&value->u.reg);
2285}
2286
2288{
2290 return UINT64_MAX;
2291 return register_get_uint64_value(&value->u.reg);
2292}
2293
2294static unsigned int sm6_parser_alloc_ssa_id(struct sm6_parser *sm6)
2295{
2296 return sm6->ssa_next_id++;
2297}
2298
2300 enum vkd3d_shader_opcode handler_idx, const struct sm6_value *resource, struct sm6_parser *sm6)
2301{
2302 vsir_instruction_init(ins, &sm6->p.location, handler_idx);
2303 ins->resource_type = resource->u.handle.d->resource_type;
2304 ins->raw = resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER;
2305 ins->structured = resource->u.handle.d->kind == RESOURCE_KIND_STRUCTUREDBUFFER;
2306}
2307
2309 unsigned int count, struct sm6_parser *sm6)
2310{
2312
2313 if (!(params = vsir_program_get_src_params(sm6->p.program, count)))
2314 {
2315 ERR("Failed to allocate src params.\n");
2317 "Out of memory allocating instruction src parameters.");
2318 return NULL;
2319 }
2320 ins->src = params;
2321 ins->src_count = count;
2322 return params;
2323}
2324
2326 unsigned int count, struct sm6_parser *sm6)
2327{
2329
2330 if (!(params = vsir_program_get_dst_params(sm6->p.program, count)))
2331 {
2332 ERR("Failed to allocate dst params.\n");
2334 "Out of memory allocating instruction dst parameters.");
2335 return NULL;
2336 }
2337 ins->dst = params;
2338 ins->dst_count = count;
2339 return params;
2340}
2341
2344{
2346 reg->idx[0].offset = id;
2347}
2348
2350{
2351 if (type->class == TYPE_CLASS_INTEGER)
2352 {
2353 switch (type->u.width)
2354 {
2355 case 1:
2356 return VKD3D_DATA_BOOL;
2357 case 8:
2358 return VKD3D_DATA_UINT8;
2359 case 16:
2360 return VKD3D_DATA_UINT16;
2361 case 32:
2362 return VKD3D_DATA_UINT;
2363 case 64:
2364 return VKD3D_DATA_UINT64;
2365 default:
2366 FIXME("Unhandled width %u.\n", type->u.width);
2367 return VKD3D_DATA_UINT;
2368 }
2369 }
2370 else if (type->class == TYPE_CLASS_FLOAT)
2371 {
2372 switch (type->u.width)
2373 {
2374 case 16:
2375 return VKD3D_DATA_HALF;
2376 case 32:
2377 return VKD3D_DATA_FLOAT;
2378 case 64:
2379 return VKD3D_DATA_DOUBLE;
2380 default:
2381 FIXME("Unhandled width %u.\n", type->u.width);
2382 return VKD3D_DATA_FLOAT;
2383 }
2384 }
2385
2386 FIXME("Unhandled type %u.\n", type->class);
2387 return VKD3D_DATA_UINT;
2388}
2389
2391 unsigned int component_count, struct sm6_value *value, struct sm6_parser *sm6)
2392{
2394 unsigned int id;
2395
2396 if (value && register_is_ssa(&value->u.reg) && value->u.reg.idx[0].offset)
2397 {
2398 id = value->u.reg.idx[0].offset;
2399 TRACE("Using forward-allocated id %u.\n", id);
2400 }
2401 else
2402 {
2403 id = sm6_parser_alloc_ssa_id(sm6);
2404 }
2408}
2409
2411 struct sm6_value *value, struct sm6_parser *sm6)
2412{
2414}
2415
2417{
2419 reg->u.immconst_u32[0] = value;
2420}
2421
2423{
2424 param->write_mask = VKD3DSP_WRITEMASK_0;
2425 param->modifiers = 0;
2426 param->shift = 0;
2427}
2428
2430{
2431 param->write_mask = mask;
2432 param->modifiers = 0;
2433 param->shift = 0;
2434}
2435
2436static inline void dst_param_init_scalar(struct vkd3d_shader_dst_param *param, unsigned int component_idx)
2437{
2438 param->write_mask = 1u << component_idx;
2439 param->modifiers = 0;
2440 param->shift = 0;
2441}
2442
2444{
2445 param->write_mask = (1u << component_count) - 1;
2446 param->modifiers = 0;
2447 param->shift = 0;
2448}
2449
2451 struct sm6_value *value, struct sm6_parser *sm6)
2452{
2455}
2456
2458{
2459 param->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
2460 param->modifiers = VKD3DSPSM_NONE;
2461}
2462
2463static void src_param_init_scalar(struct vkd3d_shader_src_param *param, unsigned int component_idx)
2464{
2465 param->swizzle = vkd3d_shader_create_swizzle(component_idx, component_idx, component_idx, component_idx);
2466 if (data_type_is_64_bit(param->reg.data_type))
2468 param->modifiers = VKD3DSPSM_NONE;
2469}
2470
2472{
2474 param->modifiers = VKD3DSPSM_NONE;
2475}
2476
2478{
2480 param->reg = src->u.reg;
2481}
2482
2484 const struct vkd3d_shader_register *reg)
2485{
2486 param->swizzle = (reg->dimension == VSIR_DIMENSION_VEC4) ? VKD3D_SHADER_NO_SWIZZLE : VKD3D_SHADER_SWIZZLE(X, X, X, X);
2487 param->modifiers = VKD3DSPSM_NONE;
2488 param->reg = *reg;
2489}
2490
2492{
2495}
2496
2498 struct sm6_parser *sm6)
2499{
2501 {
2503 idx->rel_addr = NULL;
2504 }
2505 else if (sm6_value_is_undef(address))
2506 {
2507 idx->offset = 0;
2508 idx->rel_addr = NULL;
2509 }
2510 else
2511 {
2512 struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(sm6->p.program, 1);
2513 if (rel_addr)
2515 idx->offset = 0;
2516 idx->rel_addr = rel_addr;
2517 }
2518}
2519
2521{
2524
2525 if (!(param = instruction_dst_params_alloc(ins, 1, sm6)))
2526 return false;
2527
2528 dst_param_init_ssa_scalar(param, dst->type, dst, sm6);
2529 param->write_mask = VKD3DSP_WRITEMASK_0;
2530 dst->u.reg = param->reg;
2531 return true;
2532}
2533
2535 unsigned int component_count, struct sm6_parser *sm6)
2536{
2539
2542 dst->u.reg = param->reg;
2543}
2544
2546{
2549
2550 if (!(param = instruction_dst_params_alloc(ins, 1, sm6)))
2551 return false;
2552
2554 param->write_mask = VKD3DSP_WRITEMASK_ALL;
2555 param->reg.idx[0].offset = 0;
2556 param->reg.dimension = VSIR_DIMENSION_VEC4;
2557 dst->u.reg = param->reg;
2558
2559 return true;
2560}
2561
2562/* Recurse through the block tree while maintaining a current value count. The current
2563 * count is the sum of the global count plus all declarations within the current function.
2564 * Store into value_capacity the highest count seen. */
2566 const struct dxil_block *block, size_t value_count)
2567{
2568 size_t i, old_value_count = value_count;
2569
2570 if (block->id == MODULE_BLOCK)
2572
2573 for (i = 0; i < block->child_block_count; ++i)
2574 value_count = sm6_parser_compute_max_value_count(sm6, block->child_blocks[i], value_count);
2575
2576 switch (block->id)
2577 {
2578 case CONSTANTS_BLOCK:
2579 /* Function local constants are contained in a child block of the function block. */
2581 break;
2582 case FUNCTION_BLOCK:
2583 /* A function must start with a block count, which emits no value. This formula is likely to
2584 * overestimate the value count somewhat, but this should be no problem. */
2585 value_count = size_add_with_overflow_check(value_count, max(block->record_count, 1u) - 1);
2586 sm6->value_capacity = max(sm6->value_capacity, value_count);
2587 sm6->functions[sm6->function_count++].value_count = value_count;
2588 /* The value count returns to its previous value after handling a function. */
2589 if (value_count < SIZE_MAX)
2590 value_count = old_value_count;
2591 break;
2592 default:
2593 break;
2594 }
2595
2596 return value_count;
2597}
2598
2600{
2601 size_t i;
2602
2603 /* The value relative index is 32 bits. */
2604 if (idx > UINT32_MAX)
2605 WARN("Ignoring upper 32 bits of relative index.\n");
2606 i = (uint32_t)sm6->value_count - (uint32_t)idx;
2607
2608 /* This may underflow to produce a forward reference, but it must not exceed the final value count. */
2609 if (i >= sm6->cur_max_value)
2610 {
2611 WARN("Invalid value index %"PRIx64" at %zu.\n", idx, sm6->value_count);
2613 "Invalid value relative index %u.", (unsigned int)idx);
2614 return SIZE_MAX;
2615 }
2616 if (i == sm6->value_count)
2617 {
2618 WARN("Invalid value self-reference at %zu.\n", sm6->value_count);
2619 vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Invalid value self-reference.");
2620 return SIZE_MAX;
2621 }
2622
2623 return i;
2624}
2625
2626static bool sm6_value_validate_is_register(const struct sm6_value *value, struct sm6_parser *sm6)
2627{
2629 {
2630 WARN("Operand of type %u is not a register.\n", value->value_type);
2632 "A register operand passed to a DXIL instruction is not a register.");
2633 return false;
2634 }
2635 return true;
2636}
2637
2638static bool sm6_value_validate_is_handle(const struct sm6_value *value, struct sm6_parser *sm6)
2639{
2641 {
2642 WARN("Handle parameter of type %u is not a handle.\n", value->value_type);
2644 "A handle parameter passed to a DX intrinsic function is not a handle.");
2645 return false;
2646 }
2647 return true;
2648}
2649
2651 struct sm6_parser *sm6)
2652{
2653 enum dxil_resource_kind kind;
2654
2656 return false;
2657
2658 kind = value->u.handle.d->kind;
2659 if (kind < RESOURCE_KIND_TEXTURE1D || kind > RESOURCE_KIND_TEXTURECUBEARRAY)
2660 {
2661 WARN("Resource kind %u for op %u is not a texture.\n", kind, op);
2663 "Resource kind %u for texture operation %u is not a texture.", kind, op);
2664 return false;
2665 }
2666
2667 return true;
2668}
2669
2671 struct sm6_parser *sm6)
2672{
2673 enum dxil_resource_kind kind;
2674
2676 return false;
2677
2678 kind = value->u.handle.d->kind;
2680 {
2681 WARN("Resource kind %u for op %u is not a 2DMS texture.\n", kind, op);
2683 "Resource kind %u for texture operation %u is not a 2DMS texture.", kind, op);
2684 return false;
2685 }
2686
2687 return true;
2688}
2689
2691 struct sm6_parser *sm6)
2692{
2693 enum dxil_resource_kind kind;
2694
2696 return false;
2697
2698 kind = value->u.handle.d->kind;
2699 if (kind != RESOURCE_KIND_SAMPLER)
2700 {
2701 WARN("Resource kind %u for op %u is not a sampler.\n", kind, op);
2703 "Resource kind %u for sample operation %u is not a sampler.", kind, op);
2704 return false;
2705 }
2706
2707 return true;
2708}
2709
2710static bool sm6_value_validate_is_pointer(const struct sm6_value *value, struct sm6_parser *sm6)
2711{
2712 if (!sm6_type_is_pointer(value->type))
2713 {
2714 WARN("Operand result type class %u is not a pointer.\n", value->type->class);
2716 "A pointer operand passed to a DXIL instruction is not a pointer.");
2717 return false;
2718 }
2719 return true;
2720}
2721
2722static bool sm6_value_validate_is_backward_ref(const struct sm6_value *value, struct sm6_parser *sm6)
2723{
2724 if (!value->is_back_ref)
2725 {
2726 FIXME("Forward-referenced pointers are not supported.\n");
2728 "Forward-referenced pointer declarations are not supported.");
2729 return false;
2730 }
2731 return true;
2732}
2733
2734static bool sm6_value_validate_is_numeric(const struct sm6_value *value, struct sm6_parser *sm6)
2735{
2736 if (!sm6_type_is_numeric(value->type))
2737 {
2738 WARN("Operand result type class %u is not numeric.\n", value->type->class);
2740 "A numeric operand passed to a DXIL instruction is not numeric.");
2741 return false;
2742 }
2743 return true;
2744}
2745
2746static bool sm6_value_validate_is_bool(const struct sm6_value *value, struct sm6_parser *sm6)
2747{
2748 const struct sm6_type *type = value->type;
2749 if (!sm6_type_is_bool(type))
2750 {
2751 WARN("Operand of type class %u is not bool.\n", type->class);
2753 "A bool operand of type class %u passed to a DXIL instruction is not a bool.", type->class);
2754 return false;
2755 }
2756 return true;
2757}
2758
2760{
2761 if (!sm6_type_is_pointer(value->type) || !sm6_type_is_i32(value->type->u.pointer.type))
2762 {
2763 WARN("Operand result type %u is not a pointer to i32.\n", value->type->class);
2765 "An int32 pointer operand passed to a DXIL instruction is not an int32 pointer.");
2766 return false;
2767 }
2768 return true;
2769}
2770
2771static bool sm6_value_validate_is_i32(const struct sm6_value *value, struct sm6_parser *sm6)
2772{
2773 if (!sm6_type_is_i32(value->type))
2774 {
2775 WARN("Operand result type %u is not i32.\n", value->type->class);
2777 "An int32 operand passed to a DXIL instruction is not an int32.");
2778 return false;
2779 }
2780 return true;
2781}
2782
2783static const struct sm6_value *sm6_parser_get_value_safe(struct sm6_parser *sm6, unsigned int idx)
2784{
2785 if (idx < sm6->value_count)
2786 return &sm6->values[idx];
2787
2788 WARN("Invalid value index %u.\n", idx);
2790 "Invalid value index %u.", idx);
2791 return NULL;
2792}
2793
2794static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const struct dxil_record *record,
2795 const struct sm6_type *fwd_type, unsigned int *rec_idx)
2796{
2797 struct sm6_value *value;
2798 unsigned int idx;
2799 uint64_t val_ref;
2800 size_t operand;
2801
2802 idx = *rec_idx;
2804 return SIZE_MAX;
2805 val_ref = record->operands[idx++];
2806
2807 operand = sm6_parser_get_value_index(sm6, val_ref);
2808 if (operand == SIZE_MAX)
2809 return SIZE_MAX;
2810
2811 if (operand >= sm6->value_count && !fwd_type)
2812 {
2813 /* Forward references are followed by a type id unless an earlier operand set the type,
2814 * or it is contained in a function declaration. */
2816 return SIZE_MAX;
2817 if (!(fwd_type = sm6_parser_get_type(sm6, record->operands[idx++])))
2818 return SIZE_MAX;
2819 }
2820 *rec_idx = idx;
2821
2822 if (fwd_type)
2823 {
2824 value = &sm6->values[operand];
2825 if (value->type)
2826 {
2827 if (value->type != fwd_type)
2828 {
2829 WARN("Value already has a mismatching type.\n");
2831 "The type of a source value does not match the predefined type.");
2832 }
2833 }
2834 else
2835 {
2836 value->type = fwd_type;
2837 value->value_type = VALUE_TYPE_REG;
2840 value->u.reg.dimension = sm6_type_is_scalar(fwd_type) ? VSIR_DIMENSION_SCALAR
2842 }
2843 }
2844
2845 return operand;
2846}
2847
2848static const struct sm6_value *sm6_parser_get_value_by_ref(struct sm6_parser *sm6,
2849 const struct dxil_record *record, const struct sm6_type *type, unsigned int *rec_idx)
2850{
2851 size_t operand = sm6_parser_get_value_idx_by_ref(sm6, record, type, rec_idx);
2852 return operand == SIZE_MAX ? NULL : &sm6->values[operand];
2853}
2854
2855static bool sm6_parser_declare_function(struct sm6_parser *sm6, const struct dxil_record *record)
2856{
2857 const struct sm6_type *type, *ret_type;
2858 const unsigned int max_count = 15;
2859 struct sm6_value *fn;
2860 unsigned int i, j;
2861
2863 return false;
2864
2866 fn->value_type = VALUE_TYPE_FUNCTION;
2867 if (!(fn->u.function.name = sm6_parser_get_global_symbol_name(sm6, sm6->value_count)))
2868 {
2869 WARN("Missing symbol name for function %zu.\n", sm6->value_count);
2870 fn->u.function.name = "";
2871 }
2872
2873 if (!(type = sm6_parser_get_type(sm6, record->operands[0])))
2874 return false;
2876 {
2877 WARN("Type is not a function.\n");
2878 return false;
2879 }
2880 ret_type = type->u.function->ret_type;
2881
2883 {
2884 WARN("Failed to get pointer type for type %u.\n", type->class);
2885 return false;
2886 }
2887
2888 if (record->operands[1])
2889 WARN("Ignoring calling convention %#"PRIx64".\n", record->operands[1]);
2890
2891 fn->u.function.is_prototype = !!record->operands[2];
2892
2893 if (record->operands[3])
2894 WARN("Ignoring linkage %#"PRIx64".\n", record->operands[3]);
2895
2896 if (record->operands[4] > UINT_MAX)
2897 WARN("Invalid attributes id %#"PRIx64".\n", record->operands[4]);
2898 /* 1-based index. */
2899 if ((fn->u.function.attribs_id = record->operands[4]))
2900 TRACE("Ignoring function attributes.\n");
2901
2902 /* These always seem to be zero. */
2903 for (i = 5, j = 0; i < min(record->operand_count, max_count); ++i)
2904 j += !!record->operands[i];
2905 if (j)
2906 WARN("Ignoring %u operands.\n", j);
2907
2909 && !sm6_type_is_numeric_aggregate(ret_type) && !sm6_type_is_handle(ret_type))
2910 {
2911 WARN("Unexpected return type for dx intrinsic function '%s'.\n", fn->u.function.name);
2912 }
2913
2914 ++sm6->value_count;
2915
2916 return true;
2917}
2918
2920{
2921 if (value != 1)
2922 {
2923 bool neg = value & 1;
2924 value >>= 1;
2925 return neg ? -value : value;
2926 }
2927 return value << 63;
2928}
2929
2930static float bitcast_uint_to_float(unsigned int value)
2931{
2932 union
2933 {
2934 uint32_t uint32_value;
2935 float float_value;
2936 } u;
2937
2938 u.uint32_value = value;
2939 return u.float_value;
2940}
2941
2943{
2944 union
2945 {
2946 uint64_t uint64_value;
2947 double double_value;
2948 } u;
2949
2950 u.uint64_value = value;
2951 return u.double_value;
2952}
2953
2955{
2957 return 0.0;
2958
2959 if (reg->dimension == VSIR_DIMENSION_VEC4)
2960 WARN("Returning vec4.x.\n");
2961
2962 if (reg->type == VKD3DSPR_IMMCONST64)
2963 {
2964 WARN("Truncating double to float.\n");
2965 return bitcast_uint64_to_double(reg->u.immconst_u64[0]);
2966 }
2967
2968 return bitcast_uint_to_float(reg->u.immconst_u32[0]);
2969}
2970
2972 const uint64_t *operands, struct sm6_parser *sm6)
2973{
2975 const struct sm6_type *elem_type;
2976 unsigned int i, size, count;
2977
2978 elem_type = type->u.array.elem_type;
2979 /* Multidimensional arrays are emitted in flattened form. */
2980 if (elem_type->class != TYPE_CLASS_INTEGER && elem_type->class != TYPE_CLASS_FLOAT)
2981 {
2982 FIXME("Unhandled element type %u for data array.\n", elem_type->class);
2984 "The element data type for an immediate constant buffer is not scalar integer or floating point.");
2986 }
2987
2988 /* Arrays of bool are not used in DXIL. dxc will emit an array of int32 instead if necessary. */
2989 if (!(size = elem_type->u.width / CHAR_BIT))
2990 {
2991 WARN("Invalid data type width %u.\n", elem_type->u.width);
2993 "An immediate constant buffer is declared with boolean elements.");
2995 }
2996 size = max(size, sizeof(icb->data[0]));
2997 count = operands ? type->u.array.count * size / sizeof(icb->data[0]) : 0;
2998
3000 {
3001 ERR("Failed to allocate buffer, count %u.\n", count);
3003 "Out of memory allocating an immediate constant buffer of count %u.", count);
3005 }
3006 if (!shader_instruction_array_add_icb(&sm6->p.program->instructions, icb))
3007 {
3008 ERR("Failed to store icb object.\n");
3009 vkd3d_free(icb);
3011 "Out of memory storing an immediate constant buffer object.");
3013 }
3014
3015 dst->value_type = VALUE_TYPE_ICB;
3016 dst->u.icb = icb;
3017
3018 icb->register_idx = sm6->icb_count++;
3019 icb->data_type = vkd3d_data_type_from_sm6_type(elem_type);
3020 icb->element_count = type->u.array.count;
3021 icb->component_count = 1;
3022 icb->is_null = !operands;
3023
3024 if (!operands)
3025 return VKD3D_OK;
3026
3027 count = type->u.array.count;
3028 if (size > sizeof(icb->data[0]))
3029 {
3030 uint64_t *data = (uint64_t *)icb->data;
3031 for (i = 0; i < count; ++i)
3032 data[i] = operands[i];
3033 }
3034 else
3035 {
3036 for (i = 0; i < count; ++i)
3037 icb->data[i] = operands[i];
3038 }
3039
3040 return VKD3D_OK;
3041}
3042
3044 struct sm6_value *dst)
3045{
3046 const struct sm6_type *elem_type, *pointee_type, *gep_type, *ptr_type;
3047 struct sm6_value *operands[3];
3048 unsigned int i, j, offset;
3050
3051 i = 0;
3052 pointee_type = (record->operand_count & 1) ? sm6_parser_get_type(sm6, record->operands[i++]) : NULL;
3053
3054 if (!dxil_record_validate_operand_count(record, i + 6, i + 6, sm6))
3056
3057 for (j = 0; i < record->operand_count; i += 2, ++j)
3058 {
3059 if (!(elem_type = sm6_parser_get_type(sm6, record->operands[i])))
3061
3062 if ((value = record->operands[i + 1]) >= sm6->cur_max_value)
3063 {
3064 WARN("Invalid value index %"PRIu64".\n", value);
3066 "Invalid value index %"PRIu64".", value);
3068 }
3069 else if (value == sm6->value_count)
3070 {
3071 WARN("Invalid value self-reference at %"PRIu64".\n", value);
3073 "Invalid value self-reference for a constexpr GEP.");
3075 }
3076
3077 operands[j] = &sm6->values[value];
3078 if (value > sm6->value_count)
3079 {
3080 operands[j]->type = elem_type;
3081 }
3082 else if (operands[j]->type != elem_type)
3083 {
3084 WARN("Type mismatch.\n");
3086 "Type mismatch in constexpr GEP elements.");
3087 }
3088 }
3089
3090 if (operands[0]->u.reg.idx_count > 1)
3091 {
3092 WARN("Unsupported stacked GEP.\n");
3094 "A GEP instruction on the result of a previous GEP is unsupported.");
3096 }
3097
3098 if (!sm6_value_is_constant_zero(operands[1]))
3099 {
3100 WARN("Expected constant zero.\n");
3102 "The pointer dereference index for a constexpr GEP instruction is not constant zero.");
3104 }
3105 if (!sm6_value_is_constant(operands[2]) || !sm6_type_is_integer(operands[2]->type))
3106 {
3107 WARN("Element index is not constant int.\n");
3109 "A constexpr GEP element index is not a constant integer.");
3111 }
3112
3113 dst->structure_stride = operands[0]->structure_stride;
3114
3115 ptr_type = operands[0]->type;
3116 if (!sm6_type_is_pointer(ptr_type))
3117 {
3118 WARN("Constexpr GEP base value is not a pointer.\n");
3120 "A constexpr GEP base value is not a pointer.");
3122 }
3123
3124 if (!pointee_type)
3125 {
3126 pointee_type = ptr_type->u.pointer.type;
3127 }
3128 else if (pointee_type != ptr_type->u.pointer.type)
3129 {
3130 WARN("Explicit pointee type mismatch.\n");
3132 "Explicit pointee type for constexpr GEP does not match the element type.");
3133 }
3134
3135 offset = sm6_value_get_constant_uint(operands[2]);
3136 if (!(gep_type = sm6_type_get_element_type_at_index(pointee_type, offset)))
3137 {
3138 WARN("Failed to get element type.\n");
3140 "Failed to get the element type of a constexpr GEP.");
3142 }
3143
3144 if (!(dst->type = sm6_type_get_pointer_to_type(gep_type, ptr_type->u.pointer.addr_space, sm6)))
3145 {
3146 WARN("Failed to get pointer type for type %u.\n", gep_type->class);
3148 "Module does not define a pointer type for a constexpr GEP result.");
3150 }
3151 dst->u.reg = operands[0]->u.reg;
3152 dst->u.reg.idx[1].offset = offset;
3153 dst->u.reg.idx[1].is_in_bounds = record->code == CST_CODE_CE_INBOUNDS_GEP;
3154 dst->u.reg.idx_count = 2;
3155
3156 return VKD3D_OK;
3157}
3158
3160{
3162 const struct sm6_type *type, *elem_type, *ptr_type;
3163 size_t i, base_value_idx, value_idx;
3164 enum vkd3d_data_type reg_data_type;
3165 const struct dxil_record *record;
3166 const struct sm6_value *src;
3167 enum vkd3d_result ret;
3168 struct sm6_value *dst;
3170
3171 for (i = 0, type = NULL, base_value_idx = sm6->value_count; i < block->record_count; ++i)
3172 {
3173 sm6->p.location.column = i;
3174 record = block->records[i];
3175 value_idx = sm6->value_count;
3176
3177 if (record->code == CST_CODE_SETTYPE)
3178 {
3181
3182 if (!(type = sm6_parser_get_type(sm6, record->operands[0])))
3184
3185 elem_type = sm6_type_get_element_type(type);
3186 if (sm6_type_is_numeric(elem_type))
3187 {
3188 reg_data_type = vkd3d_data_type_from_sm6_type(elem_type);
3190 }
3191 else
3192 {
3193 reg_data_type = VKD3D_DATA_UNUSED;
3195 }
3196
3197 if (i == block->record_count - 1)
3198 WARN("Unused SETTYPE record.\n");
3199
3200 continue;
3201 }
3202
3203 if (!type)
3204 {
3205 WARN("Constant record %zu has no type.\n", value_idx);
3207 }
3208
3210 dst->type = type;
3211 dst->value_type = VALUE_TYPE_REG;
3212 dst->is_back_ref = true;
3213 vsir_register_init(&dst->u.reg, reg_type, reg_data_type, 0);
3214
3215 switch (record->code)
3216 {
3217 case CST_CODE_NULL:
3219 && (ret = value_allocate_constant_array(dst, type, NULL, sm6)) < 0)
3220 {
3221 return ret;
3222 }
3223 /* For non-aggregates, register constant data is already zero-filled. */
3224 break;
3225
3226 case CST_CODE_INTEGER:
3229
3231 {
3232 WARN("Invalid integer of non-integer type %u at constant idx %zu.\n", type->class, value_idx);
3234 }
3235
3237 if (type->u.width <= 32)
3238 dst->u.reg.u.immconst_u32[0] = value & ((1ull << type->u.width) - 1);
3239 else
3240 dst->u.reg.u.immconst_u64[0] = value;
3241
3242 break;
3243
3244 case CST_CODE_FLOAT:
3247
3249 {
3250 WARN("Invalid float of non-fp type %u at constant idx %zu.\n", type->class, value_idx);
3252 }
3253
3254 if (type->u.width == 16)
3255 dst->u.reg.u.immconst_u32[0] = record->operands[0];
3256 else if (type->u.width == 32)
3257 dst->u.reg.u.immconst_f32[0] = bitcast_uint_to_float(record->operands[0]);
3258 else if (type->u.width == 64)
3259 dst->u.reg.u.immconst_f64[0] = bitcast_uint64_to_double(record->operands[0]);
3260 else
3262
3263 break;
3264
3265 case CST_CODE_DATA:
3266 if (!sm6_type_is_array(type))
3267 {
3268 WARN("Invalid type %u for data constant idx %zu.\n", type->class, value_idx);
3270 "The type of a constant array is not an array type.");
3272 }
3273 if (!dxil_record_validate_operand_count(record, type->u.array.count, type->u.array.count, sm6))
3275
3276 if ((ret = value_allocate_constant_array(dst, type, record->operands, sm6)) < 0)
3277 return ret;
3278
3279 break;
3280
3281 case CST_CODE_CE_GEP:
3283 if ((ret = sm6_parser_init_constexpr_gep(sm6, record, dst)) < 0)
3284 return ret;
3285 break;
3286
3287 case CST_CODE_CE_CAST:
3290
3291 if ((value = record->operands[0]) != CAST_BITCAST)
3292 {
3293 WARN("Unhandled constexpr cast op %"PRIu64".\n", value);
3295 "Constexpr cast op %"PRIu64" is unhandled.", value);
3297 }
3298
3299 ptr_type = sm6_parser_get_type(sm6, record->operands[1]);
3300 if (!sm6_type_is_pointer(ptr_type))
3301 {
3302 WARN("Constexpr cast at constant idx %zu is not a pointer.\n", value_idx);
3304 "Constexpr cast source operand is not a pointer.");
3306 }
3307
3308 if ((value = record->operands[2]) >= sm6->cur_max_value)
3309 {
3310 WARN("Invalid value index %"PRIu64".\n", value);
3312 "Invalid value index %"PRIu64".", value);
3314 }
3315 else if (value == value_idx)
3316 {
3317 WARN("Invalid value self-reference at %"PRIu64".\n", value);
3319 "Invalid value self-reference for a constexpr cast.");
3321 }
3322
3323 /* Resolve later in case forward refs exist. */
3324 dst->type = type;
3325 dst->u.reg.type = VKD3DSPR_COUNT;
3326 dst->u.reg.idx[0].offset = value;
3327 break;
3328
3329 case CST_CODE_UNDEF:
3331 dst->u.reg.type = VKD3DSPR_UNDEF;
3332 /* Mark as explicitly undefined, not the result of a missing constant code or instruction. */
3333 dst->is_undefined = true;
3334 break;
3335
3336 default:
3337 FIXME("Unhandled constant code %u.\n", record->code);
3339 "Constant code %u is unhandled.", record->code);
3340 dst->u.reg.type = VKD3DSPR_UNDEF;
3341 break;
3342 }
3343
3344 if (record->attachment)
3345 {
3346 WARN("Ignoring metadata attachment.\n");
3348 "Ignoring a metadata attachment for a constant.");
3349 }
3350
3351 ++sm6->value_count;
3352 }
3353
3354 /* Resolve cast forward refs. */
3355 for (i = base_value_idx; i < sm6->value_count; ++i)
3356 {
3357 dst = &sm6->values[i];
3358 if (dst->u.reg.type != VKD3DSPR_COUNT)
3359 continue;
3360
3361 type = dst->type;
3362
3363 src = &sm6->values[dst->u.reg.idx[0].offset];
3365 {
3366 WARN("Value is not an array.\n");
3368 "Constexpr cast source value is not a global array element.");
3370 }
3371
3372 *dst = *src;
3373 dst->type = type;
3374 dst->u.reg.data_type = vkd3d_data_type_from_sm6_type(type->u.pointer.type);
3375 }
3376
3377 return VKD3D_OK;
3378}
3379
3380static bool bitcode_parse_alignment(uint64_t encoded_alignment, unsigned int *alignment)
3381{
3382 if (encoded_alignment > MAX_ALIGNMENT_EXPONENT + 1)
3383 {
3384 *alignment = 0;
3385 return false;
3386 }
3387 *alignment = (1u << encoded_alignment) >> 1;
3388 return true;
3389}
3390
3392{
3393 struct vkd3d_shader_instruction_array *instructions = &sm6->p.program->instructions;
3394
3395 if (!shader_instruction_array_reserve(instructions, instructions->count + extra))
3396 {
3397 ERR("Failed to allocate instruction.\n");
3398 return NULL;
3399 }
3400 return &instructions->elements[instructions->count];
3401}
3402
3403/* Space should be reserved before calling this. It is intended to require no checking of the returned pointer. */
3405 enum vkd3d_shader_opcode handler_idx)
3406{
3408 VKD3D_ASSERT(ins);
3409 vsir_instruction_init(ins, &sm6->p.location, handler_idx);
3410 ++sm6->p.program->instructions.count;
3411 return ins;
3412}
3413
3414static void sm6_parser_declare_icb(struct sm6_parser *sm6, const struct sm6_type *elem_type, unsigned int count,
3415 unsigned int alignment, unsigned int init, struct sm6_value *dst)
3416{
3418 struct vkd3d_shader_instruction *ins;
3419
3421 /* The icb value index will be resolved later so forward references can be handled. */
3422 ins->declaration.icb = (void *)(intptr_t)init;
3424}
3425
3426static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const struct sm6_type *elem_type,
3427 unsigned int count, unsigned int alignment, bool has_function_scope, unsigned int init,
3428 struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
3429{
3431
3432 if (ins)
3434 else
3436 ins->declaration.indexable_temp.register_idx = sm6->indexable_temp_count++;
3437 ins->declaration.indexable_temp.register_size = count;
3438 ins->declaration.indexable_temp.alignment = alignment;
3439 ins->declaration.indexable_temp.data_type = data_type;
3440 ins->declaration.indexable_temp.component_count = 1;
3441 ins->declaration.indexable_temp.has_function_scope = has_function_scope;
3442 /* The initialiser value index will be resolved later so forward references can be handled. */
3443 ins->declaration.indexable_temp.initialiser = (void *)(uintptr_t)init;
3444
3446}
3447
3448static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6_type *elem_type,
3449 unsigned int alignment, unsigned int init, struct sm6_value *dst)
3450{
3452 struct vkd3d_shader_instruction *ins;
3453 unsigned int byte_count;
3454
3458 dst->u.reg = ins->declaration.tgsm_raw.reg.reg;
3459 dst->structure_stride = 0;
3460 ins->declaration.tgsm_raw.alignment = alignment;
3461 byte_count = elem_type->u.width / 8u;
3462 if (byte_count != 4)
3463 {
3464 FIXME("Unsupported byte count %u.\n", byte_count);
3466 "Raw TGSM byte count %u is not supported.", byte_count);
3467 }
3468 ins->declaration.tgsm_raw.byte_count = byte_count;
3469 /* The initialiser value index will be resolved later when forward references can be handled. */
3470 ins->flags = init;
3471}
3472
3473static void sm6_parser_declare_tgsm_structured(struct sm6_parser *sm6, const struct sm6_type *elem_type,
3474 unsigned int count, unsigned int alignment, unsigned int init, struct sm6_value *dst)
3475{
3477 struct vkd3d_shader_instruction *ins;
3478 unsigned int structure_stride;
3479
3483 data_type, sm6->tgsm_count++);
3484 dst->u.reg = ins->declaration.tgsm_structured.reg.reg;
3485 structure_stride = elem_type->u.width / 8u;
3486 if (structure_stride != 4)
3487 {
3488 FIXME("Unsupported structure stride %u.\n", structure_stride);
3490 "Structured TGSM byte stride %u is not supported.", structure_stride);
3491 }
3492 dst->structure_stride = structure_stride;
3493 ins->declaration.tgsm_structured.alignment = alignment;
3494 ins->declaration.tgsm_structured.byte_stride = structure_stride;
3495 ins->declaration.tgsm_structured.structure_count = count;
3496 /* The initialiser value index will be resolved later when forward references can be handled. */
3497 ins->flags = init;
3498}
3499
3500static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_record *record)
3501{
3502 const struct sm6_type *type, *scalar_type;
3503 unsigned int alignment, count;
3505 struct sm6_value *dst;
3506 bool is_constant;
3507
3509 return false;
3510
3511 if (!(type = sm6_parser_get_type(sm6, record->operands[0])))
3512 return false;
3514 {
3515 if (!sm6_type_is_scalar(type->u.array.elem_type))
3516 {
3517 FIXME("Unsupported nested type class %u.\n", type->u.array.elem_type->class);
3519 "Global array variables with nested type class %u are not supported.",
3520 type->u.array.elem_type->class);
3521 return false;
3522 }
3523 count = type->u.array.count;
3524 scalar_type = type->u.array.elem_type;
3525 }
3526 else if (sm6_type_is_scalar(type))
3527 {
3528 count = 1;
3529 scalar_type = type;
3530 }
3531 else
3532 {
3533 FIXME("Unsupported type class %u.\n", type->class);
3535 "Global variables of type class %u are not supported.", type->class);
3536 return false;
3537 }
3538
3539 is_constant = record->operands[1] & GLOBALVAR_FLAG_IS_CONSTANT;
3540
3541 if (record->operands[1] & GLOBALVAR_FLAG_EXPLICIT_TYPE)
3542 {
3544
3546 {
3547 WARN("Failed to get pointer type for type class %u, address space %"PRIu64".\n",
3548 type->class, address_space);
3550 "Module does not define a pointer type for a global variable.");
3551 return false;
3552 }
3553 }
3554 else
3555 {
3557 {
3558 WARN("Type is not a pointer.\n");
3560 "The type of a global variable is not a pointer.");
3561 return false;
3562 }
3563 address_space = type->u.pointer.addr_space;
3564 }
3565
3566 if ((init = record->operands[2]))
3567 {
3568 if (init - 1 >= sm6->value_capacity)
3569 {
3570 WARN("Invalid value index %"PRIu64" for initialiser.", init - 1);
3572 "Global variable initialiser value index %"PRIu64" is invalid.", init - 1);
3573 return false;
3574 }
3575 }
3576
3577 /* LINKAGE_EXTERNAL is common but not relevant here. */
3578 if (record->operands[3] != LINKAGE_EXTERNAL && record->operands[3] != LINKAGE_INTERNAL)
3579 WARN("Ignoring linkage %"PRIu64".\n", record->operands[3]);
3580
3581 if (!bitcode_parse_alignment(record->operands[4], &alignment))
3582 WARN("Invalid alignment %"PRIu64".\n", record->operands[4]);
3583
3584 if (record->operands[5])
3585 WARN("Ignoring section code %"PRIu64".\n", record->operands[5]);
3586
3588 WARN("Missing symbol name for global variable at index %zu.\n", sm6->value_count);
3589 /* TODO: store global symbol names in struct vkd3d_shader_desc? */
3590
3591 if (record->operand_count > 6 && record->operands[6])
3592 WARN("Ignoring visibility %"PRIu64".\n", record->operands[6]);
3593 if (record->operand_count > 7 && record->operands[7])
3594 WARN("Ignoring thread local mode %"PRIu64".\n", record->operands[7]);
3595 /* record->operands[8] contains unnamed_addr, a flag indicating the address
3596 * is not important, only the content is. This info is not relevant. */
3597 if (record->operand_count > 9 && record->operands[9])
3598 WARN("Ignoring external_init %"PRIu64".\n", record->operands[9]);
3599 if (record->operand_count > 10 && record->operands[10])
3600 WARN("Ignoring dll storage class %"PRIu64".\n", record->operands[10]);
3601 if (record->operand_count > 11 && record->operands[11])
3602 WARN("Ignoring comdat %"PRIu64".\n", record->operands[11]);
3603
3605 dst->type = type;
3606 dst->value_type = VALUE_TYPE_REG;
3607 dst->is_back_ref = true;
3608
3609 if (is_constant && !init)
3610 {
3611 WARN("Constant array has no initialiser.\n");
3613 "A constant global variable has no initialiser.");
3614 return false;
3615 }
3616
3618 {
3619 if (is_constant)
3620 sm6_parser_declare_icb(sm6, scalar_type, count, alignment, init, dst);
3621 else
3622 sm6_parser_declare_indexable_temp(sm6, scalar_type, count, alignment, false, init, NULL, dst);
3623 }
3625 {
3626 if (!sm6_type_is_numeric(scalar_type))
3627 {
3628 WARN("Unsupported type class %u.\n", scalar_type->class);
3630 "TGSM variables of type class %u are not supported.", scalar_type->class);
3631 return false;
3632 }
3633 if (count == 1)
3634 sm6_parser_declare_tgsm_raw(sm6, scalar_type, alignment, init, dst);
3635 else
3637 }
3638 else
3639 {
3640 FIXME("Unhandled address space %"PRIu64".\n", address_space);
3642 "Global variables with address space %"PRIu64" are not supported.", address_space);
3643 return false;
3644 }
3645
3646 ++sm6->value_count;
3647 return true;
3648}
3649
3651 size_t index, struct sm6_parser *sm6)
3652{
3653 const struct sm6_value *value;
3654
3656 --index;
3658 {
3659 WARN("Invalid initialiser index %zu.\n", index);
3661 "Global variable initialiser value index %zu is invalid.", index);
3662 return NULL;
3663 }
3664 else if (sm6_value_is_icb(value))
3665 {
3666 return value->u.icb;
3667 }
3668 /* In VSIR, initialisation with undefined values of objects is implied, not explicit. */
3669 return NULL;
3670}
3671
3672static bool resolve_forward_zero_initialiser(size_t index, struct sm6_parser *sm6)
3673{
3674 const struct sm6_value *value;
3675
3676 if (!index)
3677 return false;
3678
3679 --index;
3682 {
3683 WARN("Invalid initialiser index %zu.\n", index);
3685 "TGSM initialiser value index %zu is invalid.", index);
3686 return false;
3687 }
3688 else if ((sm6_value_is_icb(value) && value->u.icb->is_null) || sm6_value_is_constant_zero(value))
3689 {
3690 return true;
3691 }
3692 else if (sm6_value_is_undef(value))
3693 {
3694 /* In VSIR, initialisation with undefined values of objects is implied, not explicit. */
3695 return false;
3696 }
3697
3698 FIXME("Non-zero initialisers are not supported.\n");
3700 "Non-zero TGSM initialisers are not supported.");
3701 return false;
3702}
3703
3705{
3706 size_t i, count, base_value_idx = sm6->value_count;
3707 const struct dxil_block *block = &sm6->root_block;
3708 struct vkd3d_shader_instruction *ins;
3709 const struct dxil_record *record;
3710 enum vkd3d_result ret;
3712
3713 sm6->p.location.line = block->id;
3714 sm6->p.location.column = 0;
3715
3716 for (i = 0, count = 0; i < block->record_count; ++i)
3717 count += block->records[i]->code == MODULE_CODE_GLOBALVAR;
3719
3720 for (i = 0; i < block->record_count; ++i)
3721 {
3722 sm6->p.location.column = i;
3723 record = block->records[i];
3724 switch (record->code)
3725 {
3728 {
3730 "A DXIL function declaration is invalid.");
3732 }
3733 break;
3734
3738 break;
3739
3743 if ((version = record->operands[0]) != 1)
3744 {
3745 FIXME("Unsupported format version %#"PRIx64".\n", version);
3747 "Bitcode format version %#"PRIx64" is unsupported.", version);
3749 }
3750 break;
3751
3752 default:
3753 break;
3754 }
3755 }
3756
3757 for (i = 0; i < block->child_block_count; ++i)
3758 {
3759 if (block->child_blocks[i]->id == CONSTANTS_BLOCK
3760 && (ret = sm6_parser_constants_init(sm6, block->child_blocks[i])) < 0)
3761 return ret;
3762 }
3763
3764 /* Resolve initialiser forward references. */
3765 for (i = 0; i < sm6->p.program->instructions.count; ++i)
3766 {
3767 ins = &sm6->p.program->instructions.elements[i];
3768 if (ins->opcode == VKD3DSIH_DCL_INDEXABLE_TEMP && ins->declaration.indexable_temp.initialiser)
3769 {
3771 (uintptr_t)ins->declaration.indexable_temp.initialiser, sm6);
3772 }
3774 {
3776 }
3777 else if (ins->opcode == VKD3DSIH_DCL_TGSM_RAW)
3778 {
3779 ins->declaration.tgsm_raw.zero_init = resolve_forward_zero_initialiser(ins->flags, sm6);
3780 ins->flags = 0;
3781 }
3782 else if (ins->opcode == VKD3DSIH_DCL_TGSM_STRUCTURED)
3783 {
3785 ins->flags = 0;
3786 }
3787 }
3788 for (i = base_value_idx; i < sm6->value_count; ++i)
3789 {
3791 struct sm6_value *value = &sm6->values[i];
3792
3794 continue;
3795
3796 if ((icb = resolve_forward_initialiser(value->u.reg.idx[0].offset, sm6)))
3797 value->u.reg.idx[0].offset = icb->register_idx;
3798 }
3799
3800 return VKD3D_OK;
3801}
3802
3805{
3807
3808 param->write_mask = e->mask;
3809 param->modifiers = 0;
3810 param->shift = 0;
3811 /* DXIL types do not have signedness. Load signed elements as unsigned. */
3812 component_type = e->component_type == VKD3D_SHADER_COMPONENT_INT ? VKD3D_SHADER_COMPONENT_UINT : e->component_type;
3814 param->reg.dimension = VSIR_DIMENSION_VEC4;
3815}
3816
3818 const struct sm6_value **operands, unsigned int count)
3819{
3820 unsigned int i;
3821
3822 for (i = 0; i < count; ++i)
3823 src_param_init_from_value(&src_params[i], operands[i]);
3824}
3825
3827 enum vkd3d_shader_sysval_semantic sysval_semantic)
3828{
3829 switch (sysval_semantic)
3830 {
3831 /* VSIR does not use an I/O register for SV_SampleIndex, but its
3832 * signature element has a register index of UINT_MAX and it is
3833 * convenient to return a valid register type here to handle it. */
3835 return VKD3DSPR_NULL;
3837 return VKD3DSPR_COVERAGE;
3839 return VKD3DSPR_DEPTHOUT;
3841 return VKD3DSPR_DEPTHOUTGE;
3843 return VKD3DSPR_DEPTHOUTLE;
3844 default:
3845 return VKD3DSPR_INVALID;
3846 }
3847}
3848
3849static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shader_signature *s,
3851{
3852 enum vkd3d_shader_type shader_type = sm6->p.program->shader_version.type;
3853 enum vkd3d_shader_register_type io_reg_type;
3854 bool is_patch_constant, is_control_point;
3856 const struct signature_element *e;
3857 unsigned int i, count;
3858
3859 is_patch_constant = reg_type == VKD3DSPR_PATCHCONST;
3860
3861 is_control_point = false;
3862 if (!is_patch_constant)
3863 {
3864 switch (shader_type)
3865 {
3868 is_control_point = is_input;
3869 break;
3870
3872 is_control_point = true;
3873 break;
3874
3875 default:
3876 break;
3877 }
3878 }
3879
3880 for (i = 0; i < s->element_count; ++i)
3881 {
3882 e = &s->elements[i];
3883
3884 param = &params[i];
3885
3886 if (e->register_index == UINT_MAX
3887 && (io_reg_type = register_type_from_dxil_semantic_kind(e->sysval_semantic)) != VKD3DSPR_NULL)
3888 {
3889 dst_param_io_init(param, e, io_reg_type);
3890 continue;
3891 }
3892
3894 count = 0;
3895
3896 if (is_control_point)
3897 {
3899 param->reg.idx[count].rel_addr = vsir_program_create_outpointid_param(sm6->p.program);
3900 param->reg.idx[count++].offset = 0;
3901 }
3902
3903 if (e->register_count > 1 || (is_patch_constant && vsir_sysval_semantic_is_tess_factor(e->sysval_semantic)))
3904 param->reg.idx[count++].offset = 0;
3905
3906 VKD3D_ASSERT(count < ARRAY_SIZE(param->reg.idx));
3907 param->reg.idx[count++].offset = i;
3908 param->reg.idx_count = count;
3909 }
3910}
3911
3912static void sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature)
3913{
3914 sm6_parser_init_signature(sm6, output_signature, false, VKD3DSPR_OUTPUT, sm6->output_params);
3915}
3916
3917static void sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct shader_signature *input_signature)
3918{
3919 sm6_parser_init_signature(sm6, input_signature, true, VKD3DSPR_INPUT, sm6->input_params);
3920}
3921
3923 const struct shader_signature *patch_constant_signature)
3924{
3925 bool is_input = sm6->p.program->shader_version.type == VKD3D_SHADER_TYPE_DOMAIN;
3926
3927 sm6_parser_init_signature(sm6, patch_constant_signature, is_input, VKD3DSPR_PATCHCONST,
3929}
3930
3932{
3933 size_t i, count = sm6->function_count;
3934
3935 for (i = 0; i < sm6->value_count; ++i)
3936 {
3937 if (sm6_type_is_function_pointer(sm6->values[i].type) && !sm6->values[i].u.function.is_prototype && !count--)
3938 break;
3939 }
3940 if (i == sm6->value_count)
3941 return NULL;
3942
3943 ++sm6->function_count;
3944 return &sm6->values[i];
3945}
3946
3948{
3949 struct sm6_block *block = vkd3d_calloc(1, sizeof(*block));
3950 return block;
3951}
3952
3954{
3955 struct sm6_phi *phi;
3956
3957 if (!vkd3d_array_reserve((void **)&block->phi, &block->phi_capacity, block->phi_count + 1, sizeof(*block->phi)))
3958 {
3959 ERR("Failed to allocate phi array.\n");
3961 "Out of memory allocating a phi instruction.");
3962 return NULL;
3963 }
3964 phi = &block->phi[block->phi_count++];
3965
3966 phi->incoming = NULL;
3967 phi->incoming_capacity = 0;
3968 phi->incoming_count = 0;
3969
3970 return phi;
3971}
3972
3974{
3977 unsigned int temp_idx;
3978};
3979
3980static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, const struct vkd3d_shader_register **operand_regs,
3982
3983static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_record *record,
3984 struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
3985{
3986 const struct sm6_type *type[2], *elem_type;
3987 const struct sm6_value *size;
3988 unsigned int i, alignment;
3989 uint64_t packed_operands;
3990
3992 return;
3993
3994 for (i = 0; i < 2; ++i)
3995 {
3996 if (!(type[i] = sm6_parser_get_type(sm6, record->operands[i])))
3997 return;
3998 }
3999
4000 packed_operands = record->operands[3];
4001 if (packed_operands & ALLOCA_FLAG_IN_ALLOCA)
4002 WARN("Ignoring in_alloca flag.\n");
4003 if (!(packed_operands & ALLOCA_FLAG_EXPLICIT_TYPE))
4004 {
4005 FIXME("Unhandled implicit type.\n");
4007 "Implicit result type for ALLOCA instructions is not supported.");
4008 return;
4009 }
4010 packed_operands &= ~(ALLOCA_FLAG_IN_ALLOCA | ALLOCA_FLAG_EXPLICIT_TYPE);
4011
4012 if (!sm6_type_is_array(type[0]) || !sm6_type_is_numeric(elem_type = type[0]->u.array.elem_type))
4013 {
4014 WARN("Type is not a numeric array.\n");
4016 "Result type of an ALLOCA instruction is not a numeric array.");
4017 return;
4018 }
4019 /* The second type operand is the type of the allocation size operand, in case it is a
4020 * forward reference. We only support a constant size, so no forward ref support is needed. */
4021 if (!sm6_type_is_integer(type[1]))
4022 {
4023 WARN("Size operand type is not scalar integer.\n");
4025 "The type of the allocation size operand of an ALLOCA instruction is not scalar integer.");
4026 return;
4027 }
4028
4030 {
4031 WARN("Failed to get pointer type for type class %u.\n", type[0]->class);
4033 "Module does not define a pointer type for an ALLOCA instruction.");
4034 return;
4035 }
4036
4037 if (!(size = sm6_parser_get_value_safe(sm6, record->operands[2])))
4038 return;
4039 /* A size of 1 means one instance of type[0], i.e. one array. */
4041 {
4042 FIXME("Allocation size is not 1.\n");
4044 "ALLOCA instruction allocation sizes other than 1 are not supported.");
4045 return;
4046 }
4047
4049 WARN("Invalid alignment %"PRIu64".\n", packed_operands);
4050 packed_operands &= ~ALLOCA_ALIGNMENT_MASK;
4051
4052 if (packed_operands)
4053 WARN("Ignoring flags %#"PRIx64".\n", packed_operands);
4054
4055 sm6_parser_declare_indexable_temp(sm6, elem_type, type[0]->u.array.count, alignment, true, 0, ins, dst);
4056}
4057
4059{
4060 switch (code)
4061 {
4062 case RMW_ADD:
4064 case RMW_AND:
4066 case RMW_MAX:
4068 case RMW_MIN:
4070 case RMW_OR:
4072 case RMW_UMAX:
4074 case RMW_UMIN:
4076 case RMW_XCHG:
4078 case RMW_XOR:
4080 default:
4081 /* DXIL currently doesn't use SUB and NAND. */
4082 return VKD3DSIH_INVALID;
4083 }
4084}
4085
4086static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_record *record,
4087 struct function_emission_state *state, struct sm6_value *dst)
4088{
4089 struct vkd3d_shader_register coord, const_offset, const_zero;
4090 const struct vkd3d_shader_register *regs[2];
4091 struct vkd3d_shader_dst_param *dst_params;
4092 struct vkd3d_shader_src_param *src_params;
4093 struct vkd3d_shader_instruction *ins;
4094 const struct sm6_value *ptr, *src;
4096 unsigned int i = 0;
4097 bool is_volatile;
4098 uint64_t code;
4099
4100 if (!(ptr = sm6_parser_get_value_by_ref(sm6, record, NULL, &i))
4103 return;
4104
4105 if (ptr->u.reg.type != VKD3DSPR_GROUPSHAREDMEM)
4106 {
4107 WARN("Register is not groupshared.\n");
4109 "The destination register for an atomicrmw instruction is not groupshared memory.");
4110 return;
4111 }
4112
4113 dst->type = ptr->type->u.pointer.type;
4114
4115 if (!(src = sm6_parser_get_value_by_ref(sm6, record, dst->type, &i)))
4116 return;
4117
4118 if (!dxil_record_validate_operand_count(record, i + 4, i + 4, sm6))
4119 return;
4120
4121 if ((op = map_dx_atomicrmw_op(code = record->operands[i++])) == VKD3DSIH_INVALID)
4122 {
4123 FIXME("Unhandled atomicrmw op %"PRIu64".\n", code);
4125 "Operation %"PRIu64" for an atomicrmw instruction is unhandled.", code);
4126 return;
4127 }
4128
4129 is_volatile = record->operands[i++];
4130
4131 /* It's currently not possible to specify an atomic ordering in HLSL, and it defaults to seq_cst. */
4132 if ((code = record->operands[i++]) != ORDERING_SEQCST)
4133 FIXME("Unhandled atomic ordering %"PRIu64".\n", code);
4134
4135 if ((code = record->operands[i]) != 1)
4136 WARN("Ignoring synchronisation scope %"PRIu64".\n", code);
4137
4138 if (ptr->structure_stride)
4139 {
4140 if (ptr->u.reg.idx[1].rel_addr)
4141 {
4142 regs[0] = &ptr->u.reg.idx[1].rel_addr->reg;
4143 }
4144 else
4145 {
4146 register_make_constant_uint(&const_offset, ptr->u.reg.idx[1].offset);
4147 regs[0] = &const_offset;
4148 }
4149 register_make_constant_uint(&const_zero, 0);
4150 regs[1] = &const_zero;
4152 return;
4153 }
4154
4155 ins = state->ins;
4156 vsir_instruction_init(ins, &sm6->p.location, op);
4158
4159 if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
4160 return;
4161 if (ptr->structure_stride)
4162 src_param_init_vector_from_reg(&src_params[0], &coord);
4163 else
4164 src_param_make_constant_uint(&src_params[0], 0);
4165 src_param_init_from_value(&src_params[1], src);
4166
4167 dst_params = instruction_dst_params_alloc(ins, 2, sm6);
4168 register_init_ssa_scalar(&dst_params[0].reg, dst->type, dst, sm6);
4169 dst_param_init(&dst_params[0]);
4170
4171 dst_params[1].reg = ptr->u.reg;
4172 dst_params[1].reg.data_type = VKD3D_DATA_UNUSED;
4173 dst_params[1].reg.idx[1].rel_addr = NULL;
4174 dst_params[1].reg.idx[1].offset = ~0u;
4175 dst_params[1].reg.idx_count = 1;
4176 dst_param_init(&dst_params[1]);
4177
4178 dst->u.reg = dst_params[0].reg;
4179}
4180
4181static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_type *type_a,
4182 const struct sm6_type *type_b, struct sm6_parser *sm6)
4183{
4184 bool is_int = sm6_type_is_bool_i16_i32_i64(type_a);
4185 bool is_double = sm6_type_is_double(type_a);
4186 bool is_bool = sm6_type_is_bool(type_a);
4188 bool is_valid;
4189
4190 if (!is_int && !sm6_type_is_floating_point(type_a))
4191 {
4192 WARN("Argument type %u is not bool, int16/32/64 or floating point.\n", type_a->class);
4194 "An argument to a binary operation is not bool, int16/32/64 or floating point.");
4195 return VKD3DSIH_INVALID;
4196 }
4197 if (type_a != type_b)
4198 {
4199 WARN("Type mismatch, type %u width %u vs type %u width %u.\n", type_a->class,
4200 type_a->u.width, type_b->class, type_b->u.width);
4202 "Type mismatch in binary operation arguments.");
4203 }
4204
4205 switch (code)
4206 {
4207 case BINOP_ADD:
4208 case BINOP_SUB:
4209 /* NEG is applied later for subtraction. */
4210 op = is_int ? VKD3DSIH_IADD : (is_double ? VKD3DSIH_DADD : VKD3DSIH_ADD);
4211 is_valid = !is_bool;
4212 break;
4213 case BINOP_AND:
4214 op = VKD3DSIH_AND;
4215 is_valid = is_int;
4216 break;
4217 case BINOP_ASHR:
4218 op = VKD3DSIH_ISHR;
4219 is_valid = is_int && !is_bool;
4220 break;
4221 case BINOP_LSHR:
4222 op = VKD3DSIH_USHR;
4223 is_valid = is_int && !is_bool;
4224 break;
4225 case BINOP_MUL:
4226 op = is_int ? VKD3DSIH_UMUL : (is_double ? VKD3DSIH_DMUL : VKD3DSIH_MUL);
4227 is_valid = !is_bool;
4228 break;
4229 case BINOP_OR:
4230 op = VKD3DSIH_OR;
4231 is_valid = is_int;
4232 break;
4233 case BINOP_SDIV:
4234 op = is_int ? VKD3DSIH_IDIV : (is_double ? VKD3DSIH_DDIV : VKD3DSIH_DIV);
4235 is_valid = !is_bool;
4236 break;
4237 case BINOP_SREM:
4239 is_valid = !is_bool;
4240 break;
4241 case BINOP_SHL:
4242 op = VKD3DSIH_ISHL;
4243 is_valid = is_int && !is_bool;
4244 break;
4245 case BINOP_UDIV:
4246 case BINOP_UREM:
4247 op = VKD3DSIH_UDIV;
4248 is_valid = is_int && !is_bool;
4249 break;
4250 case BINOP_XOR:
4251 op = VKD3DSIH_XOR;
4252 is_valid = is_int;
4253 break;
4254 default:
4255 FIXME("Unhandled binary op %#"PRIx64".\n", code);
4257 "Binary operation %#"PRIx64" is unhandled.", code);
4258 return VKD3DSIH_INVALID;
4259 }
4260
4261 if (!is_valid)
4262 {
4263 WARN("Invalid operation %u for type %u, width %u.\n", op, type_a->class, type_a->u.width);
4265 "Binary operation %u is invalid on type class %u, width %u.", op, type_a->class, type_a->u.width);
4266 }
4267
4268 return op;
4269}
4270
4271static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_record *record,
4272 struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
4273{
4274 struct vkd3d_shader_src_param *src_params;
4275 enum vkd3d_shader_opcode handler_idx;
4276 const struct sm6_value *a, *b;
4278 bool silence_warning;
4279 unsigned int i = 0;
4280
4282 if (!a)
4283 return;
4284 b = sm6_parser_get_value_by_ref(sm6, record, a->type, &i);
4285 if (!b)
4286 return;
4287
4288 if (!dxil_record_validate_operand_count(record, i + 1, i + 2, sm6))
4289 return;
4290
4291 code = record->operands[i++];
4292 if ((handler_idx = map_binary_op(code, a->type, b->type, sm6)) == VKD3DSIH_INVALID)
4293 return;
4294
4295 vsir_instruction_init(ins, &sm6->p.location, handler_idx);
4296
4297 flags = (record->operand_count > i) ? record->operands[i] : 0;
4298 silence_warning = false;
4299
4300 switch (handler_idx)
4301 {
4302 case VKD3DSIH_ADD:
4303 case VKD3DSIH_MUL:
4304 case VKD3DSIH_DIV:
4305 case VKD3DSIH_FREM:
4307 ins->flags |= VKD3DSI_PRECISE_X;
4309 /* SPIR-V FPFastMathMode is only available in the Kernel execution model. */
4310 silence_warning = !(flags & ~(FP_NO_NAN | FP_NO_INF | FP_NO_SIGNED_ZEROS | FP_ALLOW_RECIPROCAL));
4311 break;
4312 case VKD3DSIH_IADD:
4313 case VKD3DSIH_UMUL:
4314 case VKD3DSIH_ISHL:
4315 silence_warning = !(flags & ~(OB_NO_UNSIGNED_WRAP | OB_NO_SIGNED_WRAP));
4316 break;
4317 case VKD3DSIH_ISHR:
4318 case VKD3DSIH_USHR:
4319 case VKD3DSIH_IDIV:
4320 case VKD3DSIH_UDIV:
4321 silence_warning = !(flags & ~PEB_EXACT);
4322 break;
4323 default:
4324 break;
4325 }
4326 /* The above flags are very common and cause warning spam. */
4327 if (flags && silence_warning)
4328 {
4329 TRACE("Ignoring flags %#"PRIx64".\n", flags);
4330 }
4331 else if (flags)
4332 {
4333 WARN("Ignoring flags %#"PRIx64".\n", flags);
4335 "Ignoring flags %#"PRIx64" for a binary operation.", flags);
4336 }
4337
4338 if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
4339 return;
4340 src_param_init_from_value(&src_params[0], a);
4341 src_param_init_from_value(&src_params[1], b);
4342 if (code == BINOP_SUB)
4343 src_params[1].modifiers = VKD3DSPSM_NEG;
4344
4345 dst->type = a->type;
4346
4347 if (handler_idx == VKD3DSIH_UMUL || handler_idx == VKD3DSIH_UDIV || handler_idx == VKD3DSIH_IDIV)
4348 {
4349 struct vkd3d_shader_dst_param *dst_params = instruction_dst_params_alloc(ins, 2, sm6);
4350 unsigned int index = code != BINOP_UDIV && code != BINOP_SDIV;
4351
4352 dst_param_init(&dst_params[0]);
4353 dst_param_init(&dst_params[1]);
4354 register_init_ssa_scalar(&dst_params[index].reg, a->type, dst, sm6);
4356 dst->u.reg = dst_params[index].reg;
4357 }
4358 else
4359 {
4360 if (handler_idx == VKD3DSIH_ISHL || handler_idx == VKD3DSIH_ISHR || handler_idx == VKD3DSIH_USHR)
4361 {
4362 /* DXC emits AND instructions where necessary to mask shift counts. Shift binops
4363 * do not imply masking the shift as the TPF equivalents do. */
4365 }
4367 }
4368}
4369
4370static const struct sm6_block *sm6_function_get_block(const struct sm6_function *function, uint64_t index,
4371 struct sm6_parser *sm6)
4372{
4373 if (index >= function->block_count)
4374 {
4375 WARN("Invalid code block index %#"PRIx64".\n", index);
4377 "Invalid code block index %#"PRIx64" for a control flow instruction.", index);
4378 return NULL;
4379 }
4380 return function->blocks[index];
4381}
4382
4383static void sm6_parser_emit_br(struct sm6_parser *sm6, const struct dxil_record *record,
4384 struct sm6_function *function, struct sm6_block *code_block, struct vkd3d_shader_instruction *ins)
4385{
4386 const struct sm6_value *value;
4387 unsigned int i = 2;
4388
4389 if (record->operand_count != 1 && record->operand_count < 3)
4390 {
4391 WARN("Invalid operand count %u.\n", record->operand_count);
4393 "Invalid operand count %u for a branch instruction.", record->operand_count);
4394 return;
4395 }
4396
4397 if (record->operand_count == 1)
4398 {
4399 code_block->terminator.type = TERMINATOR_UNCOND_BR;
4400 code_block->terminator.true_block = sm6_function_get_block(function, record->operands[0], sm6);
4401 }
4402 else
4403 {
4404 if (!sm6->bool_type)
4405 {
4406 WARN("Bool type not found.\n");
4408 "Module does not define a boolean type for conditions.");
4409 return;
4410 }
4411 if (!(value = sm6_parser_get_value_by_ref(sm6, record, sm6->bool_type, &i))
4413 return;
4415
4416 code_block->terminator.type = TERMINATOR_COND_BR;
4417 code_block->terminator.conditional_reg = value->u.reg;
4418 code_block->terminator.true_block = sm6_function_get_block(function, record->operands[0], sm6);
4419 code_block->terminator.false_block = sm6_function_get_block(function, record->operands[1], sm6);
4420 }
4421
4422 ins->opcode = VKD3DSIH_NOP;
4423}
4424
4425static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, const struct vkd3d_shader_register **operand_regs,
4427{
4428 struct vkd3d_shader_instruction *ins = state->ins;
4429 struct vkd3d_shader_src_param *src_params;
4430 struct vkd3d_shader_dst_param *dst_param;
4431 bool all_constant = true;
4432 unsigned int i;
4433
4434 if (component_count == 1)
4435 {
4436 *reg = *operand_regs[0];
4437 return true;
4438 }
4439
4440 for (i = 0; i < component_count; ++i)
4441 all_constant &= register_is_constant(operand_regs[i]);
4442
4443 if (all_constant)
4444 {
4445 vsir_register_init(reg, VKD3DSPR_IMMCONST, operand_regs[0]->data_type, 0);
4446 reg->dimension = VSIR_DIMENSION_VEC4;
4447 for (i = 0; i < component_count; ++i)
4448 reg->u.immconst_u32[i] = operand_regs[i]->u.immconst_u32[0];
4449 for (; i < VKD3D_VEC4_SIZE; ++i)
4450 reg->u.immconst_u32[i] = 0;
4451 return true;
4452 }
4453
4454 register_init_with_id(reg, VKD3DSPR_TEMP, operand_regs[0]->data_type, state->temp_idx++);
4455 reg->dimension = VSIR_DIMENSION_VEC4;
4456
4457 for (i = 0; i < component_count; ++i, ++ins)
4458 {
4459 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
4460
4461 if (!(src_params = instruction_src_params_alloc(ins, 1, sm6)))
4462 return false;
4463
4464 src_param_init(&src_params[0]);
4465 src_params[0].reg = *operand_regs[i];
4466
4467 if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6)))
4468 return false;
4469
4470 dst_param_init_scalar(dst_param, i);
4471 dst_param->reg = *reg;
4472 }
4473
4474 state->ins = ins;
4475 state->code_block->instruction_count += component_count;
4476
4477 return true;
4478}
4479
4480static bool sm6_parser_emit_composite_construct(struct sm6_parser *sm6, const struct sm6_value **operands,
4482{
4483 const struct vkd3d_shader_register *operand_regs[VKD3D_VEC4_SIZE];
4484 unsigned int i;
4485
4486 for (i = 0; i < component_count; ++i)
4487 operand_regs[i] = &operands[i]->u.reg;
4488
4490}
4491
4492static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const struct sm6_value **operands,
4493 unsigned int max_operands, const struct sm6_value *z_operand, struct function_emission_state *state,
4494 struct vkd3d_shader_register *reg)
4495{
4496 const struct vkd3d_shader_register *operand_regs[VKD3D_VEC4_SIZE];
4497 unsigned int component_count;
4498
4499 for (component_count = 0; component_count < max_operands; ++component_count)
4500 {
4501 if (!z_operand && operands[component_count]->is_undefined)
4502 break;
4503 operand_regs[component_count] = &operands[component_count]->u.reg;
4504 }
4505 if (z_operand)
4506 {
4507 operand_regs[component_count++] = &z_operand->u.reg;
4508 }
4509
4511}
4512
4514{
4515 switch (op)
4516 {
4519 default:
4521 }
4522}
4523
4525 const struct sm6_value **operands, struct function_emission_state *state)
4526{
4527 struct vkd3d_shader_instruction *ins = state->ins;
4528 vsir_instruction_init(ins, &sm6->p.location, sm6_dx_map_void_op(op));
4530}
4531
4533{
4534 switch (op)
4535 {
4536 case DX_ISNAN:
4537 return VKD3DSIH_ISNAN;
4538 case DX_ISINF:
4539 return VKD3DSIH_ISINF;
4540 case DX_ISFINITE:
4541 return VKD3DSIH_ISFINITE;
4542 case DX_TAN:
4543 return VKD3DSIH_TAN;
4544 case DX_ACOS:
4545 return VKD3DSIH_ACOS;
4546 case DX_ASIN:
4547 return VKD3DSIH_ASIN;
4548 case DX_ATAN:
4549 return VKD3DSIH_ATAN;
4550 case DX_HCOS:
4551 return VKD3DSIH_HCOS;
4552 case DX_HSIN:
4553 return VKD3DSIH_HSIN;
4554 case DX_HTAN:
4555 return VKD3DSIH_HTAN;
4556 case DX_EXP:
4557 return VKD3DSIH_EXP;
4558 case DX_FRC:
4559 return VKD3DSIH_FRC;
4560 case DX_LOG:
4561 return VKD3DSIH_LOG;
4562 case DX_SQRT:
4563 return VKD3DSIH_SQRT;
4564 case DX_RSQRT:
4565 return VKD3DSIH_RSQ;
4566 case DX_ROUND_NE:
4567 return VKD3DSIH_ROUND_NE;
4568 case DX_ROUND_NI:
4569 return VKD3DSIH_ROUND_NI;
4570 case DX_ROUND_PI:
4571 return VKD3DSIH_ROUND_PI;
4572 case DX_ROUND_Z:
4573 return VKD3DSIH_ROUND_Z;
4574 case DX_BFREV:
4575 return VKD3DSIH_BFREV;
4576 case DX_COUNT_BITS:
4577 return VKD3DSIH_COUNTBITS;
4578 case DX_FIRST_BIT_LO:
4579 return VKD3DSIH_FIRSTBIT_LO;
4580 case DX_FIRST_BIT_HI:
4581 return VKD3DSIH_FIRSTBIT_HI;
4582 case DX_FIRST_BIT_SHI:
4583 return VKD3DSIH_FIRSTBIT_SHI;
4584 case DX_DERIV_COARSEX:
4585 return VKD3DSIH_DSX_COARSE;
4586 case DX_DERIV_COARSEY:
4587 return VKD3DSIH_DSY_COARSE;
4588 case DX_DERIV_FINEX:
4589 return VKD3DSIH_DSX_FINE;
4590 case DX_DERIV_FINEY:
4591 return VKD3DSIH_DSY_FINE;
4592 case DX_LEGACY_F32TOF16:
4593 return VKD3DSIH_F32TOF16;
4594 case DX_LEGACY_F16TOF32:
4595 return VKD3DSIH_F16TOF32;
4600 case DX_WAVE_ALL_TRUE:
4602 case DX_WAVE_ANY_TRUE:
4608 default:
4610 }
4611}
4612
4614 const struct sm6_value **operands, struct function_emission_state *state)
4615{
4616 struct vkd3d_shader_instruction *ins = state->ins;
4617 struct vkd3d_shader_src_param *src_param;
4618
4619 vsir_instruction_init(ins, &sm6->p.location, map_dx_unary_op(op));
4620 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
4621 return;
4622 src_param_init_from_value(src_param, operands[0]);
4623
4625}
4626
4628{
4629 switch (op)
4630 {
4631 case DX_FMAX:
4632 return type->u.width == 64 ? VKD3DSIH_DMAX : VKD3DSIH_MAX;
4633 case DX_FMIN:
4634 return type->u.width == 64 ? VKD3DSIH_DMIN : VKD3DSIH_MIN;
4635 case DX_IMAX:
4636 return VKD3DSIH_IMAX;
4637 case DX_IMIN:
4638 return VKD3DSIH_IMIN;
4641 case DX_UMAX:
4642 return VKD3DSIH_UMAX;
4643 case DX_UMIN:
4644 return VKD3DSIH_UMIN;
4647 default:
4649 }
4650}
4651
4653 const struct sm6_value **operands, struct function_emission_state *state)
4654{
4655 struct vkd3d_shader_instruction *ins = state->ins;
4656 struct vkd3d_shader_src_param *src_params;
4657
4658 vsir_instruction_init(ins, &sm6->p.location, map_dx_binary_op(op, operands[0]->type));
4659 if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
4660 return;
4661 src_param_init_from_value(&src_params[0], operands[0]);
4662 src_param_init_from_value(&src_params[1], operands[1]);
4663
4665}
4666
4667static enum vkd3d_shader_opcode map_dx_atomic_binop(const struct sm6_value *operand, struct sm6_parser *sm6)
4668{
4670
4671 switch (code)
4672 {
4673 case ATOMIC_BINOP_ADD:
4675 case ATOMIC_BINOP_AND:
4677 case ATOMIC_BINOP_IMAX:
4679 case ATOMIC_BINOP_IMIN:
4681 case ATOMIC_BINOP_OR:
4683 case ATOMIC_BINOP_UMAX:
4685 case ATOMIC_BINOP_UMIN:
4687 case ATOMIC_BINOP_XCHG:
4689 case ATOMIC_BINOP_XOR:
4691 /* DXIL currently doesn't use SUB and NAND. */
4692 default:
4693 FIXME("Unhandled atomic binop %"PRIu64".\n", code);
4695 "Operation %"PRIu64" for an atomic binop instruction is unhandled.", code);
4696 return VKD3DSIH_INVALID;
4697 }
4698}
4699
4701 const struct sm6_value **operands, struct function_emission_state *state)
4702{
4704 enum vkd3d_shader_resource_type resource_type;
4705 bool is_cmp_xchg = op == DX_ATOMIC_CMP_XCHG;
4706 unsigned int i, coord_idx, coord_count = 1;
4707 struct vkd3d_shader_dst_param *dst_params;
4708 struct vkd3d_shader_src_param *src_params;
4709 enum vkd3d_shader_opcode handler_idx;
4710 struct vkd3d_shader_instruction *ins;
4711 const struct sm6_value *resource;
4713
4714 resource = operands[0];
4716 return;
4717
4718 if (is_cmp_xchg)
4719 handler_idx = VKD3DSIH_IMM_ATOMIC_CMP_EXCH;
4720 else if ((handler_idx = map_dx_atomic_binop(operands[1], sm6)) == VKD3DSIH_INVALID)
4721 return;
4722
4723 coord_idx = 2 - is_cmp_xchg;
4724 resource_type = resource->u.handle.d->resource_type;
4725 if (resource_type != VKD3D_SHADER_RESOURCE_BUFFER || resource->u.handle.d->kind == RESOURCE_KIND_STRUCTUREDBUFFER)
4726 {
4727 coord_count = 2 + (resource_type != VKD3D_SHADER_RESOURCE_BUFFER);
4728 if (!sm6_parser_emit_coordinate_construct(sm6, &operands[coord_idx], coord_count, NULL, state, &reg))
4729 return;
4730 }
4731 else
4732 {
4733 reg = operands[coord_idx]->u.reg;
4734 }
4735
4736 for (i = coord_idx + coord_count; i < coord_idx + 3; ++i)
4737 {
4738 if (!operands[i]->is_undefined)
4739 {
4740 WARN("Ignoring unexpected operand.\n");
4742 "Ignoring an unexpected defined operand value for atomic instruction %u.", handler_idx);
4743 break;
4744 }
4745 }
4746
4747 ins = state->ins;
4748 vsir_instruction_init(ins, &sm6->p.location, handler_idx);
4749
4750 if (!(src_params = instruction_src_params_alloc(ins, 2 + is_cmp_xchg, sm6)))
4751 return;
4752 src_param_init_vector_from_reg(&src_params[0], &reg);
4753 if (is_cmp_xchg)
4754 src_param_init_from_value(&src_params[1], operands[4]);
4755 src_param_init_from_value(&src_params[1 + is_cmp_xchg], operands[5]);
4756
4757 dst_params = instruction_dst_params_alloc(ins, 2, sm6);
4758 dst_param_init(&dst_params[0]);
4759 register_init_ssa_scalar(&dst_params[0].reg, dst->type, dst, sm6);
4760 dst_param_init(&dst_params[1]);
4761 dst_params[1].reg = resource->u.handle.reg;
4762
4763 dst->u.reg = dst_params[0].reg;
4764}
4765
4767 const struct sm6_value **operands, struct function_emission_state *state)
4768{
4769 struct vkd3d_shader_instruction *ins = state->ins;
4771
4772 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SYNC);
4773 flags = sm6_value_get_constant_uint(operands[0]);
4775 if (flags & SYNC_GLOBAL_UAV)
4776 ins->flags |= VKD3DSSF_GLOBAL_UAV;
4780 {
4781 FIXME("Unhandled flags %#x.\n", flags);
4783 "Barrier flags %#x are unhandled.", flags);
4784 }
4785}
4786
4788 const struct sm6_value **operands, struct function_emission_state *state)
4789{
4790 struct vkd3d_shader_instruction *ins = state->ins;
4791 struct vkd3d_shader_src_param *src_params;
4792 const struct sm6_value *resource;
4793 unsigned int i;
4794 int8_t inc;
4795
4796 resource = operands[0];
4798 return;
4799
4800 if (!sm6_value_is_constant(operands[1]))
4801 {
4802 FIXME("Unsupported dynamic update operand.\n");
4804 "A dynamic update value for a UAV counter operation is not supported.");
4805 return;
4806 }
4807 i = sm6_value_get_constant_uint(operands[1]);
4808 if (i != 1 && i != 255)
4809 {
4810 WARN("Unexpected update value %#x.\n", i);
4812 "Update value %#x for a UAV counter operation is not supported.", i);
4813 }
4814 inc = i;
4815
4817 if (!(src_params = instruction_src_params_alloc(ins, 1, sm6)))
4818 return;
4819 src_param_init_vector_from_reg(&src_params[0], &resource->u.handle.reg);
4820
4822}
4823
4825 const struct sm6_value **operands, struct function_emission_state *state)
4826{
4827 const struct sm6_value *resource, *sampler;
4828 struct vkd3d_shader_src_param *src_params;
4829 struct vkd3d_shader_instruction *ins;
4831 unsigned int clamp;
4832
4833 resource = operands[0];
4834 sampler = operands[1];
4837 {
4838 return;
4839 }
4840
4841 if (!sm6_parser_emit_coordinate_construct(sm6, &operands[2], 3, NULL, state, &coord))
4842 return;
4843
4844 clamp = sm6_value_get_constant_uint(operands[5]);
4845
4846 ins = state->ins;
4847 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_LOD);
4848 if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
4849 return;
4850 src_param_init_vector_from_reg(&src_params[0], &coord);
4851 src_params[1].reg = resource->u.handle.reg;
4852 src_param_init_scalar(&src_params[1], !clamp);
4853 src_param_init_vector_from_reg(&src_params[2], &sampler->u.handle.reg);
4854
4856}
4857
4859 const struct sm6_value **operands, struct function_emission_state *state)
4860{
4862 struct vkd3d_shader_instruction *ins = state->ins;
4863 struct vkd3d_shader_src_param *src_param;
4864 const struct sm6_value *buffer;
4865 const struct sm6_type *type;
4866
4867 buffer = operands[0];
4869 return;
4870
4871 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
4872
4873 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
4874 return;
4875 src_param_init_vector_from_reg(src_param, &buffer->u.handle.reg);
4876 /* Differently from other descriptors, constant buffers require an
4877 * additional index, used to index within the constant buffer itself. */
4878 src_param->reg.idx_count = 3;
4879 register_index_address_init(&src_param->reg.idx[2], operands[1], sm6);
4880
4881 type = sm6_type_get_scalar_type(dst->type, 0);
4883 src_param->reg.data_type = vkd3d_data_type_from_sm6_type(type);
4884 if (data_type_is_64_bit(src_param->reg.data_type))
4885 src_param->swizzle = vsir_swizzle_64_from_32(src_param->swizzle);
4886
4888}
4889
4890static void sm6_parser_dcl_register_builtin(struct sm6_parser *sm6, enum vkd3d_shader_opcode handler_idx,
4892{
4893 struct vkd3d_shader_dst_param *dst_param;
4894 struct vkd3d_shader_instruction *ins;
4895
4897 {
4899 ins = sm6_parser_add_instruction(sm6, handler_idx);
4900 dst_param = &ins->declaration.dst;
4901 vsir_register_init(&dst_param->reg, reg_type, data_type, 0);
4903 }
4904}
4905
4908{
4909 struct vkd3d_shader_src_param *src_param;
4910
4911 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
4912
4913 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
4914 return;
4916 vsir_register_init(&src_param->reg, reg_type, data_type, 0);
4917 src_param_init(src_param);
4918
4920}
4921
4923 const struct sm6_value **operands, struct function_emission_state *state)
4924{
4926}
4927
4929 enum vkd3d_shader_descriptor_type type, unsigned int id, const struct sm6_value *address)
4930{
4931 const struct sm6_descriptor_info *d;
4932 unsigned int register_index;
4933 size_t i;
4934
4935 for (i = 0; i < sm6->descriptor_count; ++i)
4936 {
4937 d = &sm6->descriptors[i];
4938
4939 if (d->type != type || d->id != id)
4940 continue;
4941
4943 return d;
4944
4945 register_index = sm6_value_get_constant_uint(address);
4946 if (register_index >= d->range.first && register_index <= d->range.last)
4947 return d;
4948 }
4949
4950 return NULL;
4951}
4952
4954 const struct sm6_value **operands, struct function_emission_state *state)
4955{
4956 struct vkd3d_shader_instruction *ins = state->ins;
4958 const struct sm6_descriptor_info *d;
4959 struct vkd3d_shader_register *reg;
4960 struct sm6_value *dst;
4961 unsigned int id;
4962
4963 type = sm6_value_get_constant_uint(operands[0]);
4964 id = sm6_value_get_constant_uint(operands[1]);
4965 if (!(d = sm6_parser_get_descriptor(sm6, type, id, operands[2])))
4966 {
4967 WARN("Failed to find resource type %#x, id %#x.\n", type, id);
4969 "Descriptor for resource type %#x, id %#x was not found.", type, id);
4970 return;
4971 }
4972
4974 dst->value_type = VALUE_TYPE_HANDLE;
4975 dst->u.handle.d = d;
4976
4977 reg = &dst->u.handle.reg;
4978 vsir_register_init(reg, d->reg_type, d->reg_data_type, 2);
4979 reg->dimension = VSIR_DIMENSION_VEC4;
4980 reg->idx[0].offset = id;
4981 register_index_address_init(&reg->idx[1], operands[2], sm6);
4982 reg->non_uniform = !!sm6_value_get_constant_uint(operands[3]);
4983
4984 /* NOP is used to flag no instruction emitted. */
4985 ins->opcode = VKD3DSIH_NOP;
4986}
4987
4989 const struct sm6_value **operands, struct function_emission_state *state)
4990{
4991 struct vkd3d_shader_instruction *ins = state->ins;
4992 struct vkd3d_shader_src_param *src_param;
4993 unsigned int i;
4994
4996
4997 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
4998 return;
4999
5000 i = sm6_value_get_constant_uint(operands[0]);
5001 if (i >= MAX_GS_OUTPUT_STREAMS)
5002 {
5003 WARN("Invalid stream index %u.\n", i);
5005 "Output stream index %u is invalid.", i);
5006 }
5007
5008 /* VKD3D_DATA_UNUSED would be more reasonable, but TPF uses data type 0 here. */
5009 register_init_with_id(&src_param->reg, VKD3DSPR_STREAM, 0, i);
5010 src_param_init(src_param);
5011
5013 {
5014 ++state->ins;
5015 ++state->code_block->instruction_count;
5017 }
5018}
5019
5021 const struct sm6_value **operands, struct function_emission_state *state)
5022{
5023 struct vkd3d_shader_instruction *ins = state->ins;
5024 struct vkd3d_shader_src_param *src_param;
5025
5026 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DISCARD);
5027
5028 if ((src_param = instruction_src_params_alloc(ins, 1, sm6)))
5029 src_param_init_from_value(src_param, operands[0]);
5030}
5031
5033 const struct sm6_value **operands, struct function_emission_state *state)
5034{
5035 struct vkd3d_shader_instruction *ins = state->ins;
5036 struct vkd3d_shader_src_param *src_param;
5037 unsigned int component_idx;
5038
5039 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
5040
5041 if ((component_idx = sm6_value_get_constant_uint(operands[0])) >= 3)
5042 {
5043 WARN("Invalid component index %u.\n", component_idx);
5045 "Invalid domain location component index %u.", component_idx);
5046 component_idx = 0;
5047 }
5048
5049 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
5050 return;
5053 src_param->reg.dimension = VSIR_DIMENSION_VEC4;
5054 src_param_init_scalar(src_param, component_idx);
5055
5057}
5058
5060 const struct sm6_value **operands, struct function_emission_state *state)
5061{
5062 struct vkd3d_shader_src_param *src_params;
5063 struct vkd3d_shader_instruction *ins;
5064 struct vkd3d_shader_register regs[2];
5065 enum vkd3d_shader_opcode handler_idx;
5066 unsigned int component_count;
5067
5068 switch (op)
5069 {
5070 case DX_DOT2:
5071 handler_idx = VKD3DSIH_DP2;
5072 component_count = 2;
5073 break;
5074 case DX_DOT3:
5075 handler_idx = VKD3DSIH_DP3;
5076 component_count = 3;
5077 break;
5078 case DX_DOT4:
5079 handler_idx = VKD3DSIH_DP4;
5080 component_count = 4;
5081 break;
5082 default:
5084 }
5085
5086 if (!sm6_parser_emit_composite_construct(sm6, &operands[0], component_count, state, &regs[0]))
5087 return;
5089 return;
5090
5091 ins = state->ins;
5092 vsir_instruction_init(ins, &sm6->p.location, handler_idx);
5093 if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
5094 return;
5095 src_param_init_vector_from_reg(&src_params[0], &regs[0]);
5096 src_param_init_vector_from_reg(&src_params[1], &regs[1]);
5097
5099}
5100
5102 const struct sm6_value **operands, struct function_emission_state *state)
5103{
5104 struct vkd3d_shader_instruction *ins = state->ins;
5105 struct vkd3d_shader_src_param *src_param;
5106
5107 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
5108 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
5109 return;
5110 src_param_init_from_value(src_param, operands[0]);
5111 src_param->modifiers = VKD3DSPSM_ABS;
5112
5114}
5115
5117 const struct sm6_value **operands, struct function_emission_state *state)
5118{
5119 unsigned int component_count = 3, component_idx = 0;
5120 struct vkd3d_shader_instruction *ins = state->ins;
5121 struct vkd3d_shader_src_param *src_param;
5123
5124 switch (op)
5125 {
5126 case DX_THREAD_ID:
5128 break;
5129 case DX_GROUP_ID:
5131 break;
5134 break;
5137 component_count = 1;
5138 break;
5139 default:
5141 }
5142
5144 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
5145 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
5146 return;
5148 if (component_count > 1)
5149 {
5150 src_param->reg.dimension = VSIR_DIMENSION_VEC4;
5151 component_idx = sm6_value_get_constant_uint(operands[0]);
5152 }
5153 src_param_init_scalar(src_param, component_idx);
5154
5156}
5157
5159{
5160 switch (op)
5161 {
5162 case DX_FMA:
5163 return VKD3DSIH_DFMA;
5164 case DX_FMAD:
5165 return VKD3DSIH_MAD;
5166 case DX_IMAD:
5167 case DX_UMAD:
5168 return VKD3DSIH_IMAD;
5169 default:
5171 }
5172}
5173
5175 const struct sm6_value **operands, struct function_emission_state *state)
5176{
5177 struct vkd3d_shader_instruction *ins = state->ins;
5178 struct vkd3d_shader_src_param *src_params;
5179 unsigned int i;
5180
5181 vsir_instruction_init(ins, &sm6->p.location, sm6_dx_map_ma_op(op, operands[0]->type));
5182 if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
5183 return;
5184 for (i = 0; i < 3; ++i)
5185 src_param_init_from_value(&src_params[i], operands[i]);
5186
5188}
5189
5191 const struct sm6_value **operands, struct function_emission_state *state)
5192{
5193 struct vkd3d_shader_instruction *ins = state->ins;
5194 struct vkd3d_shader_src_param *src_params;
5195 unsigned int is_texture, component_count;
5196 enum dxil_resource_kind resource_kind;
5198 const struct sm6_value *resource;
5199
5200 resource = operands[0];
5202 return;
5203 is_texture = resource->u.handle.d->resource_type != VKD3D_SHADER_RESOURCE_BUFFER;
5204 resource_kind = resource->u.handle.d->kind;
5205
5207
5208 if (!(src_params = instruction_src_params_alloc(ins, 1 + is_texture, sm6)))
5209 return;
5210 src_param_init_vector_from_reg(&src_params[is_texture], &resource->u.handle.reg);
5211
5212 if (is_texture)
5213 {
5215 src_param_init_from_value(&src_params[0], operands[1]);
5217
5218 if (resource_kind_is_multisampled(resource_kind))
5219 {
5221 state->temp_idx = 1;
5222
5223 /* DXIL does not have an intrinsic for sample info, and resinfo is expected to return
5224 * the sample count in .w for MS textures. The result is always a struct of 4 x uint32. */
5225 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SAMPLE_INFO);
5227
5228 if (!(src_params = instruction_src_params_alloc(ins, 1, sm6)))
5229 return;
5230 src_param_init_vector_from_reg(&src_params[0], &resource->u.handle.reg);
5231 src_params[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
5232
5234 return;
5235 dst = ins->dst;
5236 dst->write_mask = VKD3DSP_WRITEMASK_3;
5237
5238 /* Move the result to an SSA in case another instruction overwrites r0 before
5239 * the components are extracted for use. */
5240 ++ins;
5241 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
5242 if (!(src_params = instruction_src_params_alloc(ins, 1, sm6)))
5243 return;
5244 src_param_init_vector_from_reg(&src_params[0], &dst->reg);
5245
5246 state->ins = ins;
5247 state->code_block->instruction_count += 2;
5248 }
5249 }
5250 else
5251 {
5252 if (!operands[1]->is_undefined)
5253 {
5254 WARN("Ignoring unexpected operand.\n");
5256 "Ignoring an unexpected defined LOD value for buffer GetDimensions.");
5257 }
5258 component_count = 1 + (resource_kind == RESOURCE_KIND_STRUCTUREDBUFFER);
5259 }
5260
5262}
5263
5265{
5266 switch (op)
5267 {
5268 case DX_IBFE:
5269 return VKD3DSIH_IBFE;
5270 case DX_UBFE:
5271 return VKD3DSIH_UBFE;
5272 default:
5274 }
5275}
5276
5278 const struct sm6_value **operands, struct function_emission_state *state)
5279{
5280 struct vkd3d_shader_instruction *ins = state->ins;
5281 struct vkd3d_shader_src_param *src_params;
5282 unsigned int i;
5283
5284 vsir_instruction_init(ins, &sm6->p.location, sm6_dx_map_tertiary_op(op));
5285 if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
5286 return;
5287 for (i = 0; i < 3; ++i)
5288 src_param_init_from_value(&src_params[i], operands[i]);
5289
5291}
5292
5294 const struct sm6_value **operands, struct function_emission_state *state)
5295{
5296 bool is_control_point = op == DX_LOAD_OUTPUT_CONTROL_POINT;
5297 bool is_patch_constant = op == DX_LOAD_PATCH_CONSTANT;
5298 struct vkd3d_shader_instruction *ins = state->ins;
5299 struct vsir_program *program = sm6->p.program;
5300 unsigned int count, row_index, column_index;
5301 const struct vkd3d_shader_dst_param *params;
5302 struct vkd3d_shader_src_param *src_param;
5303 const struct shader_signature *signature;
5304 const struct signature_element *e;
5305
5306 row_index = sm6_value_get_constant_uint(operands[0]);
5307 column_index = sm6_value_get_constant_uint(operands[2]);
5308
5309 if (is_control_point && operands[3]->is_undefined)
5310 {
5311 /* dxcompiler will compile source which does this, so let it pass. */
5312 WARN("Control point id is undefined.\n");
5314 "The index for a control point load is undefined.");
5315 }
5316
5317 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
5318
5319 if (is_patch_constant)
5320 {
5321 signature = &program->patch_constant_signature;
5323 }
5324 else if (is_control_point)
5325 {
5326 signature = &program->output_signature;
5327 params = sm6->output_params;
5328 }
5329 else
5330 {
5331 signature = &program->input_signature;
5332 params = sm6->input_params;
5333 }
5334 if (row_index >= signature->element_count)
5335 {
5336 WARN("Invalid row index %u.\n", row_index);
5338 "Invalid input row index %u.", row_index);
5339 return;
5340 }
5341 e = &signature->elements[row_index];
5342
5343 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
5344 return;
5345 src_param->reg = params[row_index].reg;
5346 src_param_init_scalar(src_param, column_index);
5347 count = 0;
5348
5349 if (e->register_count > 1)
5350 register_index_address_init(&src_param->reg.idx[count++], operands[1], sm6);
5351
5352 if (!is_patch_constant && !operands[3]->is_undefined)
5353 {
5354 VKD3D_ASSERT(src_param->reg.idx_count > count);
5355 register_index_address_init(&src_param->reg.idx[count], operands[3], sm6);
5356 }
5357
5359}
5360
5362 const struct sm6_value **operands, struct function_emission_state *state)
5363{
5364 struct vkd3d_shader_src_param *src_params;
5365 struct vkd3d_shader_instruction *ins;
5367
5368 if (!sm6_parser_emit_composite_construct(sm6, &operands[0], 2, state, &reg))
5369 return;
5370
5371 ins = state->ins;
5372 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
5373 if (!(src_params = instruction_src_params_alloc(ins, 1, sm6)))
5374 return;
5375 src_params[0].reg = reg;
5376 src_param_init_vector(&src_params[0], 2);
5377
5379}
5380
5382 const struct sm6_value **operands, struct function_emission_state *state)
5383{
5385}
5386
5388 const struct sm6_value **operands, struct function_emission_state *state)
5389{
5391}
5392
5394{
5395 switch (op)
5396 {
5397 case QUAD_READ_ACROSS_X:
5399 case QUAD_READ_ACROSS_Y:
5401 case QUAD_READ_ACROSS_D:
5403 default:
5404 return VKD3DSIH_INVALID;
5405 }
5406}
5407
5409 const struct sm6_value **operands, struct function_emission_state *state)
5410{
5411 struct vkd3d_shader_instruction *ins = state->ins;
5412 struct vkd3d_shader_src_param *src_param;
5413 enum vkd3d_shader_opcode opcode;
5414 enum dxil_quad_op_kind quad_op;
5415
5416 quad_op = sm6_value_get_constant_uint(operands[1]);
5417 if ((opcode = dx_map_quad_op(quad_op)) == VKD3DSIH_INVALID)
5418 {
5419 FIXME("Unhandled quad op kind %u.\n", quad_op);
5421 "Quad op kind %u is unhandled.", quad_op);
5422 return;
5423 }
5424
5425 vsir_instruction_init(ins, &sm6->p.location, opcode);
5426
5427 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
5428 return;
5429 src_param_init_from_value(src_param, operands[0]);
5430
5432}
5433
5435 const struct sm6_value **operands, struct function_emission_state *state)
5436{
5437 unsigned int operand_count, write_mask, component_count = VKD3D_VEC4_SIZE;
5438 struct vkd3d_shader_instruction *ins = state->ins;
5439 struct vkd3d_shader_src_param *src_params;
5440 const struct sm6_value *resource;
5441 bool raw;
5442
5443 resource = operands[0];
5445 return;
5446 raw = resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER;
5447
5448 if (op == DX_RAW_BUFFER_LOAD)
5449 {
5450 write_mask = sm6_value_get_constant_uint(operands[3]);
5451 if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL)
5452 {
5453 WARN("Invalid write mask %#x.\n", write_mask);
5455 "Write mask %#x for a raw/structured buffer load operation is invalid.", write_mask);
5456 return;
5457 }
5458 else if (write_mask & (write_mask + 1))
5459 {
5460 FIXME("Unhandled write mask %#x.\n", write_mask);
5462 "Write mask %#x for a raw/structured buffer load operation is unhandled.", write_mask);
5463 }
5465 }
5466
5468 operand_count = 2 + !raw;
5469 if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6)))
5470 return;
5471 src_params_init_from_operands(src_params, &operands[1], operand_count - 1);
5472 src_param_init_vector_from_reg(&src_params[operand_count - 1], &resource->u.handle.reg);
5473
5475}
5476
5478 const struct sm6_value **operands, struct function_emission_state *state)
5479{
5480 unsigned int write_mask, component_count, alignment = 0, operand_count;
5481 struct vkd3d_shader_src_param *src_params;
5482 struct vkd3d_shader_dst_param *dst_param;
5483 struct vkd3d_shader_instruction *ins;
5485 const struct sm6_value *resource;
5486 bool raw;
5487
5488 resource = operands[0];
5490 return;
5491 raw = resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER;
5492
5493 write_mask = sm6_value_get_constant_uint(operands[7]);
5494 if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL)
5495 {
5496 WARN("Invalid write mask %#x.\n", write_mask);
5498 "Write mask %#x for a raw/structured buffer store operation is invalid.", write_mask);
5499 return;
5500 }
5501 else if (write_mask & (write_mask + 1))
5502 {
5503 /* In this case, it is unclear which source operands will be defined unless we encounter it in a shader. */
5504 FIXME("Unhandled write mask %#x.\n", write_mask);
5506 "Write mask %#x for a raw/structured buffer store operation is unhandled.", write_mask);
5507 }
5509
5510 if (op == DX_RAW_BUFFER_STORE)
5511 {
5512 if (!raw && resource->u.handle.d->kind != RESOURCE_KIND_STRUCTUREDBUFFER)
5513 {
5514 WARN("Resource is not a raw or structured buffer.\n");
5516 "Resource for a raw buffer store is not a raw or structured buffer.");
5517 }
5518
5520 if (alignment & (alignment - 1))
5521 {
5522 FIXME("Invalid alignment %#x.\n", alignment);
5524 "Alignment %#x for a raw/structured buffer store operation is invalid.", alignment);
5525 }
5526 }
5527
5529 return;
5530
5531 ins = state->ins;
5533 operand_count = 2 + !raw;
5534
5535 if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6)))
5536 return;
5537 src_params_init_from_operands(src_params, &operands[1], operand_count - 1);
5538 data.data_type = VKD3D_DATA_UINT;
5539 src_param_init_vector_from_reg(&src_params[operand_count - 1], &data);
5540
5541 dst_param = instruction_dst_params_alloc(ins, 1, sm6);
5542 dst_param_init_with_mask(dst_param, write_mask);
5543 dst_param->reg = resource->u.handle.reg;
5544 dst_param->reg.alignment = alignment;
5545}
5546
5548 const struct sm6_value **operands, struct function_emission_state *state)
5549{
5550 struct vkd3d_shader_instruction *ins = state->ins;
5551 struct vkd3d_shader_src_param *src_params;
5552 const struct sm6_value *resource;
5553
5554 resource = operands[0];
5556 return;
5557
5558 if (resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER
5559 || resource->u.handle.d->kind == RESOURCE_KIND_STRUCTUREDBUFFER)
5560 {
5561 return sm6_parser_emit_dx_raw_buffer_load(sm6, op, operands, state);
5562 }
5563
5564 if (resource->u.handle.d->kind != RESOURCE_KIND_TYPEDBUFFER)
5565 {
5566 WARN("Resource is not a typed buffer.\n");
5568 "Resource for a typed buffer load is not a typed buffer.");
5569 }
5570
5573
5574 if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
5575 return;
5576 src_param_init_from_value(&src_params[0], operands[1]);
5577 if (!sm6_value_is_undef(operands[2]))
5578 {
5579 /* Constant zero would be ok, but is not worth checking for unless it shows up. */
5580 WARN("Ignoring structure offset.\n");
5582 "Ignoring structure offset for a typed buffer load.");
5583 }
5584 src_param_init_vector_from_reg(&src_params[1], &resource->u.handle.reg);
5585
5587}
5588
5590 const struct sm6_value **operands, struct function_emission_state *state)
5591{
5592 struct vkd3d_shader_src_param *src_params;
5593 struct vkd3d_shader_dst_param *dst_param;
5594 unsigned int write_mask, component_count;
5595 struct vkd3d_shader_instruction *ins;
5596 struct vkd3d_shader_register texel;
5597 const struct sm6_value *resource;
5598
5599 resource = operands[0];
5601 return;
5602
5603 if (resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER
5604 || resource->u.handle.d->kind == RESOURCE_KIND_STRUCTUREDBUFFER)
5605 {
5606 return sm6_parser_emit_dx_raw_buffer_store(sm6, op, operands, state);
5607 }
5608
5609 if (resource->u.handle.d->kind != RESOURCE_KIND_TYPEDBUFFER)
5610 {
5611 WARN("Resource is not a typed buffer.\n");
5613 "Resource for a typed buffer store is not a typed buffer.");
5614 }
5615
5616 write_mask = sm6_value_get_constant_uint(operands[7]);
5617 if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL)
5618 {
5619 WARN("Invalid write mask %#x.\n", write_mask);
5621 "Write mask %#x for a typed buffer store operation is invalid.", write_mask);
5622 return;
5623 }
5624 else if (write_mask & (write_mask + 1))
5625 {
5626 /* In this case, it is unclear which source operands will be defined unless we encounter it in a shader. */
5627 FIXME("Unhandled write mask %#x.\n", write_mask);
5629 "Write mask %#x for a typed buffer store operation is unhandled.", write_mask);
5630 }
5632
5633 if (!sm6_parser_emit_composite_construct(sm6, &operands[3], component_count, state, &texel))
5634 return;
5635
5636 ins = state->ins;
5637 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_STORE_UAV_TYPED);
5638
5639 if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
5640 return;
5641 src_param_init_from_value(&src_params[0], operands[1]);
5642 if (!sm6_value_is_undef(operands[2]))
5643 {
5644 /* Constant zero would have no effect, but is not worth checking for unless it shows up. */
5645 WARN("Ignoring structure offset.\n");
5647 "Ignoring structure offset for a typed buffer store.");
5648 }
5649 src_param_init_vector_from_reg(&src_params[1], &texel);
5650
5651 dst_param = instruction_dst_params_alloc(ins, 1, sm6);
5652 dst_param_init_with_mask(dst_param, write_mask);
5653 dst_param->reg = resource->u.handle.reg;
5654}
5655
5657 const struct sm6_value **operands, struct function_emission_state *state)
5658{
5659 struct vkd3d_shader_instruction *ins = state->ins;
5660 struct vkd3d_shader_src_param *src_param;
5661
5662 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SAMPLE_INFO);
5664
5665 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
5666 return;
5668 src_param->reg.dimension = VSIR_DIMENSION_VEC4;
5669 src_param_init(src_param);
5670
5672 ins->dst->reg.data_type = VKD3D_DATA_FLOAT;
5673}
5674
5676 const struct sm6_value **operands, struct function_emission_state *state)
5677{
5678 struct vkd3d_shader_instruction *ins = state->ins;
5679 struct vkd3d_shader_src_param *src_params;
5680 const struct sm6_value *resource = NULL;
5681
5683 {
5684 resource = operands[0];
5686 return;
5687 }
5688
5689 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SAMPLE_POS);
5690
5691 if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
5692 return;
5694 {
5695 src_param_init_vector_from_reg(&src_params[0], &resource->u.handle.reg);
5696 src_param_init_from_value(&src_params[1], operands[1]);
5697 }
5698 else
5699 {
5700 src_param_init_vector(&src_params[0], 2);
5702 src_params[0].reg.dimension = VSIR_DIMENSION_VEC4;
5703 src_param_init_from_value(&src_params[1], operands[0]);
5704 }
5705
5707}
5708
5709static unsigned int sm6_value_get_texel_offset(const struct sm6_value *value)
5710{
5712}
5713
5715 const struct sm6_value **operands, struct sm6_parser *sm6)
5716{
5717 ins->texel_offset.u = sm6_value_get_texel_offset(operands[0]);
5718 ins->texel_offset.v = sm6_value_get_texel_offset(operands[1]);
5719 ins->texel_offset.w = sm6_value_get_texel_offset(operands[2]);
5720}
5721
5723 const struct sm6_value **operands, struct function_emission_state *state)
5724{
5725 unsigned int clamp_idx = 0, component_count = VKD3D_VEC4_SIZE;
5726 struct vkd3d_shader_register coord, ddx, ddy;
5727 const struct sm6_value *resource, *sampler;
5728 struct vkd3d_shader_src_param *src_params;
5729 struct vkd3d_shader_instruction *ins;
5730
5731 resource = operands[0];
5732 sampler = operands[1];
5735 {
5736 return;
5737 }
5738
5740 return;
5741
5742 if (op == DX_SAMPLE_GRAD)
5743 {
5744 if (!sm6_parser_emit_coordinate_construct(sm6, &operands[9], 3, NULL, state, &ddx))
5745 return;
5746 if (!sm6_parser_emit_coordinate_construct(sm6, &operands[12], 3, NULL, state, &ddy))
5747 return;
5748 }
5749
5750 ins = state->ins;
5751 switch (op)
5752 {
5753 case DX_SAMPLE:
5755 src_params = instruction_src_params_alloc(ins, 3, sm6);
5756 clamp_idx = 9;
5757 break;
5758 case DX_SAMPLE_B:
5759 clamp_idx = 10;
5760 /* fall through */
5761 case DX_SAMPLE_LOD:
5763 resource, sm6);
5764 src_params = instruction_src_params_alloc(ins, 4, sm6);
5765 src_param_init_from_value(&src_params[3], operands[9]);
5766 break;
5767 case DX_SAMPLE_C:
5768 clamp_idx = 10;
5769 /* fall through */
5770 case DX_SAMPLE_C_LZ:
5772 resource, sm6);
5773 src_params = instruction_src_params_alloc(ins, 4, sm6);
5774 src_param_init_from_value(&src_params[3], operands[9]);
5775 component_count = 1;
5776 break;
5777 case DX_SAMPLE_GRAD:
5779 src_params = instruction_src_params_alloc(ins, 5, sm6);
5780 src_param_init_vector_from_reg(&src_params[3], &ddx);
5781 src_param_init_vector_from_reg(&src_params[4], &ddy);
5782 clamp_idx = 15;
5783 break;
5784 default:
5786 }
5787
5788 if (!src_params)
5789 return;
5790
5791 if (clamp_idx && !sm6_value_is_undef(operands[clamp_idx]))
5792 {
5793 FIXME("Ignoring LOD clamp value.\n");
5795 "Ignoring LOD clamp value for a sample operation.");
5796 }
5797
5798 src_param_init_vector_from_reg(&src_params[0], &coord);
5799 src_param_init_vector_from_reg(&src_params[1], &resource->u.handle.reg);
5800 src_param_init_vector_from_reg(&src_params[2], &sampler->u.handle.reg);
5801 instruction_set_texel_offset(ins, &operands[6], sm6);
5802
5804}
5805
5807 const struct sm6_value **operands, struct function_emission_state *state)
5808{
5809 const struct shader_signature *signature = &sm6->p.program->input_signature;
5810 struct vkd3d_shader_instruction *ins = state->ins;
5811 struct vkd3d_shader_src_param *src_param;
5812 unsigned int element_idx;
5813
5814 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
5815
5816 /* SV_SampleIndex is identified in VSIR by its signature element index,
5817 * but the index is not supplied as a parameter to the DXIL intrinsic. */
5819 {
5820 WARN("Sample index is not in the signature.\n");
5822 "Sample index signature element for a sample index operation is missing.");
5823 return;
5824 }
5825
5826 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
5827 return;
5828 src_param->reg = sm6->input_params[element_idx].reg;
5829 src_param_init(src_param);
5830
5832}
5833
5835 const struct sm6_value **operands, struct function_emission_state *state)
5836{
5837 struct vkd3d_shader_instruction *ins = state->ins;
5838 struct vkd3d_shader_src_param *src_param;
5839
5840 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
5841 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
5842 return;
5843 src_param_init_from_value(src_param, operands[0]);
5844
5846 ins->dst->modifiers = VKD3DSPDM_SATURATE;
5847}
5848
5850 const struct sm6_value **operands, struct function_emission_state *state)
5851{
5853 struct vkd3d_shader_instruction *ins = state->ins;
5854 struct vkd3d_shader_dst_param *dst_params;
5855 struct vkd3d_shader_src_param *src_param;
5856 unsigned int index;
5857
5858 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SINCOS);
5859 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
5860 return;
5861 src_param_init_from_value(src_param, operands[0]);
5862
5863 index = op == DX_COS;
5864 dst_params = instruction_dst_params_alloc(ins, 2, sm6);
5865 dst_param_init(&dst_params[0]);
5866 dst_param_init(&dst_params[1]);
5867 register_init_ssa_scalar(&dst_params[index].reg, dst->type, dst, sm6);
5869 dst->u.reg = dst_params[index].reg;
5870}
5871
5873 const struct sm6_value **operands, struct function_emission_state *state)
5874{
5875 struct vkd3d_shader_instruction *ins = state->ins;
5876 struct vkd3d_shader_src_param *src_param;
5877
5878 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
5879 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
5880 return;
5881 src_param_init_from_value(src_param, operands[0]);
5882
5884}
5885
5887 const struct sm6_value **operands, struct function_emission_state *state)
5888{
5889 bool is_patch_constant = op == DX_STORE_PATCH_CONSTANT;
5890 struct vkd3d_shader_instruction *ins = state->ins;
5891 struct vsir_program *program = sm6->p.program;
5892 struct vkd3d_shader_src_param *src_param;
5893 struct vkd3d_shader_dst_param *dst_param;
5894 const struct shader_signature *signature;
5895 unsigned int row_index, column_index;
5896 const struct signature_element *e;
5897 const struct sm6_value *value;
5898
5899 row_index = sm6_value_get_constant_uint(operands[0]);
5900 column_index = sm6_value_get_constant_uint(operands[2]);
5901
5902 signature = is_patch_constant ? &program->patch_constant_signature : &program->output_signature;
5903 if (row_index >= signature->element_count)
5904 {
5905 WARN("Invalid row index %u.\n", row_index);
5907 "Invalid output row index %u.", row_index);
5908 return;
5909 }
5910 e = &signature->elements[row_index];
5911 if (!e->sysval_semantic)
5912 column_index += vsir_write_mask_get_component_idx(e->mask);
5913
5914 if (column_index >= VKD3D_VEC4_SIZE)
5915 {
5916 WARN("Invalid column index %u.\n", column_index);
5918 "Invalid output column index %u.", column_index);
5919 return;
5920 }
5921
5922 value = operands[3];
5924 {
5925 WARN("Source value is not a register.\n");
5927 "Expected store operation source to be a register.");
5928 return;
5929 }
5930
5931 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
5932
5933 if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6)))
5934 return;
5935 dst_param_init_scalar(dst_param, column_index);
5936 dst_param->reg = is_patch_constant ? sm6->patch_constant_params[row_index].reg : sm6->output_params[row_index].reg;
5937 if (e->register_count > 1)
5938 register_index_address_init(&dst_param->reg.idx[0], operands[1], sm6);
5939
5940 if (e->register_index == UINT_MAX)
5941 {
5943 dst_param->reg.data_type, vsir_write_mask_component_count(e->mask));
5944 }
5945
5946 if ((src_param = instruction_src_params_alloc(ins, 1, sm6)))
5947 src_param_init_from_value(src_param, value);
5948}
5949
5951 const struct sm6_value **operands, struct function_emission_state *state)
5952{
5954 const struct sm6_value *resource, *sampler;
5955 struct vkd3d_shader_src_param *src_params;
5956 struct vkd3d_shader_instruction *ins;
5957 unsigned int swizzle;
5958 bool extended_offset;
5959
5960 resource = operands[0];
5961 sampler = operands[1];
5964 {
5965 return;
5966 }
5967
5969 return;
5970
5971 if ((extended_offset = !sm6_value_vector_is_constant_or_undef(&operands[6], 2))
5972 && !sm6_parser_emit_coordinate_construct(sm6, &operands[6], 2, NULL, state, &offset))
5973 {
5974 return;
5975 }
5976
5977 ins = state->ins;
5978 if (op == DX_TEXTURE_GATHER)
5979 {
5981 if (!(src_params = instruction_src_params_alloc(ins, 3 + extended_offset, sm6)))
5982 return;
5983 }
5984 else
5985 {
5987 if (!(src_params = instruction_src_params_alloc(ins, 4 + extended_offset, sm6)))
5988 return;
5989 src_param_init_from_value(&src_params[3 + extended_offset], operands[9]);
5990 }
5991
5992 src_param_init_vector_from_reg(&src_params[0], &coord);
5993 if (extended_offset)
5994 src_param_init_vector_from_reg(&src_params[1], &offset);
5995 else
5996 instruction_set_texel_offset(ins, &operands[6], sm6);
5997 src_param_init_vector_from_reg(&src_params[1 + extended_offset], &resource->u.handle.reg);
5998 src_param_init_vector_from_reg(&src_params[2 + extended_offset], &sampler->u.handle.reg);
5999 /* Swizzle stored in the sampler parameter is the scalar component index to be gathered. */
6000 swizzle = sm6_value_get_constant_uint(operands[8]);
6001 if (swizzle >= VKD3D_VEC4_SIZE)
6002 {
6003 WARN("Invalid swizzle %#x.\n", swizzle);
6005 "Swizzle %#x for a texture gather operation is invalid.", swizzle);
6006 }
6007 src_params[2 + extended_offset].swizzle = swizzle;
6008
6010}
6011
6013 const struct sm6_value **operands, struct function_emission_state *state)
6014{
6015 const struct sm6_value *resource, *mip_level_or_sample_count;
6016 enum vkd3d_shader_resource_type resource_type;
6017 struct vkd3d_shader_src_param *src_params;
6018 struct vkd3d_shader_instruction *ins;
6020 bool is_multisample, is_uav;
6021 unsigned int i;
6022
6023 resource = operands[0];
6025 return;
6026
6027 resource_type = resource->u.handle.d->resource_type;
6028 is_multisample = resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS
6029 || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY;
6030 is_uav = resource->u.handle.d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV;
6031
6032 mip_level_or_sample_count = (resource_type != VKD3D_SHADER_RESOURCE_BUFFER) ? operands[1] : NULL;
6033 if (!sm6_parser_emit_coordinate_construct(sm6, &operands[2], 3,
6034 is_multisample ? NULL : mip_level_or_sample_count, state, &coord))
6035 {
6036 return;
6037 }
6038
6039 ins = state->ins;
6041 : is_multisample ? VKD3DSIH_LD2DMS : VKD3DSIH_LD, resource, sm6);
6042 instruction_set_texel_offset(ins, &operands[5], sm6);
6043
6044 for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
6045 ins->resource_data_type[i] = resource->u.handle.d->resource_data_type;
6046
6047 if (!(src_params = instruction_src_params_alloc(ins, 2 + is_multisample, sm6)))
6048 return;
6049 src_param_init_vector_from_reg(&src_params[0], &coord);
6050 src_param_init_vector_from_reg(&src_params[1], &resource->u.handle.reg);
6051 if (is_multisample)
6052 src_param_init_from_value(&src_params[2], mip_level_or_sample_count);
6053
6055}
6056
6058 const struct sm6_value **operands, struct function_emission_state *state)
6059{
6060 struct vkd3d_shader_register coord, texel;
6061 struct vkd3d_shader_src_param *src_params;
6062 struct vkd3d_shader_dst_param *dst_param;
6063 unsigned int write_mask, component_count;
6064 struct vkd3d_shader_instruction *ins;
6065 const struct sm6_value *resource;
6066
6067 resource = operands[0];
6069 return;
6070
6071 if (!sm6_parser_emit_coordinate_construct(sm6, &operands[1], 3, NULL, state, &coord))
6072 return;
6073
6074 write_mask = sm6_value_get_constant_uint(operands[8]);
6075 if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL)
6076 {
6077 WARN("Invalid write mask %#x.\n", write_mask);
6079 "Write mask %#x for a texture store operation is invalid.", write_mask);
6080 return;
6081 }
6082 else if (write_mask & (write_mask + 1))
6083 {
6084 /* In this case, it is unclear which source operands will be defined unless we encounter it in a shader. */
6085 FIXME("Unhandled write mask %#x.\n", write_mask);
6087 "Write mask %#x for a texture store operation is unhandled.", write_mask);
6088 }
6090
6091 if (!sm6_parser_emit_composite_construct(sm6, &operands[4], component_count, state, &texel))
6092 return;
6093
6094 ins = state->ins;
6095 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_STORE_UAV_TYPED);
6096
6097 if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
6098 return;
6099 src_param_init_vector_from_reg(&src_params[0], &coord);
6100 src_param_init_vector_from_reg(&src_params[1], &texel);
6101
6102 dst_param = instruction_dst_params_alloc(ins, 1, sm6);
6103 dst_param->reg = resource->u.handle.reg;
6104 dst_param_init_with_mask(dst_param, write_mask);
6105}
6106
6108 const struct sm6_value **operands, struct function_emission_state *state)
6109{
6110 struct vkd3d_shader_instruction *ins = state->ins;
6111 struct vkd3d_shader_src_param *src_param;
6112
6114 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
6115 return;
6116 src_param_init_from_value(src_param, operands[0]);
6117
6119}
6120
6122 struct sm6_parser *sm6)
6123{
6124 switch (op)
6125 {
6126 case WAVE_BIT_OP_AND:
6128 case WAVE_BIT_OP_OR:
6130 case WAVE_BIT_OP_XOR:
6132 default:
6133 FIXME("Unhandled wave bit op %u.\n", op);
6135 "Wave bit operation %u is unhandled.\n", op);
6136 return VKD3DSIH_INVALID;
6137 }
6138}
6139
6141 const struct sm6_value **operands, struct function_emission_state *state)
6142{
6143 struct vkd3d_shader_instruction *ins = state->ins;
6144 struct vkd3d_shader_src_param *src_param;
6145 enum dxil_wave_bit_op_kind wave_op;
6146 enum vkd3d_shader_opcode opcode;
6147
6148 wave_op = sm6_value_get_constant_uint(operands[1]);
6149
6150 if ((opcode = sm6_dx_map_wave_bit_op(wave_op, sm6)) == VKD3DSIH_INVALID)
6151 return;
6152 vsir_instruction_init(ins, &sm6->p.location, opcode);
6153
6154 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
6155 return;
6156 src_param_init_from_value(src_param, operands[0]);
6157
6159}
6160
6162 struct sm6_parser *sm6)
6163{
6164 switch (op)
6165 {
6166 case WAVE_OP_ADD:
6167 return VKD3DSIH_WAVE_OP_ADD;
6168 case WAVE_OP_MUL:
6169 return VKD3DSIH_WAVE_OP_MUL;
6170 case WAVE_OP_MIN:
6171 if (is_float)
6172 return VKD3DSIH_WAVE_OP_MIN;
6173 return is_signed ? VKD3DSIH_WAVE_OP_IMIN : VKD3DSIH_WAVE_OP_UMIN;
6174 case WAVE_OP_MAX:
6175 if (is_float)
6176 return VKD3DSIH_WAVE_OP_MAX;
6177 return is_signed ? VKD3DSIH_WAVE_OP_IMAX : VKD3DSIH_WAVE_OP_UMAX;
6178 default:
6179 FIXME("Unhandled wave op %u.\n", op);
6181 "Wave operation %u is unhandled.\n", op);
6182 return VKD3DSIH_INVALID;
6183 }
6184}
6185
6187 const struct sm6_value **operands, struct function_emission_state *state)
6188{
6189 struct vkd3d_shader_instruction *ins = state->ins;
6190 struct vkd3d_shader_src_param *src_param;
6191 enum vkd3d_shader_opcode opcode;
6192 enum dxil_wave_op_kind wave_op;
6193 bool is_signed;
6194
6195 wave_op = sm6_value_get_constant_uint(operands[1]);
6196 is_signed = !sm6_value_get_constant_uint(operands[2]);
6197 opcode = sm6_dx_map_wave_op(wave_op, is_signed, sm6_type_is_floating_point(operands[0]->type), sm6);
6198
6199 if (opcode == VKD3DSIH_INVALID)
6200 return;
6201
6202 vsir_instruction_init(ins, &sm6->p.location, opcode);
6204
6205 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
6206 return;
6207 src_param_init_from_value(src_param, operands[0]);
6208
6210}
6211
6213 const struct sm6_value **operands, struct function_emission_state *state)
6214{
6216
6217 switch (op)
6218 {
6221 break;
6224 break;
6225 default:
6227 }
6228
6230}
6231
6233{
6234 const char *ret_type;
6235 const char *operand_info;
6236 void (*handler)(struct sm6_parser *, enum dx_intrinsic_opcode, const struct sm6_value **,
6237 struct function_emission_state *);
6238};
6239
6240/*
6241 1 -> int1
6242 8 -> int8
6243 b -> constant int1
6244 c -> constant int8/16/32
6245 C -> constant or undefined int8/16/32
6246 i -> int32
6247 m -> int16/32/64
6248 n -> any numeric
6249 f -> float
6250 d -> double
6251 e -> half/float
6252 g -> half/float/double
6253 H -> handle
6254 D -> Dimensions
6255 S -> splitdouble
6256 V -> 4 x i32
6257 v -> void
6258 o -> overloaded
6259 R -> matches the return type
6260 */
6262{
6263 [DX_ACOS ] = {"g", "R", sm6_parser_emit_dx_unary},
6264 [DX_ASIN ] = {"g", "R", sm6_parser_emit_dx_unary},
6265 [DX_ATAN ] = {"g", "R", sm6_parser_emit_dx_unary},
6268 [DX_BARRIER ] = {"v", "c", sm6_parser_emit_dx_barrier},
6269 [DX_BFREV ] = {"m", "R", sm6_parser_emit_dx_unary},
6271 [DX_BUFFER_STORE ] = {"v", "Hiiooooc", sm6_parser_emit_dx_buffer_store},
6275 [DX_COS ] = {"g", "R", sm6_parser_emit_dx_sincos},
6276 [DX_COUNT_BITS ] = {"i", "m", sm6_parser_emit_dx_unary},
6284 [DX_DISCARD ] = {"v", "1", sm6_parser_emit_dx_discard},
6286 [DX_DOT2 ] = {"g", "RRRR", sm6_parser_emit_dx_dot},
6287 [DX_DOT3 ] = {"g", "RRRRRR", sm6_parser_emit_dx_dot},
6288 [DX_DOT4 ] = {"g", "RRRRRRRR", sm6_parser_emit_dx_dot},
6291 [DX_EXP ] = {"g", "R", sm6_parser_emit_dx_unary},
6292 [DX_FABS ] = {"g", "R", sm6_parser_emit_dx_fabs},
6297 [DX_FMA ] = {"g", "RRR", sm6_parser_emit_dx_ma},
6298 [DX_FMAD ] = {"g", "RRR", sm6_parser_emit_dx_ma},
6299 [DX_FMAX ] = {"g", "RR", sm6_parser_emit_dx_binary},
6300 [DX_FMIN ] = {"g", "RR", sm6_parser_emit_dx_binary},
6301 [DX_FRC ] = {"g", "R", sm6_parser_emit_dx_unary},
6304 [DX_IBFE ] = {"m", "iiR", sm6_parser_emit_dx_tertiary},
6305 [DX_HCOS ] = {"g", "R", sm6_parser_emit_dx_unary},
6306 [DX_HSIN ] = {"g", "R", sm6_parser_emit_dx_unary},
6307 [DX_HTAN ] = {"g", "R", sm6_parser_emit_dx_unary},
6308 [DX_IMAD ] = {"m", "RRR", sm6_parser_emit_dx_ma},
6309 [DX_IMAX ] = {"m", "RR", sm6_parser_emit_dx_binary},
6310 [DX_IMIN ] = {"m", "RR", sm6_parser_emit_dx_binary},
6311 [DX_ISFINITE ] = {"1", "g", sm6_parser_emit_dx_unary},
6312 [DX_ISINF ] = {"1", "g", sm6_parser_emit_dx_unary},
6313 [DX_ISNAN ] = {"1", "g", sm6_parser_emit_dx_unary},
6316 [DX_LOAD_INPUT ] = {"o", "ii8i", sm6_parser_emit_dx_load_input},
6319 [DX_LOG ] = {"g", "R", sm6_parser_emit_dx_unary},
6323 [DX_QUAD_OP ] = {"n", "Rc", sm6_parser_emit_dx_quad_op},
6327 [DX_ROUND_NE ] = {"g", "R", sm6_parser_emit_dx_unary},
6328 [DX_ROUND_NI ] = {"g", "R", sm6_parser_emit_dx_unary},
6329 [DX_ROUND_PI ] = {"g", "R", sm6_parser_emit_dx_unary},
6330 [DX_ROUND_Z ] = {"g", "R", sm6_parser_emit_dx_unary},
6331 [DX_RSQRT ] = {"g", "R", sm6_parser_emit_dx_unary},
6334 [DX_SAMPLE ] = {"o", "HHffffiiif", sm6_parser_emit_dx_sample},
6335 [DX_SAMPLE_B ] = {"o", "HHffffiiiff", sm6_parser_emit_dx_sample},
6336 [DX_SAMPLE_C ] = {"o", "HHffffiiiff", sm6_parser_emit_dx_sample},
6337 [DX_SAMPLE_C_LZ ] = {"o", "HHffffiiif", sm6_parser_emit_dx_sample},
6338 [DX_SAMPLE_GRAD ] = {"o", "HHffffiiifffffff", sm6_parser_emit_dx_sample},
6340 [DX_SAMPLE_LOD ] = {"o", "HHffffiiif", sm6_parser_emit_dx_sample},
6342 [DX_SIN ] = {"g", "R", sm6_parser_emit_dx_sincos},
6344 [DX_SQRT ] = {"g", "R", sm6_parser_emit_dx_unary},
6347 [DX_TAN ] = {"g", "R", sm6_parser_emit_dx_unary},
6351 [DX_TEXTURE_LOAD ] = {"o", "HiiiiCCC", sm6_parser_emit_dx_texture_load},
6352 [DX_TEXTURE_STORE ] = {"v", "Hiiiooooc", sm6_parser_emit_dx_texture_store},
6355 [DX_UBFE ] = {"m", "iiR", sm6_parser_emit_dx_tertiary},
6356 [DX_UMAD ] = {"m", "RRR", sm6_parser_emit_dx_ma},
6357 [DX_UMAX ] = {"m", "RR", sm6_parser_emit_dx_binary},
6358 [DX_UMIN ] = {"m", "RR", sm6_parser_emit_dx_binary},
6373};
6374
6375static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struct sm6_value *value, char info_type,
6376 const struct sm6_type *ret_type, bool is_return)
6377{
6378 const struct sm6_type *type = value->type;
6379
6380 if (info_type != 'H' && !sm6_value_is_register(value))
6381 return false;
6382
6383 switch (info_type)
6384 {
6385 case 0:
6386 FIXME("Invalid operand count.\n");
6387 return false;
6388 case '1':
6389 return sm6_type_is_bool(type);
6390 case '8':
6391 return sm6_type_is_i8(type);
6392 case 'b':
6394 case 'c':
6395 return sm6_value_is_constant(value) && sm6_type_is_integer(type) && type->u.width >= 8
6396 && type->u.width <= 32;
6397 case 'C':
6399 && sm6_type_is_integer(type) && type->u.width >= 8 && type->u.width <= 32;
6400 case 'i':
6401 return sm6_type_is_i32(type);
6402 case 'm':
6404 case 'n':
6405 return sm6_type_is_numeric(type);
6406 case 'f':
6407 return sm6_type_is_float(type);
6408 case 'd':
6409 return sm6_type_is_double(type);
6410 case 'e':
6411 return sm6_type_is_f16_f32(type);
6412 case 'g':
6414 case 'H':
6415 return (is_return || sm6_value_is_handle(value)) && type == sm6->handle_type;
6416 case 'D':
6417 return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.Dimensions");
6418 case 'S':
6419 return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.splitdouble");
6420 case 'V':
6421 return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.fouri32");
6422 case 'v':
6423 return !type;
6424 case 'o':
6425 /* TODO: some type checking may be possible */
6426 return true;
6427 case 'R':
6428 return type == ret_type;
6429 default:
6430 FIXME("Unhandled operand code '%c'.\n", info_type);
6431 return false;
6432 }
6433}
6434
6435static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const char *name,
6436 const struct sm6_value **operands, unsigned int operand_count, struct sm6_value *dst)
6437{
6438 const struct sm6_dx_opcode_info *info;
6439 unsigned int i;
6440
6442
6443 VKD3D_ASSERT(info->ret_type[0]);
6444 if (!sm6_parser_validate_operand_type(sm6, dst, info->ret_type[0], NULL, true))
6445 {
6446 WARN("Failed to validate return type for dx intrinsic id %u, '%s'.\n", op, name);
6447 /* Return type validation failure is not so critical. We only need to set
6448 * a data type for the SSA result. */
6449 }
6450
6451 for (i = 0; i < operand_count; ++i)
6452 {
6453 const struct sm6_value *value = operands[i];
6454 if (!sm6_parser_validate_operand_type(sm6, value, info->operand_info[i], dst->type, false))
6455 {
6456 WARN("Failed to validate operand %u for dx intrinsic id %u, '%s'.\n", i + 1, op, name);
6458 "Operand %u for call to dx intrinsic function '%s' is invalid.", i + 1, name);
6459 return false;
6460 }
6461 }
6462 if (info->operand_info[operand_count])
6463 {
6464 WARN("Missing operands for dx intrinsic id %u, '%s'.\n", op, name);
6466 "Call to dx intrinsic function '%s' has missing operands.", name);
6467 return false;
6468 }
6469
6470 return true;
6471}
6472
6474 struct sm6_value *dst)
6475{
6476 const struct sm6_type *type;
6477
6478 ins->opcode = VKD3DSIH_NOP;
6479
6480 if (!dst->type)
6481 return;
6482
6483 type = sm6_type_get_scalar_type(dst->type, 0);
6485 /* dst->is_undefined is not set here because it flags only explicitly undefined values. */
6486}
6487
6489 const char *name, const struct sm6_value **operands, unsigned int operand_count,
6490 struct function_emission_state *state, struct sm6_value *dst)
6491{
6492 if (op >= ARRAY_SIZE(sm6_dx_op_table) || !sm6_dx_op_table[op].operand_info)
6493 {
6494 FIXME("Unhandled dx intrinsic function id %u, '%s'.\n", op, name);
6496 "Call to intrinsic function %s is unhandled.", name);
6498 return;
6499 }
6500
6501 if (sm6_parser_validate_dx_op(sm6, op, name, operands, operand_count, dst))
6502 sm6_dx_op_table[op].handler(sm6, op, operands, state);
6503 else
6505}
6506
6507static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_record *record,
6508 struct function_emission_state *state, struct sm6_value *dst)
6509{
6510 const struct sm6_value *operands[DXIL_OP_MAX_OPERANDS];
6511 const struct sm6_value *fn_value, *op_value;
6512 unsigned int i = 1, j, operand_count;
6513 const struct sm6_type *type = NULL;
6514 uint64_t call_conv;
6515
6517 return;
6518
6519 /* TODO: load the 1-based attributes index from record->operands[0] and validate against attribute count. */
6520
6521 if ((call_conv = record->operands[i++]) & CALL_CONV_FLAG_EXPLICIT_TYPE)
6522 type = sm6_parser_get_type(sm6, record->operands[i++]);
6523 if (call_conv &= ~CALL_CONV_FLAG_EXPLICIT_TYPE)
6524 WARN("Ignoring calling convention %#"PRIx64".\n", call_conv);
6525
6526 if (!(fn_value = sm6_parser_get_value_by_ref(sm6, record, NULL, &i)))
6527 return;
6528 if (!sm6_value_is_function_dcl(fn_value))
6529 {
6530 WARN("Function target value is not a function declaration.\n");
6532 "Function call target value is not a function declaration.");
6533 return;
6534 }
6535
6536 if (type && type != fn_value->type->u.pointer.type)
6537 WARN("Explicit call type does not match function type.\n");
6538 type = fn_value->type->u.pointer.type;
6539
6540 if (!sm6_type_is_void(type->u.function->ret_type))
6541 dst->type = type->u.function->ret_type;
6542
6543 operand_count = type->u.function->param_count;
6544 if (operand_count > ARRAY_SIZE(operands))
6545 {
6546 WARN("Ignoring %zu operands.\n", operand_count - ARRAY_SIZE(operands));
6548 "Ignoring %zu operands for function call.", operand_count - ARRAY_SIZE(operands));
6549 operand_count = ARRAY_SIZE(operands);
6550 }
6551
6552 for (j = 0; j < operand_count; ++j)
6553 {
6554 if (!(operands[j] = sm6_parser_get_value_by_ref(sm6, record, type->u.function->param_types[j], &i)))
6555 return;
6556 }
6557 if ((j = record->operand_count - i))
6558 {
6559 WARN("Ignoring %u operands beyond the function parameter list.\n", j);
6561 "Ignoring %u function call operands beyond the parameter list.", j);
6562 }
6563
6564 if (!fn_value->u.function.is_prototype)
6565 {
6566 FIXME("Unhandled call to local function.\n");
6568 "Call to a local function is unsupported.");
6569 return;
6570 }
6571 if (!sm6_value_is_dx_intrinsic_dcl(fn_value))
6572 WARN("External function is not a dx intrinsic.\n");
6573
6574 if (!operand_count)
6575 {
6576 WARN("Missing dx intrinsic function id.\n");
6578 "The id for a dx intrinsic function is missing.");
6579 return;
6580 }
6581
6582 op_value = operands[0];
6583 if (!sm6_value_is_constant(op_value) || !sm6_type_is_integer(op_value->type))
6584 {
6585 WARN("dx intrinsic function id is not a constant int.\n");
6587 "Expected a constant integer dx intrinsic function id.");
6588 return;
6589 }
6591 fn_value->u.function.name, &operands[1], operand_count - 1, state, dst);
6592}
6593
6595 const struct sm6_type *to, struct sm6_parser *sm6)
6596{
6598 bool from_int, to_int, from_fp, to_fp;
6599 bool is_valid = false;
6600
6601 from_int = sm6_type_is_integer(from);
6604 to_fp = sm6_type_is_floating_point(to);
6605
6606 /* NOTE: DXIL currently doesn't use vectors here. */
6607 if ((!from_int && !from_fp) || (!to_int && !to_fp))
6608 {
6609 FIXME("Unhandled cast of type class %u to type class %u.\n", from->class, to->class);
6611 "Cast of type class %u to type class %u is not implemented.", from->class, to->class);
6612 return VKD3DSIH_INVALID;
6613 }
6614 if (to->u.width == 8 || from->u.width == 8)
6615 {
6616 FIXME("Unhandled 8-bit value.\n");
6618 "Cast to/from an 8-bit type is not implemented.");
6619 return VKD3DSIH_INVALID;
6620 }
6621
6622 /* DXC emits minimum precision types as 16-bit. These must be emitted
6623 * as 32-bit in VSIR, so all width extensions to 32 bits are no-ops. */
6624 switch (code)
6625 {
6626 case CAST_TRUNC:
6627 /* nop or min precision. TODO: native 16-bit */
6628 if (to->u.width == from->u.width || (to->u.width == 16 && from->u.width == 32))
6629 op = VKD3DSIH_NOP;
6630 else
6631 op = VKD3DSIH_UTOU;
6632 is_valid = from_int && to_int && to->u.width <= from->u.width;
6633 break;
6634 case CAST_ZEXT:
6635 case CAST_SEXT:
6636 /* nop or min precision. TODO: native 16-bit.
6637 * Extension instructions could be emitted for min precision, but in Windows
6638 * the AMD RX 580 simply drops such instructions, which makes sense as no
6639 * assumptions should be made about any behaviour which depends on bit width. */
6640 if (to->u.width == from->u.width || (to->u.width == 32 && from->u.width == 16))
6641 {
6642 op = VKD3DSIH_NOP;
6643 is_valid = from_int && to_int;
6644 }
6645 else if (to->u.width > from->u.width)
6646 {
6648 VKD3D_ASSERT(from->u.width == 1 || to->u.width == 64);
6649 is_valid = from_int && to_int;
6650 }
6651 break;
6652 case CAST_FPTOUI:
6653 op = VKD3DSIH_FTOU;
6654 is_valid = from_fp && to_int && to->u.width > 1;
6655 break;
6656 case CAST_FPTOSI:
6657 op = VKD3DSIH_FTOI;
6658 is_valid = from_fp && to_int && to->u.width > 1;
6659 break;
6660 case CAST_UITOFP:
6661 op = VKD3DSIH_UTOF;
6662 is_valid = from_int && to_fp;
6663 break;
6664 case CAST_SITOFP:
6665 op = VKD3DSIH_ITOF;
6666 is_valid = from_int && to_fp;
6667 break;
6668 case CAST_FPTRUNC:
6669 /* TODO: native 16-bit */
6670 op = (from->u.width == 64) ? VKD3DSIH_DTOF : VKD3DSIH_NOP;
6671 is_valid = from_fp && to_fp;
6672 break;
6673 case CAST_FPEXT:
6674 /* TODO: native 16-bit */
6675 op = (to->u.width == 64) ? VKD3DSIH_FTOD : VKD3DSIH_NOP;
6676 is_valid = from_fp && to_fp;
6677 break;
6678 case CAST_BITCAST:
6679 op = VKD3DSIH_MOV;
6680 is_valid = to->u.width == from->u.width;
6681 break;
6682 default:
6683 FIXME("Unhandled cast op %"PRIu64".\n", code);
6685 "Cast operation %"PRIu64" is unhandled.\n", code);
6686 return VKD3DSIH_INVALID;
6687 }
6688
6689 if (!is_valid)
6690 {
6691 FIXME("Invalid types %u and/or %u for op %"PRIu64".\n", from->class, to->class, code);
6693 "Cast operation %"PRIu64" from type class %u, width %u to type class %u, width %u is invalid.\n",
6694 code, from->class, from->u.width, to->class, to->u.width);
6695 return VKD3DSIH_INVALID;
6696 }
6697
6698 return op;
6699}
6700
6701static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_record *record,
6702 struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
6703{
6704 struct vkd3d_shader_src_param *src_param;
6705 enum vkd3d_shader_opcode handler_idx;
6706 const struct sm6_value *value;
6707 const struct sm6_type *type;
6708 unsigned int i = 0;
6709
6710 if (!(value = sm6_parser_get_value_by_ref(sm6, record, NULL, &i)))
6711 return;
6712
6713 if (!dxil_record_validate_operand_count(record, i + 2, i + 2, sm6))
6714 return;
6715
6716 if (!(type = sm6_parser_get_type(sm6, record->operands[i++])))
6717 return;
6718
6719 dst->type = type;
6720
6722 {
6723 *dst = *value;
6724 dst->type = type;
6725 ins->opcode = VKD3DSIH_NOP;
6726 return;
6727 }
6728
6729 if ((handler_idx = sm6_map_cast_op(record->operands[i], value->type, type, sm6)) == VKD3DSIH_INVALID)
6730 return;
6731
6732 vsir_instruction_init(ins, &sm6->p.location, handler_idx);
6733
6734 if (handler_idx == VKD3DSIH_NOP)
6735 {
6736 dst->u.reg = value->u.reg;
6737 /* Set the result type for casts from 16-bit min precision. */
6738 if (type->u.width != 16)
6739 dst->u.reg.data_type = vkd3d_data_type_from_sm6_type(type);
6740 return;
6741 }
6742
6743 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
6744 return;
6745 src_param_init_from_value(src_param, value);
6746
6748
6749 /* bitcast */
6750 if (handler_idx == VKD3DSIH_MOV)
6751 src_param->reg.data_type = dst->u.reg.data_type;
6752}
6753
6755{
6758};
6759
6761{
6762 static const struct sm6_cmp_info cmp_op_table[] =
6763 {
6765 [FCMP_OEQ] = {VKD3DSIH_EQO},
6766 [FCMP_OGT] = {VKD3DSIH_LTO, true},
6767 [FCMP_OGE] = {VKD3DSIH_GEO},
6768 [FCMP_OLT] = {VKD3DSIH_LTO},
6769 [FCMP_OLE] = {VKD3DSIH_GEO, true},
6770 [FCMP_ONE] = {VKD3DSIH_NEO},
6771 [FCMP_ORD] = {VKD3DSIH_ORD},
6772 [FCMP_UNO] = {VKD3DSIH_UNO},
6773 [FCMP_UEQ] = {VKD3DSIH_EQU},
6774 [FCMP_UGT] = {VKD3DSIH_LTU, true},
6775 [FCMP_UGE] = {VKD3DSIH_GEU},
6776 [FCMP_ULT] = {VKD3DSIH_LTU},
6777 [FCMP_ULE] = {VKD3DSIH_GEU, true},
6778 [FCMP_UNE] = {VKD3DSIH_NEU},
6780
6781 [ICMP_EQ] = {VKD3DSIH_IEQ},
6782 [ICMP_NE] = {VKD3DSIH_INE},
6783 [ICMP_UGT] = {VKD3DSIH_ULT, true},
6784 [ICMP_UGE] = {VKD3DSIH_UGE},
6785 [ICMP_ULT] = {VKD3DSIH_ULT},
6786 [ICMP_ULE] = {VKD3DSIH_UGE, true},
6787 [ICMP_SGT] = {VKD3DSIH_ILT, true},
6788 [ICMP_SGE] = {VKD3DSIH_IGE},
6789 [ICMP_SLT] = {VKD3DSIH_ILT},
6790 [ICMP_SLE] = {VKD3DSIH_IGE, true},
6791 };
6792
6793 return (code < ARRAY_SIZE(cmp_op_table)) ? &cmp_op_table[code] : NULL;
6794}
6795
6796static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_record *record,
6797 struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
6798{
6799 struct vkd3d_shader_src_param *src_params;
6800 const struct sm6_type *type_a, *type_b;
6801 bool is_int, is_fp, silence_warning;
6802 const struct sm6_cmp_info *cmp;
6803 const struct sm6_value *a, *b;
6805 unsigned int i = 0;
6806
6807 if (!(dst->type = sm6->bool_type))
6808 {
6809 WARN("Bool type not found.\n");
6811 "Module does not define a boolean type for comparison results.");
6812 return;
6813 }
6814
6816 if (!a)
6817 return;
6818 b = sm6_parser_get_value_by_ref(sm6, record, a->type, &i);
6819 if (!b)
6820 return;
6821
6822 if (!dxil_record_validate_operand_count(record, i + 1, i + 2, sm6))
6823 return;
6824
6825 type_a = a->type;
6826 type_b = b->type;
6828 is_fp = sm6_type_is_floating_point(type_a);
6829
6830 code = record->operands[i++];
6831
6832 /* dxcompiler occasionally emits bool not-equal-to-false, which is a no-op. Bool comparisons
6833 * do not otherwise occur, so deleting these avoids the need for backend support. */
6835 {
6836 ins->opcode = VKD3DSIH_NOP;
6837 *dst = *a;
6838 return;
6839 }
6840
6841 if ((!is_int && !is_fp) || is_int != (code >= ICMP_EQ))
6842 {
6843 FIXME("Invalid operation %"PRIu64" on type class %u.\n", code, type_a->class);
6845 "Comparison operation %"PRIu64" on type class %u is invalid.", code, type_a->class);
6846 return;
6847 }
6848
6849 if (type_a != type_b)
6850 {
6851 WARN("Type mismatch, type %u width %u vs type %u width %u.\n", type_a->class,
6852 type_a->u.width, type_b->class, type_b->u.width);
6854 "Type mismatch in comparison operation arguments.");
6855 }
6856
6857 if (!(cmp = sm6_map_cmp2_op(code)) || !cmp->handler_idx || cmp->handler_idx == VKD3DSIH_INVALID)
6858 {
6859 FIXME("Unhandled operation %"PRIu64".\n", code);
6861 "Comparison operation %"PRIu64" is unhandled.", code);
6862 return;
6863 }
6864
6865 vsir_instruction_init(ins, &sm6->p.location, cmp->handler_idx);
6866
6867 flags = (record->operand_count > i) ? record->operands[i] : 0;
6868 silence_warning = false;
6869
6870 if (is_fp)
6871 {
6873 ins->flags |= VKD3DSI_PRECISE_X;
6875 /* SPIR-V FPFastMathMode is only available in the Kernel execution model. */
6876 silence_warning = !(flags & ~(FP_NO_NAN | FP_NO_INF | FP_NO_SIGNED_ZEROS | FP_ALLOW_RECIPROCAL));
6877 }
6878 if (flags && silence_warning)
6879 {
6880 TRACE("Ignoring fast FP modifier %#"PRIx64".\n", flags);
6881 }
6882 else if (flags)
6883 {
6884 WARN("Ignoring flags %#"PRIx64".\n", flags);
6886 "Ignoring flags %#"PRIx64" for a comparison operation.", flags);
6887 }
6888
6889 if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
6890 return;
6891 src_param_init_from_value(&src_params[0 ^ cmp->src_swap], a);
6892 src_param_init_from_value(&src_params[1 ^ cmp->src_swap], b);
6893
6895}
6896
6897static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_record *record,
6898 struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
6899{
6900 uint64_t success_ordering, failure_ordering;
6901 struct vkd3d_shader_dst_param *dst_params;
6902 struct vkd3d_shader_src_param *src_params;
6903 const struct sm6_value *ptr, *cmp, *new;
6904 unsigned int i = 0;
6905 bool is_volatile;
6906 uint64_t code;
6907
6908 if (!(ptr = sm6_parser_get_value_by_ref(sm6, record, NULL, &i))
6911 return;
6912
6913 if (ptr->u.reg.type != VKD3DSPR_GROUPSHAREDMEM)
6914 {
6915 WARN("Register is not groupshared.\n");
6917 "The destination register for a cmpxchg instruction is not groupshared memory.");
6918 return;
6919 }
6920
6921 if (!(dst->type = sm6_type_get_cmpxchg_result_struct(sm6)))
6922 {
6923 WARN("Failed to find result struct.\n");
6925 "Module does not define a result struct type for a cmpxchg instruction.");
6926 return;
6927 }
6928
6929 /* Forward-referenced comparands are stored as value/type pairs, even
6930 * though in principle we could use the destination type. */
6932 new = sm6_parser_get_value_by_ref(sm6, record, ptr->type->u.pointer.type, &i);
6933 if (!cmp || !new)
6934 return;
6935
6937 || !sm6_value_validate_is_i32(new, sm6)
6938 || !dxil_record_validate_operand_count(record, i + 3, i + 5, sm6))
6939 {
6940 return;
6941 }
6942
6943 is_volatile = record->operands[i++];
6944 success_ordering = record->operands[i++];
6945
6946 if ((code = record->operands[i++]) != 1)
6947 FIXME("Ignoring synchronisation scope %"PRIu64".\n", code);
6948
6949 failure_ordering = (record->operand_count > i) ? record->operands[i++] : success_ordering;
6950
6951 /* It's currently not possible to specify an atomic ordering in HLSL, and it defaults to seq_cst. */
6952 if (success_ordering != ORDERING_SEQCST)
6953 FIXME("Unhandled success ordering %"PRIu64".\n", success_ordering);
6954 if (success_ordering != failure_ordering)
6955 FIXME("Unhandled failure ordering %"PRIu64".\n", failure_ordering);
6956
6957 if (record->operand_count > i && record->operands[i])
6958 FIXME("Ignoring weak cmpxchg.\n");
6959
6962
6963 if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
6964 return;
6965 src_param_make_constant_uint(&src_params[0], 0);
6966 src_param_init_from_value(&src_params[1], cmp);
6967 src_param_init_from_value(&src_params[2], new);
6968
6969 if (!(dst_params = instruction_dst_params_alloc(ins, 2, sm6)))
6970 return;
6971 register_init_ssa_scalar(&dst_params[0].reg, dst->type, dst, sm6);
6972 dst_param_init(&dst_params[0]);
6973 dst_params[1].reg = ptr->u.reg;
6974 dst_param_init(&dst_params[1]);
6975
6976 dst->u.reg = dst_params[0].reg;
6977}
6978
6979static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil_record *record,
6980 struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
6981{
6982 struct vkd3d_shader_src_param *src_param;
6983 const struct sm6_type *type;
6984 const struct sm6_value *src;
6985 unsigned int i = 0;
6986 uint64_t elem_idx;
6987
6988 if (!(src = sm6_parser_get_value_by_ref(sm6, record, NULL, &i)))
6989 return;
6990
6992 return;
6993
6994 if (record->operand_count > i + 1)
6995 {
6996 FIXME("Unhandled multiple indices.\n");
6998 "Multiple extractval indices are not supported.");
6999 return;
7000 }
7001
7002 type = src->type;
7004 {
7005 WARN("Invalid extraction from non-aggregate.\n");
7007 "Source type of an extractval instruction is not an aggregate.");
7008 return;
7009 }
7010
7011 elem_idx = record->operands[i];
7012 if (!(type = sm6_type_get_element_type_at_index(type, elem_idx)))
7013 {
7014 WARN("Invalid element index %"PRIu64".\n", elem_idx);
7016 "Element index %"PRIu64" for an extractval instruction is out of bounds.", elem_idx);
7017 return;
7018 }
7020 {
7021 FIXME("Nested extraction is not supported.\n");
7023 "Extraction from nested aggregates is not supported.");
7024 return;
7025 }
7026 dst->type = type;
7027
7028 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
7029
7030 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
7031 return;
7032 src_param->reg = src->u.reg;
7033 src_param_init_scalar(src_param, elem_idx);
7034
7036}
7037
7038static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record *record,
7039 struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
7040{
7041 const struct sm6_type *type, *pointee_type;
7042 unsigned int elem_idx, operand_idx = 2;
7043 enum bitcode_address_space addr_space;
7044 const struct sm6_value *elem_value;
7045 struct vkd3d_shader_register *reg;
7046 const struct sm6_value *src;
7047 bool is_in_bounds;
7048
7050 || !(type = sm6_parser_get_type(sm6, record->operands[1]))
7051 || !(src = sm6_parser_get_value_by_ref(sm6, record, NULL, &operand_idx))
7054 || !dxil_record_validate_operand_min_count(record, operand_idx + 2, sm6))
7055 {
7056 return;
7057 }
7058
7059 if (src->u.reg.idx_count > 1)
7060 {
7061 WARN("Unsupported stacked GEP.\n");
7063 "A GEP instruction on the result of a previous GEP is unsupported.");
7064 return;
7065 }
7066
7067 is_in_bounds = record->operands[0];
7068
7069 if ((pointee_type = src->type->u.pointer.type) != type)
7070 {
7071 WARN("Type mismatch, type %u width %u vs type %u width %u.\n", type->class,
7072 type->u.width, pointee_type->class, pointee_type->u.width);
7074 "Type mismatch in GEP operation arguments.");
7075 }
7076 addr_space = src->type->u.pointer.addr_space;
7077
7078 if (!(elem_value = sm6_parser_get_value_by_ref(sm6, record, NULL, &operand_idx)))
7079 return;
7080
7081 /* The first index is always zero, to form a simple pointer dereference. */
7082 if (sm6_value_get_constant_uint(elem_value))
7083 {
7084 WARN("Expected constant zero.\n");
7086 "The pointer dereference index for a GEP instruction is not constant zero.");
7087 return;
7088 }
7089
7090 if (!sm6_type_is_array(pointee_type))
7091 {
7092 WARN("Invalid GEP on type class %u.\n", pointee_type->class);
7094 "Source type for index 1 of a GEP instruction is not an array.");
7095 return;
7096 }
7097
7098 if (!(elem_value = sm6_parser_get_value_by_ref(sm6, record, NULL, &operand_idx)))
7099 return;
7100
7101 /* If indexing is dynamic, just get the type at offset zero. */
7102 elem_idx = sm6_value_is_constant(elem_value) ? sm6_value_get_constant_uint(elem_value) : 0;
7103 type = sm6_type_get_element_type_at_index(pointee_type, elem_idx);
7104 if (!type)
7105 {
7106 WARN("Invalid element index %u.\n", elem_idx);
7108 "Element index %u for a GEP instruction is out of bounds.", elem_idx);
7109 return;
7110 }
7111
7112 if (operand_idx < record->operand_count)
7113 {
7114 FIXME("Multiple element indices are not implemented.\n");
7116 "Multi-dimensional addressing in GEP instructions is not supported.");
7117 return;
7118 }
7119
7120 if (!(dst->type = sm6_type_get_pointer_to_type(type, addr_space, sm6)))
7121 {
7122 WARN("Failed to get pointer type for type %u.\n", type->class);
7124 "Module does not define a pointer type for a GEP instruction.");
7125 return;
7126 }
7127
7128 reg = &dst->u.reg;
7129 *reg = src->u.reg;
7130 reg->idx[1].offset = 0;
7131 register_index_address_init(&reg->idx[1], elem_value, sm6);
7132 reg->idx[1].is_in_bounds = is_in_bounds;
7133 reg->idx_count = 2;
7134 dst->structure_stride = src->structure_stride;
7135
7136 ins->opcode = VKD3DSIH_NOP;
7137}
7138
7139static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_record *record,
7140 struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
7141{
7142 const struct sm6_type *elem_type = NULL, *pointee_type;
7143 unsigned int alignment, operand_count, i = 0;
7144 struct vkd3d_shader_src_param *src_params;
7145 const struct sm6_value *ptr;
7146 uint64_t alignment_code;
7147
7148 if (!(ptr = sm6_parser_get_value_by_ref(sm6, record, NULL, &i)))
7149 return;
7153 || !dxil_record_validate_operand_count(record, i + 2, i + 3, sm6))
7154 return;
7155
7156 if (record->operand_count > i + 2 && !(elem_type = sm6_parser_get_type(sm6, record->operands[i++])))
7157 return;
7158
7159 if (!elem_type)
7160 {
7161 elem_type = ptr->type->u.pointer.type;
7162 }
7163 else if (elem_type != (pointee_type = ptr->type->u.pointer.type))
7164 {
7165 WARN("Type mismatch.\n");
7167 "Type mismatch in pointer load arguments.");
7168 }
7169
7170 dst->type = elem_type;
7171
7173 return;
7174
7175 alignment_code = record->operands[i++];
7176 if (!bitcode_parse_alignment(alignment_code, &alignment))
7177 WARN("Invalid alignment %"PRIu64".\n", alignment_code);
7178
7179 if (record->operands[i])
7180 WARN("Ignoring volatile modifier.\n");
7181
7182 if (ptr->structure_stride)
7183 {
7185 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_LD_STRUCTURED);
7186
7187 if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
7188 return;
7189 if (ptr->u.reg.idx[1].rel_addr)
7190 src_params[0] = *ptr->u.reg.idx[1].rel_addr;
7191 else
7192 src_param_make_constant_uint(&src_params[0], ptr->u.reg.idx[1].offset);
7193 /* Struct offset is always zero as there is no struct, just an array. */
7194 src_param_make_constant_uint(&src_params[1], 0);
7195 src_param_init_from_value(&src_params[2], ptr);
7196 src_params[2].reg.alignment = alignment;
7197 }
7198 else
7199 {
7200 operand_count = 1 + (ptr->u.reg.type == VKD3DSPR_GROUPSHAREDMEM);
7201 vsir_instruction_init(ins, &sm6->p.location, (operand_count > 1) ? VKD3DSIH_LD_RAW : VKD3DSIH_MOV);
7202
7203 if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6)))
7204 return;
7205 if (operand_count > 1)
7206 src_param_make_constant_uint(&src_params[0], 0);
7207 src_param_init_from_value(&src_params[operand_count - 1], ptr);
7208 src_params[operand_count - 1].reg.alignment = alignment;
7209 }
7210
7212}
7213
7214static int phi_incoming_compare(const void *a, const void *b)
7215{
7216 const struct incoming_value *incoming_a = a, *incoming_b = b;
7217
7218 return (incoming_a->block > incoming_b->block) - (incoming_a->block < incoming_b->block);
7219}
7220
7221static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record *record,
7222 struct sm6_function *function, struct sm6_block *code_block, struct vkd3d_shader_instruction *ins,
7223 struct sm6_value *dst)
7224{
7225 struct incoming_value *incoming;
7226 const struct sm6_type *type;
7227 struct sm6_phi *phi;
7228 unsigned int i, j;
7229 uint64_t src_idx;
7230
7231 if (!(record->operand_count & 1))
7232 {
7233 WARN("Invalid operand count %u.\n", record->operand_count);
7235 "Invalid operand count %u for phi instruction.", record->operand_count);
7236 return;
7237 }
7238
7239 if (!(type = sm6_parser_get_type(sm6, record->operands[0])))
7240 return;
7242 {
7243 /* dxc doesn't seem to use buffer/resource read return types here. */
7244 FIXME("Only scalar numeric types are supported.\n");
7246 "Result type class %u of a phi instruction is not scalar numeric.", type->class);
7247 return;
7248 }
7249
7250 dst->type = type;
7251 register_init_ssa_scalar(&dst->u.reg, type, dst, sm6);
7252
7253 if (!(phi = sm6_block_phi_require_space(code_block, sm6)))
7254 return;
7255 phi->reg = dst->u.reg;
7256 phi->incoming_count = record->operand_count / 2u;
7257
7258 if (!vkd3d_array_reserve((void **)&phi->incoming, &phi->incoming_capacity, phi->incoming_count,
7259 sizeof(*phi->incoming)))
7260 {
7261 ERR("Failed to allocate phi incoming array.\n");
7263 "Out of memory allocating a phi incoming array.");
7264 return;
7265 }
7266 incoming = phi->incoming;
7267
7268 for (i = 1; i < record->operand_count; i += 2)
7269 {
7270 src_idx = sm6->value_count - decode_rotated_signed_value(record->operands[i]);
7271 /* May be a forward reference. */
7272 if (src_idx >= sm6->cur_max_value)
7273 {
7274 WARN("Invalid value index %"PRIu64".\n", src_idx);
7276 "Invalid value index %"PRIu64" for a phi incoming value.", src_idx);
7277 return;
7278 }
7279
7280 j = i / 2u;
7281 /* Store the value index in the register for later resolution. */
7282 incoming[j].reg.idx[0].offset = src_idx;
7283 incoming[j].block = sm6_function_get_block(function, record->operands[i + 1], sm6);
7284 }
7285
7286 ins->opcode = VKD3DSIH_NOP;
7287
7289
7290 for (i = 1, j = 1; i < phi->incoming_count; ++i)
7291 {
7292 if (incoming[i].block != incoming[i - 1].block)
7293 {
7294 incoming[j++] = incoming[i];
7295 continue;
7296 }
7297
7298 if (incoming[i].reg.idx[0].offset != incoming[i - 1].reg.idx[0].offset)
7299 {
7300 WARN("PHI conflict.\n");
7302 "Two phi incomings have the same block but different values.");
7303 }
7304 }
7305 /* if (j == 1) we should be able to set dst->u.reg to incoming[0].reg, but structurisation
7306 * may potentially add new incomings. */
7307 phi->incoming_count = j;
7308}
7309
7310static void sm6_parser_emit_ret(struct sm6_parser *sm6, const struct dxil_record *record,
7311 struct sm6_block *code_block, struct vkd3d_shader_instruction *ins)
7312{
7314 return;
7315
7316 if (record->operand_count)
7317 FIXME("Non-void return is not implemented.\n");
7318
7319 code_block->terminator.type = TERMINATOR_RET;
7320
7321 ins->opcode = VKD3DSIH_NOP;
7322}
7323
7324static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_record *record,
7325 struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
7326{
7327 unsigned int i = 0, alignment, operand_count;
7328 struct vkd3d_shader_src_param *src_params;
7329 struct vkd3d_shader_dst_param *dst_param;
7330 const struct sm6_value *ptr, *src;
7331 uint64_t alignment_code;
7332
7333 if (!(ptr = sm6_parser_get_value_by_ref(sm6, record, NULL, &i))
7337 {
7338 return;
7339 }
7340
7341 /* Forward-referenced sources are stored as value/type pairs, even
7342 * though in principle we could use the destination type. */
7343 if (!(src = sm6_parser_get_value_by_ref(sm6, record, NULL, &i)))
7344 return;
7346 return;
7347
7348 if (ptr->type->u.pointer.type != src->type)
7349 {
7350 WARN("Type mismatch.\n");
7352 "Type mismatch in pointer store arguments.");
7353 }
7354
7355 if (!dxil_record_validate_operand_count(record, i + 2, i + 2, sm6))
7356 return;
7357
7358 alignment_code = record->operands[i++];
7359 if (!bitcode_parse_alignment(alignment_code, &alignment))
7360 WARN("Invalid alignment %"PRIu64".\n", alignment_code);
7361
7362 if (record->operands[i])
7363 WARN("Ignoring volatile modifier.\n");
7364
7365 if (ptr->structure_stride)
7366 {
7369
7370 if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
7371 return;
7372 if (ptr->u.reg.idx[1].rel_addr)
7373 src_params[0] = *ptr->u.reg.idx[1].rel_addr;
7374 else
7375 src_param_make_constant_uint(&src_params[0], ptr->u.reg.idx[1].offset);
7376 /* Struct offset is always zero as there is no struct, just an array. */
7377 src_param_make_constant_uint(&src_params[1], 0);
7378 src_param_init_from_value(&src_params[2], src);
7379 }
7380 else
7381 {
7382 operand_count = 1 + (ptr->u.reg.type == VKD3DSPR_GROUPSHAREDMEM);
7383 vsir_instruction_init(ins, &sm6->p.location, (operand_count > 1) ? VKD3DSIH_STORE_RAW : VKD3DSIH_MOV);
7384
7385 if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6)))
7386 return;
7387 if (operand_count > 1)
7388 src_param_make_constant_uint(&src_params[0], 0);
7389 src_param_init_from_value(&src_params[operand_count - 1], src);
7390 }
7391
7392 dst_param = instruction_dst_params_alloc(ins, 1, sm6);
7393 dst_param_init(dst_param);
7394 dst_param->reg = ptr->u.reg;
7395 dst_param->reg.alignment = alignment;
7396 /* Groupshared stores contain the address in the src params. */
7397 if (dst_param->reg.type != VKD3DSPR_IDXTEMP)
7398 dst_param->reg.idx_count = 1;
7399}
7400
7401static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_record *record,
7403{
7404 struct sm6_block_terminator *terminator = &code_block->terminator;
7405 const struct sm6_type *type;
7406 const struct sm6_value *src;
7407 unsigned int i = 1, j;
7408
7409 if (record->operand_count < 3 || !(record->operand_count & 1))
7410 {
7411 WARN("Invalid operand count %u.\n", record->operand_count);
7413 "Invalid operand count %u for a switch instruction.", record->operand_count);
7414 return;
7415 }
7416
7417 if (!(type = sm6_parser_get_type(sm6, record->operands[0])))
7418 return;
7419
7420 if (!(src = sm6_parser_get_value_by_ref(sm6, record, type, &i))
7422 return;
7423 VKD3D_ASSERT(i == 2);
7424
7425 if (src->type != type)
7426 {
7427 WARN("Type mismatch.\n");
7429 "The type of a switch selector value does not match the selector type.");
7430 }
7432 {
7433 WARN("Selector is not scalar integer.\n");
7435 "Selector type class %u of a switch instruction is not scalar integer.", type->class);
7436 return;
7437 }
7438
7439 terminator->conditional_reg = src->u.reg;
7440 terminator->type = TERMINATOR_SWITCH;
7441
7442 terminator->case_count = record->operand_count / 2u;
7443 if (!(terminator->cases = vkd3d_calloc(terminator->case_count, sizeof(*terminator->cases))))
7444 {
7445 ERR("Failed to allocate case array.\n");
7447 "Out of memory allocating a switch case array.");
7448 return;
7449 }
7450
7451 /* Executes 'operand_count / 2' times because operand_count is uneven. */
7452 for (; i < record->operand_count; i += 2)
7453 {
7454 j = i / 2u - 1;
7455 terminator->cases[j].block = sm6_function_get_block(function, record->operands[i], sm6);
7456 /* For structurisation it is convenient to store the default in the case array. */
7457 terminator->cases[j].is_default = !j;
7458 }
7459
7460 for (i = 3; i < record->operand_count; i += 2)
7461 {
7462 if (!(src = sm6_parser_get_value_safe(sm6, record->operands[i])))
7463 return;
7464
7465 if (src->type != type)
7466 {
7467 WARN("Type mismatch.\n");
7469 "The type of a switch case value does not match the selector type.");
7470 }
7472 {
7473 WARN("Case value is not a constant.\n");
7475 "A switch case value is not a constant.");
7476 }
7477
7478 terminator->cases[i / 2u].value = sm6_value_get_constant_uint64(src);
7479 }
7480
7481 ins->opcode = VKD3DSIH_NOP;
7482}
7483
7484static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_record *record,
7485 struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
7486{
7487 struct vkd3d_shader_src_param *src_params;
7488 const struct sm6_value *src[3];
7489 unsigned int i = 0;
7490
7491 if (!(src[1] = sm6_parser_get_value_by_ref(sm6, record, NULL, &i))
7492 || !(src[2] = sm6_parser_get_value_by_ref(sm6, record, src[1]->type, &i))
7493 || !(src[0] = sm6_parser_get_value_by_ref(sm6, record, NULL, &i)))
7494 {
7495 return;
7496 }
7498
7499 for (i = 0; i < 3; ++i)
7500 {
7502 return;
7503 }
7504
7505 dst->type = src[1]->type;
7506
7507 if (!sm6_value_validate_is_bool(src[0], sm6))
7508 return;
7509
7510 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOVC);
7511
7512 if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
7513 return;
7514 for (i = 0; i < 3; ++i)
7515 src_param_init_from_value(&src_params[i], src[i]);
7516
7518}
7519
7521{
7522 return m && m->type == VKD3D_METADATA_NODE;
7523}
7524
7526{
7527 return m && m->type == VKD3D_METADATA_VALUE;
7528}
7529
7531{
7532 return m && m->type == VKD3D_METADATA_STRING;
7533}
7534
7536{
7538 && (sm6_value_is_undef(m->u.value) || sm6_value_is_constant_zero(m->u.value));
7539}
7540
7541static bool sm6_metadata_get_uint_value(const struct sm6_parser *sm6,
7542 const struct sm6_metadata_value *m, unsigned int *u)
7543{
7544 const struct sm6_value *value;
7545
7546 if (!m || m->type != VKD3D_METADATA_VALUE)
7547 return false;
7548
7549 value = m->u.value;
7551 return false;
7552 if (!sm6_type_is_integer(value->type))
7553 return false;
7554
7555 *u = register_get_uint_value(&value->u.reg);
7556
7557 return true;
7558}
7559
7560static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6,
7561 const struct sm6_metadata_value *m, uint64_t *u)
7562{
7563 const struct sm6_value *value;
7564
7565 if (!m || m->type != VKD3D_METADATA_VALUE)
7566 return false;
7567
7568 value = m->u.value;
7570 return false;
7571 if (!sm6_type_is_integer(value->type))
7572 return false;
7573
7574 *u = register_get_uint64_value(&value->u.reg);
7575
7576 return true;
7577}
7578
7579static bool sm6_metadata_get_float_value(const struct sm6_parser *sm6,
7580 const struct sm6_metadata_value *m, float *f)
7581{
7582 const struct sm6_value *value;
7583
7584 if (!m || m->type != VKD3D_METADATA_VALUE)
7585 return false;
7586
7587 value = m->u.value;
7589 return false;
7591 return false;
7592
7593 *f = register_get_float_value(&value->u.reg);
7594
7595 return true;
7596}
7597
7598static void sm6_parser_metadata_attachment_block_init(struct sm6_parser *sm6, const struct dxil_block *target_block,
7599 const struct dxil_block *block)
7600{
7601 struct dxil_record *target_record;
7602 const struct dxil_record *record;
7603 unsigned int i;
7605
7606 for (i = 0; i < block->record_count; ++i)
7607 {
7608 record = block->records[i];
7609 if (record->code != METADATA_ATTACHMENT)
7610 {
7611 WARN("Ignoring record with code %u.\n", record->code);
7613 "Ignoring a metadata attachment record with code %u.", record->code);
7614 continue;
7615 }
7616 if (!(record->operand_count & 1))
7617 {
7618 WARN("Ignoring function attachment.\n");
7620 "Ignoring a metadata function attachment.");
7621 continue;
7622 }
7623
7624 index = record->operands[0];
7625 if (!target_block->record_count || index >= target_block->record_count - 1)
7626 {
7627 WARN("Invalid record index %"PRIu64".\n", index);
7629 "Invalid record index %"PRIu64" for a metadata attachment.", index);
7630 continue;
7631 }
7632 /* 'index' is an instruction index, but records[0] is DECLAREBLOCKS, not an instruction. */
7633 target_record = target_block->records[index + 1];
7634 if (target_record->attachment)
7635 {
7636 WARN("Overwriting record attachment.\n");
7638 "The target record for a metadata attachment already has an attachment.");
7639 }
7640 target_record->attachment = record;
7641 }
7642}
7643
7645{
7646 unsigned int i;
7647
7648 for (i = 0; i < block->child_block_count; ++i)
7649 {
7650 if (block->child_blocks[i]->id == METADATA_ATTACHMENT_BLOCK)
7652 }
7653}
7654
7655static const struct sm6_metadata_value *sm6_parser_find_metadata_kind(const struct sm6_parser *sm6, uint64_t id)
7656{
7657 unsigned int i, j;
7658
7659 for (i = 0; i < ARRAY_SIZE(sm6->metadata_tables); ++i)
7660 {
7661 for (j = 0; j < sm6->metadata_tables[i].count; ++j)
7662 {
7663 if (sm6->metadata_tables[i].values[j].type == VKD3D_METADATA_KIND
7664 && sm6->metadata_tables[i].values[j].u.kind.id == id)
7665 return &sm6->metadata_tables[i].values[j];
7666 }
7667 }
7668
7669 return NULL;
7670}
7671
7673{
7674 unsigned int i;
7675
7676 for (i = 0; i < ARRAY_SIZE(sm6->metadata_tables); ++i)
7677 {
7678 if (sm6->metadata_tables[i].count > index)
7679 break;
7680 index -= sm6->metadata_tables[i].count;
7681 }
7682
7683 return (index < sm6->metadata_tables[i].count) ? &sm6->metadata_tables[i].values[index] : NULL;
7684}
7685
7686static bool metadata_node_get_unary_uint(const struct sm6_metadata_node *node, unsigned int *operand,
7687 struct sm6_parser *sm6)
7688{
7689 if (node->operand_count != 1)
7690 {
7691 FIXME("Ignoring node with %u operands.\n", node->operand_count);
7693 "Ignoring metadata attachment node with %u operands; expected unary.", node->operand_count);
7694 return false;
7695 }
7696 if (!sm6_metadata_value_is_value(node->operands[0])
7697 || !sm6_metadata_get_uint_value(sm6, node->operands[0], operand))
7698 {
7699 WARN("Failed to get operand value.\n");
7701 "Failed to get a metadata attachment operand value; ignoring the attachment.");
7702 return false;
7703 }
7704
7705 return true;
7706}
7707
7709 struct vkd3d_shader_instruction *ins, struct sm6_value *dst, struct sm6_parser *sm6)
7710{
7711 static const char *ignored_names[] =
7712 {
7713 "alias.scope",
7714 "dx.controlflow.hints",
7715 "llvm.loop",
7716 "noalias",
7717 "tbaa",
7718 "range",
7719 };
7720 const struct sm6_metadata_node *node;
7721 const struct sm6_metadata_value *m;
7722 unsigned int i, j, operand;
7723 bool ignored = false;
7724 const char *name;
7725
7726 if (record->attachment)
7727 {
7728 WARN("Ignoring nested metadata attachment.\n");
7730 "Ignoring a nested metadata attachment.");
7731 }
7732
7733 VKD3D_ASSERT(record->operand_count & 1);
7734 for (i = 1; i < record->operand_count; i += 2)
7735 {
7736 if (!(m = sm6_parser_find_metadata_kind(sm6, record->operands[i])))
7737 {
7738 WARN("Failed to find metadata kind %"PRIx64".\n", record->operands[i]);
7740 "Failed to find metadata kind %"PRIx64" for an attachment.", record->operands[i]);
7741 continue;
7742 }
7743 name = m->u.kind.name;
7744
7745 m = sm6_parser_metadata_get_value(sm6, record->operands[i + 1]);
7746 if (!m || !sm6_metadata_value_is_node(m))
7747 {
7748 WARN("Failed to retrieve metadata attachment node.\n");
7750 "Failed to retrieve a metadata attachment node.");
7751 continue;
7752 }
7753 node = m->u.node;
7754
7755 if (!strcmp(name, "dx.precise"))
7756 {
7758 {
7759 WARN("Precise value is not a register.\n");
7761 "A value marked as precise is not a register.");
7762 }
7763 else if (metadata_node_get_unary_uint(node, &operand, sm6) && operand)
7764 {
7766 }
7767 }
7768 else if (!strcmp(name, "dx.nonuniform"))
7769 {
7771 {
7772 WARN("Non-uniform value is not a register.\n");
7774 "A value marked as non-uniform is not a register.");
7775 }
7776 else if (metadata_node_get_unary_uint(node, &operand, sm6))
7777 {
7778 dst->u.reg.non_uniform = !!operand;
7779 }
7780 }
7781 else
7782 {
7783 for (j = 0; j < ARRAY_SIZE(ignored_names); ++j)
7784 if (!strcmp(name, ignored_names[j]))
7785 break;
7786 if (j == ARRAY_SIZE(ignored_names))
7787 {
7788 WARN("Ignoring metadata attachment '%s'.\n", name);
7790 "Ignoring a metadata attachment named '%s'.", name);
7791 }
7792 ignored = true;
7793 }
7794
7795 if (func_code != FUNC_CODE_INST_CALL && !ignored)
7796 WARN("Metadata attachment target is not a function call.\n");
7797 }
7798}
7799
7800static bool sm6_function_blocks_reserve(struct sm6_function *function, unsigned int reserve)
7801{
7802 if (!vkd3d_array_reserve((void **)&function->blocks, &function->block_capacity,
7803 reserve, sizeof(*function->blocks)))
7804 {
7805 ERR("Failed to allocate code block array.\n");
7806 return false;
7807 }
7808 return true;
7809}
7810
7811static struct sm6_block *sm6_function_create_block(struct sm6_function *function)
7812{
7813 struct sm6_block *block;
7814
7815 if (!(block = sm6_block_create()))
7816 return NULL;
7817
7818 function->blocks[function->block_count++] = block;
7819 /* Set the id to the array index + 1. */
7820 block->id = function->block_count;
7821
7822 return block;
7823}
7824
7826 struct sm6_parser *sm6)
7827{
7828 const struct sm6_block *block;
7829 size_t i, j, block_idx;
7830
7831 for (block_idx = 0; block_idx < function->block_count; ++block_idx)
7832 {
7833 block = function->blocks[block_idx];
7834
7835 for (i = 0; i < block->phi_count; ++i)
7836 {
7837 struct sm6_phi *phi = &block->phi[i];
7838 const struct sm6_value *src;
7839
7840 for (j = 0; j < phi->incoming_count; ++j)
7841 {
7842 src = &sm6->values[phi->incoming[j].reg.idx[0].offset];
7844 {
7845 FIXME("PHI incoming value is not a constant or SSA register.\n");
7847 "A PHI incoming value is not a constant or SSA register.");
7849 }
7850 if (src->u.reg.data_type != phi->reg.data_type)
7851 {
7852 WARN("Type mismatch.\n");
7854 "The type of a phi incoming value does not match the result type.");
7855 }
7856 phi->incoming[j].reg = src->u.reg;
7857 }
7858 }
7859 }
7860
7861 return VKD3D_OK;
7862}
7863
7864static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const struct dxil_block *block,
7865 struct sm6_function *function)
7866{
7867 struct vsir_program *program = sm6->p.program;
7868 struct vkd3d_shader_instruction *ins;
7869 size_t i, block_idx, block_count;
7870 const struct dxil_record *record;
7871 const struct sm6_type *fwd_type;
7872 bool ret_found, is_terminator;
7873 struct sm6_block *code_block;
7874 struct sm6_value *dst;
7875
7876 if (!(function->declaration = sm6_parser_next_function_definition(sm6)))
7877 {
7878 WARN("Failed to find definition to match function body.\n");
7880 }
7881
7882 if (block->record_count < 2)
7883 {
7884 /* It should contain at least a block count and a RET instruction. */
7885 WARN("Invalid function block record count %zu.\n", block->record_count);
7887 }
7888 if (block->records[0]->code != FUNC_CODE_DECLAREBLOCKS || !block->records[0]->operand_count
7889 || block->records[0]->operands[0] > UINT_MAX)
7890 {
7891 WARN("Block count declaration not found or invalid.\n");
7893 }
7894
7895 if (!(block_count = block->records[0]->operands[0]))
7896 {
7897 WARN("Function contains no blocks.\n");
7899 }
7900
7901 if (!sm6_function_blocks_reserve(function, block_count))
7903
7904 /* Pre-allocate all blocks to simplify instruction parsing. */
7905 for (i = 0; i < block_count; ++i)
7906 {
7908 {
7909 ERR("Failed to allocate code block.\n");
7911 }
7912 }
7913 function->block_count = block_count;
7914 code_block = function->blocks[0];
7915
7916 sm6->cur_max_value = function->value_count;
7917
7918 for (i = 1, block_idx = 0, ret_found = false; i < block->record_count; ++i)
7919 {
7920 sm6->p.location.column = i;
7921
7922 if (!code_block)
7923 {
7924 WARN("Invalid block count %zu.\n", function->block_count);
7926 "Invalid block count %zu.", function->block_count);
7928 }
7929
7930 /* Some instructions can emit >1 IR instruction, so extra may be used. */
7931 if (!vkd3d_array_reserve((void **)&code_block->instructions, &code_block->instruction_capacity,
7933 sizeof(*code_block->instructions)))
7934 {
7935 ERR("Failed to allocate instructions.\n");
7937 }
7938
7939 ins = &code_block->instructions[code_block->instruction_count];
7940 ins->opcode = VKD3DSIH_INVALID;
7941
7943 fwd_type = dst->type;
7944 dst->type = NULL;
7945 dst->value_type = VALUE_TYPE_REG;
7946 dst->is_back_ref = true;
7947 is_terminator = false;
7948
7949 record = block->records[i];
7950 switch (record->code)
7951 {
7953 sm6_parser_emit_alloca(sm6, record, ins, dst);
7954 break;
7956 {
7959 program->temp_count = max(program->temp_count, state.temp_idx);
7960 break;
7961 }
7964 break;
7965 case FUNC_CODE_INST_BR:
7966 sm6_parser_emit_br(sm6, record, function, code_block, ins);
7967 is_terminator = true;
7968 break;
7970 {
7973 program->temp_count = max(program->temp_count, state.temp_idx);
7974 break;
7975 }
7978 break;
7981 break;
7984 break;
7987 break;
7988 case FUNC_CODE_INST_GEP:
7990 break;
7993 break;
7994 case FUNC_CODE_INST_PHI:
7995 sm6_parser_emit_phi(sm6, record, function, code_block, ins, dst);
7996 break;
7997 case FUNC_CODE_INST_RET:
7999 is_terminator = true;
8000 ret_found = true;
8001 break;
8004 break;
8006 sm6_parser_emit_switch(sm6, record, function, code_block, ins);
8007 is_terminator = true;
8008 break;
8011 break;
8012 default:
8013 FIXME("Unhandled dxil instruction %u.\n", record->code);
8015 }
8016
8017 if (sm6->p.failed)
8018 return VKD3D_ERROR;
8019
8020 if (record->attachment)
8021 metadata_attachment_record_apply(record->attachment, record->code, ins, dst, sm6);
8022
8023 if (is_terminator)
8024 {
8025 ++block_idx;
8026 code_block = (block_idx < function->block_count) ? function->blocks[block_idx] : NULL;
8027 }
8028 if (code_block)
8029 code_block->instruction_count += ins->opcode != VKD3DSIH_NOP;
8030
8031 if (dst->type && fwd_type && dst->type != fwd_type)
8032 {
8033 WARN("Type mismatch.\n");
8035 "The type of a result value does not match the type defined by a forward reference.");
8036 }
8037
8038 sm6->value_count += !!dst->type;
8039 }
8040
8041 if (!ret_found)
8042 {
8043 WARN("Function contains no RET instruction.\n");
8045 }
8046
8047 return sm6_function_resolve_phi_incomings(function, sm6);
8048}
8049
8050static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_parser *sm6)
8051{
8052 struct vkd3d_shader_src_param *src_params;
8053 struct vkd3d_shader_instruction *ins;
8054 unsigned int i, count;
8055
8056 switch (block->terminator.type)
8057 {
8059 if (!block->terminator.true_block)
8060 return;
8062 if (!(src_params = instruction_src_params_alloc(ins, 1, sm6)))
8063 return;
8064 vsir_src_param_init_label(&src_params[0], block->terminator.true_block->id);
8065 break;
8066
8067 case TERMINATOR_COND_BR:
8068 if (!block->terminator.true_block || !block->terminator.false_block)
8069 return;
8071 if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
8072 return;
8073 src_param_init(&src_params[0]);
8074 src_params[0].reg = block->terminator.conditional_reg;
8075 vsir_src_param_init_label(&src_params[1], block->terminator.true_block->id);
8076 vsir_src_param_init_label(&src_params[2], block->terminator.false_block->id);
8077 break;
8078
8079 case TERMINATOR_SWITCH:
8081 if (!(src_params = instruction_src_params_alloc(ins, block->terminator.case_count * 2u + 1, sm6)))
8082 return;
8083 src_param_init(&src_params[0]);
8084 src_params[0].reg = block->terminator.conditional_reg;
8085 /* TODO: emit the merge block id. */
8086 vsir_src_param_init_label(&src_params[2], 0);
8087
8088 for (i = 0, count = 3; i < block->terminator.case_count; ++i)
8089 {
8090 const struct terminator_case *switch_case;
8091 const struct sm6_block *case_block;
8092
8093 switch_case = &block->terminator.cases[i];
8094 if (!(case_block = switch_case->block))
8095 {
8096 VKD3D_ASSERT(sm6->p.failed);
8097 continue;
8098 }
8099 if (switch_case->is_default)
8100 {
8101 vsir_src_param_init_label(&src_params[1], case_block->id);
8102 continue;
8103 }
8104
8105 if (src_params[0].reg.data_type == VKD3D_DATA_UINT64)
8106 {
8108 src_params[count++].reg.u.immconst_u64[0] = switch_case->value;
8109 }
8110 else
8111 {
8112 if (switch_case->value > UINT_MAX)
8113 {
8114 WARN("Truncating 64-bit constant %"PRIx64".\n", switch_case->value);
8116 "Truncating 64-bit switch case value %"PRIx64" to 32 bits.", switch_case->value);
8117 }
8119 src_params[count++].reg.u.immconst_u32[0] = switch_case->value;
8120 }
8121 vsir_src_param_init_label(&src_params[count++], case_block->id);
8122 }
8123
8124 break;
8125
8126 case TERMINATOR_RET:
8128 break;
8129
8130 default:
8132 }
8133}
8134
8135static void sm6_block_emit_phi(const struct sm6_block *block, struct sm6_parser *sm6)
8136{
8137 struct vkd3d_shader_instruction *ins;
8138 unsigned int i, j, incoming_count;
8139 const struct sm6_phi *src_phi;
8140
8141 for (i = 0; i < block->phi_count; ++i)
8142 {
8143 struct vkd3d_shader_src_param *src_params;
8144 struct vkd3d_shader_dst_param *dst_param;
8145
8146 src_phi = &block->phi[i];
8147 incoming_count = src_phi->incoming_count;
8148
8150 if (!(src_params = instruction_src_params_alloc(ins, incoming_count * 2u, sm6)))
8151 return;
8152 if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6)))
8153 return;
8154
8155 for (j = 0; j < incoming_count; ++j)
8156 {
8157 const struct sm6_block *incoming_block = src_phi->incoming[j].block;
8158 unsigned int index = j * 2;
8159
8160 src_param_init(&src_params[index]);
8161 src_params[index].reg = src_phi->incoming[j].reg;
8162 if (incoming_block)
8163 vsir_src_param_init_label(&src_params[index + 1], incoming_block->id);
8164 else
8165 VKD3D_ASSERT(sm6->p.failed);
8166 }
8167
8168 dst_param_init(dst_param);
8169 dst_param->reg = src_phi->reg;
8170 }
8171}
8172
8173static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const struct dxil_block *block,
8174 unsigned int level)
8175{
8176 size_t i, old_value_count = sm6->value_count;
8177 struct sm6_function *function;
8178 enum vkd3d_result ret;
8179
8180 for (i = 0; i < block->child_block_count; ++i)
8181 {
8182 if ((ret = sm6_parser_module_init(sm6, block->child_blocks[i], level + 1)) < 0)
8183 return ret;
8184 }
8185
8186 sm6->p.location.line = block->id;
8187 sm6->p.location.column = 0;
8188
8190
8191 switch (block->id)
8192 {
8193 case CONSTANTS_BLOCK:
8194 /* Level 1 (global) constants are already done in sm6_parser_globals_init(). */
8195 if (level < 2)
8196 break;
8197 function = &sm6->functions[sm6->function_count];
8198 sm6->cur_max_value = function->value_count;
8199 return sm6_parser_constants_init(sm6, block);
8200
8201 case FUNCTION_BLOCK:
8202 function = &sm6->functions[sm6->function_count];
8203 if ((ret = sm6_parser_function_init(sm6, block, function)) < 0)
8204 return ret;
8205 /* The value index returns to its previous value after handling a function. It's usually nonzero
8206 * at the start because of global constants/variables/function declarations. Function constants
8207 * occur in a child block, so value_count is already saved before they are emitted. */
8208 memset(&sm6->values[old_value_count], 0, (sm6->value_count - old_value_count) * sizeof(*sm6->values));
8209 sm6->value_count = old_value_count;
8210 break;
8211
8212 case BLOCKINFO_BLOCK:
8213 case MODULE_BLOCK:
8214 case PARAMATTR_BLOCK:
8216 case VALUE_SYMTAB_BLOCK:
8217 case METADATA_BLOCK:
8219 case TYPE_BLOCK:
8220 break;
8221
8222 default:
8223 FIXME("Unhandled block id %u.\n", block->id);
8224 break;
8225 }
8226
8227 return VKD3D_OK;
8228}
8229
8230static void sm6_parser_emit_label(struct sm6_parser *sm6, unsigned int label_id)
8231{
8232 struct vkd3d_shader_src_param *src_param;
8233 struct vkd3d_shader_instruction *ins;
8234
8236
8237 if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
8238 return;
8239 vsir_src_param_init_label(src_param, label_id);
8240}
8241
8242static enum vkd3d_result sm6_function_emit_blocks(const struct sm6_function *function, struct sm6_parser *sm6)
8243{
8244 struct vsir_program *program = sm6->p.program;
8245 unsigned int i;
8246
8247 program->block_count = function->block_count;
8248
8249 for (i = 0; i < function->block_count; ++i)
8250 {
8251 const struct sm6_block *block = function->blocks[i];
8252
8253 /* Space for the label and terminator. */
8254 if (!sm6_parser_require_space(sm6, block->instruction_count + block->phi_count + 2))
8255 {
8257 "Out of memory emitting shader instructions.");
8259 }
8260 sm6_parser_emit_label(sm6, block->id);
8262
8263 memcpy(&program->instructions.elements[program->instructions.count], block->instructions,
8264 block->instruction_count * sizeof(*block->instructions));
8265 program->instructions.count += block->instruction_count;
8266
8268 }
8269
8270 return VKD3D_OK;
8271}
8272
8274{
8275 struct dxil_block *block;
8276 unsigned int i, j, count;
8277
8278 for (i = 0, count = 0; i < sm6->root_block.child_block_count; ++i)
8279 {
8280 block = sm6->root_block.child_blocks[i];
8281 if (block->id != METADATA_BLOCK)
8282 continue;
8283 for (j = 0; j < block->record_count; ++j)
8284 count += block->records[j]->code == METADATA_NAMED_NODE;
8285 }
8286
8287 if (!count)
8288 return true;
8289
8290 return !!(sm6->named_metadata = vkd3d_calloc(count, sizeof(*sm6->named_metadata)));
8291}
8292
8294 unsigned int dst_idx, unsigned int end_count, const struct dxil_record *record, struct sm6_parser *sm6)
8295{
8296 struct sm6_metadata_node *node;
8297 unsigned int i, offset;
8298
8299 m->type = VKD3D_METADATA_NODE;
8300 if (!(m->value_type = sm6->metadata_type))
8301 {
8302 WARN("Metadata type not found.\n");
8304 "The type for metadata values was not found.");
8306 }
8307 if (!(node = vkd3d_malloc(offsetof(struct sm6_metadata_node, operands[record->operand_count]))))
8308 {
8309 ERR("Failed to allocate metadata node with %u operands.\n", record->operand_count);
8311 "Out of memory allocating a metadata node with %u operands.", record->operand_count);
8313 }
8314 m->u.node = node;
8315
8316 node->is_distinct = record->code == METADATA_DISTINCT_NODE;
8317
8319
8320 for (i = 0; i < record->operand_count; ++i)
8321 {
8322 uint64_t ref;
8323
8324 ref = record->operands[i] - offset;
8325 if (record->operands[i] >= offset && ref >= end_count)
8326 {
8327 WARN("Invalid metadata index %"PRIu64".\n", ref);
8329 "Metadata index %"PRIu64" is invalid.", ref);
8332 }
8333
8334 if (!node->is_distinct && ref == dst_idx)
8335 {
8336 WARN("Metadata self-reference at index %u.\n", dst_idx);
8338 "Metadata index %u is self-referencing.", dst_idx);
8341 }
8342
8343 node->operands[i] = (record->operands[i] >= offset) ? &table->values[ref] : NULL;
8345 {
8346 WARN("Named node operand is not a node.\n");
8348 "The operand of a metadata named node is not a node.");
8351 }
8352 }
8353
8354 node->operand_count = record->operand_count;
8355
8356 return VKD3D_OK;
8357}
8358
8359static enum vkd3d_result sm6_parser_metadata_init(struct sm6_parser *sm6, const struct dxil_block *block,
8360 struct sm6_metadata_table *table)
8361{
8362 unsigned int i, count, table_idx, value_idx;
8363 struct sm6_metadata_value *values, *m;
8364 const struct dxil_record *record;
8365 const struct sm6_value *value;
8366 enum vkd3d_result ret;
8367 char *name;
8368
8369 for (i = 0, count = 0; i < block->record_count; ++i)
8370 count += block->records[i]->code != METADATA_NAME;
8371
8372 if (!(values = vkd3d_calloc(count, sizeof(*values))))
8373 {
8374 ERR("Failed to allocate metadata tables.\n");
8376 "Out of memory allocating metadata tables.");
8378 }
8379 table->values = values;
8380
8381 for (i = 0, name = NULL; i < block->record_count; ++i)
8382 {
8383 record = block->records[i];
8384
8385 table_idx = table->count;
8386 m = &values[table_idx];
8387
8388 switch (record->code)
8389 {
8391 if (!name)
8392 {
8393 WARN("Named node has no name.\n");
8395 "A metadata named node has no name.");
8397 }
8398
8399 /* When DXC emits metadata value array reference indices it assumes named nodes
8400 * are not included in the array. Store named nodes separately. */
8401 m = &sm6->named_metadata[sm6->named_metadata_count].value;
8402 sm6->named_metadata[sm6->named_metadata_count].name = name;
8403 name = NULL;
8404
8406 return ret;
8407 ++sm6->named_metadata_count;
8408 /* Skip incrementing the table count. */
8409 continue;
8410
8412 case METADATA_NODE:
8413 if ((ret = metadata_value_create_node(m, table, table_idx, count, record, sm6)) < 0)
8414 return ret;
8415 break;
8416
8417 case METADATA_KIND:
8420
8421 m->type = VKD3D_METADATA_KIND;
8422 m->u.kind.id = record->operands[0];
8423 if (!(m->u.kind.name = dxil_record_to_string(record, 1, sm6)))
8424 {
8425 ERR("Failed to allocate name of a kind.\n");
8427 }
8428 break;
8429
8430 case METADATA_NAME:
8431 /* Check the next record to avoid freeing 'name' in all exit paths. */
8432 if (i + 1 == block->record_count || block->records[i + 1]->code != METADATA_NAMED_NODE)
8433 {
8434 WARN("Name is not followed by a named node.\n");
8436 "A metadata node name is not followed by a named node.");
8438 }
8439 /* LLVM allows an empty string here. */
8440 if (!(name = dxil_record_to_string(record, 0, sm6)))
8441 {
8442 ERR("Failed to allocate name.\n");
8444 }
8445 continue;
8446
8447 case METADATA_STRING:
8448 /* LLVM allows an empty string here. */
8449 m->type = VKD3D_METADATA_STRING;
8450 if (!(m->u.string_value = dxil_record_to_string(record, 0, sm6)))
8451 {
8452 ERR("Failed to allocate string.\n");
8454 }
8455 break;
8456
8457 case METADATA_VALUE:
8460
8461 m->type = VKD3D_METADATA_VALUE;
8462 if (!(m->value_type = sm6_parser_get_type(sm6, record->operands[0])))
8464
8465 if (record->operands[1] > UINT_MAX)
8466 WARN("Truncating value index %"PRIu64".\n", record->operands[1]);
8467 value_idx = record->operands[1];
8468 if (!(value = sm6_parser_get_value_safe(sm6, value_idx)))
8470
8473 {
8474 WARN("Value at index %u is not a constant or a function declaration.\n", value_idx);
8476 "Metadata value at index %u is not a constant or a function declaration.", value_idx);
8478 }
8479 m->u.value = value;
8480
8481 if (value->type != m->value_type)
8482 {
8483 WARN("Type mismatch.\n");
8485 "The type of a metadata value does not match its referenced value at index %u.", value_idx);
8486 }
8487
8488 break;
8489
8490 default:
8491 FIXME("Unhandled metadata type %u.\n", record->code);
8493 "Metadata type %u is unhandled.", record->code);
8495 }
8496 ++table->count;
8497 }
8498
8499 return VKD3D_OK;
8500}
8501
8503{
8504 switch (type)
8505 {
8506 case COMPONENT_TYPE_I1:
8508 case COMPONENT_TYPE_I16:
8509 case COMPONENT_TYPE_I32:
8511 case COMPONENT_TYPE_U16:
8512 case COMPONENT_TYPE_U32:
8514 case COMPONENT_TYPE_F16:
8515 case COMPONENT_TYPE_F32:
8519 case COMPONENT_TYPE_F64:
8523 default:
8524 FIXME("Unhandled component type %u.\n", type);
8526 }
8527}
8528
8530{
8531 switch (type)
8532 {
8533 case COMPONENT_TYPE_F16:
8535 case COMPONENT_TYPE_I16:
8537 case COMPONENT_TYPE_U16:
8539 default:
8541 }
8542}
8543
8545{
8560};
8561
8564{
8565 if (kind == SEMANTIC_KIND_TESSFACTOR)
8566 {
8567 switch (domain)
8568 {
8575 default:
8576 /* Error is handled during parsing. */
8578 }
8579 }
8580 else if (kind == SEMANTIC_KIND_INSIDETESSFACTOR)
8581 {
8582 switch (domain)
8583 {
8590 default:
8591 /* Error is handled during parsing. */
8593 }
8594 }
8595 else if (kind < ARRAY_SIZE(sysval_semantic_table))
8596 {
8597 return sysval_semantic_table[kind];
8598 }
8599 else
8600 {
8601 return VKD3D_SHADER_SV_NONE;
8602 }
8603}
8604
8605static const struct sm6_metadata_value *sm6_parser_find_named_metadata(struct sm6_parser *sm6, const char *name)
8606{
8607 const struct sm6_metadata_node *node;
8608 unsigned int i;
8609
8610 for (i = 0; i < sm6->named_metadata_count; ++i)
8611 {
8612 if (strcmp(sm6->named_metadata[i].name, name))
8613 continue;
8614
8615 node = sm6->named_metadata[i].value.u.node;
8616 if (!node->operand_count)
8617 return NULL;
8618 if (node->operand_count > 1)
8619 {
8620 FIXME("Ignoring %u extra operands for %s.\n", node->operand_count - 1, name);
8622 "Ignoring %u extra operands for metadata node %s.", node->operand_count - 1, name);
8623 }
8624 return node->operands[0];
8625 }
8626
8627 return NULL;
8628}
8629
8632{
8633 unsigned int size;
8634
8635 if (!sm6_metadata_value_is_value(node->operands[1]))
8636 {
8637 WARN("Resource data type is not a value.\n");
8638 return false;
8639 }
8640 if (!sm6_type_is_pointer(node->operands[1]->value_type))
8641 {
8642 WARN("Resource type is not a pointer.\n");
8644 "Resource metadata value type is not a pointer.");
8645 }
8646
8647 if (!sm6_metadata_get_uint_value(sm6, node->operands[3], &range->space))
8648 {
8649 WARN("Failed to load register space.\n");
8650 return false;
8651 }
8652 if (!sm6_metadata_get_uint_value(sm6, node->operands[4], &range->first))
8653 {
8654 WARN("Failed to load register first.\n");
8655 return false;
8656 }
8657 if (!sm6_metadata_get_uint_value(sm6, node->operands[5], &size))
8658 {
8659 WARN("Failed to load register range size.\n");
8660 return false;
8661 }
8662 if (!size || (size != UINT_MAX && !vkd3d_bound_range(range->first, size, UINT_MAX)))
8663 {
8664 WARN("Invalid register range, first %u, size %u.\n", range->first, size);
8665 return false;
8666 }
8667 range->last = (size == UINT_MAX) ? UINT_MAX : range->first + size - 1;
8668
8669 return true;
8670}
8671
8673{
8674 if (resource_kind_is_texture(kind))
8675 return kind + 1;
8676
8677 switch (kind)
8678 {
8683 default:
8685 }
8686}
8687
8689{
8709};
8710
8712 struct sm6_parser *sm6)
8713{
8715
8717 {
8718 FIXME("Unhandled component type %u.\n", type);
8720 "Resource descriptor component type %u is unhandled.", type);
8721 return VKD3D_DATA_FLOAT;
8722 }
8723
8724 return data_type;
8725}
8726
8728{
8730 unsigned int byte_stride;
8731};
8732
8734 const struct sm6_metadata_node *node, enum dxil_resource_kind kind, struct sm6_parser *sm6)
8735{
8736 unsigned int i, operand_count, tag, value;
8737
8738 info->data_type = VKD3D_DATA_UNUSED;
8739 info->byte_stride = 0;
8740
8741 if (node->operand_count & 1)
8742 {
8743 WARN("Operand count is not even.\n");
8745 "Operand count for resource descriptor tag/value pairs is not even.");
8746 }
8747 operand_count = node->operand_count & ~1u;
8748
8749 for (i = 0; i < operand_count; i += 2)
8750 {
8751 if (!sm6_metadata_get_uint_value(sm6, node->operands[i], &tag)
8752 || !sm6_metadata_get_uint_value(sm6, node->operands[i + 1], &value))
8753 {
8754 WARN("Failed to load tag/value pair at index %u.\n", i);
8756 "Resource descriptor tag/value pair at index %u is not an integer pair.", i);
8757 return false;
8758 }
8759
8760 switch (tag)
8761 {
8764 {
8765 WARN("Invalid type %u for an untyped resource.\n", value);
8767 "An untyped resource has type %u.", value);
8768 return false;
8769 }
8771 break;
8772
8775 {
8776 WARN("Invalid stride %u for an unstructured resource.\n", value);
8778 "An unstructured resource has a byte stride.");
8779 return false;
8780 }
8781 info->byte_stride = value;
8782 break;
8783
8785 /* MinMip = 0, MipRegionUsed = 1 */
8786 FIXME("Unhandled sampler feedback kind %u.\n", value);
8788 "Sampler feedback kind %u is unhandled.", value);
8789 break;
8790
8792 if (value)
8793 {
8794 FIXME("Unsupported 64-bit atomic ops.\n");
8796 "64-bit atomic ops on resources are not supported.");
8797 }
8798 break;
8799
8800 default:
8801 FIXME("Unhandled tag %u, value %u.\n", tag, value);
8803 "Tag %u for resource descriptor additional value %u is unhandled.", tag, value);
8804 break;
8805 }
8806 }
8807
8808 return true;
8809}
8810
8812 const struct sm6_metadata_value *type_value, bool is_uav, enum dxil_resource_kind kind,
8813 const struct sm6_metadata_value *m, struct vkd3d_shader_instruction *ins)
8814{
8815 struct resource_additional_values resource_values;
8816 enum vkd3d_shader_resource_type resource_type;
8817 unsigned int i;
8818
8819 if (!(resource_type = shader_resource_type_from_dxil_resource_kind(kind)))
8820 {
8821 FIXME("Unhandled resource kind %u.\n", kind);
8823 "Resource kind %u is unhandled.", kind);
8824 return NULL;
8825 }
8826 ins->resource_type = resource_type;
8827
8828 if (!m)
8829 {
8831 ins->declaration.raw_resource.resource.reg.write_mask = 0;
8832 return &ins->declaration.raw_resource.resource;
8833 }
8834
8836 {
8837 WARN("Resource metadata list is not a node.\n");
8839 "Resource descriptor metadata list is not a node.");
8840 return NULL;
8841 }
8842
8843 if (!resources_load_additional_values(&resource_values, m->u.node, kind, sm6))
8844 return NULL;
8845
8847 {
8848 if (resource_values.data_type == VKD3D_DATA_UNUSED)
8849 {
8850 WARN("No data type defined.\n");
8852 "A typed resource has no data type.");
8853 }
8854
8855 ins->opcode = is_uav ? VKD3DSIH_DCL_UAV_TYPED : VKD3DSIH_DCL;
8856 for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
8857 ins->declaration.semantic.resource_data_type[i] = resource_values.data_type;
8858 ins->declaration.semantic.resource_type = resource_type;
8859 ins->declaration.semantic.resource.reg.write_mask = VKD3DSP_WRITEMASK_ALL;
8860
8861 return &ins->declaration.semantic.resource;
8862 }
8863 else if (kind == RESOURCE_KIND_RAWBUFFER)
8864 {
8866 ins->declaration.raw_resource.resource.reg.write_mask = 0;
8867
8868 return &ins->declaration.raw_resource.resource;
8869 }
8870 else if (kind == RESOURCE_KIND_STRUCTUREDBUFFER)
8871 {
8873 ins->declaration.structured_resource.byte_stride = resource_values.byte_stride;
8874 ins->declaration.structured_resource.resource.reg.write_mask = 0;
8875
8876 /* TODO: 16-bit resources. */
8877 if (ins->declaration.structured_resource.byte_stride % 4u)
8878 {
8879 WARN("Byte stride %u is not a multiple of 4.\n", ins->declaration.structured_resource.byte_stride);
8881 "Structured resource byte stride %u is not a multiple of 4.",
8882 ins->declaration.structured_resource.byte_stride);
8883 }
8884
8885 return &ins->declaration.structured_resource.resource;
8886 }
8887 else
8888 {
8889 FIXME("Unhandled resource kind %u.\n", kind);
8891 "Resource kind %u is unhandled.", kind);
8892 }
8893
8894 return NULL;
8895}
8896
8899 const struct vkd3d_shader_register_range *range)
8900{
8901 struct vkd3d_shader_dst_param *param = &resource->reg;
8902
8903 param->modifiers = 0;
8904 param->shift = 0;
8906 param->reg.idx[0].offset = id;
8907 param->reg.idx[1].offset = range->first;
8908 param->reg.idx[2].offset = range->last;
8909
8910 resource->range = *range;
8911}
8912
8914 const struct sm6_metadata_node *node, struct sm6_descriptor_info *d, struct vkd3d_shader_instruction *ins)
8915{
8917 unsigned int kind;
8918
8919 if (node->operand_count < 9)
8920 {
8921 WARN("Invalid operand count %u.\n", node->operand_count);
8923 "Invalid operand count %u for an SRV descriptor.", node->operand_count);
8925 }
8926 if (node->operand_count > 9)
8927 {
8928 WARN("Ignoring %u extra operands.\n", node->operand_count - 9);
8930 "Ignoring %u extra operands for an SRV descriptor.", node->operand_count - 9);
8931 }
8932
8933 if (!sm6_metadata_get_uint_value(sm6, node->operands[6], &kind))
8934 {
8935 WARN("Failed to load resource type.\n");
8937 "SRV resource type metadata value is not an integer.");
8939 }
8940
8941 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_INVALID);
8942
8943 if (!(resource = sm6_parser_resources_load_common_info(sm6, node->operands[1], false, kind,
8944 node->operands[8], ins)))
8945 {
8947 }
8948
8949 d->resource_type = ins->resource_type;
8950 d->kind = kind;
8951 d->reg_type = VKD3DSPR_RESOURCE;
8952 d->reg_data_type = VKD3D_DATA_UNUSED;
8953 d->resource_data_type = (ins->opcode == VKD3DSIH_DCL)
8954 ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED;
8955
8956 init_resource_declaration(resource, VKD3DSPR_RESOURCE, d->reg_data_type, d->id, &d->range);
8957
8959 {
8960 if (!sm6_metadata_get_uint_value(sm6, node->operands[7], &ins->declaration.semantic.sample_count))
8961 {
8962 WARN("Failed to load sample count.\n");
8964 "SRV sample count metadata value is not an integer.");
8966 }
8967 }
8968 else if (!sm6_metadata_value_is_zero_or_undef(node->operands[7]))
8969 {
8970 WARN("Ignoring sample count value.\n");
8972 "Ignoring an SRV descriptor sample count metadata value which is not constant zero or undefined.");
8973 }
8974
8975 return VKD3D_OK;
8976}
8977
8979 const struct sm6_metadata_node *node, struct sm6_descriptor_info *d, struct vkd3d_shader_instruction *ins)
8980{
8982 unsigned int i, values[4];
8983
8984 if (node->operand_count < 11)
8985 {
8986 WARN("Invalid operand count %u.\n", node->operand_count);
8988 "Invalid operand count %u for a UAV descriptor.", node->operand_count);
8990 }
8991 if (node->operand_count > 11)
8992 {
8993 WARN("Ignoring %u extra operands.\n", node->operand_count - 11);
8995 "Ignoring %u extra operands for a UAV descriptor.", node->operand_count - 11);
8996 }
8997
8998 for (i = 6; i < 10; ++i)
8999 {
9000 if (!sm6_metadata_get_uint_value(sm6, node->operands[i], &values[i - 6]))
9001 {
9002 WARN("Failed to load uint value at index %u.\n", i);
9004 "A UAV descriptor operand metadata value is not an integer.");
9006 }
9007 }
9008
9009 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_INVALID);
9010 if (values[1])
9012 if (values[2])
9014 if (values[3])
9016
9017 if (!(resource = sm6_parser_resources_load_common_info(sm6, node->operands[1], true, values[0],
9018 node->operands[10], ins)))
9019 {
9021 }
9022
9023 d->resource_type = ins->resource_type;
9024 d->kind = values[0];
9025 d->reg_type = VKD3DSPR_UAV;
9026 d->reg_data_type = VKD3D_DATA_UNUSED;
9027 d->resource_data_type = (ins->opcode == VKD3DSIH_DCL_UAV_TYPED)
9028 ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED;
9029
9030 init_resource_declaration(resource, VKD3DSPR_UAV, d->reg_data_type, d->id, &d->range);
9031
9032 return VKD3D_OK;
9033}
9034
9036 const struct sm6_metadata_node *node, struct sm6_descriptor_info *d, struct vkd3d_shader_instruction *ins)
9037{
9038 struct vkd3d_shader_register *reg;
9039 unsigned int buffer_size;
9040
9041 if (node->operand_count < 7)
9042 {
9043 WARN("Invalid operand count %u.\n", node->operand_count);
9045 "Invalid operand count %u for a CBV descriptor.", node->operand_count);
9047 }
9048 if (node->operand_count > 7 && node->operands[7])
9049 {
9050 WARN("Ignoring %u extra operands.\n", node->operand_count - 7);
9052 "Ignoring %u extra operands for a CBV descriptor.", node->operand_count - 7);
9053 }
9054
9055 if (!sm6_metadata_get_uint_value(sm6, node->operands[6], &buffer_size))
9056 {
9057 WARN("Failed to load buffer size.\n");
9059 "Constant buffer size metadata value is not an integer.");
9061 }
9062
9065 ins->declaration.cb.size = buffer_size;
9066 ins->declaration.cb.src.swizzle = VKD3D_SHADER_NO_SWIZZLE;
9067 ins->declaration.cb.src.modifiers = VKD3DSPSM_NONE;
9068
9069 reg = &ins->declaration.cb.src.reg;
9071 reg->idx[0].offset = d->id;
9072 reg->idx[1].offset = d->range.first;
9073 reg->idx[2].offset = d->range.last;
9074
9075 ins->declaration.cb.range = d->range;
9076
9077 d->reg_type = VKD3DSPR_CONSTBUFFER;
9078 d->reg_data_type = VKD3D_DATA_FLOAT;
9079 d->resource_data_type = VKD3D_DATA_FLOAT;
9080
9081 return VKD3D_OK;
9082}
9083
9085 const struct sm6_metadata_node *node, struct sm6_descriptor_info *d, struct vkd3d_shader_instruction *ins)
9086{
9087 struct vkd3d_shader_register *reg;
9088 unsigned int kind;
9089
9090 if (node->operand_count < 7)
9091 {
9092 WARN("Invalid operand count %u.\n", node->operand_count);
9094 "Invalid operand count %u for a sampler descriptor.", node->operand_count);
9096 }
9097 if (node->operand_count > 7 && node->operands[7])
9098 {
9099 WARN("Ignoring %u extra operands.\n", node->operand_count - 7);
9101 "Ignoring %u extra operands for a sampler descriptor.", node->operand_count - 7);
9102 }
9103
9104 vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DCL_SAMPLER);
9106
9107 if (!sm6_metadata_get_uint_value(sm6, node->operands[6], &kind))
9108 {
9109 WARN("Failed to load sampler mode.\n");
9111 "Sampler mode metadata value is not an integer.");
9113 }
9114 switch (kind)
9115 {
9117 break;
9120 break;
9121 default:
9122 FIXME("Ignoring sampler kind %u.\n", kind);
9124 "Ignoring sampler kind %u.", kind);
9125 break;
9126 }
9127
9128 ins->declaration.sampler.src.swizzle = VKD3D_SHADER_NO_SWIZZLE;
9129 ins->declaration.sampler.src.modifiers = VKD3DSPSM_NONE;
9130
9131 reg = &ins->declaration.sampler.src.reg;
9133 reg->idx[0].offset = d->id;
9134 reg->idx[1].offset = d->range.first;
9135 reg->idx[2].offset = d->range.last;
9136
9137 ins->declaration.sampler.range = d->range;
9138
9139 d->resource_type = ins->resource_type;
9140 d->kind = RESOURCE_KIND_SAMPLER;
9141 d->reg_type = VKD3DSPR_SAMPLER;
9142 d->reg_data_type = VKD3D_DATA_UNUSED;
9143 d->resource_data_type = VKD3D_DATA_UNUSED;
9144
9145 return VKD3D_OK;
9146}
9147
9149 enum vkd3d_shader_descriptor_type type, const struct sm6_metadata_node *descriptor_node)
9150{
9151 struct vkd3d_shader_instruction *ins;
9152 const struct sm6_metadata_node *node;
9153 const struct sm6_metadata_value *m;
9154 struct sm6_descriptor_info *d;
9155 enum vkd3d_result ret;
9156 unsigned int i;
9157
9158 for (i = 0; i < descriptor_node->operand_count; ++i)
9159 {
9160 m = descriptor_node->operands[i];
9162 {
9163 WARN("Resource descriptor is not a node.\n");
9165 "Resource descriptor is not a metadata node.");
9167 }
9168
9169 node = m->u.node;
9170 if (node->operand_count < 6)
9171 {
9172 WARN("Invalid operand count %u.\n", node->operand_count);
9174 "Invalid operand count %u for a descriptor.", node->operand_count);
9176 }
9177
9178 if (!vkd3d_array_reserve((void **)&sm6->descriptors, &sm6->descriptor_capacity,
9179 sm6->descriptor_count + 1, sizeof(*sm6->descriptors)))
9180 {
9181 ERR("Failed to allocate descriptor array.\n");
9183 "Out of memory allocating the descriptor array.");
9185 }
9186 d = &sm6->descriptors[sm6->descriptor_count];
9187 d->type = type;
9188
9189 if (!sm6_metadata_get_uint_value(sm6, node->operands[0], &d->id))
9190 {
9191 WARN("Failed to load resource id.\n");
9193 "Resource id metadata value is not an integer.");
9195 }
9196
9198 {
9200 "Resource register range is invalid.");
9202 }
9203
9204 if (!(ins = sm6_parser_require_space(sm6, 1)))
9205 {
9206 ERR("Failed to allocate instruction.\n");
9208 }
9209
9210 switch (type)
9211 {
9213 if ((ret = sm6_parser_resources_load_cbv(sm6, node, d, ins)) < 0)
9214 return ret;
9215 break;
9217 if ((ret = sm6_parser_resources_load_srv(sm6, node, d, ins)) < 0)
9218 return ret;
9219 break;
9221 if ((ret = sm6_parser_resources_load_uav(sm6, node, d, ins)) < 0)
9222 return ret;
9223 break;
9225 if ((ret = sm6_parser_resources_load_sampler(sm6, node, d, ins)) < 0)
9226 return ret;
9227 break;
9228 default:
9229 FIXME("Unsupported descriptor type %u.\n", type);
9231 "Resource descriptor type %u is unsupported.", type);
9233 }
9234
9235 ++sm6->descriptor_count;
9236 ++sm6->p.program->instructions.count;
9237 }
9238
9239 return VKD3D_OK;
9240}
9241
9243{
9244 const struct sm6_metadata_value *m = sm6_parser_find_named_metadata(sm6, "dx.resources");
9246 const struct sm6_metadata_node *node;
9247 enum vkd3d_result ret;
9248
9249 if (!m)
9250 return VKD3D_OK;
9251
9252 node = m->u.node;
9253 if (node->operand_count != SHADER_DESCRIPTOR_TYPE_COUNT)
9254 {
9255 WARN("Unexpected descriptor type count %u.\n", node->operand_count);
9257 "Descriptor type count %u is invalid.", node->operand_count);
9259 }
9260
9262 {
9263 if (!(m = node->operands[type]))
9264 continue;
9265
9267 {
9268 WARN("Resource list is not a node.\n");
9270 "Resource list is not a metadata node.");
9272 }
9273
9274 if ((ret = sm6_parser_descriptor_type_init(sm6, type, m->u.node)) < 0)
9275 return ret;
9276 }
9277
9278 return VKD3D_OK;
9279}
9280
9282 const struct sm6_metadata_node *node, struct sm6_parser *sm6)
9283{
9284 unsigned int i, operand_count, value, tag;
9285
9286 if (node->operand_count < 11 || !node->operands[10])
9287 return;
9288
9289 if (!sm6_metadata_value_is_node(node->operands[10]))
9290 {
9291 WARN("Additional values list is not a node.\n");
9293 "Signature element additional values list is not a metadata node.");
9294 return;
9295 }
9296
9297 node = node->operands[10]->u.node;
9298 if (node->operand_count & 1)
9299 {
9300 WARN("Operand count is not even.\n");
9302 "Operand count for signature element additional tag/value pairs is not even.");
9303 }
9304 operand_count = node->operand_count & ~1u;
9305
9306 for (i = 0; i < operand_count; i += 2)
9307 {
9308 if (!sm6_metadata_get_uint_value(sm6, node->operands[i], &tag)
9309 || !sm6_metadata_get_uint_value(sm6, node->operands[i + 1], &value))
9310 {
9311 WARN("Failed to extract tag/value pair.\n");
9313 "Signature element tag/value pair at index %u is not an integer pair.", i);
9314 continue;
9315 }
9316
9317 switch (tag)
9318 {
9320 e->stream_index = value;
9321 break;
9323 /* A mask of components accessed via relative addressing. Seems to replace TPF 'dcl_index_range'. */
9325 {
9326 WARN("Invalid relative addressed mask %#x.\n", value);
9328 "Mask %#x of relative-addressed components is invalid.", value);
9329 }
9330 break;
9333 {
9334 WARN("Invalid used mask %#x.\n", value);
9336 "Mask %#x of used components is invalid.", value);
9338 }
9339 e->used_mask = value;
9340 break;
9341 default:
9342 FIXME("Unhandled tag %u, value %u.\n", tag, value);
9344 "Tag %#x for signature element additional value %#x is unhandled.", tag, value);
9345 break;
9346 }
9347 }
9348}
9349
9351 struct shader_signature *s, enum vkd3d_tessellator_domain tessellator_domain)
9352{
9353 unsigned int i, j, column_count, operand_count, index;
9354 const struct sm6_metadata_node *node, *element_node;
9355 struct signature_element *elements, *e;
9356 unsigned int values[10];
9357 bool is_register;
9358
9359 if (!m)
9360 return VKD3D_OK;
9361
9363 {
9364 WARN("Signature element list is not a node.\n");
9366 "Signature element list is not a metadata node.");
9368 }
9369
9370 node = m->u.node;
9371 operand_count = node->operand_count;
9372
9373 if (!(elements = vkd3d_calloc(operand_count, sizeof(*elements))))
9374 {
9375 ERR("Failed to allocate %u signature elements.\n", operand_count);
9377 "Out of memory allocating %u signature elements.", operand_count);
9379 }
9380
9381 for (i = 0; i < operand_count; ++i)
9382 {
9383 m = node->operands[i];
9384
9386 {
9387 WARN("Signature element is not a node.\n");
9389 "Signature element is not a metadata node.");
9390 goto invalid;
9391 }
9392
9393 element_node = m->u.node;
9394 if (element_node->operand_count < 10)
9395 {
9396 WARN("Invalid operand count %u.\n", element_node->operand_count);
9398 "Invalid signature element operand count %u.", element_node->operand_count);
9399 goto invalid;
9400 }
9401 if (element_node->operand_count > 11)
9402 {
9403 WARN("Ignoring %u extra operands.\n", element_node->operand_count - 11);
9405 "Ignoring %u extra operands for a signature element.", element_node->operand_count - 11);
9406 }
9407
9408 for (j = 0; j < 10; ++j)
9409 {
9410 /* 1 is the semantic name, 4 is semantic index metadata. */
9411 if (j == 1 || j == 4)
9412 continue;
9413 if (!sm6_metadata_get_uint_value(sm6, element_node->operands[j], &values[j]))
9414 {
9415 WARN("Failed to load uint value at index %u.\n", j);
9417 "Signature element value at index %u is not an integer.", j);
9418 goto invalid;
9419 }
9420 }
9421
9422 e = &elements[i];
9423
9424 if (values[0] != i)
9425 {
9426 FIXME("Unsupported element id %u not equal to its index %u.\n", values[0], i);
9428 "A non-sequential and non-zero-based element id is not supported.");
9429 goto invalid;
9430 }
9431
9432 if (!sm6_metadata_value_is_string(element_node->operands[1]))
9433 {
9434 WARN("Element name is not a string.\n");
9436 "Signature element name is not a metadata string.");
9437 goto invalid;
9438 }
9439 e->semantic_name = element_node->operands[1]->u.string_value;
9440
9443
9444 j = values[3];
9445 e->sysval_semantic = sysval_semantic_from_dxil_semantic_kind(j, tessellator_domain);
9446 if (j != SEMANTIC_KIND_ARBITRARY && j != SEMANTIC_KIND_TARGET && e->sysval_semantic == VKD3D_SHADER_SV_NONE)
9447 {
9448 WARN("Unhandled semantic kind %u.\n", j);
9450 "DXIL semantic kind %u is unhandled.", j);
9451 goto invalid;
9452 }
9453
9454 if ((e->interpolation_mode = values[5]) >= VKD3DSIM_COUNT)
9455 {
9456 WARN("Unhandled interpolation mode %u.\n", e->interpolation_mode);
9458 "Interpolation mode %u is unhandled.", e->interpolation_mode);
9459 goto invalid;
9460 }
9461
9462 e->register_count = values[6];
9463 column_count = values[7];
9464 e->register_index = values[8];
9465 e->target_location = e->register_index;
9466
9467 if ((is_register = e->register_index == UINT_MAX))
9468 {
9470 {
9471 WARN("Unhandled I/O register semantic kind %u.\n", j);
9473 "DXIL semantic kind %u is unhandled for an I/O register.", j);
9474 goto invalid;
9475 }
9476 }
9477 else if (e->register_index > MAX_REG_OUTPUT || e->register_count > MAX_REG_OUTPUT - e->register_index)
9478 {
9479 WARN("Invalid row start %u with row count %u.\n", e->register_index, e->register_count);
9481 "A signature element starting row of %u with count %u is invalid.",
9482 e->register_index, e->register_count);
9483 goto invalid;
9484 }
9485
9486 index = values[9];
9487 if (index != UINT8_MAX && (index >= VKD3D_VEC4_SIZE || column_count > VKD3D_VEC4_SIZE - index))
9488 {
9489 WARN("Invalid column start %u with count %u.\n", index, column_count);
9491 "A signature element starting column %u with count %u is invalid.", index, column_count);
9492 goto invalid;
9493 }
9494
9495 e->mask = vkd3d_write_mask_from_component_count(column_count);
9496 e->used_mask = e->mask;
9498
9499 if (index != UINT8_MAX)
9500 {
9501 e->mask <<= index;
9502 e->used_mask <<= index;
9503 }
9504
9505 /* DXIL reads/writes uint for bool I/O. */
9506 if (e->component_type == VKD3D_SHADER_COMPONENT_BOOL)
9507 e->component_type = VKD3D_SHADER_COMPONENT_UINT;
9508
9509 m = element_node->operands[4];
9511 {
9512 WARN("Semantic index list is not a node.\n");
9514 "Signature element semantic index list is not a metadata node.");
9515 goto invalid;
9516 }
9517
9518 element_node = m->u.node;
9519 for (j = 0; j < element_node->operand_count; ++j)
9520 {
9521 if (!sm6_metadata_get_uint_value(sm6, element_node->operands[j], &index))
9522 {
9523 WARN("Failed to get semantic index for row %u.\n", j);
9525 "Signature element semantic index for row %u is not an integer.", j);
9526 }
9527 else if (!j)
9528 {
9529 e->semantic_index = index;
9530 }
9531 else if (index != e->semantic_index + j)
9532 {
9533 WARN("Semantic index %u for row %u is not of an incrementing sequence.\n", index, j);
9535 "Signature element semantic index %u for row %u is not of an incrementing sequence.", index, j);
9536 }
9537 }
9538 }
9539
9540 for (i = 0; i < operand_count; ++i)
9541 {
9542 if ((elements[i].semantic_name = vkd3d_strdup(elements[i].semantic_name)))
9543 continue;
9544
9546 "Failed to allocate signature element semantic name.");
9547 for (j = 0; j < i; ++j)
9548 {
9549 vkd3d_free((void *)elements[j].semantic_name);
9550 }
9551 vkd3d_free(elements);
9553 }
9554
9556 s->elements = elements;
9557 s->element_count = operand_count;
9558
9559 return VKD3D_OK;
9560
9561invalid:
9562 vkd3d_free(elements);
9564}
9565
9567 enum vkd3d_tessellator_domain tessellator_domain)
9568{
9569 struct vsir_program *program = sm6->p.program;
9570 enum vkd3d_result ret;
9571
9573 {
9574 WARN("Signature table is not a node.\n");
9576 "Signature table is not a metadata node.");
9578 }
9579
9580 if (m->u.node->operand_count && (ret = sm6_parser_read_signature(sm6, m->u.node->operands[0],
9581 &program->input_signature, tessellator_domain)) < 0)
9582 {
9583 return ret;
9584 }
9585 if (m->u.node->operand_count > 1 && (ret = sm6_parser_read_signature(sm6, m->u.node->operands[1],
9586 &program->output_signature, tessellator_domain)) < 0)
9587 {
9588 return ret;
9589 }
9590 if (m->u.node->operand_count > 1 && (ret = sm6_parser_read_signature(sm6, m->u.node->operands[2],
9591 &program->patch_constant_signature, tessellator_domain)) < 0)
9592 {
9593 return ret;
9594 }
9595
9596 sm6_parser_init_input_signature(sm6, &program->input_signature);
9597 sm6_parser_init_output_signature(sm6, &program->output_signature);
9598 sm6_parser_init_patch_constant_signature(sm6, &program->patch_constant_signature);
9599
9600 return VKD3D_OK;
9601}
9602
9603static void sm6_parser_emit_global_flags(struct sm6_parser *sm6, const struct sm6_metadata_value *m)
9604{
9605 enum vsir_global_flags global_flags, mask, rotated_flags;
9606 struct vkd3d_shader_instruction *ins;
9607
9609 {
9610 WARN("Failed to load global flags.\n");
9612 "Global flags metadata value is not an integer.");
9613 return;
9614 }
9615 /* Rotate SKIP_OPTIMIZATION from bit 0 to bit 4 to match vsir_global_flags. */
9616 mask = (VKD3DSGF_SKIP_OPTIMIZATION << 1) - 1;
9617 rotated_flags = global_flags & mask;
9618 rotated_flags = (rotated_flags >> 1) | ((rotated_flags & 1) << 4);
9619 global_flags = (global_flags & ~mask) | rotated_flags;
9620
9623 sm6->p.program->global_flags = global_flags;
9624}
9625
9627{
9628 struct vkd3d_shader_version *version = &sm6->p.program->shader_version;
9629 const struct sm6_metadata_node *node;
9630 struct vkd3d_shader_instruction *ins;
9631 unsigned int group_sizes[3];
9632 unsigned int i;
9633
9635 {
9636 WARN("Shader of type %#x has thread group dimensions.\n", version->type);
9638 "Shader has thread group dimensions but is not a compute shader.");
9640 }
9641
9642 if (!m || !sm6_metadata_value_is_node(m))
9643 {
9644 WARN("Thread group dimension value is not a node.\n");
9646 "Thread group dimension metadata value is not a node.");
9648 }
9649
9650 node = m->u.node;
9651 if (node->operand_count != 3)
9652 {
9653 WARN("Invalid operand count %u.\n", node->operand_count);
9655 "Thread group dimension operand count %u is invalid.", node->operand_count);
9657 }
9658
9659 for (i = 0; i < 3; ++i)
9660 {
9661 if (!sm6_metadata_get_uint_value(sm6, node->operands[i], &group_sizes[i]))
9662 {
9663 WARN("Thread group dimension is not an integer value.\n");
9665 "Thread group dimension metadata value is not an integer.");
9667 }
9668 if (!group_sizes[i] || group_sizes[i] > dx_max_thread_group_size[i])
9669 {
9670 char dim = "XYZ"[i];
9671 WARN("Invalid thread group %c dimension %u.\n", dim, group_sizes[i]);
9673 "Thread group %c dimension %u is invalid.", dim, group_sizes[i]);
9675 }
9676 }
9677
9679 ins->declaration.thread_group_size.x = group_sizes[0];
9680 ins->declaration.thread_group_size.y = group_sizes[1];
9681 ins->declaration.thread_group_size.z = group_sizes[2];
9682 sm6->p.program->thread_group_size = ins->declaration.thread_group_size;
9683
9684 return VKD3D_OK;
9685}
9686
9687static void sm6_parser_emit_dcl_count(struct sm6_parser *sm6, enum vkd3d_shader_opcode handler_idx, unsigned int count)
9688{
9689 struct vkd3d_shader_instruction *ins;
9690
9691 ins = sm6_parser_add_instruction(sm6, handler_idx);
9692 ins->declaration.count = count;
9693}
9694
9697 unsigned int patch_vertex_count)
9698{
9699 struct vkd3d_shader_instruction *ins;
9700
9701 ins = sm6_parser_add_instruction(sm6, handler_idx);
9703 ins->declaration.primitive_type.patch_vertex_count = patch_vertex_count;
9704}
9705
9708{
9709 struct vkd3d_shader_instruction *ins;
9710
9712 {
9713 WARN("Unhandled domain %u.\n", tessellator_domain);
9715 "Domain shader tessellator domain %u is unhandled.", tessellator_domain);
9716 }
9717
9720}
9721
9722static void sm6_parser_validate_control_point_count(struct sm6_parser *sm6, unsigned int count,
9723 const char *type)
9724{
9725 if (!count || count > 32)
9726 {
9727 WARN("%s control point count %u invalid.\n", type, count);
9729 "%s control point count %u is invalid.", type, count);
9730 }
9731}
9732
9735{
9736 struct vkd3d_shader_instruction *ins;
9737
9739 {
9740 WARN("Unhandled partitioning %u.\n", tessellator_partitioning);
9742 "Hull shader tessellator partitioning %u is unhandled.", tessellator_partitioning);
9743 }
9744
9747}
9748
9751{
9752 struct vkd3d_shader_instruction *ins;
9753
9754 if (!primitive || primitive > VKD3D_SHADER_TESSELLATOR_OUTPUT_TRIANGLE_CCW)
9755 {
9756 WARN("Unhandled output primitive %u.\n", primitive);
9758 "Hull shader tessellator output primitive %u is unhandled.", primitive);
9759 }
9760
9763}
9764
9766{
9767 struct vkd3d_shader_instruction *ins;
9769
9771 {
9772 WARN("Max tess factor property is not a float value.\n");
9774 "Hull shader max tessellation factor property operand is not a float.");
9775 return;
9776 }
9777
9778 /* Exclude non-finite values. */
9779 if (!(max_tessellation_factor >= 1.0f && max_tessellation_factor <= 64.0f))
9780 {
9781 WARN("Invalid max tess factor %f.\n", max_tessellation_factor);
9783 "Hull shader max tessellation factor %f is invalid.", max_tessellation_factor);
9784 }
9785
9788}
9789
9790static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m)
9791{
9792 enum vkd3d_primitive_type input_primitive = VKD3D_PT_TRIANGLELIST, output_primitive;
9793 unsigned int i, input_control_point_count = 1, patch_vertex_count = 0;
9794 const struct sm6_metadata_node *node;
9795 unsigned int operands[5] = {0};
9796
9797 if (!m || !sm6_metadata_value_is_node(m))
9798 {
9799 WARN("Missing or invalid GS properties.\n");
9801 "Geometry shader properties node is missing or invalid.");
9802 return;
9803 }
9804
9805 node = m->u.node;
9806 if (node->operand_count < ARRAY_SIZE(operands))
9807 {
9808 WARN("Invalid operand count %u.\n", node->operand_count);
9810 "Geometry shader properties operand count %u is invalid.", node->operand_count);
9811 return;
9812 }
9813 if (node->operand_count > ARRAY_SIZE(operands))
9814 {
9815 WARN("Ignoring %zu extra operands.\n", node->operand_count - ARRAY_SIZE(operands));
9817 "Ignoring %zu extra operands for geometry shader properties.",
9818 node->operand_count - ARRAY_SIZE(operands));
9819 }
9820
9821 for (i = 0; i < node->operand_count; ++i)
9822 {
9823 if (!sm6_metadata_get_uint_value(sm6, node->operands[i], &operands[i]))
9824 {
9825 WARN("GS property at index %u is not a uint value.\n", i);
9827 "Geometry shader properties operand at index %u is not an integer.", i);
9828 }
9829 }
9830
9831 switch (i = operands[0])
9832 {
9834 input_primitive = VKD3D_PT_POINTLIST;
9835 input_control_point_count = 1;
9836 break;
9837
9839 input_primitive = VKD3D_PT_LINELIST;
9840 input_control_point_count = 2;
9841 break;
9842
9844 input_primitive = VKD3D_PT_TRIANGLELIST;
9845 input_control_point_count = 3;
9846 break;
9847
9849 input_primitive = VKD3D_PT_LINELIST_ADJ;
9850 input_control_point_count = 4;
9851 break;
9852
9854 input_primitive = VKD3D_PT_TRIANGLELIST_ADJ;
9855 input_control_point_count = 6;
9856 break;
9857
9858 default:
9860 {
9861 input_primitive = VKD3D_PT_PATCH;
9862 patch_vertex_count = i - INPUT_PRIMITIVE_PATCH1 + 1;
9863 break;
9864 }
9865
9866 WARN("Unhandled input primitive %u.\n", i);
9868 "Geometry shader input primitive %u is unhandled.", i);
9869 break;
9870 }
9871
9872 sm6_parser_emit_dcl_primitive_topology(sm6, VKD3DSIH_DCL_INPUT_PRIMITIVE, input_primitive, patch_vertex_count);
9873 sm6->p.program->input_control_point_count = input_control_point_count;
9874
9875 i = operands[1];
9876 /* Max total scalar count sets an upper limit. We would need to scan outputs to be more precise. */
9878 {
9879 WARN("GS output vertex count %u invalid.\n", i);
9881 "Geometry shader output vertex count %u is invalid.", i);
9882 }
9884
9885 if (operands[2] > 1)
9886 {
9887 FIXME("Unhandled stream mask %#x.\n", operands[2]);
9889 "Geometry shader stream mask %#x is unhandled.", operands[2]);
9890 }
9891
9892 output_primitive = operands[3];
9893 if (output_primitive == VKD3D_PT_UNDEFINED || output_primitive >= VKD3D_PT_COUNT)
9894 {
9895 WARN("Unhandled output primitive %u.\n", output_primitive);
9897 "Geometry shader output primitive %u is unhandled.", output_primitive);
9898 output_primitive = VKD3D_PT_TRIANGLELIST;
9899 }
9901
9902 i = operands[4];
9903 if (!i || i > MAX_GS_INSTANCE_COUNT)
9904 {
9905 WARN("GS instance count %u invalid.\n", i);
9907 "Geometry shader instance count %u is invalid.", i);
9908 }
9910}
9911
9913 const struct sm6_metadata_value *m)
9914{
9915 const struct sm6_metadata_node *node;
9916 unsigned int operands[2] = {0};
9917 unsigned int i;
9918
9919 if (!m || !sm6_metadata_value_is_node(m))
9920 {
9921 WARN("Missing or invalid DS properties.\n");
9923 "Domain shader properties node is missing or invalid.");
9924 return 0;
9925 }
9926
9927 node = m->u.node;
9928 if (node->operand_count < ARRAY_SIZE(operands))
9929 {
9930 WARN("Invalid operand count %u.\n", node->operand_count);
9932 "Domain shader properties operand count %u is invalid.", node->operand_count);
9933 return 0;
9934 }
9935 if (node->operand_count > ARRAY_SIZE(operands))
9936 {
9937 WARN("Ignoring %zu extra operands.\n", node->operand_count - ARRAY_SIZE(operands));
9939 "Ignoring %zu extra operands for domain shader properties.",
9940 node->operand_count - ARRAY_SIZE(operands));
9941 }
9942
9943 for (i = 0; i < node->operand_count; ++i)
9944 {
9945 if (!sm6_metadata_get_uint_value(sm6, node->operands[i], &operands[i]))
9946 {
9947 WARN("DS property at index %u is not a uint value.\n", i);
9949 "Domain shader properties operand at index %u is not an integer.", i);
9950 }
9951 }
9952
9954 sm6_parser_validate_control_point_count(sm6, operands[1], "Domain shader input");
9955 sm6->p.program->input_control_point_count = operands[1];
9956
9957 return operands[0];
9958}
9959
9961 const struct sm6_metadata_value *m)
9962{
9963 struct vsir_program *program = sm6->p.program;
9964 const struct sm6_metadata_node *node;
9965 unsigned int operands[6] = {0};
9966 unsigned int i;
9967
9968 if (!m || !sm6_metadata_value_is_node(m))
9969 {
9970 WARN("Missing or invalid HS properties.\n");
9972 "Hull shader properties node is missing or invalid.");
9973 return 0;
9974 }
9975
9976 node = m->u.node;
9977 if (node->operand_count < 7)
9978 {
9979 WARN("Invalid operand count %u.\n", node->operand_count);
9981 "Hull shader properties operand count %u is invalid.", node->operand_count);
9982 return 0;
9983 }
9984 if (node->operand_count > 7)
9985 {
9986 WARN("Ignoring %u extra operands.\n", node->operand_count - 7);
9988 "Ignoring %u extra operands for hull shader properties.", node->operand_count - 7);
9989 }
9990
9991 m = node->operands[0];
9993 {
9994 WARN("Patch constant function node is not a function value.\n");
9996 "Hull shader patch constant function node is not a function value.");
9997 }
9998 else
9999 {
10000 sm6->patch_constant_function = m->u.value->u.function.name;
10001 }
10002
10003 for (i = 1; i < min(node->operand_count, ARRAY_SIZE(operands)); ++i)
10004 {
10005 if (!sm6_metadata_get_uint_value(sm6, node->operands[i], &operands[i]))
10006 {
10007 WARN("HS property at index %u is not a uint value.\n", i);
10009 "Hull shader properties operand at index %u is not an integer.", i);
10010 }
10011 }
10012
10013 sm6_parser_validate_control_point_count(sm6, operands[1], "Hull shader input");
10014 program->input_control_point_count = operands[1];
10015 sm6_parser_validate_control_point_count(sm6, operands[2], "Hull shader output");
10017 program->output_control_point_count = operands[2];
10022
10023 return operands[3];
10024}
10025
10027{
10028 const struct sm6_metadata_value *m = sm6_parser_find_named_metadata(sm6, "dx.entryPoints");
10029 const struct sm6_metadata_node *node, *entry_node = m ? m->u.node : NULL;
10030 enum vkd3d_tessellator_domain tessellator_domain = 0;
10031 unsigned int i, operand_count, tag;
10032 const struct sm6_value *value;
10033 enum vkd3d_result ret;
10034
10035 if (!entry_node || entry_node->operand_count < 2 || !(m = entry_node->operands[0]))
10036 {
10037 WARN("No entry point definition found.\n");
10039 "No entry point definition found in the metadata.");
10041 }
10042
10043 if (m->type != VKD3D_METADATA_VALUE)
10044 {
10045 WARN("Entry point definition is not a value.\n");
10047 "Entry point definition is not a metadata value.");
10049 }
10050
10051 value = m->u.value;
10053 {
10054 WARN("Entry point value is not a function definition.\n");
10056 "Entry point metadata value does not contain a function definition.");
10058 }
10059
10060 sm6->entry_point = value->u.function.name;
10061 if (!sm6_metadata_value_is_string(entry_node->operands[1])
10062 || strcmp(sm6->entry_point, entry_node->operands[1]->u.string_value))
10063 {
10064 WARN("Entry point function name %s mismatch.\n", sm6->entry_point);
10066 "Entry point function name %s does not match the name in metadata.", sm6->entry_point);
10067 }
10068
10069 if (entry_node->operand_count >= 5 && (m = entry_node->operands[4]))
10070 {
10072 {
10073 WARN("Shader properties list is not a node.\n");
10075 "Shader properties tag/value list is not a metadata node.");
10077 }
10078
10079 node = m->u.node;
10080 if (node->operand_count & 1)
10081 {
10082 WARN("Operand count is not even.\n");
10084 "Operand count for shader properties tag/value pairs is not even.");
10085 }
10086 operand_count = node->operand_count & ~1u;
10087
10088 for (i = 0; i < operand_count; i += 2)
10089 {
10090 if (!sm6_metadata_get_uint_value(sm6, node->operands[i], &tag))
10091 {
10092 WARN("Tag is not an integer value.\n");
10094 "Shader properties tag at index %u is not an integer.", i);
10096 }
10097
10098 switch (tag)
10099 {
10101 sm6_parser_emit_global_flags(sm6, node->operands[i + 1]);
10102 break;
10104 sm6_parser_gs_properties_init(sm6, node->operands[i + 1]);
10105 break;
10107 tessellator_domain = sm6_parser_ds_properties_init(sm6, node->operands[i + 1]);
10108 break;
10110 tessellator_domain = sm6_parser_hs_properties_init(sm6, node->operands[i + 1]);
10111 break;
10113 if ((ret = sm6_parser_emit_thread_group(sm6, node->operands[i + 1])) < 0)
10114 return ret;
10115 break;
10116 default:
10117 FIXME("Unhandled tag %#x.\n", tag);
10119 "Shader properties tag %#x is unhandled.", tag);
10120 break;
10121 }
10122 }
10123 }
10124
10125 if (entry_node->operand_count >= 3 && (m = entry_node->operands[2])
10126 && (ret = sm6_parser_signatures_init(sm6, m, tessellator_domain)) < 0)
10127 {
10128 return ret;
10129 }
10130
10131 return VKD3D_OK;
10132}
10133
10135{
10136 switch (m->type)
10137 {
10139 vkd3d_free(m->u.node);
10140 break;
10142 vkd3d_free(m->u.kind.name);
10143 break;
10145 vkd3d_free(m->u.string_value);
10146 break;
10147 default:
10148 break;
10149 }
10150}
10151
10153{
10154 unsigned int i, j;
10155
10156 for (i = 0; i < ARRAY_SIZE(sm6->metadata_tables); ++i)
10157 {
10158 for (j = 0; j < sm6->metadata_tables[i].count; ++j)
10160 vkd3d_free(sm6->metadata_tables[i].values);
10161 }
10162 for (i = 0; i < sm6->named_metadata_count; ++i)
10163 {
10165 vkd3d_free(sm6->named_metadata[i].name);
10166 }
10168}
10169
10170static void sm6_type_table_cleanup(struct sm6_type *types, size_t count)
10171{
10172 size_t i;
10173
10174 if (!types)
10175 return;
10176
10177 for (i = 0; i < count; ++i)
10178 {
10179 switch (types[i].class)
10180 {
10181 case TYPE_CLASS_STRUCT:
10182 vkd3d_free((void *)types[i].u.struc->name);
10183 vkd3d_free(types[i].u.struc);
10184 break;
10186 vkd3d_free(types[i].u.function);
10187 break;
10188 default:
10189 break;
10190 }
10191 }
10192
10194}
10195
10196static void sm6_symtab_cleanup(struct sm6_symbol *symbols, size_t count)
10197{
10198 size_t i;
10199
10200 for (i = 0; i < count; ++i)
10201 vkd3d_free((void *)symbols[i].name);
10202 vkd3d_free(symbols);
10203}
10204
10205static void sm6_phi_destroy(struct sm6_phi *phi)
10206{
10207 vkd3d_free(phi->incoming);
10208}
10209
10211{
10212 unsigned int i;
10213
10214 vkd3d_free(block->instructions);
10215 for (i = 0; i < block->phi_count; ++i)
10216 sm6_phi_destroy(&block->phi[i]);
10217 vkd3d_free(block->phi);
10218 vkd3d_free(block->terminator.cases);
10220}
10221
10222static void sm6_functions_cleanup(struct sm6_function *functions, size_t count)
10223{
10224 size_t i, j;
10225
10226 for (i = 0; i < count; ++i)
10227 {
10228 for (j = 0; j < functions[i].block_count; ++j)
10229 sm6_block_destroy(functions[i].blocks[j]);
10230 vkd3d_free(functions[i].blocks);
10231 }
10232 vkd3d_free(functions);
10233}
10234
10235static void sm6_parser_cleanup(struct sm6_parser *sm6)
10236{
10243 vkd3d_free(sm6->descriptors);
10244 vkd3d_free(sm6->values);
10245}
10246
10247static struct sm6_function *sm6_parser_get_function(const struct sm6_parser *sm6, const char *name)
10248{
10249 size_t i;
10250 for (i = 0; i < sm6->function_count; ++i)
10251 if (!strcmp(sm6->functions[i].declaration->u.function.name, name))
10252 return &sm6->functions[i];
10253 return NULL;
10254}
10255
10257 const struct vkd3d_shader_compile_info *compile_info,
10258 struct vkd3d_shader_message_context *message_context, struct dxbc_shader_desc *dxbc_desc)
10259{
10260 size_t count, length, function_count, expected_function_count, byte_code_size = dxbc_desc->byte_code_size;
10261 const struct vkd3d_shader_location location = {.source_name = compile_info->source_name};
10262 struct shader_signature *patch_constant_signature, *output_signature, *input_signature;
10263 uint32_t version_token, dxil_version, token_count, magic;
10264 const uint32_t *byte_code = dxbc_desc->byte_code;
10265 unsigned int chunk_offset, chunk_size;
10268 struct dxil_block *block;
10269 struct sm6_function *fn;
10270 enum vkd3d_result ret;
10271 unsigned int i, j;
10272
10273 count = byte_code_size / sizeof(*byte_code);
10274 if (count < 6)
10275 {
10276 WARN("Invalid data size %zu.\n", byte_code_size);
10278 "DXIL chunk size %zu is smaller than the DXIL header size.", byte_code_size);
10280 }
10281
10282 version_token = byte_code[0];
10283 TRACE("Compiler version: 0x%08x.\n", version_token);
10284 token_count = byte_code[1];
10285 TRACE("Token count: %u.\n", token_count);
10286
10287 if (token_count < 6 || count < token_count)
10288 {
10289 WARN("Invalid token count %u (word count %zu).\n", token_count, count);
10291 "DXIL chunk token count %#x is invalid (word count %zu).", token_count, count);
10293 }
10294
10295 if (byte_code[2] != TAG_DXIL)
10296 WARN("Unknown magic number 0x%08x.\n", byte_code[2]);
10297
10298 dxil_version = byte_code[3];
10299 if (dxil_version > 0x102)
10300 WARN("Unknown DXIL version: 0x%08x.\n", dxil_version);
10301 else
10302 TRACE("DXIL version: 0x%08x.\n", dxil_version);
10303
10304 chunk_offset = byte_code[4];
10305 if (chunk_offset < 16 || chunk_offset >= byte_code_size)
10306 {
10307 WARN("Invalid bitcode chunk offset %#x (data size %zu).\n", chunk_offset, byte_code_size);
10309 "DXIL bitcode chunk has invalid offset %#x (data size %#zx).", chunk_offset, byte_code_size);
10311 }
10312 chunk_size = byte_code[5];
10313 if (chunk_size > byte_code_size - chunk_offset)
10314 {
10315 WARN("Invalid bitcode chunk size %#x (data size %zu, chunk offset %#x).\n",
10316 chunk_size, byte_code_size, chunk_offset);
10318 "DXIL bitcode chunk has invalid size %#x (data size %#zx, chunk offset %#x).",
10319 chunk_size, byte_code_size, chunk_offset);
10321 }
10322
10323 sm6->start = (const uint32_t *)((const char*)&byte_code[2] + chunk_offset);
10324 if ((magic = sm6->start[0]) != BITCODE_MAGIC)
10325 {
10326 WARN("Unknown magic number 0x%08x.\n", magic);
10328 "DXIL bitcode chunk magic number 0x%08x is not the expected 0x%08x.", magic, BITCODE_MAGIC);
10329 }
10330
10331 sm6->end = &sm6->start[(chunk_size + sizeof(*sm6->start) - 1) / sizeof(*sm6->start)];
10332
10333 if ((version.type = version_token >> 16) >= VKD3D_SHADER_TYPE_COUNT)
10334 {
10335 FIXME("Unknown shader type %#x.\n", version.type);
10337 "Unknown shader type %#x.", version.type);
10338 }
10339
10340 version.major = VKD3D_SM6_VERSION_MAJOR(version_token);
10341 version.minor = VKD3D_SM6_VERSION_MINOR(version_token);
10342
10343 if ((abbr = sm6->start[1] & 3) != ENTER_SUBBLOCK)
10344 {
10345 WARN("Initial block abbreviation %u is not ENTER_SUBBLOCK.\n", abbr);
10347 "DXIL bitcode chunk has invalid initial block abbreviation %u.", abbr);
10349 }
10350
10351 /* Estimate instruction count to avoid reallocation in most shaders. */
10352 count = max(token_count, 400) - 400;
10353 if (!vsir_program_init(program, compile_info, &version,
10354 (count + (count >> 2)) / 2u + 10, VSIR_CF_BLOCKS, VSIR_FULLY_NORMALISED_IO))
10356 vkd3d_shader_parser_init(&sm6->p, program, message_context, compile_info->source_name);
10357 sm6->ptr = &sm6->start[1];
10358 sm6->bitpos = 2;
10359
10360 switch (program->shader_version.type)
10361 {
10364 break;
10365
10366 default:
10367 if (program->patch_constant_signature.element_count != 0)
10368 {
10369 WARN("The patch constant signature only makes sense for Hull and Domain Shaders, ignoring it.\n");
10370 shader_signature_cleanup(&program->patch_constant_signature);
10371 }
10372 break;
10373 }
10374
10375 input_signature = &program->input_signature;
10376 output_signature = &program->output_signature;
10377 patch_constant_signature = &program->patch_constant_signature;
10378 *input_signature = dxbc_desc->input_signature;
10379 *output_signature = dxbc_desc->output_signature;
10380 *patch_constant_signature = dxbc_desc->patch_constant_signature;
10381 memset(dxbc_desc, 0, sizeof(*dxbc_desc));
10382
10383 block = &sm6->root_block;
10384 if ((ret = dxil_block_init(block, NULL, sm6)) < 0)
10385 {
10388 "Out of memory parsing DXIL bitcode chunk.");
10389 else if (ret == VKD3D_ERROR_INVALID_SHADER)
10391 "DXIL bitcode chunk has invalid bitcode.");
10392 else
10394 goto fail;
10395 }
10396
10398 sm6->abbrevs = NULL;
10399 sm6->abbrev_count = 0;
10400
10401 length = sm6->ptr - sm6->start - block->start;
10402 if (length != block->length)
10403 {
10404 WARN("Invalid block length %zu; expected %u.\n", length, block->length);
10406 "Root block ends with length %zu but indicated length is %u.", length, block->length);
10407 }
10408 if (sm6->ptr != sm6->end)
10409 {
10410 size_t expected_length = sm6->end - sm6->start;
10411 length = sm6->ptr - sm6->start;
10412 WARN("Invalid module length %zu; expected %zu.\n", length, expected_length);
10414 "Module ends with length %zu but indicated length is %zu.", length, expected_length);
10415 }
10416
10417 if ((ret = sm6_parser_type_table_init(sm6)) < 0)
10418 {
10421 "Out of memory parsing DXIL type table.");
10422 else if (ret == VKD3D_ERROR_INVALID_SHADER)
10424 "DXIL type table is invalid.");
10425 else
10427 goto fail;
10428 }
10429
10430 if ((ret = sm6_parser_symtab_init(sm6)) < 0)
10431 {
10434 "Out of memory parsing DXIL value symbol table.");
10435 else if (ret == VKD3D_ERROR_INVALID_SHADER)
10437 "DXIL value symbol table is invalid.");
10438 else
10440 goto fail;
10441 }
10442
10443 if (!(sm6->output_params = vsir_program_get_dst_params(program, output_signature->element_count))
10444 || !(sm6->input_params = vsir_program_get_dst_params(program, input_signature->element_count))
10446 patch_constant_signature->element_count)))
10447 {
10448 ERR("Failed to allocate input/output parameters.\n");
10450 "Out of memory allocating input/output parameters.");
10452 goto fail;
10453 }
10454
10455 function_count = dxil_block_compute_function_count(&sm6->root_block);
10456 if (!(sm6->functions = vkd3d_calloc(function_count, sizeof(*sm6->functions))))
10457 {
10458 ERR("Failed to allocate function array.\n");
10460 "Out of memory allocating DXIL function array.");
10462 goto fail;
10463 }
10464
10466 {
10467 WARN("Value array count overflowed.\n");
10469 "Overflow occurred in the DXIL module value count.");
10471 goto fail;
10472 }
10473 if (!(sm6->values = vkd3d_calloc(sm6->value_capacity, sizeof(*sm6->values))))
10474 {
10475 ERR("Failed to allocate value array.\n");
10477 "Out of memory allocating DXIL value array.");
10479 goto fail;
10480 }
10481 sm6->function_count = 0;
10482 sm6->ssa_next_id = 1;
10483
10484 if ((ret = sm6_parser_globals_init(sm6)) < 0)
10485 {
10486 WARN("Failed to load global declarations.\n");
10487 goto fail;
10488 }
10489
10491 {
10492 ERR("Failed to allocate named metadata array.\n");
10494 goto fail;
10495 }
10496
10497 for (i = 0, j = 0; i < sm6->root_block.child_block_count; ++i)
10498 {
10499 block = sm6->root_block.child_blocks[i];
10500 if (block->id != METADATA_BLOCK)
10501 continue;
10502
10503 if (j == ARRAY_SIZE(sm6->metadata_tables))
10504 {
10505 FIXME("Too many metadata tables.\n");
10507 "A metadata table count greater than %zu is unsupported.", ARRAY_SIZE(sm6->metadata_tables));
10509 goto fail;
10510 }
10511
10512 if ((ret = sm6_parser_metadata_init(sm6, block, &sm6->metadata_tables[j++])) < 0)
10513 goto fail;
10514 }
10515
10516 if ((ret = sm6_parser_entry_point_init(sm6)) < 0)
10517 goto fail;
10518
10519 if ((ret = sm6_parser_resources_init(sm6)) < 0)
10520 goto fail;
10521
10522 if ((ret = sm6_parser_module_init(sm6, &sm6->root_block, 0)) < 0)
10523 {
10526 "Out of memory parsing DXIL module.");
10527 else if (ret == VKD3D_ERROR_INVALID_SHADER)
10529 "DXIL module is invalid.");
10530 goto fail;
10531 }
10532
10533 if (!sm6_parser_require_space(sm6, output_signature->element_count + input_signature->element_count
10534 + patch_constant_signature->element_count))
10535 {
10537 "Out of memory emitting shader signature declarations.");
10539 goto fail;
10540 }
10541
10542 program->ssa_count = sm6->ssa_next_id;
10543
10544 if (!(fn = sm6_parser_get_function(sm6, sm6->entry_point)))
10545 {
10546 WARN("Failed to find entry point %s.\n", sm6->entry_point);
10548 "The definition of the entry point function '%s' was not found.", sm6->entry_point);
10550 goto fail;
10551 }
10552
10553 if (version.type == VKD3D_SHADER_TYPE_HULL)
10554 {
10556
10557 if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
10558 goto fail;
10559
10561 {
10562 WARN("Failed to find patch constant function '%s'.\n", sm6->patch_constant_function);
10564 "Failed to find the patch constant function '%s' for a hull shader.",
10567 goto fail;
10568 }
10569
10571 if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
10572 goto fail;
10573
10574 expected_function_count = 2;
10575 }
10576 else
10577 {
10578 if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
10579 goto fail;
10580 expected_function_count = 1;
10581 }
10582
10583 if (sm6->function_count > expected_function_count)
10584 {
10585 FIXME("%zu unhandled functions.\n", sm6->function_count - expected_function_count);
10587 "%zu functions were not emitted.", sm6->function_count - expected_function_count);
10588 }
10589
10591
10592 if (sm6->p.failed)
10593 {
10595 goto fail;
10596 }
10597
10598 return VKD3D_OK;
10599
10600fail:
10601 sm6_parser_cleanup(sm6);
10603 return ret;
10604}
10605
10606int dxil_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
10607 struct vkd3d_shader_message_context *message_context, struct vsir_program *program)
10608{
10609 struct dxbc_shader_desc dxbc_desc = {0};
10610 struct sm6_parser sm6 = {0};
10611 uint32_t *byte_code = NULL;
10612 int ret;
10613
10614 MESSAGE("Creating a DXIL parser. This is unsupported; you get to keep all the pieces if it breaks.\n");
10615
10616 dxbc_desc.is_dxil = true;
10617 if ((ret = shader_extract_from_dxbc(&compile_info->source, message_context, compile_info->source_name,
10618 &dxbc_desc)) < 0)
10619 {
10620 WARN("Failed to extract shader, vkd3d result %d.\n", ret);
10621 return ret;
10622 }
10623
10624 if (((uintptr_t)dxbc_desc.byte_code & (VKD3D_DXBC_CHUNK_ALIGNMENT - 1)))
10625 {
10626 /* LLVM bitcode should be 32-bit aligned, but before dxc v1.7.2207 this was not always the case in the DXBC
10627 * container due to missing padding after signature names. Get an aligned copy to prevent unaligned access. */
10628 if (!(byte_code = vkd3d_malloc(align(dxbc_desc.byte_code_size, VKD3D_DXBC_CHUNK_ALIGNMENT))))
10629 {
10630 ERR("Failed to allocate aligned chunk.\n");
10631 free_dxbc_shader_desc(&dxbc_desc);
10633 }
10634
10635 memcpy(byte_code, dxbc_desc.byte_code, dxbc_desc.byte_code_size);
10636 dxbc_desc.byte_code = byte_code;
10637 }
10638
10639 ret = sm6_parser_init(&sm6, program, compile_info, message_context, &dxbc_desc);
10640 free_dxbc_shader_desc(&dxbc_desc);
10641 vkd3d_free(byte_code);
10642
10643 if (ret < 0)
10644 return ret;
10645
10646 sm6_parser_cleanup(&sm6);
10647
10648 return VKD3D_OK;
10649}
_Check_return_ _Ret_maybenull_ _In_ size_t alignment
Definition: align.cpp:48
static int state
Definition: maze.c:121
#define index(s, c)
Definition: various.h:29
#define ARRAY_SIZE(A)
Definition: main.h:20
static __inline void bitmap_set(IN bitmap4 *mask, IN uint32_t word, IN uint32_t flag)
Definition: util.h:62
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
r l[0]
Definition: byte_order.h:168
unsigned int component_count
component_type
range
Definition: d3dx9_private.h:58
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
UINT64 uint64_t
Definition: types.h:77
UINT op
Definition: effect.c:235
static BOOL reserve(struct dynamic_array *array, int count, int itemsize)
Definition: mesh.c:5499
unsigned int idx
Definition: utils.c:40
#define CHAR_BIT
Definition: cabinet.h:45
static BOOL is_valid(HIMAGELIST himl)
Definition: imagelist.c:4092
static const WCHAR version[]
Definition: asmname.c:66
int intptr_t
Definition: corecrt.h:176
unsigned int uintptr_t
Definition: corecrt.h:185
#define PRIx64
Definition: inttypes.h:29
#define PRIu64
Definition: inttypes.h:28
#define SIZE_MAX
Definition: limits.h:49
#define UINT_MAX
Definition: limits.h:27
_ACRTIMP void __cdecl qsort(void *, size_t, size_t, int(__cdecl *)(const void *, const void *))
#define UINT64_MAX
Definition: stdint.h:86
#define UINT32_MAX
Definition: stdint.h:85
#define UINT8_MAX
Definition: stdint.h:83
signed char int8_t
Definition: stdint.h:32
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3324
_ACRTIMP int __cdecl strncmp(const char *, const char *, size_t)
Definition: string.c:3335
static BOOL is_int(CIMTYPE type)
Definition: query.c:148
uacpi_u16 uacpi_gpe_triggering uacpi_gpe_handler uacpi_handle ctx uacpi_u16 uacpi_namespace_node *wake_device uacpi_u16 idx uacpi_u16 idx uacpi_u16 idx uacpi_u16 idx uacpi_u16 idx uacpi_u64 uacpi_address_space address_space
Definition: event.h:273
return ret
Definition: mutex.c:147
r parent
Definition: btrfs.c:3010
switch(r->id)
Definition: btrfs.c:3046
int shader_extract_from_dxbc(const struct vkd3d_shader_code *dxbc, struct vkd3d_shader_message_context *message_context, const char *source_name, struct dxbc_shader_desc *desc)
Definition: dxbc.c:580
void free_dxbc_shader_desc(struct dxbc_shader_desc *desc)
Definition: dxbc.c:573
dxil_semantic_kind
Definition: dxil.c:246
@ SEMANTIC_KIND_INNERCOVERAGE
Definition: dxil.c:262
@ SEMANTIC_KIND_INSIDETESSFACTOR
Definition: dxil.c:273
@ SEMANTIC_KIND_INSTANCEID
Definition: dxil.c:249
@ SEMANTIC_KIND_BARYCENTRICS
Definition: dxil.c:275
@ SEMANTIC_KIND_TESSFACTOR
Definition: dxil.c:272
@ SEMANTIC_KIND_VIEWID
Definition: dxil.c:274
@ SEMANTIC_KIND_SAMPLEINDEX
Definition: dxil.c:259
@ SEMANTIC_KIND_POSITION
Definition: dxil.c:250
@ SEMANTIC_KIND_VIEWPORTARRAYINDEX
Definition: dxil.c:252
@ SEMANTIC_KIND_GROUPID
Definition: dxil.c:269
@ SEMANTIC_KIND_ISFRONTFACE
Definition: dxil.c:260
@ SEMANTIC_KIND_GSINSTANCEID
Definition: dxil.c:258
@ SEMANTIC_KIND_DISPATCHTHREADID
Definition: dxil.c:268
@ SEMANTIC_KIND_OUTPUTCONTROLPOINTID
Definition: dxil.c:255
@ SEMANTIC_KIND_DEPTHLESSEQUAL
Definition: dxil.c:265
@ SEMANTIC_KIND_SHADINGRATE
Definition: dxil.c:276
@ SEMANTIC_KIND_GROUPTHREADID
Definition: dxil.c:271
@ SEMANTIC_KIND_RTARRAYINDEX
Definition: dxil.c:251
@ SEMANTIC_KIND_COUNT
Definition: dxil.c:278
@ SEMANTIC_KIND_STENCILREF
Definition: dxil.c:267
@ SEMANTIC_KIND_ARBITRARY
Definition: dxil.c:247
@ SEMANTIC_KIND_DOMAINLOCATION
Definition: dxil.c:256
@ SEMANTIC_KIND_CULLPRIMITIVE
Definition: dxil.c:277
@ SEMANTIC_KIND_INVALID
Definition: dxil.c:279
@ SEMANTIC_KIND_CULLDISTANCE
Definition: dxil.c:254
@ SEMANTIC_KIND_TARGET
Definition: dxil.c:263
@ SEMANTIC_KIND_GROUPINDEX
Definition: dxil.c:270
@ SEMANTIC_KIND_COVERAGE
Definition: dxil.c:261
@ SEMANTIC_KIND_VERTEXID
Definition: dxil.c:248
@ SEMANTIC_KIND_PRIMITIVEID
Definition: dxil.c:257
@ SEMANTIC_KIND_DEPTH
Definition: dxil.c:264
@ SEMANTIC_KIND_DEPTHGREATEREQUAL
Definition: dxil.c:266
@ SEMANTIC_KIND_CLIPDISTANCE
Definition: dxil.c:253
static const struct sm6_metadata_value * sm6_parser_metadata_get_value(const struct sm6_parser *sm6, uint64_t index)
Definition: dxil.c:7672
static bool sm6_type_is_bool_i16_i32_i64(const struct sm6_type *type)
Definition: dxil.c:1868
static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:4953
dxil_quad_op_kind
Definition: dxil.c:583
@ QUAD_READ_ACROSS_D
Definition: dxil.c:586
@ QUAD_READ_ACROSS_X
Definition: dxil.c:584
@ QUAD_READ_ACROSS_Y
Definition: dxil.c:585
static bool sm6_value_is_constant_zero(const struct sm6_value *value)
Definition: dxil.c:2245
static bool sm6_parser_resources_load_register_range(struct sm6_parser *sm6, const struct sm6_metadata_node *node, struct vkd3d_shader_register_range *range)
Definition: dxil.c:8630
static size_t size_add_with_overflow_check(size_t a, size_t b)
Definition: dxil.c:916
static bool sm6_value_is_constant(const struct sm6_value *value)
Definition: dxil.c:2240
static void src_param_init_scalar(struct vkd3d_shader_src_param *param, unsigned int component_idx)
Definition: dxil.c:2463
static enum vkd3d_shader_opcode sm6_dx_map_wave_bit_op(enum dxil_wave_bit_op_kind op, struct sm6_parser *sm6)
Definition: dxil.c:6121
static bool sm6_metadata_get_uint_value(const struct sm6_parser *sm6, const struct sm6_metadata_value *m, unsigned int *u)
Definition: dxil.c:7541
static void sm6_parser_emit_ret(struct sm6_parser *sm6, const struct dxil_record *record, struct sm6_block *code_block, struct vkd3d_shader_instruction *ins)
Definition: dxil.c:7310
static bool sm6_metadata_value_is_value(const struct sm6_metadata_value *m)
Definition: dxil.c:7525
static void sm6_parser_validate_control_point_count(struct sm6_parser *sm6, unsigned int count, const char *type)
Definition: dxil.c:9722
static void register_init_ssa_vector(struct vkd3d_shader_register *reg, const struct sm6_type *type, unsigned int component_count, struct sm6_value *value, struct sm6_parser *sm6)
Definition: dxil.c:2390
static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_record *record, struct function_emission_state *state, struct sm6_value *dst)
Definition: dxil.c:6507
static bool sm6_type_is_integer(const struct sm6_type *type)
Definition: dxil.c:1863
static void sm6_parser_dcl_register_builtin(struct sm6_parser *sm6, enum vkd3d_shader_opcode handler_idx, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int component_count)
Definition: dxil.c:4890
static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const struct dxil_block *block, struct sm6_function *function)
Definition: dxil.c:7864
static const struct sm6_type * sm6_type_get_scalar_type(const struct sm6_type *type, unsigned int elem_idx)
Definition: dxil.c:2044
static bool resolve_forward_zero_initialiser(size_t index, struct sm6_parser *sm6)
Definition: dxil.c:3672
static bool sm6_type_is_floating_point(const struct sm6_type *type)
Definition: dxil.c:1908
static void sm6_parser_emit_dcl_tessellator_output_primitive(struct sm6_parser *sm6, enum vkd3d_shader_tessellator_output_primitive primitive)
Definition: dxil.c:9749
static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record *record, struct sm6_function *function, struct sm6_block *code_block, struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
Definition: dxil.c:7221
static const struct sm6_value * sm6_parser_get_value_safe(struct sm6_parser *sm6, unsigned int idx)
Definition: dxil.c:2783
dxil_resource_tag
Definition: dxil.c:208
@ RESOURCE_TAG_SAMPLER_FEEDBACK_KIND
Definition: dxil.c:211
@ RESOURCE_TAG_ENABLE_ATOMIC_64
Definition: dxil.c:212
@ RESOURCE_TAG_ELEMENT_STRIDE
Definition: dxil.c:210
@ RESOURCE_TAG_ELEMENT_TYPE
Definition: dxil.c:209
static bool sm6_type_is_float(const struct sm6_type *type)
Definition: dxil.c:1893
static bool sm6_type_is_numeric(const struct sm6_type *type)
Definition: dxil.c:1918
static void sm6_parser_emit_dx_wave_active_bit(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:6140
static void sm6_parser_emit_dcl_tessellator_partitioning(struct sm6_parser *sm6, enum vkd3d_shader_tessellator_partitioning tessellator_partitioning)
Definition: dxil.c:9733
static bool sm6_value_validate_is_i32(const struct sm6_value *value, struct sm6_parser *sm6)
Definition: dxil.c:2771
static enum vkd3d_result dxil_block_read(struct dxil_block *parent, struct sm6_parser *sm6)
Definition: dxil.c:1350
static void dst_param_init_with_mask(struct vkd3d_shader_dst_param *param, unsigned int mask)
Definition: dxil.c:2429
static struct vkd3d_shader_resource * sm6_parser_resources_load_common_info(struct sm6_parser *sm6, const struct sm6_metadata_value *type_value, bool is_uav, enum dxil_resource_kind kind, const struct sm6_metadata_value *m, struct vkd3d_shader_instruction *ins)
Definition: dxil.c:8811
static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5032
static bool sm6_parser_read_vbr_operand(struct sm6_parser *sm6, uint64_t context, uint64_t *op)
Definition: dxil.c:1120
static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m)
Definition: dxil.c:9790
static enum vkd3d_result dxil_abbrev_init(struct dxil_abbrev *abbrev, unsigned int count, struct sm6_parser *sm6)
Definition: dxil.c:1142
static bool bitcode_parse_alignment(uint64_t encoded_alignment, unsigned int *alignment)
Definition: dxil.c:3380
static void sm6_parser_emit_dx_wave_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:6186
static bool sm6_type_is_f16_f32(const struct sm6_type *type)
Definition: dxil.c:1898
static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const char *name, const struct sm6_value **operands, unsigned int operand_count, struct function_emission_state *state, struct sm6_value *dst)
Definition: dxil.c:6488
static void src_param_make_constant_uint(struct vkd3d_shader_src_param *param, unsigned int value)
Definition: dxil.c:2491
static void src_param_init_from_value(struct vkd3d_shader_src_param *param, const struct sm6_value *src)
Definition: dxil.c:2477
static struct vkd3d_shader_src_param * instruction_src_params_alloc(struct vkd3d_shader_instruction *ins, unsigned int count, struct sm6_parser *sm6)
Definition: dxil.c:2308
static void sm6_phi_destroy(struct sm6_phi *phi)
Definition: dxil.c:10205
static void sm6_block_emit_phi(const struct sm6_block *block, struct sm6_parser *sm6)
Definition: dxil.c:8135
static const unsigned int MAX_GS_OUTPUT_STREAMS
Definition: dxil.c:42
static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const struct sm6_value **operands, unsigned int max_operands, const struct sm6_value *z_operand, struct function_emission_state *state, struct vkd3d_shader_register *reg)
Definition: dxil.c:4492
static bool sm6_type_is_numeric_aggregate(const struct sm6_type *type)
Definition: dxil.c:1933
static struct sm6_value * sm6_parser_get_current_value(const struct sm6_parser *sm6)
Definition: dxil.c:2224
int dxil_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags, struct vkd3d_shader_message_context *message_context, struct vsir_program *program)
Definition: dxil.c:10606
static const struct sm6_type * sm6_type_get_cmpxchg_result_struct(struct sm6_parser *sm6)
Definition: dxil.c:2003
static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const struct sm6_type *elem_type, unsigned int count, unsigned int alignment, bool has_function_scope, unsigned int init, struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
Definition: dxil.c:3426
static const struct sm6_type * sm6_type_get_pointer_to_type(const struct sm6_type *type, enum bitcode_address_space addr_space, struct sm6_parser *sm6)
Definition: dxil.c:1985
static const uint64_t ALLOCA_FLAG_EXPLICIT_TYPE
Definition: dxil.c:33
#define VKD3D_SM6_MAX_METADATA_TABLES
Definition: dxil.c:24
static enum vkd3d_result sm6_parser_resources_load_sampler(struct sm6_parser *sm6, const struct sm6_metadata_node *node, struct sm6_descriptor_info *d, struct vkd3d_shader_instruction *ins)
Definition: dxil.c:9084
static void sm6_parser_declare_icb(struct sm6_parser *sm6, const struct sm6_type *elem_type, unsigned int count, unsigned int alignment, unsigned int init, struct sm6_value *dst)
Definition: dxil.c:3414
static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const char *name, const struct sm6_value **operands, unsigned int operand_count, struct sm6_value *dst)
Definition: dxil.c:6435
static const struct dxil_block * sm6_parser_get_level_one_block(const struct sm6_parser *sm6, enum bitcode_block_id id, bool *is_unique)
Definition: dxil.c:1533
sm6_metadata_type
Definition: dxil.c:785
@ VKD3D_METADATA_KIND
Definition: dxil.c:786
@ VKD3D_METADATA_NODE
Definition: dxil.c:787
@ VKD3D_METADATA_VALUE
Definition: dxil.c:789
@ VKD3D_METADATA_STRING
Definition: dxil.c:788
static char * dxil_record_to_string(const struct dxil_record *record, unsigned int offset, struct sm6_parser *sm6)
Definition: dxil.c:1554
static void sm6_parser_emit_dx_get_sample_count(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5656
static enum vkd3d_shader_resource_type shader_resource_type_from_dxil_resource_kind(enum dxil_resource_kind kind)
Definition: dxil.c:8672
static const struct sm6_type * sm6_type_get_element_type(const struct sm6_type *type)
Definition: dxil.c:1980
static bool dxil_record_validate_operand_min_count(const struct dxil_record *record, unsigned int min_count, struct sm6_parser *sm6)
Definition: dxil.c:1573
static const struct sm6_value * sm6_parser_next_function_definition(struct sm6_parser *sm6)
Definition: dxil.c:3931
static const uint64_t MAX_ALIGNMENT_EXPONENT
Definition: dxil.c:28
static enum vkd3d_result sm6_parser_resources_load_uav(struct sm6_parser *sm6, const struct sm6_metadata_node *node, struct sm6_descriptor_info *d, struct vkd3d_shader_instruction *ins)
Definition: dxil.c:8978
static void sm6_parser_emit_dx_void(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:4524
static void sm6_parser_emit_dx_output_control_point_id(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5381
static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_record *record, struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
Definition: dxil.c:4271
dxil_wave_op_kind
Definition: dxil.c:575
@ WAVE_OP_MUL
Definition: dxil.c:577
@ WAVE_OP_ADD
Definition: dxil.c:576
@ WAVE_OP_MAX
Definition: dxil.c:579
@ WAVE_OP_MIN
Definition: dxil.c:578
static void sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature)
Definition: dxil.c:3912
static void src_param_init_vector_from_reg(struct vkd3d_shader_src_param *param, const struct vkd3d_shader_register *reg)
Definition: dxil.c:2483
static enum vkd3d_result dxil_block_init(struct dxil_block *block, const struct dxil_block *parent, struct sm6_parser *sm6)
Definition: dxil.c:1451
static bool sm6_type_is_aggregate(const struct sm6_type *type)
Definition: dxil.c:1928
static size_t sm6_parser_get_value_index(struct sm6_parser *sm6, uint64_t idx)
Definition: dxil.c:2599
dxil_sampler_kind
Definition: dxil.c:239
@ SAMPLER_KIND_COMPARISON
Definition: dxil.c:241
@ SAMPLER_KIND_DEFAULT
Definition: dxil.c:240
@ SAMPLER_KIND_MONO
Definition: dxil.c:242
static bool sm6_value_validate_is_handle(const struct sm6_value *value, struct sm6_parser *sm6)
Definition: dxil.c:2638
static enum vkd3d_result sm6_parser_add_global_abbrev(struct sm6_parser *sm6)
Definition: dxil.c:1205
static unsigned int sm6_type_max_vector_size(const struct sm6_type *type)
Definition: dxil.c:2067
dxil_shader_properties_tag
Definition: dxil.c:303
@ SHADER_PROPERTIES_HULL
Definition: dxil.c:307
@ SHADER_PROPERTIES_DOMAIN
Definition: dxil.c:306
@ SHADER_PROPERTIES_ENTRY_ROOT_SIG
Definition: dxil.c:316
@ SHADER_PROPERTIES_COMPUTE
Definition: dxil.c:308
@ SHADER_PROPERTIES_AUTO_BINDING_SPACE
Definition: dxil.c:309
@ SHADER_PROPERTIES_RAY_PAYLOAD_SIZE
Definition: dxil.c:310
@ SHADER_PROPERTIES_RAY_ATTRIB_SIZE
Definition: dxil.c:311
@ SHADER_PROPERTIES_SHADER_KIND
Definition: dxil.c:312
@ SHADER_PROPERTIES_MESH
Definition: dxil.c:313
@ SHADER_PROPERTIES_FLAGS
Definition: dxil.c:304
@ SHADER_PROPERTIES_GEOMETRY
Definition: dxil.c:305
@ SHADER_PROPERTIES_WAVE_SIZE
Definition: dxil.c:315
@ SHADER_PROPERTIES_AMPLIFICATION
Definition: dxil.c:314
static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_record *record, struct function_emission_state *state, struct sm6_value *dst)
Definition: dxil.c:4086
static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5950
static const unsigned int GLOBALVAR_ADDRESS_SPACE_SHIFT
Definition: dxil.c:31
static enum vkd3d_result sm6_parser_type_table_init(struct sm6_parser *sm6)
Definition: dxil.c:1603
static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record *record, struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
Definition: dxil.c:7038
static size_t sm6_parser_compute_global_abbrev_count_for_block_id(struct sm6_parser *sm6, unsigned int block_id)
Definition: dxil.c:1419
static void register_init_ssa_scalar(struct vkd3d_shader_register *reg, const struct sm6_type *type, struct sm6_value *value, struct sm6_parser *sm6)
Definition: dxil.c:2410
static bool sm6_parser_read_fixed_operand(struct sm6_parser *sm6, uint64_t context, uint64_t *op)
Definition: dxil.c:1114
static uint32_t sm6_parser_read_bits(struct sm6_parser *sm6, unsigned int length)
Definition: dxil.c:937
static bool sm6_value_is_function_dcl(const struct sm6_value *value)
Definition: dxil.c:2213
static unsigned int register_get_uint_value(const struct vkd3d_shader_register *reg)
Definition: dxil.c:2184
static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5434
static const struct sm6_dx_opcode_info sm6_dx_op_table[]
Definition: dxil.c:6261
static void sm6_parser_emit_dx_binary(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:4652
static bool sm6_parser_read_blob_operand(struct sm6_parser *sm6, uint64_t context, uint64_t *op)
Definition: dxil.c:1132
static enum vkd3d_result dxil_block_add_record(struct dxil_block *block, struct dxil_record *record)
Definition: dxil.c:1049
bitcode_block_id
Definition: dxil.c:49
@ PARAMATTR_GROUP_BLOCK
Definition: dxil.c:53
@ MODULE_BLOCK
Definition: dxil.c:51
@ VALUE_SYMTAB_BLOCK
Definition: dxil.c:56
@ BLOCKINFO_BLOCK
Definition: dxil.c:50
@ PARAMATTR_BLOCK
Definition: dxil.c:52
@ METADATA_ATTACHMENT_BLOCK
Definition: dxil.c:58
@ CONSTANTS_BLOCK
Definition: dxil.c:54
@ TYPE_BLOCK
Definition: dxil.c:59
@ USELIST_BLOCK
Definition: dxil.c:60
@ METADATA_BLOCK
Definition: dxil.c:57
@ FUNCTION_BLOCK
Definition: dxil.c:55
static void sm6_parser_emit_global_flags(struct sm6_parser *sm6, const struct sm6_metadata_value *m)
Definition: dxil.c:9603
static size_t sm6_parser_compute_max_value_count(struct sm6_parser *sm6, const struct dxil_block *block, size_t value_count)
Definition: dxil.c:2565
static struct sm6_block * sm6_block_create()
Definition: dxil.c:3947
static void instruction_dst_param_init_ssa_vector(struct vkd3d_shader_instruction *ins, unsigned int component_count, struct sm6_parser *sm6)
Definition: dxil.c:2534
static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5190
static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_function *function, struct sm6_parser *sm6)
Definition: dxil.c:7825
bitcode_metadata_code
Definition: dxil.c:140
@ METADATA_DISTINCT_NODE
Definition: dxil.c:145
@ METADATA_VALUE
Definition: dxil.c:142
@ METADATA_ATTACHMENT
Definition: dxil.c:149
@ METADATA_NAME
Definition: dxil.c:144
@ METADATA_KIND
Definition: dxil.c:146
@ METADATA_STRING
Definition: dxil.c:141
@ METADATA_NODE
Definition: dxil.c:143
@ METADATA_LOCATION
Definition: dxil.c:147
@ METADATA_NAMED_NODE
Definition: dxil.c:148
static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const struct sm6_metadata_value *m, struct shader_signature *s, enum vkd3d_tessellator_domain tessellator_domain)
Definition: dxil.c:9350
static bool sm6_parser_allocate_named_metadata(struct sm6_parser *sm6)
Definition: dxil.c:8273
static bool sm6_parser_is_end(struct sm6_parser *sm6)
Definition: dxil.c:922
bitcode_module_code
Definition: dxil.c:96
@ MODULE_CODE_FUNCTION
Definition: dxil.c:99
@ MODULE_CODE_VERSION
Definition: dxil.c:97
@ MODULE_CODE_GLOBALVAR
Definition: dxil.c:98
static const struct sm6_metadata_value * sm6_parser_find_named_metadata(struct sm6_parser *sm6, const char *name)
Definition: dxil.c:8605
dxil_binop_code
Definition: dxil.c:320
@ BINOP_AND
Definition: dxil.c:331
@ BINOP_UDIV
Definition: dxil.c:324
@ BINOP_SREM
Definition: dxil.c:327
@ BINOP_XOR
Definition: dxil.c:333
@ BINOP_SDIV
Definition: dxil.c:325
@ BINOP_UREM
Definition: dxil.c:326
@ BINOP_SUB
Definition: dxil.c:322
@ BINOP_LSHR
Definition: dxil.c:329
@ BINOP_ASHR
Definition: dxil.c:330
@ BINOP_MUL
Definition: dxil.c:323
@ BINOP_SHL
Definition: dxil.c:328
@ BINOP_OR
Definition: dxil.c:332
@ BINOP_ADD
Definition: dxil.c:321
sm6_value_type
Definition: dxil.c:643
@ VALUE_TYPE_REG
Definition: dxil.c:645
@ VALUE_TYPE_ICB
Definition: dxil.c:646
@ VALUE_TYPE_FUNCTION
Definition: dxil.c:644
@ VALUE_TYPE_HANDLE
Definition: dxil.c:647
static bool sm6_type_is_bool(const struct sm6_type *type)
Definition: dxil.c:1878
static const unsigned int dx_max_thread_group_size[3]
Definition: dxil.c:38
static float bitcast_uint_to_float(unsigned int value)
Definition: dxil.c:2930
static enum vkd3d_shader_sysval_semantic sysval_semantic_from_dxil_semantic_kind(enum dxil_semantic_kind kind, enum vkd3d_tessellator_domain domain)
Definition: dxil.c:8562
static size_t dxil_block_compute_constants_count(const struct dxil_block *block)
Definition: dxil.c:1515
static void instruction_set_texel_offset(struct vkd3d_shader_instruction *ins, const struct sm6_value **operands, struct sm6_parser *sm6)
Definition: dxil.c:5714
dxil_resource_kind
Definition: dxil.c:185
@ RESOURCE_KIND_TEXTURECUBE
Definition: dxil.c:191
@ RESOURCE_KIND_RAWBUFFER
Definition: dxil.c:197
@ RESOURCE_KIND_TEXTURE1DARRAY
Definition: dxil.c:192
@ RESOURCE_KIND_TEXTURE1D
Definition: dxil.c:187
@ RESOURCE_KIND_TEXTURECUBEARRAY
Definition: dxil.c:195
@ RESOURCE_KIND_CBUFFER
Definition: dxil.c:199
@ RESOURCE_KIND_FEEDBACKTEXTURE2D
Definition: dxil.c:203
@ RESOURCE_KIND_INVALID
Definition: dxil.c:186
@ RESOURCE_KIND_TEXTURE2DARRAY
Definition: dxil.c:193
@ RESOURCE_KIND_TYPEDBUFFER
Definition: dxil.c:196
@ RESOURCE_KIND_RTACCELERATIONSTRUCTURE
Definition: dxil.c:202
@ RESOURCE_KIND_SAMPLER
Definition: dxil.c:200
@ RESOURCE_KIND_TEXTURE3D
Definition: dxil.c:190
@ RESOURCE_KIND_TEXTURE2DMSARRAY
Definition: dxil.c:194
@ RESOURCE_KIND_FEEDBACKTEXTURE2DARRAY
Definition: dxil.c:204
@ RESOURCE_KIND_TEXTURE2DMS
Definition: dxil.c:189
@ RESOURCE_KIND_TBUFFER
Definition: dxil.c:201
@ RESOURCE_KIND_TEXTURE2D
Definition: dxil.c:188
@ RESOURCE_KIND_STRUCTUREDBUFFER
Definition: dxil.c:198
static enum vkd3d_shader_sysval_semantic sysval_semantic_table[]
Definition: dxil.c:8544
static bool sm6_type_is_i8(const struct sm6_type *type)
Definition: dxil.c:1883
static void sm6_parser_emit_dcl_max_tessellation_factor(struct sm6_parser *sm6, struct sm6_metadata_value *m)
Definition: dxil.c:9765
static bool sm6_parser_declare_function(struct sm6_parser *sm6, const struct dxil_record *record)
Definition: dxil.c:2855
static void sm6_parser_emit_dx_input_register_mov(struct sm6_parser *sm6, struct vkd3d_shader_instruction *ins, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type)
Definition: dxil.c:4906
static bool resource_kind_is_multisampled(enum dxil_resource_kind kind)
Definition: dxil.c:2089
static void sm6_parser_declare_tgsm_structured(struct sm6_parser *sm6, const struct sm6_type *elem_type, unsigned int count, unsigned int alignment, unsigned int init, struct sm6_value *dst)
Definition: dxil.c:3473
static bool dxil_block_handle_blockinfo_record(struct dxil_block *block, struct dxil_record *record)
Definition: dxil.c:1016
static enum vkd3d_result sm6_parser_entry_point_init(struct sm6_parser *sm6)
Definition: dxil.c:10026
static void sm6_parser_emit_dx_wave_active_ballot(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:6107
static enum vkd3d_result sm6_parser_metadata_init(struct sm6_parser *sm6, const struct dxil_block *block, struct sm6_metadata_table *table)
Definition: dxil.c:8359
dxil_atomic_ordering
Definition: dxil.c:535
@ ORDERING_ACQUIRE
Definition: dxil.c:539
@ ORDERING_UNORDERED
Definition: dxil.c:537
@ ORDERING_NOTATOMIC
Definition: dxil.c:536
@ ORDERING_ACQREL
Definition: dxil.c:541
@ ORDERING_RELEASE
Definition: dxil.c:540
@ ORDERING_SEQCST
Definition: dxil.c:542
@ ORDERING_MONOTONIC
Definition: dxil.c:538
static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6)
Definition: dxil.c:3704
static enum vkd3d_result sm6_parser_symtab_init(struct sm6_parser *sm6)
Definition: dxil.c:2099
dxil_cast_code
Definition: dxil.c:473
@ CAST_SITOFP
Definition: dxil.c:480
@ CAST_BITCAST
Definition: dxil.c:485
@ CAST_FPTOUI
Definition: dxil.c:477
@ CAST_SEXT
Definition: dxil.c:476
@ CAST_INTTOPTR
Definition: dxil.c:484
@ CAST_ZEXT
Definition: dxil.c:475
@ CAST_ADDRSPACECAST
Definition: dxil.c:486
@ CAST_TRUNC
Definition: dxil.c:474
@ CAST_FPTOSI
Definition: dxil.c:478
@ CAST_PTRTOINT
Definition: dxil.c:483
@ CAST_FPTRUNC
Definition: dxil.c:481
@ CAST_UITOFP
Definition: dxil.c:479
@ CAST_FPEXT
Definition: dxil.c:482
static void sm6_parser_emit_dx_coverage(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:4922
static void dst_param_init(struct vkd3d_shader_dst_param *param)
Definition: dxil.c:2422
static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m)
Definition: dxil.c:9912
static struct vkd3d_shader_instruction * sm6_parser_require_space(struct sm6_parser *sm6, size_t extra)
Definition: dxil.c:3391
static void sm6_parser_emit_dx_fabs(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5101
static enum vkd3d_shader_opcode sm6_dx_map_tertiary_op(enum dx_intrinsic_opcode op)
Definition: dxil.c:5264
static void sm6_parser_emit_dx_buffer_store(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5589
static const struct sm6_block * sm6_function_get_block(const struct sm6_function *function, uint64_t index, struct sm6_parser *sm6)
Definition: dxil.c:4370
static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_record *record, struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
Definition: dxil.c:7139
static bool sm6_value_validate_is_backward_ref(const struct sm6_value *value, struct sm6_parser *sm6)
Definition: dxil.c:2722
static void sm6_parser_emit_dx_barrier(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:4766
static bool sm6_metadata_value_is_string(const struct sm6_metadata_value *m)
Definition: dxil.c:7530
static bool sm6_parser_emit_composite_construct(struct sm6_parser *sm6, const struct sm6_value **operands, unsigned int component_count, struct function_emission_state *state, struct vkd3d_shader_register *reg)
Definition: dxil.c:4480
static enum vkd3d_result sm6_parser_read_abbrev_record(struct sm6_parser *sm6, unsigned int abbrev_id)
Definition: dxil.c:1273
static void sm6_parser_emit_dcl_primitive_topology(struct sm6_parser *sm6, enum vkd3d_shader_opcode handler_idx, enum vkd3d_primitive_type primitive_type, unsigned int patch_vertex_count)
Definition: dxil.c:9695
static bool sm6_value_validate_is_texture_2dms_handle(const struct sm6_value *value, enum dx_intrinsic_opcode op, struct sm6_parser *sm6)
Definition: dxil.c:2670
sm6_type_class
Definition: dxil.c:616
@ TYPE_CLASS_METADATA
Definition: dxil.c:626
@ TYPE_CLASS_FUNCTION
Definition: dxil.c:622
@ TYPE_CLASS_LABEL
Definition: dxil.c:625
@ TYPE_CLASS_VECTOR
Definition: dxil.c:623
@ TYPE_CLASS_FLOAT
Definition: dxil.c:619
@ TYPE_CLASS_POINTER
Definition: dxil.c:620
@ TYPE_CLASS_VOID
Definition: dxil.c:617
@ TYPE_CLASS_ARRAY
Definition: dxil.c:624
@ TYPE_CLASS_STRUCT
Definition: dxil.c:621
@ TYPE_CLASS_INTEGER
Definition: dxil.c:618
static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5059
static float register_get_float_value(const struct vkd3d_shader_register *reg)
Definition: dxil.c:2954
bitcode_constant_code
Definition: dxil.c:103
@ CST_CODE_CE_CAST
Definition: dxil.c:110
@ CST_CODE_NULL
Definition: dxil.c:105
@ CST_CODE_DATA
Definition: dxil.c:113
@ CST_CODE_CE_GEP
Definition: dxil.c:111
@ CST_CODE_UNDEF
Definition: dxil.c:106
@ CST_CODE_STRING
Definition: dxil.c:109
@ CST_CODE_FLOAT
Definition: dxil.c:108
@ CST_CODE_CE_INBOUNDS_GEP
Definition: dxil.c:112
@ CST_CODE_INTEGER
Definition: dxil.c:107
@ CST_CODE_SETTYPE
Definition: dxil.c:104
static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:4858
static bool sm6_metadata_get_float_value(const struct sm6_parser *sm6, const struct sm6_metadata_value *m, float *f)
Definition: dxil.c:7579
static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op)
Definition: dxil.c:4532
static void sm6_parser_emit_dx_get_sample_pos(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5675
static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_type *type_a, const struct sm6_type *type_b, struct sm6_parser *sm6)
Definition: dxil.c:4181
static bool sm6_metadata_value_is_node(const struct sm6_metadata_value *m)
Definition: dxil.c:7520
static void dxil_global_abbrevs_cleanup(struct dxil_global_abbrev **abbrevs, size_t count)
Definition: dxil.c:1524
static const unsigned int MAX_GS_INSTANCE_COUNT
Definition: dxil.c:40
static const uint64_t CALL_CONV_FLAG_EXPLICIT_TYPE
Definition: dxil.c:914
static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_record *record, struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
Definition: dxil.c:7324
static void sm6_parser_metadata_attachments_init(struct sm6_parser *sm6, const struct dxil_block *block)
Definition: dxil.c:7644
static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, const struct vkd3d_shader_register **operand_regs, unsigned int component_count, struct function_emission_state *state, struct vkd3d_shader_register *reg)
Definition: dxil.c:4425
static bool resource_kind_is_texture(enum dxil_resource_kind kind)
Definition: dxil.c:2084
static const char * sm6_parser_get_global_symbol_name(const struct sm6_parser *sm6, size_t id)
Definition: dxil.c:2168
static bool sm6_value_is_ssa(const struct sm6_value *value)
Definition: dxil.c:2270
static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:4988
static bool sm6_type_is_double(const struct sm6_type *type)
Definition: dxil.c:1903
bitcode_block_abbreviation
Definition: dxil.c:71
@ END_BLOCK
Definition: dxil.c:72
@ DEFINE_ABBREV
Definition: dxil.c:74
@ ENTER_SUBBLOCK
Definition: dxil.c:73
@ UNABBREV_RECORD
Definition: dxil.c:75
dxil_fast_fp_flags
Definition: dxil.c:337
@ FP_ALLOW_UNSAFE_ALGEBRA
Definition: dxil.c:338
@ FP_NO_INF
Definition: dxil.c:340
@ FP_NO_SIGNED_ZEROS
Definition: dxil.c:341
@ FP_NO_NAN
Definition: dxil.c:339
@ FP_ALLOW_RECIPROCAL
Definition: dxil.c:342
static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context, struct dxbc_shader_desc *dxbc_desc)
Definition: dxil.c:10256
static const uint64_t ALLOCA_ALIGNMENT_MASK
Definition: dxil.c:34
static int global_symbol_compare(const void *a, const void *b)
Definition: dxil.c:2094
static bool sm6_value_is_dx_intrinsic_dcl(const struct sm6_value *fn)
Definition: dxil.c:2218
static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, const struct sm6_metadata_value *m)
Definition: dxil.c:9626
static bool sm6_value_validate_is_numeric(const struct sm6_value *value, struct sm6_parser *sm6)
Definition: dxil.c:2734
static uint32_t sm6_parser_read_uint32(struct sm6_parser *sm6)
Definition: dxil.c:927
static void register_init_with_id(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int id)
Definition: dxil.c:2342
static void register_make_constant_uint(struct vkd3d_shader_register *reg, unsigned int value)
Definition: dxil.c:2416
bitcode_function_code
Definition: dxil.c:117
@ FUNC_CODE_INST_STORE
Definition: dxil.c:134
@ FUNC_CODE_INST_PHI
Definition: dxil.c:124
@ FUNC_CODE_INST_BR
Definition: dxil.c:122
@ FUNC_CODE_INST_ALLOCA
Definition: dxil.c:125
@ FUNC_CODE_INST_CMP2
Definition: dxil.c:128
@ FUNC_CODE_DECLAREBLOCKS
Definition: dxil.c:118
@ FUNC_CODE_INST_BINOP
Definition: dxil.c:119
@ FUNC_CODE_INST_CAST
Definition: dxil.c:120
@ FUNC_CODE_INST_STOREATOMIC
Definition: dxil.c:135
@ FUNC_CODE_INST_ATOMICRMW
Definition: dxil.c:131
@ FUNC_CODE_INST_VSELECT
Definition: dxil.c:129
@ FUNC_CODE_INST_LOADATOMIC
Definition: dxil.c:132
@ FUNC_CODE_INST_GEP
Definition: dxil.c:133
@ FUNC_CODE_INST_CMPXCHG
Definition: dxil.c:136
@ FUNC_CODE_INST_RET
Definition: dxil.c:121
@ FUNC_CODE_INST_LOAD
Definition: dxil.c:126
@ FUNC_CODE_INST_CALL
Definition: dxil.c:130
@ FUNC_CODE_INST_EXTRACTVAL
Definition: dxil.c:127
@ FUNC_CODE_INST_SWITCH
Definition: dxil.c:123
static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m, enum vkd3d_tessellator_domain tessellator_domain)
Definition: dxil.c:9566
static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struct sm6_value *value, char info_type, const struct sm6_type *ret_type, bool is_return)
Definition: dxil.c:6375
static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_type *from, const struct sm6_type *to, struct sm6_parser *sm6)
Definition: dxil.c:6594
static size_t dxil_block_compute_module_decl_count(const struct dxil_block *block)
Definition: dxil.c:1506
static double bitcast_uint64_to_double(uint64_t value)
Definition: dxil.c:2942
static void sm6_parser_emit_unhandled(struct sm6_parser *sm6, struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
Definition: dxil.c:6473
static void sm6_symtab_cleanup(struct sm6_symbol *symbols, size_t count)
Definition: dxil.c:10196
static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, const struct dxil_record *record, struct sm6_value *dst)
Definition: dxil.c:3043
static bool sm6_type_is_function_pointer(const struct sm6_type *type)
Definition: dxil.c:1970
static bool resources_load_additional_values(struct resource_additional_values *info, const struct sm6_metadata_node *node, enum dxil_resource_kind kind, struct sm6_parser *sm6)
Definition: dxil.c:8733
static bool sm6_parser_read_char6_operand(struct sm6_parser *sm6, uint64_t context, uint64_t *op)
Definition: dxil.c:1126
static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5547
static unsigned int sm6_value_get_constant_uint(const struct sm6_value *value)
Definition: dxil.c:2280
static const uint64_t ALLOCA_FLAG_IN_ALLOCA
Definition: dxil.c:32
static uint64_t sm6_parser_read_vbr(struct sm6_parser *sm6, unsigned int length)
Definition: dxil.c:973
static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5849
static void sm6_parser_emit_dx_unary(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:4613
static bool sm6_type_is_scalar(const struct sm6_type *type)
Definition: dxil.c:1913
static struct sm6_block * sm6_function_create_block(struct sm6_function *function)
Definition: dxil.c:7811
static enum vkd3d_data_type data_type_table[]
Definition: dxil.c:8688
static void sm6_functions_cleanup(struct sm6_function *functions, size_t count)
Definition: dxil.c:10222
static void sm6_parser_emit_dx_make_double(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5361
static void metadata_attachment_record_apply(const struct dxil_record *record, enum bitcode_function_code func_code, struct vkd3d_shader_instruction *ins, struct sm6_value *dst, struct sm6_parser *sm6)
Definition: dxil.c:7708
static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const struct dxil_block *block, unsigned int level)
Definition: dxil.c:8173
static void sm6_parser_emit_dx_primitive_id(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5387
static void sm6_metadata_value_destroy(struct sm6_metadata_value *m)
Definition: dxil.c:10134
bitcode_address_space
Definition: dxil.c:88
@ ADDRESS_SPACE_GROUPSHARED
Definition: dxil.c:92
@ ADDRESS_SPACE_DEFAULT
Definition: dxil.c:89
@ ADDRESS_SPACE_DEVICEMEM
Definition: dxil.c:90
@ ADDRESS_SPACE_CBUFFER
Definition: dxil.c:91
static enum vkd3d_shader_opcode map_dx_atomic_binop(const struct sm6_value *operand, struct sm6_parser *sm6)
Definition: dxil.c:4667
static void sm6_parser_cleanup(struct sm6_parser *sm6)
Definition: dxil.c:10235
static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind(enum vkd3d_shader_sysval_semantic sysval_semantic)
Definition: dxil.c:3826
static void sm6_parser_metadata_cleanup(struct sm6_parser *sm6)
Definition: dxil.c:10152
static enum vkd3d_shader_minimum_precision minimum_precision_from_dxil_component_type(enum dxil_component_type type)
Definition: dxil.c:8529
static void register_index_address_init(struct vkd3d_shader_register_index *idx, const struct sm6_value *address, struct sm6_parser *sm6)
Definition: dxil.c:2497
static bool sm6_type_is_struct(const struct sm6_type *type)
Definition: dxil.c:1960
static const unsigned int SHADER_DESCRIPTOR_TYPE_COUNT
Definition: dxil.c:35
static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_record *record, struct sm6_function *function, struct sm6_block *code_block, struct vkd3d_shader_instruction *ins)
Definition: dxil.c:7401
static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5886
dxil_overflowing_binop_flags
Definition: dxil.c:346
@ OB_NO_SIGNED_WRAP
Definition: dxil.c:349
@ OB_NO_UNSIGNED_WRAP
Definition: dxil.c:348
static void sm6_parser_emit_dx_sample_index(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5806
static void sm6_parser_emit_dx_calculate_lod(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:4824
static void dst_param_init_vector(struct vkd3d_shader_dst_param *param, unsigned int component_count)
Definition: dxil.c:2443
static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_record *record, struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
Definition: dxil.c:6701
static void sm6_type_table_cleanup(struct sm6_type *types, size_t count)
Definition: dxil.c:10170
static bool metadata_node_get_unary_uint(const struct sm6_metadata_node *node, unsigned int *operand, struct sm6_parser *sm6)
Definition: dxil.c:7686
static bool dxil_record_validate_operand_count(const struct dxil_record *record, unsigned int min_count, unsigned int max_count, struct sm6_parser *sm6)
Definition: dxil.c:1596
static void sm6_parser_align_32(struct sm6_parser *sm6)
Definition: dxil.c:1001
static uint64_t sm6_value_get_constant_uint64(const struct sm6_value *value)
Definition: dxil.c:2287
dx_intrinsic_opcode
Definition: dxil.c:359
@ DX_SAMPLE_C
Definition: dxil.c:411
@ DX_CALCULATE_LOD
Definition: dxil.c:427
@ DX_BFREV
Definition: dxil.c:385
@ DX_UMAX
Definition: dxil.c:394
@ DX_LEGACY_F32TOF16
Definition: dxil.c:464
@ DX_WAVE_PREFIX_OP
Definition: dxil.c:461
@ DX_LEGACY_F16TOF32
Definition: dxil.c:465
@ DX_ROUND_Z
Definition: dxil.c:384
@ DX_SAMPLE
Definition: dxil.c:407
@ DX_WAVE_PREFIX_BIT_COUNT
Definition: dxil.c:467
@ DX_FMA
Definition: dxil.c:397
@ DX_SAMPLE_LOD
Definition: dxil.c:409
@ DX_EXP
Definition: dxil.c:376
@ DX_CUT_STREAM
Definition: dxil.c:440
@ DX_DERIV_FINEY
Definition: dxil.c:432
@ DX_ISFINITE
Definition: dxil.c:366
@ DX_ISNAN
Definition: dxil.c:364
@ DX_STORE_OUTPUT
Definition: dxil.c:361
@ DX_COS
Definition: dxil.c:367
@ DX_DERIV_FINEX
Definition: dxil.c:431
@ DX_FMIN
Definition: dxil.c:391
@ DX_WAVE_ALL_TRUE
Definition: dxil.c:454
@ DX_ROUND_NI
Definition: dxil.c:382
@ DX_HCOS
Definition: dxil.c:373
@ DX_ASIN
Definition: dxil.c:371
@ DX_RSQRT
Definition: dxil.c:380
@ DX_QUAD_OP
Definition: dxil.c:463
@ DX_WAVE_READ_LANE_FIRST
Definition: dxil.c:458
@ DX_TEX2DMS_GET_SAMPLE_POS
Definition: dxil.c:421
@ DX_FMAD
Definition: dxil.c:396
@ DX_SAMPLE_INDEX
Definition: dxil.c:433
@ DX_ISINF
Definition: dxil.c:365
@ DX_WAVE_ACTIVE_BALLOT
Definition: dxil.c:456
@ DX_BUFFER_STORE
Definition: dxil.c:416
@ DX_DOT4
Definition: dxil.c:404
@ DX_SAMPLE_B
Definition: dxil.c:408
@ DX_FIRST_BIT_LO
Definition: dxil.c:387
@ DX_LOAD_INPUT
Definition: dxil.c:360
@ DX_COUNT_BITS
Definition: dxil.c:386
@ DX_TEXTURE_GATHER
Definition: dxil.c:419
@ DX_EMIT_STREAM
Definition: dxil.c:439
@ DX_IMIN
Definition: dxil.c:393
@ DX_ATOMIC_BINOP
Definition: dxil.c:424
@ DX_TEXTURE_STORE
Definition: dxil.c:414
@ DX_DOT3
Definition: dxil.c:403
@ DX_STORE_PATCH_CONSTANT
Definition: dxil.c:447
@ DX_QUAD_READ_LANE_AT
Definition: dxil.c:462
@ DX_TEXTURE_GATHER_CMP
Definition: dxil.c:420
@ DX_BUFFER_UPDATE_COUNTER
Definition: dxil.c:417
@ DX_THREAD_ID
Definition: dxil.c:435
@ DX_SPLIT_DOUBLE
Definition: dxil.c:443
@ DX_UMAD
Definition: dxil.c:399
@ DX_DOT2
Definition: dxil.c:402
@ DX_SQRT
Definition: dxil.c:379
@ DX_THREAD_ID_IN_GROUP
Definition: dxil.c:437
@ DX_FIRST_BIT_HI
Definition: dxil.c:388
@ DX_WAVE_IS_FIRST_LANE
Definition: dxil.c:450
@ DX_SAMPLE_GRAD
Definition: dxil.c:410
@ DX_WAVE_ACTIVE_ALL_EQUAL
Definition: dxil.c:455
@ DX_PRIMITIVE_ID
Definition: dxil.c:449
@ DX_RAW_BUFFER_LOAD
Definition: dxil.c:468
@ DX_LOG
Definition: dxil.c:378
@ DX_RT_GET_SAMPLE_COUNT
Definition: dxil.c:423
@ DX_ACOS
Definition: dxil.c:370
@ DX_DOMAIN_LOCATION
Definition: dxil.c:446
@ DX_UBFE
Definition: dxil.c:401
@ DX_IMAD
Definition: dxil.c:398
@ DX_DERIV_COARSEY
Definition: dxil.c:430
@ DX_ATOMIC_CMP_XCHG
Definition: dxil.c:425
@ DX_SATURATE
Definition: dxil.c:363
@ DX_LOAD_OUTPUT_CONTROL_POINT
Definition: dxil.c:444
@ DX_SIN
Definition: dxil.c:368
@ DX_IMAX
Definition: dxil.c:392
@ DX_MAKE_DOUBLE
Definition: dxil.c:442
@ DX_ROUND_NE
Definition: dxil.c:381
@ DX_ATAN
Definition: dxil.c:372
@ DX_WAVE_ALL_BIT_COUNT
Definition: dxil.c:466
@ DX_FABS
Definition: dxil.c:362
@ DX_HTAN
Definition: dxil.c:375
@ DX_WAVE_ANY_TRUE
Definition: dxil.c:453
@ DX_WAVE_GET_LANE_COUNT
Definition: dxil.c:452
@ DX_DISCARD
Definition: dxil.c:428
@ DX_RAW_BUFFER_STORE
Definition: dxil.c:469
@ DX_RT_GET_SAMPLE_POS
Definition: dxil.c:422
@ DX_WAVE_READ_LANE_AT
Definition: dxil.c:457
@ DX_FIRST_BIT_SHI
Definition: dxil.c:389
@ DX_FMAX
Definition: dxil.c:390
@ DX_LOAD_PATCH_CONSTANT
Definition: dxil.c:445
@ DX_BUFFER_LOAD
Definition: dxil.c:415
@ DX_TEXTURE_LOAD
Definition: dxil.c:413
@ DX_GET_DIMENSIONS
Definition: dxil.c:418
@ DX_SAMPLE_C_LZ
Definition: dxil.c:412
@ DX_TAN
Definition: dxil.c:369
@ DX_UMIN
Definition: dxil.c:395
@ DX_EMIT_THEN_CUT_STREAM
Definition: dxil.c:441
@ DX_BARRIER
Definition: dxil.c:426
@ DX_GROUP_ID
Definition: dxil.c:436
@ DX_COVERAGE
Definition: dxil.c:434
@ DX_IBFE
Definition: dxil.c:400
@ DX_DERIV_COARSEX
Definition: dxil.c:429
@ DX_WAVE_GET_LANE_INDEX
Definition: dxil.c:451
@ DX_FLATTENED_THREAD_ID_IN_GROUP
Definition: dxil.c:438
@ DX_ROUND_PI
Definition: dxil.c:383
@ DX_WAVE_ACTIVE_OP
Definition: dxil.c:459
@ DX_FRC
Definition: dxil.c:377
@ DX_CREATE_HANDLE
Definition: dxil.c:405
@ DX_CBUFFER_LOAD_LEGACY
Definition: dxil.c:406
@ DX_HSIN
Definition: dxil.c:374
@ DX_OUTPUT_CONTROL_POINT_ID
Definition: dxil.c:448
@ DX_WAVE_ACTIVE_BIT
Definition: dxil.c:460
static void sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct shader_signature *input_signature)
Definition: dxil.c:3917
static enum vkd3d_result metadata_value_create_node(struct sm6_metadata_value *m, struct sm6_metadata_table *table, unsigned int dst_idx, unsigned int end_count, const struct dxil_record *record, struct sm6_parser *sm6)
Definition: dxil.c:8293
static void sm6_parser_emit_dx_tertiary(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5277
static const struct vkd3d_shader_immediate_constant_buffer * resolve_forward_initialiser(size_t index, struct sm6_parser *sm6)
Definition: dxil.c:3650
static bool sm6_type_is_function(const struct sm6_type *type)
Definition: dxil.c:1965
#define VKD3D_SM6_VERSION_MAJOR(version)
Definition: dxil.c:21
#define BITCODE_MAGIC
Definition: dxil.c:26
static void sm6_parser_emit_dx_split_double(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5872
static bool sm6_type_is_pointer(const struct sm6_type *type)
Definition: dxil.c:1923
static void dxil_record_validate_operand_max_count(const struct dxil_record *record, unsigned int max_count, struct sm6_parser *sm6)
Definition: dxil.c:1585
static const uint64_t GLOBALVAR_FLAG_EXPLICIT_TYPE
Definition: dxil.c:30
static bool sm6_type_is_handle(const struct sm6_type *type)
Definition: dxil.c:1975
static bool sm6_value_is_register(const struct sm6_value *value)
Definition: dxil.c:2230
static bool sm6_value_validate_is_pointer(const struct sm6_value *value, struct sm6_parser *sm6)
Definition: dxil.c:2710
static void sm6_parser_metadata_attachment_block_init(struct sm6_parser *sm6, const struct dxil_block *target_block, const struct dxil_block *block)
Definition: dxil.c:7598
static const uint64_t GLOBALVAR_FLAG_IS_CONSTANT
Definition: dxil.c:29
static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6, const struct sm6_metadata_value *m, uint64_t *u)
Definition: dxil.c:7560
static void signature_element_read_additional_element_values(struct signature_element *e, const struct sm6_metadata_node *node, struct sm6_parser *sm6)
Definition: dxil.c:9281
static size_t dxil_block_compute_function_count(const struct dxil_block *root)
Definition: dxil.c:1496
static uint64_t decode_rotated_signed_value(uint64_t value)
Definition: dxil.c:2919
static void dst_param_init_ssa_scalar(struct vkd3d_shader_dst_param *param, const struct sm6_type *type, struct sm6_value *value, struct sm6_parser *sm6)
Definition: dxil.c:2450
static const struct sm6_type * sm6_type_get_element_type_at_index(const struct sm6_type *type, uint64_t elem_idx)
Definition: dxil.c:2023
static enum vkd3d_result sm6_parser_add_block_abbrev(struct sm6_parser *sm6)
Definition: dxil.c:1244
bitcode_blockinfo_code
Definition: dxil.c:64
@ SETRECORDNAME
Definition: dxil.c:67
@ BLOCKNAME
Definition: dxil.c:66
@ SETBID
Definition: dxil.c:65
static bool sm6_metadata_value_is_zero_or_undef(const struct sm6_metadata_value *m)
Definition: dxil.c:7535
static const struct sm6_value * sm6_parser_get_value_by_ref(struct sm6_parser *sm6, const struct dxil_record *record, const struct sm6_type *type, unsigned int *rec_idx)
Definition: dxil.c:2848
dxil_element_additional_tag
Definition: dxil.c:283
@ ADDITIONAL_TAG_USED_MASK
Definition: dxil.c:287
@ ADDITIONAL_TAG_RELADDR_MASK
Definition: dxil.c:286
@ ADDITIONAL_TAG_GLOBAL_SYMBOL
Definition: dxil.c:285
@ ADDITIONAL_TAG_STREAM_INDEX
Definition: dxil.c:284
static enum vkd3d_shader_opcode dx_map_quad_op(enum dxil_quad_op_kind op)
Definition: dxil.c:5393
static void sm6_parser_emit_br(struct sm6_parser *sm6, const struct dxil_record *record, struct sm6_function *function, struct sm6_block *code_block, struct vkd3d_shader_instruction *ins)
Definition: dxil.c:4383
static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_record *record, struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
Definition: dxil.c:3983
static void sm6_parser_emit_dx_discard(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5020
static enum vkd3d_shader_component_type vkd3d_component_type_from_dxil_component_type(enum dxil_component_type type)
Definition: dxil.c:8502
static bool sm6_value_vector_is_constant_or_undef(const struct sm6_value **values, unsigned int count)
Definition: dxil.c:2256
static void sm6_block_destroy(struct sm6_block *block)
Definition: dxil.c:10210
static unsigned int sm6_value_get_texel_offset(const struct sm6_value *value)
Definition: dxil.c:5709
bitcode_abbrev_type
Definition: dxil.c:79
@ ABBREV_CHAR
Definition: dxil.c:83
@ ABBREV_VBR
Definition: dxil.c:81
@ ABBREV_ARRAY
Definition: dxil.c:82
@ ABBREV_FIXED
Definition: dxil.c:80
@ ABBREV_BLOB
Definition: dxil.c:84
static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_parser *sm6)
Definition: dxil.c:8050
static void init_resource_declaration(struct vkd3d_shader_resource *resource, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int id, const struct vkd3d_shader_register_range *range)
Definition: dxil.c:8897
static bool sm6_type_is_void(const struct sm6_type *type)
Definition: dxil.c:1858
static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:6057
static enum vkd3d_shader_opcode map_dx_binary_op(enum dx_intrinsic_opcode op, const struct sm6_type *type)
Definition: dxil.c:4627
static void sm6_parser_emit_dx_compute_builtin(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5116
static enum vkd3d_result sm6_function_emit_blocks(const struct sm6_function *function, struct sm6_parser *sm6)
Definition: dxil.c:8242
#define VKD3D_SM6_VERSION_MINOR(version)
Definition: dxil.c:22
static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6, const struct sm6_metadata_node *node, struct sm6_descriptor_info *d, struct vkd3d_shader_instruction *ins)
Definition: dxil.c:9035
static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, const struct sm6_type *type, const uint64_t *operands, struct sm6_parser *sm6)
Definition: dxil.c:2971
static const size_t MAX_IR_INSTRUCTIONS_PER_DXIL_INSTRUCTION
Definition: dxil.c:36
dxil_input_primitive
Definition: dxil.c:291
@ INPUT_PRIMITIVE_TRIANGLEWITHADJACENY
Definition: dxil.c:297
@ INPUT_PRIMITIVE_LINEWITHADJACENCY
Definition: dxil.c:296
@ INPUT_PRIMITIVE_TRIANGLE
Definition: dxil.c:295
@ INPUT_PRIMITIVE_POINT
Definition: dxil.c:293
@ INPUT_PRIMITIVE_UNDEFINED
Definition: dxil.c:292
@ INPUT_PRIMITIVE_LINE
Definition: dxil.c:294
@ INPUT_PRIMITIVE_PATCH1
Definition: dxil.c:298
@ INPUT_PRIMITIVE_PATCH32
Definition: dxil.c:299
static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5293
static enum vkd3d_shader_opcode sm6_dx_map_wave_op(enum dxil_wave_op_kind op, bool is_signed, bool is_float, struct sm6_parser *sm6)
Definition: dxil.c:6161
static void sm6_parser_emit_dx_quad_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5408
static enum vkd3d_result sm6_parser_resources_load_srv(struct sm6_parser *sm6, const struct sm6_metadata_node *node, struct sm6_descriptor_info *d, struct vkd3d_shader_instruction *ins)
Definition: dxil.c:8913
static const struct sm6_type * sm6_parser_get_type(struct sm6_parser *sm6, uint64_t type_id)
Definition: dxil.c:2072
static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6_type *elem_type, unsigned int alignment, unsigned int init, struct sm6_value *dst)
Definition: dxil.c:3448
static void sm6_parser_emit_dx_wave_builtin(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:6212
static enum vkd3d_data_type vkd3d_data_type_from_dxil_component_type(enum dxil_component_type type, struct sm6_parser *sm6)
Definition: dxil.c:8711
static bool sm6_value_is_undef(const struct sm6_value *value)
Definition: dxil.c:2251
static const struct sm6_descriptor_info * sm6_parser_get_descriptor(struct sm6_parser *sm6, enum vkd3d_shader_descriptor_type type, unsigned int id, const struct sm6_value *address)
Definition: dxil.c:4928
static void dxil_block_destroy(struct dxil_block *block)
Definition: dxil.c:1430
static void dst_param_io_init(struct vkd3d_shader_dst_param *param, const struct signature_element *e, enum vkd3d_shader_register_type reg_type)
Definition: dxil.c:3803
static uint64_t register_get_uint64_value(const struct vkd3d_shader_register *reg)
Definition: dxil.c:2202
static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_record *record, struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
Definition: dxil.c:7484
static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_record *record, struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
Definition: dxil.c:6796
static enum vkd3d_shader_opcode sm6_dx_map_ma_op(enum dx_intrinsic_opcode op, const struct sm6_type *type)
Definition: dxil.c:5158
static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type *type)
Definition: dxil.c:2349
static bool sm6_value_is_numeric_array(const struct sm6_value *value)
Definition: dxil.c:2275
static void sm6_parser_emit_dcl_count(struct sm6_parser *sm6, enum vkd3d_shader_opcode handler_idx, unsigned int count)
Definition: dxil.c:9687
static bool instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6)
Definition: dxil.c:2520
static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_record *record)
Definition: dxil.c:3500
static bool instruction_dst_param_init_temp_vector(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6)
Definition: dxil.c:2545
static bool sm6_value_validate_is_pointer_to_i32(const struct sm6_value *value, struct sm6_parser *sm6)
Definition: dxil.c:2759
static struct vkd3d_shader_instruction * sm6_parser_add_instruction(struct sm6_parser *sm6, enum vkd3d_shader_opcode handler_idx)
Definition: dxil.c:3404
static void sm6_parser_init_patch_constant_signature(struct sm6_parser *sm6, const struct shader_signature *patch_constant_signature)
Definition: dxil.c:3922
static void sm6_parser_emit_dx_saturate(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5834
static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const struct dxil_block *block)
Definition: dxil.c:3159
static const struct sm6_metadata_value * sm6_parser_find_metadata_kind(const struct sm6_parser *sm6, uint64_t id)
Definition: dxil.c:7655
static void sm6_parser_emit_dx_ma(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5174
static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const struct dxil_record *record, const struct sm6_type *fwd_type, unsigned int *rec_idx)
Definition: dxil.c:2794
static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:6012
static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_record *record, struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
Definition: dxil.c:6897
sm6_block_terminator_type
Definition: dxil.c:708
@ TERMINATOR_RET
Definition: dxil.c:712
@ TERMINATOR_UNCOND_BR
Definition: dxil.c:709
@ TERMINATOR_SWITCH
Definition: dxil.c:711
@ TERMINATOR_COND_BR
Definition: dxil.c:710
static struct sm6_function * sm6_parser_get_function(const struct sm6_parser *sm6, const char *name)
Definition: dxil.c:10247
static bool sm6_value_validate_is_bool(const struct sm6_value *value, struct sm6_parser *sm6)
Definition: dxil.c:2746
static void instruction_init_with_resource(struct vkd3d_shader_instruction *ins, enum vkd3d_shader_opcode handler_idx, const struct sm6_value *resource, struct sm6_parser *sm6)
Definition: dxil.c:2299
static enum vkd3d_shader_opcode sm6_dx_map_void_op(enum dx_intrinsic_opcode op)
Definition: dxil.c:4513
static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, enum vkd3d_shader_descriptor_type type, const struct sm6_metadata_node *descriptor_node)
Definition: dxil.c:9148
static enum vkd3d_tessellator_domain sm6_parser_hs_properties_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m)
Definition: dxil.c:9960
static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil_record *record, struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
Definition: dxil.c:6979
bitcode_value_symtab_code
Definition: dxil.c:172
@ VST_CODE_ENTRY
Definition: dxil.c:173
@ VST_CODE_BBENTRY
Definition: dxil.c:174
static bool sm6_value_is_icb(const struct sm6_value *value)
Definition: dxil.c:2265
static void src_param_init(struct vkd3d_shader_src_param *param)
Definition: dxil.c:2457
bitcode_type_code
Definition: dxil.c:153
@ TYPE_CODE_ARRAY
Definition: dxil.c:162
@ TYPE_CODE_DOUBLE
Definition: dxil.c:157
@ TYPE_CODE_LABEL
Definition: dxil.c:158
@ TYPE_CODE_NUMENTRY
Definition: dxil.c:154
@ TYPE_CODE_STRUCT_ANON
Definition: dxil.c:165
@ TYPE_CODE_INTEGER
Definition: dxil.c:159
@ TYPE_CODE_VECTOR
Definition: dxil.c:163
@ TYPE_CODE_STRUCT_NAMED
Definition: dxil.c:167
@ TYPE_CODE_FUNCTION
Definition: dxil.c:168
@ TYPE_CODE_STRUCT_NAME
Definition: dxil.c:166
@ TYPE_CODE_POINTER
Definition: dxil.c:160
@ TYPE_CODE_FLOAT
Definition: dxil.c:156
@ TYPE_CODE_VOID
Definition: dxil.c:155
@ TYPE_CODE_METADATA
Definition: dxil.c:164
@ TYPE_CODE_HALF
Definition: dxil.c:161
dxil_predicate
Definition: dxil.c:490
@ FCMP_OEQ
Definition: dxil.c:492
@ FCMP_OGE
Definition: dxil.c:494
@ FCMP_UEQ
Definition: dxil.c:500
@ ICMP_NE
Definition: dxil.c:508
@ ICMP_ULT
Definition: dxil.c:511
@ FCMP_ULT
Definition: dxil.c:503
@ ICMP_UGE
Definition: dxil.c:510
@ ICMP_SGT
Definition: dxil.c:513
@ FCMP_UGE
Definition: dxil.c:502
@ ICMP_SLT
Definition: dxil.c:515
@ FCMP_FALSE
Definition: dxil.c:491
@ FCMP_OLE
Definition: dxil.c:496
@ FCMP_OLT
Definition: dxil.c:495
@ ICMP_UGT
Definition: dxil.c:509
@ FCMP_ONE
Definition: dxil.c:497
@ ICMP_SGE
Definition: dxil.c:514
@ FCMP_ULE
Definition: dxil.c:504
@ FCMP_UNO
Definition: dxil.c:499
@ FCMP_TRUE
Definition: dxil.c:506
@ FCMP_UNE
Definition: dxil.c:505
@ FCMP_ORD
Definition: dxil.c:498
@ FCMP_UGT
Definition: dxil.c:501
@ ICMP_EQ
Definition: dxil.c:507
@ ICMP_SLE
Definition: dxil.c:516
@ FCMP_OGT
Definition: dxil.c:493
@ ICMP_ULE
Definition: dxil.c:512
static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5722
static bool sm6_value_validate_is_texture_handle(const struct sm6_value *value, enum dx_intrinsic_opcode op, struct sm6_parser *sm6)
Definition: dxil.c:2650
#define DXIL_OP_MAX_OPERANDS
Definition: dxil.c:27
static bool sm6_value_validate_is_register(const struct sm6_value *value, struct sm6_parser *sm6)
Definition: dxil.c:2626
dxil_wave_bit_op_kind
Definition: dxil.c:568
@ WAVE_BIT_OP_AND
Definition: dxil.c:569
@ WAVE_BIT_OP_XOR
Definition: dxil.c:571
@ WAVE_BIT_OP_OR
Definition: dxil.c:570
static bool sm6_parser_read_literal_operand(struct sm6_parser *sm6, uint64_t context, uint64_t *op)
Definition: dxil.c:1108
dxil_sync_flags
Definition: dxil.c:560
@ SYNC_THREAD_GROUP_UAV
Definition: dxil.c:563
@ SYNC_THREAD_GROUP
Definition: dxil.c:561
@ SYNC_GROUP_SHARED_MEMORY
Definition: dxil.c:564
@ SYNC_GLOBAL_UAV
Definition: dxil.c:562
bitcode_linkage
Definition: dxil.c:178
@ LINKAGE_APPENDING
Definition: dxil.c:180
@ LINKAGE_EXTERNAL
Definition: dxil.c:179
@ LINKAGE_INTERNAL
Definition: dxil.c:181
dxil_component_type
Definition: dxil.c:216
@ COMPONENT_TYPE_PACKEDS8X32
Definition: dxil.c:234
@ COMPONENT_TYPE_F32
Definition: dxil.c:226
@ COMPONENT_TYPE_U64
Definition: dxil.c:224
@ COMPONENT_TYPE_U32
Definition: dxil.c:222
@ COMPONENT_TYPE_I16
Definition: dxil.c:219
@ COMPONENT_TYPE_I64
Definition: dxil.c:223
@ COMPONENT_TYPE_INVALID
Definition: dxil.c:217
@ COMPONENT_TYPE_UNORMF16
Definition: dxil.c:229
@ COMPONENT_TYPE_PACKEDU8X32
Definition: dxil.c:235
@ COMPONENT_TYPE_SNORMF16
Definition: dxil.c:228
@ COMPONENT_TYPE_I1
Definition: dxil.c:218
@ COMPONENT_TYPE_F64
Definition: dxil.c:227
@ COMPONENT_TYPE_UNORMF64
Definition: dxil.c:233
@ COMPONENT_TYPE_I32
Definition: dxil.c:221
@ COMPONENT_TYPE_F16
Definition: dxil.c:225
@ COMPONENT_TYPE_U16
Definition: dxil.c:220
@ COMPONENT_TYPE_UNORMF32
Definition: dxil.c:231
@ COMPONENT_TYPE_SNORMF64
Definition: dxil.c:232
@ COMPONENT_TYPE_SNORMF32
Definition: dxil.c:230
static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shader_signature *s, bool is_input, enum vkd3d_shader_register_type reg_type, struct vkd3d_shader_dst_param *params)
Definition: dxil.c:3849
static struct vkd3d_shader_dst_param * instruction_dst_params_alloc(struct vkd3d_shader_instruction *ins, unsigned int count, struct sm6_parser *sm6)
Definition: dxil.c:2325
static const unsigned int MAX_GS_OUTPUT_TOTAL_SCALARS
Definition: dxil.c:41
static void src_param_init_vector(struct vkd3d_shader_src_param *param, unsigned int component_count)
Definition: dxil.c:2471
dxil_possibly_exact_binop_flags
Definition: dxil.c:353
@ PEB_EXACT
Definition: dxil.c:355
static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:5477
static const struct sm6_cmp_info * sm6_map_cmp2_op(uint64_t code)
Definition: dxil.c:6760
#define VKD3D_SHADER_SWIZZLE_64_MASK
Definition: dxil.c:44
static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:4700
static enum vkd3d_shader_opcode map_dx_atomicrmw_op(uint64_t code)
Definition: dxil.c:4058
static enum vkd3d_result sm6_parser_read_unabbrev_record(struct sm6_parser *sm6)
Definition: dxil.c:1077
static void sm6_parser_emit_label(struct sm6_parser *sm6, unsigned int label_id)
Definition: dxil.c:8230
static bool sm6_value_validate_is_sampler_handle(const struct sm6_value *value, enum dx_intrinsic_opcode op, struct sm6_parser *sm6)
Definition: dxil.c:2690
static void sm6_parser_emit_dcl_tessellator_domain(struct sm6_parser *sm6, enum vkd3d_tessellator_domain tessellator_domain)
Definition: dxil.c:9706
static bool sm6_type_is_array(const struct sm6_type *type)
Definition: dxil.c:1955
static int phi_incoming_compare(const void *a, const void *b)
Definition: dxil.c:7214
static void src_params_init_from_operands(struct vkd3d_shader_src_param *src_params, const struct sm6_value **operands, unsigned int count)
Definition: dxil.c:3817
static bool sm6_value_is_handle(const struct sm6_value *value)
Definition: dxil.c:2235
static bool sm6_type_is_i32(const struct sm6_type *type)
Definition: dxil.c:1888
static void dst_param_init_scalar(struct vkd3d_shader_dst_param *param, unsigned int component_idx)
Definition: dxil.c:2436
static unsigned int sm6_parser_alloc_ssa_id(struct sm6_parser *sm6)
Definition: dxil.c:2294
static struct sm6_phi * sm6_block_phi_require_space(struct sm6_block *block, struct sm6_parser *sm6)
Definition: dxil.c:3953
static enum vkd3d_result sm6_parser_resources_init(struct sm6_parser *sm6)
Definition: dxil.c:9242
static bool sm6_function_blocks_reserve(struct sm6_function *function, unsigned int reserve)
Definition: dxil.c:7800
static bool sm6_type_is_i16_i32_i64(const struct sm6_type *type)
Definition: dxil.c:1873
dxil_atomic_binop_code
Definition: dxil.c:546
@ ATOMIC_BINOP_IMAX
Definition: dxil.c:552
@ ATOMIC_BINOP_IMIN
Definition: dxil.c:551
@ ATOMIC_BINOP_INVALID
Definition: dxil.c:556
@ ATOMIC_BINOP_XCHG
Definition: dxil.c:555
@ ATOMIC_BINOP_XOR
Definition: dxil.c:550
@ ATOMIC_BINOP_AND
Definition: dxil.c:548
@ ATOMIC_BINOP_UMIN
Definition: dxil.c:553
@ ATOMIC_BINOP_ADD
Definition: dxil.c:547
@ ATOMIC_BINOP_UMAX
Definition: dxil.c:554
@ ATOMIC_BINOP_OR
Definition: dxil.c:549
dxil_rmw_code
Definition: dxil.c:520
@ RMW_XOR
Definition: dxil.c:527
@ RMW_NAND
Definition: dxil.c:525
@ RMW_OR
Definition: dxil.c:526
@ RMW_AND
Definition: dxil.c:524
@ RMW_XCHG
Definition: dxil.c:521
@ RMW_UMAX
Definition: dxil.c:530
@ RMW_ADD
Definition: dxil.c:522
@ RMW_MIN
Definition: dxil.c:529
@ RMW_SUB
Definition: dxil.c:523
@ RMW_UMIN
Definition: dxil.c:531
@ RMW_MAX
Definition: dxil.c:528
static void sm6_parser_emit_dx_buffer_update_counter(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state)
Definition: dxil.c:4787
uint8_t ignored[3]
Definition: fsck.fat.h:0
Character const *const size_t const max_count
Definition: fullpath.cpp:66
GLuint start
Definition: gl.h:1545
GLint level
Definition: gl.h:1546
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei width
Definition: gl.h:1546
GLuint address
Definition: glext.h:9393
GLenum src
Definition: glext.h:6340
GLuint GLenum swizzle
Definition: glext.h:9511
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLenum clamp
Definition: glext.h:6216
GLintptr offset
Definition: glext.h:5920
GLuint coord
Definition: glext.h:9511
GLuint sampler
Definition: glext.h:7283
GLsizei const GLvoid * pointer
Definition: glext.h:5848
GLuint index
Definition: glext.h:6031
GLenum GLint GLuint mask
Definition: glext.h:6028
GLuint program
Definition: glext.h:6723
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum const GLfloat * params
Definition: glext.h:5645
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
GLenum GLenum dst
Definition: glext.h:6340
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint64EXT * result
Definition: glext.h:11304
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat param
Definition: glext.h:5796
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLuint id
Definition: glext.h:5910
const GLfloat * m
Definition: glext.h:10848
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
enum wined3d_data_type data_type
Definition: glsl_shader.c:71
type_id
static int reg
Definition: i386-dis.c:1290
@ extra
Definition: id3.c:95
#define bits
Definition: infblock.c:15
bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, const struct vkd3d_shader_version *version, unsigned int reserve, enum vsir_control_flow_type cf_type, enum vsir_normalisation_level normalisation_level)
Definition: ir.c:76
struct vkd3d_shader_src_param * vsir_program_create_outpointid_param(struct vsir_program *program)
Definition: ir.c:1336
void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id)
Definition: ir.c:204
void vsir_program_cleanup(struct vsir_program *program)
Definition: ir.c:105
void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int idx_count)
Definition: ir.c:164
bool vsir_signature_find_sysval(const struct shader_signature *signature, enum vkd3d_shader_sysval_semantic sysval, unsigned int semantic_index, unsigned int *element_index)
Definition: ir.c:145
void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int idx_count)
Definition: ir.c:190
void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int idx_count)
Definition: ir.c:272
void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, enum vkd3d_shader_opcode opcode)
Definition: ir.c:321
static BOOL is_undefined(jsval_t v)
Definition: jsval.h:180
static BOOL is_bool(jsval_t v)
Definition: jsval.h:214
#define d
Definition: ke_i.h:81
#define e
Definition: ke_i.h:82
#define a
Definition: ke_i.h:78
#define b
Definition: ke_i.h:79
#define resource
Definition: kernel32.h:9
if(dx< 0)
Definition: linetemp.h:194
static int blocks
Definition: mkdosfs.c:527
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define MESSAGE
Definition: options.h:86
static PVOID ptr
Definition: dispmode.c:27
#define cmp(status, error)
Definition: error.c:118
#define shift
Definition: input.c:3280
#define min(a, b)
Definition: monoChain.cc:55
#define uint32_t
Definition: nsiface.idl:61
#define uint64_t
Definition: nsiface.idl:62
#define bool
Definition: nsiface.idl:72
static BOOL is_float(parse_buffer *buf)
Definition: parsing.c:520
for(i=0;i< sizeof(testsuite)/sizeof(testsuite[0]);++i) ok(call_test(testsuite[i].func)
const WCHAR * str
static calc_node_t temp
Definition: rpn_ieee.c:38
#define offsetof(TYPE, MEMBER)
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
CardRegion * from
Definition: spigame.cpp:19
enum vkd3d_shader_register_type reg_type
Definition: spirv.c:4885
wchar_t const *const size_t const buffer_size
Definition: stat.cpp:95
uint64_t id
Definition: btrfs_drv.h:451
Definition: undname.c:54
enum code_block_type type
Definition: interpreter.c:95
Definition: inflate.c:139
Definition: http.c:7252
Definition: cookie.c:42
const uint32_t * byte_code
struct shader_signature input_signature
struct shader_signature patch_constant_signature
struct shader_signature output_signature
uint64_t context
Definition: dxil.c:897
bool(* read_operand)(struct sm6_parser *sm6, uint64_t context, uint64_t *operand)
Definition: dxil.c:898
bool is_array
Definition: dxil.c:904
struct dxil_abbrev_operand operands[]
Definition: dxil.c:905
unsigned int count
Definition: dxil.c:903
struct dxil_block ** child_blocks
Definition: dxil.c:775
enum bitcode_block_id id
Definition: dxil.c:762
struct dxil_abbrev ** abbrevs
Definition: dxil.c:769
size_t child_block_capacity
Definition: dxil.c:776
size_t record_capacity
Definition: dxil.c:780
size_t child_block_count
Definition: dxil.c:777
size_t abbrev_capacity
Definition: dxil.c:770
size_t abbrev_count
Definition: dxil.c:771
unsigned int length
Definition: dxil.c:765
size_t record_count
Definition: dxil.c:781
unsigned int level
Definition: dxil.c:766
struct dxil_record ** records
Definition: dxil.c:779
unsigned int start
Definition: dxil.c:764
unsigned int blockinfo_bid
Definition: dxil.c:772
bool has_bid
Definition: dxil.c:773
unsigned int abbrev_len
Definition: dxil.c:763
const struct dxil_block * parent
Definition: dxil.c:761
unsigned int block_id
Definition: dxil.c:910
struct dxil_abbrev abbrev
Definition: dxil.c:911
unsigned int code
Definition: dxil.c:681
uint64_t operands[]
Definition: dxil.c:684
const struct dxil_record * attachment
Definition: dxil.c:683
unsigned int operand_count
Definition: dxil.c:682
struct sm6_block * code_block
Definition: dxil.c:3975
unsigned int temp_idx
Definition: dxil.c:3977
struct vkd3d_shader_instruction * ins
Definition: dxil.c:3976
struct vkd3d_shader_register reg
Definition: dxil.c:696
const struct sm6_block * block
Definition: dxil.c:695
Definition: name.c:39
WCHAR * name
Definition: name.c:42
Definition: send.c:48
unsigned int byte_stride
Definition: dxil.c:8730
enum vkd3d_data_type data_type
Definition: dxil.c:8729
unsigned int count
Definition: dxil.c:611
const struct sm6_type * elem_type
Definition: dxil.c:612
unsigned int case_count
Definition: dxil.c:729
const struct sm6_block * true_block
Definition: dxil.c:726
enum sm6_block_terminator_type type
Definition: dxil.c:725
struct vkd3d_shader_register conditional_reg
Definition: dxil.c:724
struct terminator_case * cases
Definition: dxil.c:728
const struct sm6_block * false_block
Definition: dxil.c:727
unsigned int id
Definition: dxil.c:739
size_t phi_capacity
Definition: dxil.c:742
size_t instruction_capacity
Definition: dxil.c:735
struct sm6_phi * phi
Definition: dxil.c:741
struct vkd3d_shader_instruction * instructions
Definition: dxil.c:734
size_t instruction_count
Definition: dxil.c:736
size_t phi_count
Definition: dxil.c:743
struct sm6_block_terminator terminator
Definition: dxil.c:745
bool src_swap
Definition: dxil.c:6757
enum vkd3d_shader_opcode handler_idx
Definition: dxil.c:6756
enum vkd3d_shader_register_type reg_type
Definition: dxil.c:838
enum vkd3d_data_type reg_data_type
Definition: dxil.c:839
enum dxil_resource_kind kind
Definition: dxil.c:836
enum vkd3d_data_type resource_data_type
Definition: dxil.c:837
enum vkd3d_shader_resource_type resource_type
Definition: dxil.c:835
unsigned int id
Definition: dxil.c:833
enum vkd3d_shader_descriptor_type type
Definition: dxil.c:832
void(* handler)(struct sm6_parser *, enum dx_intrinsic_opcode, const struct sm6_value **, struct function_emission_state *)
Definition: dxil.c:6236
const char * operand_info
Definition: dxil.c:6235
const char * ret_type
Definition: dxil.c:6234
const char * name
Definition: dxil.c:652
unsigned int attribs_id
Definition: dxil.c:654
bool is_prototype
Definition: dxil.c:653
const struct sm6_type * param_types[]
Definition: dxil.c:606
const struct sm6_type * ret_type
Definition: dxil.c:604
unsigned int param_count
Definition: dxil.c:605
const struct sm6_value * declaration
Definition: dxil.c:750
size_t value_count
Definition: dxil.c:756
struct sm6_block ** blocks
Definition: dxil.c:752
size_t block_count
Definition: dxil.c:754
size_t block_capacity
Definition: dxil.c:753
struct vkd3d_shader_register reg
Definition: dxil.c:660
const struct sm6_descriptor_info * d
Definition: dxil.c:659
uint64_t id
Definition: dxil.c:801
char * name
Definition: dxil.c:802
bool is_distinct
Definition: dxil.c:794
struct sm6_metadata_value * operands[]
Definition: dxil.c:796
unsigned int operand_count
Definition: dxil.c:795
unsigned int count
Definition: dxil.c:821
struct sm6_metadata_value * values
Definition: dxil.c:820
char * string_value
Definition: dxil.c:811
union sm6_metadata_value::@5994 u
struct sm6_metadata_node * node
Definition: dxil.c:813
enum sm6_metadata_type type
Definition: dxil.c:807
const struct sm6_type * value_type
Definition: dxil.c:808
struct sm6_metadata_kind kind
Definition: dxil.c:814
const struct sm6_value * value
Definition: dxil.c:812
char * name
Definition: dxil.c:826
struct dxil_block * current_block
Definition: dxil.c:848
size_t function_count
Definition: dxil.c:872
size_t descriptor_count
Definition: dxil.c:880
struct sm6_type * metadata_type
Definition: dxil.c:857
size_t abbrev_count
Definition: dxil.c:852
unsigned int bitpos
Definition: dxil.c:845
const char * patch_constant_function
Definition: dxil.c:864
struct dxil_block root_block
Definition: dxil.c:847
struct sm6_function * functions
Definition: dxil.c:871
size_t value_capacity
Definition: dxil.c:888
size_t global_symbol_count
Definition: dxil.c:861
unsigned int indexable_temp_count
Definition: dxil.c:882
size_t cur_max_value
Definition: dxil.c:889
struct sm6_type * types
Definition: dxil.c:854
struct sm6_descriptor_info * descriptors
Definition: dxil.c:878
struct sm6_named_metadata * named_metadata
Definition: dxil.c:875
unsigned int icb_count
Definition: dxil.c:883
unsigned int tgsm_count
Definition: dxil.c:884
const uint32_t * end
Definition: dxil.c:844
struct sm6_value * values
Definition: dxil.c:886
struct vkd3d_shader_parser p
Definition: dxil.c:892
struct vkd3d_shader_dst_param * patch_constant_params
Definition: dxil.c:868
struct vkd3d_shader_dst_param * input_params
Definition: dxil.c:867
struct sm6_symbol * global_symbols
Definition: dxil.c:860
const uint32_t * ptr
Definition: dxil.c:844
struct sm6_metadata_table metadata_tables[VKD3D_SM6_MAX_METADATA_TABLES]
Definition: dxil.c:874
const uint32_t * start
Definition: dxil.c:844
uint32_t io_regs_declared[VKD3D_BITMAP_SIZE(VKD3DSPR_COUNT)]
Definition: dxil.c:869
size_t type_count
Definition: dxil.c:855
struct vkd3d_shader_dst_param * output_params
Definition: dxil.c:866
size_t descriptor_capacity
Definition: dxil.c:879
unsigned int ssa_next_id
Definition: dxil.c:890
struct sm6_type * handle_type
Definition: dxil.c:858
size_t value_count
Definition: dxil.c:887
size_t abbrev_capacity
Definition: dxil.c:851
struct dxil_global_abbrev ** abbrevs
Definition: dxil.c:850
unsigned int named_metadata_count
Definition: dxil.c:876
struct sm6_type * bool_type
Definition: dxil.c:856
const char * entry_point
Definition: dxil.c:863
Definition: dxil.c:700
size_t incoming_capacity
Definition: dxil.c:703
struct vkd3d_shader_register reg
Definition: dxil.c:701
size_t incoming_count
Definition: dxil.c:704
struct incoming_value * incoming
Definition: dxil.c:702
enum bitcode_address_space addr_space
Definition: dxil.c:592
const struct sm6_type * type
Definition: dxil.c:591
const struct sm6_type * elem_types[]
Definition: dxil.c:599
const char * name
Definition: dxil.c:597
unsigned int elem_count
Definition: dxil.c:598
unsigned int id
Definition: dxil.c:689
const char * name
Definition: dxil.c:690
Definition: dxil.c:630
union sm6_type::@5992 u
struct sm6_struct_info * struc
Definition: dxil.c:636
struct sm6_function_info * function
Definition: dxil.c:637
unsigned int width
Definition: dxil.c:634
enum sm6_type_class class
Definition: dxil.c:631
struct sm6_array_info array
Definition: dxil.c:638
struct sm6_pointer_info pointer
Definition: dxil.c:635
struct sm6_function_data function
Definition: dxil.c:672
struct vkd3d_shader_register reg
Definition: dxil.c:673
const struct sm6_type * type
Definition: dxil.c:665
enum sm6_value_type value_type
Definition: dxil.c:666
bool is_back_ref
Definition: dxil.c:669
const struct vkd3d_shader_immediate_constant_buffer * icb
Definition: dxil.c:674
bool is_undefined
Definition: dxil.c:668
unsigned int structure_stride
Definition: dxil.c:667
union sm6_value::@5993 u
Definition: ecma_167.h:138
const struct sm6_block * block
Definition: dxil.c:717
bool is_default
Definition: dxil.c:719
uint64_t value
Definition: dxil.c:718
Definition: cmds.c:130
struct vkd3d_shader_code source
struct vkd3d_shader_register reg
struct vkd3d_shader_instruction * elements
struct vkd3d_shader_src_param * src
struct vkd3d_shader_sampler sampler
enum vsir_global_flags global_flags
struct vkd3d_shader_constant_buffer cb
struct vsir_thread_group_size thread_group_size
const struct vkd3d_shader_immediate_constant_buffer * icb
enum vkd3d_shader_tessellator_partitioning tessellator_partitioning
struct vkd3d_shader_texel_offset texel_offset
struct vkd3d_shader_tgsm_raw tgsm_raw
struct vkd3d_shader_raw_resource raw_resource
enum vkd3d_shader_tessellator_output_primitive tessellator_output_primitive
enum vkd3d_tessellator_domain tessellator_domain
struct vkd3d_shader_indexable_temp indexable_temp
enum vkd3d_shader_resource_type resource_type
union vkd3d_shader_instruction::@6020 declaration
struct vkd3d_shader_tgsm_structured tgsm_structured
enum vkd3d_shader_opcode opcode
enum vkd3d_data_type resource_data_type[VKD3D_VEC4_SIZE]
struct vkd3d_shader_semantic semantic
struct vkd3d_shader_structured_resource structured_resource
struct vkd3d_shader_dst_param * dst
struct vkd3d_shader_primitive_type primitive_type
uint32_t immconst_u32[VKD3D_VEC4_SIZE]
union vkd3d_shader_register::@6019 u
struct vkd3d_shader_register reg
enum vkd3d_shader_src_modifier modifiers
enum vsir_global_flags global_flags
#define max(a, b)
Definition: svc.c:63
Definition: dlist.c:348
Definition: pdh_main.c:64
HRESULT to_int(VARIANT *v, int *ret)
Definition: global.c:419
static bool vkd3d_bound_range(size_t start, size_t count, size_t limit)
Definition: vkd3d_common.h:360
static bool bitmap_is_set(const uint32_t *map, unsigned int idx)
Definition: vkd3d_common.h:408
#define vkd3d_unreachable()
Definition: vkd3d_common.h:119
#define VKD3D_BITMAP_SIZE(x)
Definition: vkd3d_common.h:396
#define VKD3D_ASSERT(cond)
Definition: vkd3d_common.h:49
static int vkd3d_u32_compare(uint32_t x, uint32_t y)
Definition: vkd3d_common.h:386
static bool vkd3d_object_range_overflow(size_t start, size_t count, size_t size)
Definition: vkd3d_common.h:371
#define TAG_DXIL
Definition: vkd3d_common.h:69
static void * vkd3d_calloc(size_t count, size_t size)
Definition: vkd3d_memory.h:43
static char * vkd3d_strdup(const char *string)
Definition: vkd3d_memory.h:57
static void * vkd3d_realloc(void *ptr, size_t size)
Definition: vkd3d_memory.h:36
static void vkd3d_free(void *ptr)
Definition: vkd3d_memory.h:52
static void * vkd3d_malloc(size_t size)
Definition: vkd3d_memory.h:28
bool vkd3d_array_reserve(void **elements, size_t *capacity, size_t element_count, size_t element_size)
Definition: memory.c:22
static uint32_t vkd3d_shader_create_swizzle(enum vkd3d_shader_swizzle_component x, enum vkd3d_shader_swizzle_component y, enum vkd3d_shader_swizzle_component z, enum vkd3d_shader_swizzle_component w)
vkd3d_shader_sysval_semantic
@ VKD3D_SHADER_SV_VERTEX_ID
@ VKD3D_SHADER_SV_DEPTH_LESS_EQUAL
@ VKD3D_SHADER_SV_PRIMITIVE_ID
@ VKD3D_SHADER_SV_COVERAGE
@ VKD3D_SHADER_SV_CULL_DISTANCE
@ VKD3D_SHADER_SV_DEPTH
@ VKD3D_SHADER_SV_TESS_FACTOR_TRIEDGE
@ VKD3D_SHADER_SV_TARGET
@ VKD3D_SHADER_SV_NONE
@ VKD3D_SHADER_SV_TESS_FACTOR_LINEDET
@ VKD3D_SHADER_SV_TESS_FACTOR_QUADEDGE
@ VKD3D_SHADER_SV_IS_FRONT_FACE
@ VKD3D_SHADER_SV_TESS_FACTOR_QUADINT
@ VKD3D_SHADER_SV_TESS_FACTOR_TRIINT
@ VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN
@ VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL
@ VKD3D_SHADER_SV_INSTANCE_ID
@ VKD3D_SHADER_SV_CLIP_DISTANCE
@ VKD3D_SHADER_SV_SAMPLE_INDEX
@ VKD3D_SHADER_SV_POSITION
vkd3d_shader_tessellator_output_primitive
@ VKD3D_SHADER_TESSELLATOR_OUTPUT_TRIANGLE_CCW
vkd3d_shader_component_type
@ VKD3D_SHADER_COMPONENT_INT
@ VKD3D_SHADER_COMPONENT_UINT
@ VKD3D_SHADER_COMPONENT_DOUBLE
@ VKD3D_SHADER_COMPONENT_FLOAT
@ VKD3D_SHADER_COMPONENT_BOOL
vkd3d_shader_descriptor_type
Definition: vkd3d_shader.h:420
@ VKD3D_SHADER_DESCRIPTOR_TYPE_UAV
Definition: vkd3d_shader.h:430
@ VKD3D_SHADER_DESCRIPTOR_TYPE_CBV
Definition: vkd3d_shader.h:435
@ VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER
Definition: vkd3d_shader.h:440
@ VKD3D_SHADER_DESCRIPTOR_TYPE_SRV
Definition: vkd3d_shader.h:425
vkd3d_shader_resource_type
@ VKD3D_SHADER_RESOURCE_NONE
@ VKD3D_SHADER_RESOURCE_TEXTURE_2DMS
@ VKD3D_SHADER_RESOURCE_BUFFER
@ VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY
vkd3d_shader_tessellator_partitioning
@ VKD3D_SHADER_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN
#define VKD3D_SHADER_SWIZZLE_SHIFT(idx)
vkd3d_shader_minimum_precision
@ VKD3D_SHADER_MINIMUM_PRECISION_UINT_16
@ VKD3D_SHADER_MINIMUM_PRECISION_NONE
@ VKD3D_SHADER_MINIMUM_PRECISION_FLOAT_16
@ VKD3D_SHADER_MINIMUM_PRECISION_INT_16
#define VKD3D_SHADER_SWIZZLE(x, y, z, w)
#define VKD3D_SHADER_NO_SWIZZLE
bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions, struct vkd3d_shader_immediate_constant_buffer *icb)
void vkd3d_shader_warning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, enum vkd3d_shader_error error, const char *format,...)
void shader_signature_cleanup(struct shader_signature *signature)
void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_program *program, struct vkd3d_shader_message_context *message_context, const char *source_name)
bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve)
#define VKD3DSI_PRECISE_XYZW
@ VKD3DSPSM_ABS
@ VKD3DSPSM_NONE
@ VKD3DSPSM_NEG
static uint32_t vsir_swizzle_64_from_32(uint32_t swizzle32)
vsir_global_flags
@ VKD3DSGF_SKIP_OPTIMIZATION
static bool data_type_is_64_bit(enum vkd3d_data_type data_type)
#define VKD3D_DXBC_CHUNK_ALIGNMENT
#define VKD3DSI_PRECISE_X
vkd3d_shader_type
@ VKD3D_SHADER_TYPE_HULL
@ VKD3D_SHADER_TYPE_GEOMETRY
@ VKD3D_SHADER_TYPE_COMPUTE
@ VKD3D_SHADER_TYPE_COUNT
@ VKD3D_SHADER_TYPE_DOMAIN
@ VKD3DSIM_COUNT
static struct vkd3d_shader_dst_param * vsir_program_get_dst_params(struct vsir_program *program, unsigned int count)
#define VKD3DSP_WRITEMASK_3
static unsigned int vsir_write_mask_component_count(uint32_t write_mask)
vkd3d_shader_register_type
@ VKD3DSPR_PRIMID
@ VKD3DSPR_DEPTHOUTGE
@ VKD3DSPR_RASTERIZER
@ VKD3DSPR_IMMCONST
@ VKD3DSPR_GROUPSHAREDMEM
@ VKD3DSPR_UNDEF
@ VKD3DSPR_NULL
@ VKD3DSPR_CONSTBUFFER
@ VKD3DSPR_SSA
@ VKD3DSPR_RESOURCE
@ VKD3DSPR_COUNT
@ VKD3DSPR_DEPTHOUT
@ VKD3DSPR_DEPTHOUTLE
@ VKD3DSPR_WAVELANECOUNT
@ VKD3DSPR_TESSCOORD
@ VKD3DSPR_COVERAGE
@ VKD3DSPR_IMMCONST64
@ VKD3DSPR_UAV
@ VKD3DSPR_TEMP
@ VKD3DSPR_THREADGROUPID
@ VKD3DSPR_IDXTEMP
@ VKD3DSPR_LOCALTHREADINDEX
@ VKD3DSPR_THREADID
@ VKD3DSPR_OUTPUT
@ VKD3DSPR_LOCALTHREADID
@ VKD3DSPR_SAMPLER
@ VKD3DSPR_OUTPOINTID
@ VKD3DSPR_IMMCONSTBUFFER
@ VKD3DSPR_WAVELANEINDEX
@ VKD3DSPR_STREAM
@ VKD3DSPR_INVALID
@ VKD3DSPR_PATCHCONST
@ VKD3DSPR_INPUT
@ VKD3DSUF_GLOBALLY_COHERENT
@ VKD3DSUF_RASTERISER_ORDERED_VIEW
@ VKD3DSUF_ORDER_PRESERVING_COUNTER
#define VKD3DSI_SAMPLER_COMPARISON_MODE
@ VKD3DARF_SEQ_CST
@ VKD3DARF_VOLATILE
static bool data_type_is_floating_point(enum vkd3d_data_type data_type)
#define VKD3DSI_WAVE_PREFIX
vkd3d_shader_error
@ VKD3D_SHADER_ERROR_DXIL_INVALID_VALUE_SYMTAB
@ VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND
@ VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT
@ VKD3D_SHADER_ERROR_DXIL_INVALID_ENTRY_POINT
@ VKD3D_SHADER_ERROR_DXIL_INVALID_BITCODE
@ VKD3D_SHADER_WARNING_DXIL_INVALID_OPERATION
@ VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH
@ VKD3D_SHADER_WARNING_DXIL_INVALID_MASK
@ VKD3D_SHADER_WARNING_DXIL_UNDEFINED_OPERAND
@ VKD3D_SHADER_ERROR_DXIL_INVALID_CHUNK_SIZE
@ VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCE_HANDLE
@ VKD3D_SHADER_ERROR_DXIL_INVALID_CHUNK_OFFSET
@ VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC
@ VKD3D_SHADER_WARNING_DXIL_ENTRY_POINT_MISMATCH
@ VKD3D_SHADER_ERROR_DXIL_INVALID_FUNCTION_DCL
@ VKD3D_SHADER_WARNING_DXIL_UNKNOWN_SHADER_TYPE
@ VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES
@ VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE
@ VKD3D_SHADER_WARNING_DXIL_INVALID_MODULE_LENGTH
@ VKD3D_SHADER_WARNING_DXIL_INVALID_BLOCK_LENGTH
@ VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES
@ VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT
@ VKD3D_SHADER_ERROR_DXIL_INVALID_TYPE_TABLE
@ VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS
@ VKD3D_SHADER_ERROR_DXIL_INVALID_TYPE_ID
@ VKD3D_SHADER_ERROR_DXIL_INVALID_SIZE
@ VKD3D_SHADER_ERROR_DXIL_INVALID_METADATA
@ VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY
@ VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED_BITCODE_FORMAT
@ VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE
@ VKD3D_SHADER_WARNING_DXIL_UNKNOWN_MAGIC_NUMBER
static unsigned int vkd3d_write_mask_from_component_count(unsigned int component_count)
#define VKD3DSP_WRITEMASK_ALL
@ VSIR_DIMENSION_SCALAR
@ VSIR_DIMENSION_VEC4
@ VKD3D_DATA_UINT64
@ VKD3D_DATA_SNORM
@ VKD3D_DATA_INT
@ VKD3D_DATA_BOOL
@ VKD3D_DATA_UNUSED
@ VKD3D_DATA_DOUBLE
@ VKD3D_DATA_HALF
@ VKD3D_DATA_UINT8
@ VKD3D_DATA_UINT
@ VKD3D_DATA_UNORM
@ VKD3D_DATA_FLOAT
@ VKD3D_DATA_UINT16
@ VSIR_FULLY_NORMALISED_IO
static struct vkd3d_shader_src_param * vsir_program_get_src_params(struct vsir_program *program, unsigned int count)
static bool data_type_is_integer(enum vkd3d_data_type data_type)
static unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask)
vkd3d_shader_opcode
@ VKD3DSIH_UTOU
@ VKD3DSIH_NOP
@ VKD3DSIH_RESINFO
@ VKD3DSIH_DP2
@ VKD3DSIH_WAVE_OP_IMAX
@ VKD3DSIH_IMAD
@ VKD3DSIH_F16TOF32
@ VKD3DSIH_UMUL
@ VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER
@ VKD3DSIH_AND
@ VKD3DSIH_QUAD_READ_LANE_AT
@ VKD3DSIH_IMM_ATOMIC_UMAX
@ VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE
@ VKD3DSIH_GEU
@ VKD3DSIH_WAVE_READ_LANE_AT
@ VKD3DSIH_GATHER4_PO_C
@ VKD3DSIH_WAVE_PREFIX_BIT_COUNT
@ VKD3DSIH_ISHL
@ VKD3DSIH_SAMPLE_C_LZ
@ VKD3DSIH_SAMPLE_INFO
@ VKD3DSIH_HSIN
@ VKD3DSIH_ROUND_PI
@ VKD3DSIH_WAVE_OP_MAX
@ VKD3DSIH_NEO
@ VKD3DSIH_WAVE_OP_UMIN
@ VKD3DSIH_UGE
@ VKD3DSIH_DSX_COARSE
@ VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL
@ VKD3DSIH_IMM_ATOMIC_XOR
@ VKD3DSIH_IADD
@ VKD3DSIH_ISINF
@ VKD3DSIH_DCL_INPUT_PRIMITIVE
@ VKD3DSIH_DP4
@ VKD3DSIH_DIV
@ VKD3DSIH_STORE_UAV_TYPED
@ VKD3DSIH_EMIT_STREAM
@ VKD3DSIH_WAVE_IS_FIRST_LANE
@ VKD3DSIH_UNO
@ VKD3DSIH_DTOF
@ VKD3DSIH_IEQ
@ VKD3DSIH_DCL_OUTPUT
@ VKD3DSIH_WAVE_ACTIVE_BIT_OR
@ VKD3DSIH_LD_UAV_TYPED
@ VKD3DSIH_XOR
@ VKD3DSIH_DCL_GS_INSTANCES
@ VKD3DSIH_SAMPLE
@ VKD3DSIH_UMAX
@ VKD3DSIH_QUAD_READ_ACROSS_X
@ VKD3DSIH_WAVE_ANY_TRUE
@ VKD3DSIH_LD_STRUCTURED
@ VKD3DSIH_SAMPLE_C
@ VKD3DSIH_DSY_FINE
@ VKD3DSIH_ISHR
@ VKD3DSIH_QUAD_READ_ACROSS_D
@ VKD3DSIH_NEU
@ VKD3DSIH_DCL_RESOURCE_RAW
@ VKD3DSIH_FTOD
@ VKD3DSIH_DCL_VERTICES_OUT
@ VKD3DSIH_ISNAN
@ VKD3DSIH_DCL_SAMPLER
@ VKD3DSIH_DADD
@ VKD3DSIH_GATHER4_PO
@ VKD3DSIH_ROUND_NE
@ VKD3DSIH_DCL_OUTPUT_TOPOLOGY
@ VKD3DSIH_IMM_ATOMIC_CONSUME
@ VKD3DSIH_ACOS
@ VKD3DSIH_MUL
@ VKD3DSIH_DCL_UAV_RAW
@ VKD3DSIH_LD2DMS
@ VKD3DSIH_EXP
@ VKD3DSIH_DISCARD
@ VKD3DSIH_BFREV
@ VKD3DSIH_DFMA
@ VKD3DSIH_LTU
@ VKD3DSIH_SAMPLE_LOD
@ VKD3DSIH_MIN
@ VKD3DSIH_INVALID
@ VKD3DSIH_SAMPLE_POS
@ VKD3DSIH_DCL_GLOBAL_FLAGS
@ VKD3DSIH_COUNTBITS
@ VKD3DSIH_HTAN
@ VKD3DSIH_UDIV
@ VKD3DSIH_RSQ
@ VKD3DSIH_CUT_STREAM
@ VKD3DSIH_LOD
@ VKD3DSIH_DCL_HS_MAX_TESSFACTOR
@ VKD3DSIH_IMAX
@ VKD3DSIH_FTOI
@ VKD3DSIH_TAN
@ VKD3DSIH_DCL_UAV_STRUCTURED
@ VKD3DSIH_DCL_INPUT
@ VKD3DSIH_HS_CONTROL_POINT_PHASE
@ VKD3DSIH_LOG
@ VKD3DSIH_ROUND_NI
@ VKD3DSIH_DMAX
@ VKD3DSIH_EQO
@ VKD3DSIH_IMM_ATOMIC_IADD
@ VKD3DSIH_IMM_ATOMIC_EXCH
@ VKD3DSIH_DCL_TGSM_RAW
@ VKD3DSIH_SYNC
@ VKD3DSIH_LD_RAW
@ VKD3DSIH_WAVE_OP_UMAX
@ VKD3DSIH_DCL_THREAD_GROUP
@ VKD3DSIH_WAVE_ACTIVE_BIT_XOR
@ VKD3DSIH_IMM_ATOMIC_IMIN
@ VKD3DSIH_F32TOF16
@ VKD3DSIH_UTOF
@ VKD3DSIH_LTO
@ VKD3DSIH_QUAD_READ_ACROSS_Y
@ VKD3DSIH_WAVE_ACTIVE_BIT_AND
@ VKD3DSIH_IMM_ATOMIC_IMAX
@ VKD3DSIH_IMM_ATOMIC_ALLOC
@ VKD3DSIH_GATHER4_C
@ VKD3DSIH_SAMPLE_B
@ VKD3DSIH_MAD
@ VKD3DSIH_IMM_ATOMIC_AND
@ VKD3DSIH_ATAN
@ VKD3DSIH_DMIN
@ VKD3DSIH_WAVE_ACTIVE_BALLOT
@ VKD3DSIH_ADD
@ VKD3DSIH_DCL_TGSM_STRUCTURED
@ VKD3DSIH_DCL_RESOURCE_STRUCTURED
@ VKD3DSIH_DSY_COARSE
@ VKD3DSIH_INE
@ VKD3DSIH_MOVC
@ VKD3DSIH_WAVE_READ_LANE_FIRST
@ VKD3DSIH_HS_FORK_PHASE
@ VKD3DSIH_UBFE
@ VKD3DSIH_ASIN
@ VKD3DSIH_MOV
@ VKD3DSIH_MAX
@ VKD3DSIH_ORD
@ VKD3DSIH_ISFINITE
@ VKD3DSIH_FIRSTBIT_HI
@ VKD3DSIH_WAVE_OP_MUL
@ VKD3DSIH_ULT
@ VKD3DSIH_IMIN
@ VKD3DSIH_STORE_RAW
@ VKD3DSIH_SWITCH_MONOLITHIC
@ VKD3DSIH_BUFINFO
@ VKD3DSIH_FTOU
@ VKD3DSIH_PHI
@ VKD3DSIH_WAVE_ALL_TRUE
@ VKD3DSIH_DSX_FINE
@ VKD3DSIH_IMM_ATOMIC_OR
@ VKD3DSIH_OR
@ VKD3DSIH_DCL_TESSELLATOR_DOMAIN
@ VKD3DSIH_WAVE_OP_ADD
@ VKD3DSIH_ILT
@ VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT
@ VKD3DSIH_STORE_STRUCTURED
@ VKD3DSIH_USHR
@ VKD3DSIH_EQU
@ VKD3DSIH_DCL
@ VKD3DSIH_DCL_UAV_TYPED
@ VKD3DSIH_WAVE_OP_IMIN
@ VKD3DSIH_IBFE
@ VKD3DSIH_WAVE_OP_MIN
@ VKD3DSIH_FRC
@ VKD3DSIH_IMM_ATOMIC_UMIN
@ VKD3DSIH_SAMPLE_GRAD
@ VKD3DSIH_DCL_CONSTANT_BUFFER
@ VKD3DSIH_LD
@ VKD3DSIH_DCL_INDEXABLE_TEMP
@ VKD3DSIH_FREM
@ VKD3DSIH_ITOI
@ VKD3DSIH_LABEL
@ VKD3DSIH_GEO
@ VKD3DSIH_ITOF
@ VKD3DSIH_IMM_ATOMIC_CMP_EXCH
@ VKD3DSIH_ROUND_Z
@ VKD3DSIH_IGE
@ VKD3DSIH_SINCOS
@ VKD3DSIH_FIRSTBIT_LO
@ VKD3DSIH_UMIN
@ VKD3DSIH_RET
@ VKD3DSIH_DP3
@ VKD3DSIH_BRANCH
@ VKD3DSIH_IDIV
@ VKD3DSIH_GATHER4
@ VKD3DSIH_SQRT
@ VKD3DSIH_DMUL
@ VKD3DSIH_WAVE_ALL_BIT_COUNT
@ VKD3DSIH_FIRSTBIT_SHI
@ VKD3DSIH_HCOS
@ VKD3DSIH_DDIV
@ VKD3DSIH_DCL_TESSELLATOR_PARTITIONING
#define VKD3DSI_RESINFO_UINT
@ VKD3DSSF_GLOBAL_UAV
@ VKD3DSSF_GROUP_SHARED_MEMORY
static bool data_type_is_bool(enum vkd3d_data_type data_type)
#define VKD3DSI_SAMPLE_INFO_UINT
static bool register_is_scalar_constant_zero(const struct vkd3d_shader_register *reg)
vkd3d_tessellator_domain
@ VKD3D_TESSELLATOR_DOMAIN_INVALID
@ VKD3D_TESSELLATOR_DOMAIN_COUNT
@ VKD3D_TESSELLATOR_DOMAIN_TRIANGLE
@ VKD3D_TESSELLATOR_DOMAIN_LINE
@ VKD3D_TESSELLATOR_DOMAIN_QUAD
static bool register_is_ssa(const struct vkd3d_shader_register *reg)
static enum vkd3d_data_type vkd3d_data_type_from_component_type(enum vkd3d_shader_component_type component_type)
static bool register_is_constant(const struct vkd3d_shader_register *reg)
static bool vsir_sysval_semantic_is_tess_factor(enum vkd3d_shader_sysval_semantic sysval_semantic)
vkd3d_primitive_type
@ VKD3D_PT_PATCH
@ VKD3D_PT_COUNT
@ VKD3D_PT_TRIANGLELIST
@ VKD3D_PT_TRIANGLELIST_ADJ
@ VKD3D_PT_UNDEFINED
@ VKD3D_PT_LINELIST_ADJ
@ VKD3D_PT_POINTLIST
@ VKD3D_PT_LINELIST
void vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser, enum vkd3d_shader_error error, const char *format,...) VKD3D_PRINTF_FUNC(3
@ VKD3DSPDM_SATURATE
void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser, enum vkd3d_shader_error error, const char *format,...) VKD3D_PRINTF_FUNC(3
#define VKD3DSP_WRITEMASK_0
@ VSIR_CF_BLOCKS
static bool register_is_numeric_array(const struct vkd3d_shader_register *reg)
#define VKD3D_VEC4_SIZE
#define VKD3DSI_SHIFT_UNMASKED
vkd3d_result
Definition: vkd3d_types.h:41
@ VKD3D_ERROR_INVALID_SHADER
Definition: vkd3d_types.h:53
@ VKD3D_ERROR
Definition: vkd3d_types.h:47
@ VKD3D_OK
Definition: vkd3d_types.h:43
@ VKD3D_ERROR_OUT_OF_MEMORY
Definition: vkd3d_types.h:49
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
#define MAX_REG_OUTPUT
static size_t align(size_t addr, size_t alignment)
static int init
Definition: wintirpc.c:33
static unsigned int block
Definition: xmlmemory.c:101