git.s-ol.nu ~forks/DiligentCore / a9bbc58
fixed DXC resource remapper azhirnov authored 6 months ago assiduous committed 6 months ago
3 changed file(s) with 263 addition(s) and 109 deletion(s). Raw diff Collapse all Expand all
16671667 return false;
16681668 }
16691669
1670 CComPtr<ID3DBlob> DisasmBlob;
1671 D3DDisassemble(pBytecode, Size, D3D_DISASM_ENABLE_INSTRUCTION_OFFSET, nullptr, &DisasmBlob);
1672
1673 const auto* DisasmStr = (char*)DisasmBlob->GetBufferPointer();
1674 (void)(DisasmStr);
1675
16761670 auto* const Ptr = static_cast<char*>(pBytecode);
16771671 const void* const EndPtr = Ptr + Size;
16781672
17861780 static_assert(sizeof(Header.Checksum) == sizeof(Checksum), "Unexpected checksum size");
17871781 memcpy(Header.Checksum, Checksum, sizeof(Header.Checksum));
17881782
1789 CComPtr<ID3DBlob> DisasmBlob2;
1790 D3DDisassemble(pBytecode, Size, D3D_DISASM_ENABLE_INSTRUCTION_OFFSET, nullptr, &DisasmBlob2);
1791
1792 const auto* DisasmStr2 = (char*)DisasmBlob2->GetBufferPointer();
1793 (void)(DisasmStr2);
1794
17951783 return true;
17961784 }
17971785
158158 };
159159 using TExtendedResourceMap = std::unordered_map<TResourceBindingMap::value_type const*, ResourceExtendedInfo>;
160160
161 static bool PatchDXIL(const TResourceBindingMap& ResourceMap, TExtendedResourceMap& ExtResMap, String& DXIL);
161 static bool PatchDXIL(const TResourceBindingMap& ResourceMap, TExtendedResourceMap& ExtResMap, SHADER_TYPE ShaderType, String& DXIL);
162162 static void PatchResourceDeclaration(const TResourceBindingMap& ResourceMap, TExtendedResourceMap& ExtResMap, String& DXIL);
163 static void PatchResourceDeclarationRT(const TResourceBindingMap& ResourceMap, TExtendedResourceMap& ExtResMap, String& DXIL);
163164 static void PatchResourceHandle(const TResourceBindingMap& ResourceMap, TExtendedResourceMap& ExtResMap, String& DXIL);
164165
165166 private:
838839 return false;
839840 }
840841
842 SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN;
843 {
844 D3D12_SHADER_DESC ShDesc = {};
845 pShaderReflection->GetDesc(&ShDesc);
846
847 const Uint32 ShType = D3D12_SHVER_GET_TYPE(ShDesc.Version);
848 switch (ShType)
849 {
850 // clang-format off
851 case D3D12_SHVER_PIXEL_SHADER: ShaderType = SHADER_TYPE_PIXEL; break;
852 case D3D12_SHVER_VERTEX_SHADER: ShaderType = SHADER_TYPE_VERTEX; break;
853 case D3D12_SHVER_GEOMETRY_SHADER: ShaderType = SHADER_TYPE_GEOMETRY; break;
854 case D3D12_SHVER_HULL_SHADER: ShaderType = SHADER_TYPE_HULL; break;
855 case D3D12_SHVER_DOMAIN_SHADER: ShaderType = SHADER_TYPE_DOMAIN; break;
856 case D3D12_SHVER_COMPUTE_SHADER: ShaderType = SHADER_TYPE_COMPUTE; break;
857 case 7: ShaderType = SHADER_TYPE_RAY_GEN; break;
858 case 8: ShaderType = SHADER_TYPE_RAY_INTERSECTION; break;
859 case 9: ShaderType = SHADER_TYPE_RAY_ANY_HIT; break;
860 case 10: ShaderType = SHADER_TYPE_RAY_CLOSEST_HIT; break;
861 case 11: ShaderType = SHADER_TYPE_RAY_MISS; break;
862 case 12: ShaderType = SHADER_TYPE_CALLABLE; break;
863 case 13: ShaderType = SHADER_TYPE_MESH; break;
864 case 14: ShaderType = SHADER_TYPE_AMPLIFICATION; break;
865 // clang-format on
866 default:
867 UNEXPECTED("Unknown shader type");
868 }
869 }
870
841871 TExtendedResourceMap ExtResourceMap;
842872
843873 for (auto& NameAndBinding : ResourceMap)
879909 }
880910
881911 # ifdef DILIGENT_DEBUG
882 static_assert(SHADER_RESOURCE_TYPE_LAST == SHADER_RESOURCE_TYPE_ACCEL_STRUCT, "Please update the switch below to handle the new shader resource type");
912 static_assert(SHADER_RESOURCE_TYPE_LAST == 8, "Please update the switch below to handle the new shader resource type");
883913 switch (NameAndBinding.second.ResType)
884914 {
885915 // clang-format off
910940 String dxilAsm;
911941 dxilAsm.assign(static_cast<const char*>(disasm->GetBufferPointer()), disasm->GetBufferSize());
912942
913 if (!PatchDXIL(ResourceMap, ExtResourceMap, dxilAsm))
943 if (!PatchDXIL(ResourceMap, ExtResourceMap, ShaderType, dxilAsm))
914944 {
915945 LOG_ERROR("Failed to patch resource bindings");
916946 return false;
963993 #endif // D3D12_SUPPORTED
964994 }
965995
966 bool DXCompilerImpl::PatchDXIL(const TResourceBindingMap& ResourceMap, TExtendedResourceMap& ExtResMap, String& DXIL)
996 bool DXCompilerImpl::PatchDXIL(const TResourceBindingMap& ResourceMap, TExtendedResourceMap& ExtResMap, SHADER_TYPE ShaderType, String& DXIL)
967997 {
968998 try
969999 {
970 PatchResourceDeclaration(ResourceMap, ExtResMap, DXIL);
1000 if (ShaderType < SHADER_TYPE_RAY_GEN)
1001 PatchResourceDeclaration(ResourceMap, ExtResMap, DXIL);
1002 else
1003 PatchResourceDeclarationRT(ResourceMap, ExtResMap, DXIL);
1004
9711005 PatchResourceHandle(ResourceMap, ExtResMap, DXIL);
9721006 return true;
9731007 }
9771011 }
9781012 }
9791013
980 void DXCompilerImpl::PatchResourceDeclaration(const TResourceBindingMap& ResourceMap, TExtendedResourceMap& ExtResMap, String& DXIL)
1014 namespace
1015 {
1016 void ReplaceRecord(String& DXIL, size_t& pos, const String& NewValue, const char* Name, const char* RecordName, const Uint32 ExpectedPrevValue)
9811017 {
9821018 #define CHECK_PATCHING_ERROR(Cond, ...) \
9831019 if (!(Cond)) \
9851021 LOG_ERROR_AND_THROW("Unable to patch DXIL for resource '", Name, "': ", ##__VA_ARGS__); \
9861022 }
9871023
1024 static const String i32 = "i32 ";
1025 static const String NumberSymbols = "+-0123456789";
1026
1027 // , i32 -1
1028 // ^
1029 CHECK_PATCHING_ERROR(DXIL[pos] == ',' && DXIL[pos + 1] == ' ', RecordName, " record is not found")
1030
1031 pos += 2;
1032 // , i32 -1
1033 // ^
1034
1035 CHECK_PATCHING_ERROR(std::strncmp(&DXIL[pos], i32.c_str(), i32.length()) == 0, "unexpected ", RecordName, " record type")
1036 pos += i32.length();
1037 // , i32 -1
1038 // ^
1039
1040 auto RecordEndPos = DXIL.find_first_not_of(NumberSymbols, pos);
1041 CHECK_PATCHING_ERROR(pos != String::npos, "unable to find the end of the ", RecordName, " record data")
1042 // , i32 -1
1043 // ^
1044 // RecordEndPos
1045
1046 Uint32 PrevValue = static_cast<Uint32>(std::stoi(DXIL.substr(pos, RecordEndPos - pos)));
1047 CHECK_PATCHING_ERROR(PrevValue == ExpectedPrevValue, "previous value does not match with expected");
1048
1049 DXIL.replace(pos, RecordEndPos - pos, NewValue);
1050 // , i32 1
1051 // ^
1052 // RecordEndPos
1053
1054 pos += NewValue.length();
1055 // , i32 1
1056 // ^
1057
1058 #undef CHECK_PATCHING_ERROR
1059 }
1060
1061 bool IsWordSymbol(char c)
1062 {
1063 return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_');
1064 }
1065
1066 bool IsNumberSymbol(char c)
1067 {
1068 return (c >= '0' && c <= '9');
1069 }
1070
1071 } // namespace
1072
1073 void DXCompilerImpl::PatchResourceDeclarationRT(const TResourceBindingMap& ResourceMap, TExtendedResourceMap& ExtResMap, String& DXIL)
1074 {
1075 #define CHECK_PATCHING_ERROR(Cond, ...) \
1076 if (!(Cond)) \
1077 { \
1078 LOG_ERROR_AND_THROW("Unable to patch DXIL for resource '", Name, "': ", ##__VA_ARGS__); \
1079 }
1080
9881081 static const String i32 = "i32 ";
9891082 static const String NumberSymbols = "+-0123456789";
9901083 static const String ResourceRecStart = "= !{";
991
992 const auto ReplaceRecord = [&DXIL](size_t& pos, const String& NewValue, const char* Name, const char* RecordName, const Uint32 ExpectedPrevValue) //
993 {
994 // , i32 -1
995 // ^
996 CHECK_PATCHING_ERROR(DXIL[pos] == ',' && DXIL[pos + 1] == ' ', RecordName, " record is not found")
997
998 pos += 2;
999 // , i32 -1
1000 // ^
1001
1002 CHECK_PATCHING_ERROR(std::strncmp(&DXIL[pos], i32.c_str(), i32.length()) == 0, "unexpected ", RecordName, " record type")
1003 pos += i32.length();
1004 // , i32 -1
1005 // ^
1006
1007 auto RecordEndPos = DXIL.find_first_not_of(NumberSymbols, pos);
1008 CHECK_PATCHING_ERROR(pos != String::npos, "unable to find the end of the ", RecordName, " record data")
1009 // , i32 -1
1010 // ^
1011 // RecordEndPos
1012
1013 Uint32 PrevValue = static_cast<Uint32>(std::stoi(DXIL.substr(pos, RecordEndPos - pos)));
1014 CHECK_PATCHING_ERROR(PrevValue == ExpectedPrevValue, "previous value does not match with expected");
1015
1016 DXIL.replace(pos, RecordEndPos - pos, NewValue);
1017 // , i32 1
1018 // ^
1019 // RecordEndPos
1020
1021 pos += NewValue.length();
1022 // , i32 1
1023 // ^
1024 };
1025
1026 const auto ReadRecord = [&DXIL](size_t& pos, Uint32& CurValue) //
1027 {
1028 // , i32 -1
1029 // ^
1030 if (DXIL[pos] != ',' || DXIL[pos + 1] != ' ')
1031 return false;
1032
1033 pos += 2;
1034 // , i32 -1
1035 // ^
1036
1037 if (std::strncmp(&DXIL[pos], i32.c_str(), i32.length()) != 0)
1038 return false;
1039 pos += i32.length();
1040 // , i32 -1
1041 // ^
1042
1043 auto RecordEndPos = DXIL.find_first_not_of(NumberSymbols, pos);
1044 if (pos == String::npos)
1045 return false;
1046 // , i32 -1
1047 // ^
1048 // RecordEndPos
1049
1050 CurValue = static_cast<Uint32>(std::stoi(DXIL.substr(pos, RecordEndPos - pos)));
1051 pos = RecordEndPos;
1052 return true;
1053 };
10541084
10551085 // This resource patching method is valid for ray tracing shaders and non-optimized shaders with metadata.
10561086 for (auto& ResPair : ResourceMap)
11111141 // !"g_ColorBuffer", i32 -1, i32 -1,
11121142 // ^
11131143 pos = EndOfResTypeRecord + DxilName.length();
1114 ReplaceRecord(pos, std::to_string(Space), Name, "space", Ext.SrcSpace);
1144 ReplaceRecord(DXIL, pos, std::to_string(Space), Name, "space", Ext.SrcSpace);
11151145
11161146 // !"g_ColorBuffer", i32 0, i32 -1,
11171147 // ^
1118 ReplaceRecord(pos, std::to_string(BindPoint), Name, "binding", Ext.SrcBindPoint);
1148 ReplaceRecord(DXIL, pos, std::to_string(BindPoint), Name, "binding", Ext.SrcBindPoint);
11191149
11201150 // !"g_ColorBuffer", i32 0, i32 1,
11211151 // ^
11221152 }
11231153 #undef CHECK_PATCHING_ERROR
1154 }
1155
1156 void DXCompilerImpl::PatchResourceDeclaration(const TResourceBindingMap& ResourceMap, TExtendedResourceMap& ExtResMap, String& DXIL)
1157 {
1158 static const String i32 = "i32 ";
1159 static const String NumberSymbols = "+-0123456789";
1160 static const String ResourceRecStart = "= !{";
1161
1162 // This resource patching method is valid for optimized shaders without metadata.
1163 static const String ResNameDecl = ", !\"";
1164 static const String SamplerPart = "%struct.SamplerState";
1165 static const String TexturePart = "%\"class.Texture";
1166 static const String RWTexturePart = "%\"class.RWTexture";
1167 static const String AccelStructPart = "%struct.RaytracingAccelerationStructure";
1168 static const String StructBufferPart = "%\"class.StructuredBuffer";
1169 static const String RWStructBufferPart = "%\"class.RWStructuredBuffer";
1170 static const String ByteAddrBufPart = "%struct.ByteAddressBuffer";
1171 static const String RWByteAddrBufPart = "%struct.RWByteAddressBuffer";
1172 static const String TexBufferPart = "%\"class.Buffer<";
1173 static const String RWTexBufferPart = "%\"class.RWBuffer<";
1174
1175 const auto ReadRecord = [&DXIL](size_t& pos, Uint32& CurValue) //
1176 {
1177 // , i32 -1
1178 // ^
1179 if (DXIL[pos] != ',' || DXIL[pos + 1] != ' ')
1180 return false;
1181
1182 pos += 2;
1183 // , i32 -1
1184 // ^
1185
1186 if (std::strncmp(&DXIL[pos], i32.c_str(), i32.length()) != 0)
1187 return false;
1188 pos += i32.length();
1189 // , i32 -1
1190 // ^
1191
1192 auto RecordEndPos = DXIL.find_first_not_of(NumberSymbols, pos);
1193 if (pos == String::npos)
1194 return false;
1195 // , i32 -1
1196 // ^
1197 // RecordEndPos
1198
1199 CurValue = static_cast<Uint32>(std::stoi(DXIL.substr(pos, RecordEndPos - pos)));
1200 pos = RecordEndPos;
1201 return true;
1202 };
1203
1204 const auto ReadResName = [&DXIL](size_t& pos, String& name) //
1205 {
1206 VERIFY_EXPR(pos > 0 && DXIL[pos - 1] == '"');
1207 const size_t startPos = pos;
1208 for (; pos < DXIL.size(); ++pos)
1209 {
1210 const char c = DXIL[pos];
1211 if (IsWordSymbol(c))
1212 continue;
1213
1214 if (c == '"')
1215 {
1216 name = DXIL.substr(startPos, pos - startPos);
1217 return true;
1218 }
1219 break;
1220 }
1221 return false;
1222 };
11241223
11251224 #define CHECK_PATCHING_ERROR(Cond, ...) \
11261225 if (!(Cond)) \
11271226 { \
11281227 LOG_ERROR_AND_THROW("Unable to patch DXIL: ", ##__VA_ARGS__); \
11291228 }
1130
1131 // This resource patching method is valid for optimized shaders without metadata.
1132 static const String EmptyResDecl = ", !\"\",";
1133 static const String SamplerPart = "%struct.SamplerState* undef";
1134 static const String TexturePart = "%\"class.Texture";
1135
11361229 for (size_t pos = 0; pos < DXIL.size();)
11371230 {
11381231 // Example:
11391232 //
11401233 // !5 = !{i32 0, %"class.Texture2D<vector<float, 4> >"* undef, !"", i32 -1, i32 -1, i32 1, i32 2, i32 0, !6}
11411234
1142 pos = DXIL.find(EmptyResDecl, pos);
1235 pos = DXIL.find(ResNameDecl, pos);
11431236 if (pos == String::npos)
11441237 break;
11451238
11471240 // ^
11481241 const size_t EndOfResTypeRecord = pos;
11491242
1243 // undef, !"", i32 -1,... or undef, !"g_Tex2D", i32 -1,...
1244 // ^ ^
1245 pos += ResNameDecl.length();
1246 const size_t BeginOfResName = pos;
1247
1248 String ResName;
1249 if (!ReadResName(pos, ResName))
1250 {
1251 // This is not a resource declaration record, continue searching.
1252 continue;
1253 }
1254
11501255 // undef, !"", i32 -1,
11511256 // ^
1152 const size_t BindingRecordStart = pos + EmptyResDecl.size() - 1;
1257 const size_t BindingRecordStart = pos + 1;
1258 VERIFY_EXPR(DXIL[BindingRecordStart] == ',');
11531259
11541260 // Parse resource class.
11551261 pos = DXIL.rfind(ResourceRecStart, EndOfResTypeRecord);
11781284
11791285 CHECK_PATCHING_ERROR(DXIL[pos] == ',' && DXIL[pos + 1] == ' ', "failed to find end of the Record ID record data");
11801286 pos += 2;
1181 // !{i32 0, %"class.Texture2D<...
1182 // ^
1183
1287 // !{i32 0, %"class.Texture2D<... or !{i32 0, [4 x %"class.Texture2D<...
1288 // ^ ^
1289
1290 // skip array declaration
1291 if (DXIL[pos] == '[')
1292 {
1293 ++pos;
1294 for (; pos < EndOfResTypeRecord; ++pos)
1295 {
1296 const char c = DXIL[pos];
1297 if (!(IsNumberSymbol(c) || (c == ' ') || (c == 'x')))
1298 break;
1299 }
1300 }
1301
1302 if (DXIL[pos] != '%')
1303 {
1304 // This is not a resource declaration record, continue searching.
1305 pos = BindingRecordStart;
1306 continue;
1307 }
1308
1309 // !{i32 0, %"class.Texture2D<... or !{i32 0, [4 x %"class.Texture2D<...
1310 // ^ ^
11841311 RES_TYPE ResType = RES_TYPE_COUNT;
1185 if (std::strncmp(&DXIL[pos], TexturePart.c_str(), TexturePart.length()) == 0)
1312 if (std::strncmp(&DXIL[pos], SamplerPart.c_str(), SamplerPart.length()) == 0)
1313 ResType = RES_TYPE_SAMPLER;
1314 else if (std::strncmp(&DXIL[pos], TexturePart.c_str(), TexturePart.length()) == 0)
11861315 ResType = RES_TYPE_SRV;
1187 else if (std::strncmp(&DXIL[pos], SamplerPart.c_str(), SamplerPart.length()) == 0)
1188 ResType = RES_TYPE_SAMPLER;
1316 else if (std::strncmp(&DXIL[pos], StructBufferPart.c_str(), StructBufferPart.length()) == 0)
1317 ResType = RES_TYPE_SRV;
1318 else if (std::strncmp(&DXIL[pos], ByteAddrBufPart.c_str(), ByteAddrBufPart.length()) == 0)
1319 ResType = RES_TYPE_SRV;
1320 else if (std::strncmp(&DXIL[pos], TexBufferPart.c_str(), TexBufferPart.length()) == 0)
1321 ResType = RES_TYPE_SRV;
1322 else if (std::strncmp(&DXIL[pos], AccelStructPart.c_str(), AccelStructPart.length()) == 0)
1323 ResType = RES_TYPE_SRV;
1324 else if (std::strncmp(&DXIL[pos], RWTexturePart.c_str(), RWTexturePart.length()) == 0)
1325 ResType = RES_TYPE_UAV;
1326 else if (std::strncmp(&DXIL[pos], RWStructBufferPart.c_str(), RWStructBufferPart.length()) == 0)
1327 ResType = RES_TYPE_UAV;
1328 else if (std::strncmp(&DXIL[pos], RWByteAddrBufPart.c_str(), RWByteAddrBufPart.length()) == 0)
1329 ResType = RES_TYPE_UAV;
1330 else if (std::strncmp(&DXIL[pos], RWTexBufferPart.c_str(), RWTexBufferPart.length()) == 0)
1331 ResType = RES_TYPE_UAV;
11891332 else
11901333 {
11911334 // Try to find constant buffer.
11971340 if (Type != RES_TYPE_CBV)
11981341 continue;
11991342
1200 const String CBName = String{"%"} + Name + "* undef";
1343 const String CBName = String{"%"} + Name;
12011344 if (std::strncmp(&DXIL[pos], CBName.c_str(), CBName.length()) == 0)
12021345 {
1346 const char c = DXIL[pos + CBName.length()];
1347
1348 if (IsWordSymbol(c))
1349 continue; // name partially equals
1350
1351 VERIFY_EXPR((c == '*' && ResInfo.first->second.ArraySize == 1) || (c == ']' && ResInfo.first->second.ArraySize > 1));
1352
12031353 ResType = RES_TYPE_CBV;
12041354 break;
12051355 }
12481398 }
12491399 CHECK_PATCHING_ERROR(pResPair != nullptr && pExt != nullptr, "failed to find resource in ResourceMap");
12501400
1401 VERIFY_EXPR(ResName.empty() || ResName == pResPair->first.GetStr());
12511402 VERIFY_EXPR(pExt->RecordId == ~0u || pExt->RecordId == RecordId);
12521403 pExt->RecordId = RecordId;
12531404
12561407
12571408 // !"", i32 -1, i32 -1,
12581409 // ^
1259 ReplaceRecord(pos, std::to_string(pResPair->second.Space), pResPair->first.GetStr(), "space", pExt->SrcSpace);
1410 ReplaceRecord(DXIL, pos, std::to_string(pResPair->second.Space), pResPair->first.GetStr(), "space", pExt->SrcSpace);
12601411
12611412 // !"", i32 0, i32 -1,
12621413 // ^
1263 ReplaceRecord(pos, std::to_string(pResPair->second.BindPoint), pResPair->first.GetStr(), "binding", pExt->SrcBindPoint);
1414 ReplaceRecord(DXIL, pos, std::to_string(pResPair->second.BindPoint), pResPair->first.GetStr(), "binding", pExt->SrcBindPoint);
12641415
12651416 // !"", i32 0, i32 1,
12661417 // ^
1418
1419 // Add resource name
1420 if (ResName.empty())
1421 {
1422 DXIL.insert(BeginOfResName, pResPair->first.GetStr());
1423 }
12671424 }
12681425 #undef CHECK_PATCHING_ERROR
12691426 }
12931450 const auto ReplaceBindPoint = [&](Uint32 ResClass, Uint32 RangeId, size_t IndexStartPos, size_t IndexEndPos) //
12941451 {
12951452 const String SrcIndexStr = DXIL.substr(IndexStartPos, IndexEndPos - IndexStartPos);
1296 VERIFY_EXPR(SrcIndexStr.front() >= '0' && SrcIndexStr.front() <= '9');
1453 VERIFY_EXPR(IsNumberSymbol(SrcIndexStr.front()));
12971454
12981455 const Uint32 SrcIndex = static_cast<Uint32>(std::stoi(SrcIndexStr));
12991456 const auto ResType = ResClassToType[ResClass];
14481605 pos += 2; // skip ', '
14491606
14501607 // second arg must be a constant
1451 CHECK_PATCHING_ERROR(DXIL[pos] >= '0' && DXIL[pos] <= '9', "second argument expected to be a integer constant");
1608 CHECK_PATCHING_ERROR(IsNumberSymbol(DXIL[pos]), "second argument expected to be a integer constant");
14521609
14531610 const size_t ArgStart = pos;
1454 CHECK_PATCHING_ERROR(NextArg(pos), "");
1455 VERIFY_EXPR(DXIL[pos] == ',' || DXIL[pos] == '\n');
1611 for (; pos < DXIL.size(); ++pos)
1612 {
1613 const char c = DXIL[pos];
1614 if (!IsNumberSymbol(c))
1615 break;
1616 }
1617 CHECK_PATCHING_ERROR(DXIL[pos] == ',' || DXIL[pos] == '\n', "failed to parse second argument");
14561618
14571619 // %22 = add i32 %17, 7
14581620 // ^
14631625 else
14641626 {
14651627 // first arg is a constant
1466 VERIFY_EXPR(DXIL[pos] >= '0' && DXIL[pos] <= '9');
1628 VERIFY_EXPR(IsNumberSymbol(DXIL[pos]));
14671629
14681630 const size_t ArgStart = pos;
1469
1470 CHECK_PATCHING_ERROR(NextArg(pos), "");
1631 for (; pos < DXIL.size(); ++pos)
1632 {
1633 const char c = DXIL[pos];
1634 if (!IsNumberSymbol(c))
1635 break;
1636 }
1637 CHECK_PATCHING_ERROR(DXIL[pos] == ',' || DXIL[pos] == '\n', "failed to parse second argument");
14711638 // %22 = add i32 7, %17
14721639 // ^
14731640
106106 // no output provided for debug - embedding PDB in shader container. Use -Qembed_debug to silence this warning.
107107 // L"-Qembed_debug", // Requires DXC1.5+
108108 #else
109 L"-Zi", // Debug info
110 L"-O3" // Optimization level 3
109 L"-O3" // Optimization level 3
111110 #endif
112111 };
113112