diff --git a/MMT/ExtractFromBuffer_CS_WW_Body.cpp b/MMT/ExtractFromBuffer_CS_WW_Body.cpp index c784d9a..e447ee9 100644 --- a/MMT/ExtractFromBuffer_CS_WW_Body.cpp +++ b/MMT/ExtractFromBuffer_CS_WW_Body.cpp @@ -178,12 +178,14 @@ void ExtractFromBuffer_CS_WW_Body(std::wstring DrawIB,std::wstring GameType) { std::wstring PositionExtractFileName = FAData.FindFrameAnalysisFileNameListWithCondition(MatchedDrawNumberCSIndex + PositionExtractSlot, L".buf")[0]; std::wstring NormalColorExtractFileName = FAData.FindFrameAnalysisFileNameListWithCondition(MatchedDrawNumberCSIndex + NormalExtractSlot, L".buf")[0]; std::wstring BlendExtractFileName = FAData.FindFrameAnalysisFileNameListWithCondition(MatchedDrawNumberCSIndex + BlendExtractSlot, L".buf")[0]; + std::wstring CS_CB0_FileName = FAData.FindFrameAnalysisFileNameListWithCondition(MatchedDrawNumberCSIndex + L"-cs-cb0=", L".buf")[0]; //这里的变量名放到上面初始化了 LOG.Info(L"PositionExtractFileName: " + PositionExtractFileName); LOG.Info(L"NormalExtractFileName: " + NormalColorExtractFileName); LOG.Info(L"BlendExtractFileName: " + BlendExtractFileName); LOG.Info(L"TexcoordExtractFileName: " + TexcoordExtractFileName); + LOG.Info(L"CS_CB0_FileName: " + CS_CB0_FileName); std::unordered_map> PositionBufMap = MMTFile_ReadBufMapFromFile(G.WorkFolder + PositionExtractFileName, MatchNumber); std::unordered_map> NormalTangentBufMap = MMTFile_ReadBufMapFromFile(G.WorkFolder + NormalColorExtractFileName, MatchNumber); @@ -193,13 +195,14 @@ void ExtractFromBuffer_CS_WW_Body(std::wstring DrawIB,std::wstring GameType) { std::wstring CategoryHash_Position = PositionExtractFileName.substr(13, 8); std::wstring CategoryHash_NormalColor = NormalColorExtractFileName.substr(13, 8); std::wstring CategoryHash_Blend = BlendExtractFileName.substr(13, 8); - std::wstring CategoryTexcoord = TexcoordExtractFileName.substr(13, 8); + std::wstring CategoryHash_Texcoord = TexcoordExtractFileName.substr(13, 8); + std::wstring CS_CB0_Hash = CS_CB0_FileName.substr(14, 8); extractConfig.CategoryHashMap["Position"] = MMTString_ToByteString(CategoryHash_Position); extractConfig.CategoryHashMap["Normal"] = MMTString_ToByteString(CategoryHash_NormalColor); extractConfig.CategoryHashMap["Blend"] = MMTString_ToByteString(CategoryHash_Blend); - extractConfig.CategoryHashMap["Texcoord"] = MMTString_ToByteString(CategoryTexcoord); - + extractConfig.CategoryHashMap["Texcoord"] = MMTString_ToByteString(CategoryHash_Texcoord); + extractConfig.VertexLimitVB = MMTString_ToByteString(CS_CB0_Hash); std::vector finalVB0Buf; for (int i = 0; i < MatchNumber; i++) { diff --git a/MMT/ExtractFromBuffer_VS_WW_Object.cpp b/MMT/ExtractFromBuffer_VS_WW_Object.cpp index 695d940..b84e87e 100644 --- a/MMT/ExtractFromBuffer_VS_WW_Object.cpp +++ b/MMT/ExtractFromBuffer_VS_WW_Object.cpp @@ -134,9 +134,6 @@ void ExtractFromBuffer_VS_WW_Object(std::wstring DrawIB, std::wstring GameType) LOG.Info(L"MatcheFirstIndex: " + ibFileData.FirstIndex + L" PartName:" + std::to_wstring(outputCount)); LOG.Info("MinNumber: " + std::to_string(ibFileData.MinNumber) + "\t\tMaxNumber:" + std::to_string(ibFileData.MaxNumber)); - std::wstring Format = ibFileData.Format; - std::unordered_map> IBFileBuf = MMTFile_ReadIBBufFromFile(IBReadBufferFilePath, Format); - //分别输出fmt,ib,vb std::wstring OutputIBBufFilePath = OutputDrawIBFolder + DrawIB + L"-" + std::to_wstring(outputCount) + L".ib"; std::wstring OutputVBBufFilePath = OutputDrawIBFolder + DrawIB + L"-" + std::to_wstring(outputCount) + L".vb"; diff --git a/MMT/Generate_CS_WW.cpp b/MMT/Generate_CS_WW.cpp index dbdc930..3c6801e 100644 --- a/MMT/Generate_CS_WW.cpp +++ b/MMT/Generate_CS_WW.cpp @@ -2,6 +2,8 @@ #include "IndexBufferBufFile.h" #include "VertexBufferBufFile.h" #include "MMTFormatUtils.h" +#include "WWUtil.h" + void Generate_CS_WW_Body() { @@ -56,13 +58,13 @@ void Generate_CS_WW_Body() { int drawNumber = 0; std::unordered_map>> partName_VBCategoryDaytaMap; std::unordered_map partNameOffsetMap; - + std::unordered_map partNameVertexCountMap; for (std::string partName : extractConfig.PartNameList) { std::wstring VBFileName = MMTString_ToWideString(partName) + L".vb"; uint64_t VBFileSize = MMTFile_GetFileSize(splitReadFolder + VBFileName); uint64_t vbFileVertexNumber = VBFileSize / SplitStride; - + partNameVertexCountMap[partName] = vbFileVertexNumber; LOG.Info(L"Processing VB file: " + VBFileName + L" size is: " + std::to_wstring(VBFileSize) + L" byte." + L" vertex number is: " + std::to_wstring(vbFileVertexNumber)); VertexBufferBufFile vbBufFile(splitReadFolder + VBFileName, d3d11GameType, extractConfig.TmpElementList); partName_VBCategoryDaytaMap[MMTString_ToWideString(partName)] = vbBufFile.CategoryVBDataMap; @@ -127,8 +129,6 @@ void Generate_CS_WW_Body() { } } LOG.NewLine(); - //TODO 可能涉及到的TANGENT翻转等等 - //直接输出 for (const auto& pair : finalVBCategoryDataMap) { @@ -156,6 +156,94 @@ void Generate_CS_WW_Body() { std::wstring outputIniFileName = splitOutputFolder + extractConfig.DrawIB + L".ini"; std::wofstream outputIniFile(outputIniFileName); + //如果是使用CS计算,则突破顶点数量限制 + //TODO 除此之外,还需要调用Dispatch,所以CSReplace需要和store命令配合使用 + //比如在1ff924db9d4048d1中,读取索引3上的计算次数到变量,通过下面填写判断变量值是否为原始顶点数 + //来执行cs-cb0替换,并且执行我们自定义数量的Dispatch + //那么是否可以通过其中一个cs-tX的Hash来替换其它cs-tX槽位上的数据呢?如果不能,Dispatch要在哪里调用呢?是需要CustomShader调用嘛? + //TODO 有空了测试上述理论,现在cs-cb0数值已经可以更改,就差最后一个Dispatch调用位置就可以突破了 + + //TODO 能否绕过Dispatch的问题?比如修改一下ComputeShader,如果检测到需要变更的Dispatch数量,则使用我们自己的数值填入变量来进行替换计算次数 + //以此绕过Dispatch限制?有空进行测试。 + bool debug = false; + if (d3d11GameType.GPUPreSkinning && debug) { + outputIniFile << std::endl; + outputIniFile << L"; -------------- Break Vertex Count Limit -----------------" << std::endl << std::endl; + outputIniFile << L"[TextureOverride_CSReplace_VertexLimitBreak]" << std::endl; + //TODO 需要收集cs-cb0的hash值 + outputIniFile << L"hash = " << MMTString_ToWideString(extractConfig.VertexLimitVB) << std::endl; + + //先读取csinfo.json里的数据 + WuwaCSInfoJsonObject wwcsinfoObject(splitReadFolder); + + //遍历每个partName + int currentOffset = 0; + for (std::string partName :extractConfig.PartNameList) { + int currentVertexCount = partNameVertexCountMap[partName]; + WuwaCSInfo wwcsInfo = wwcsinfoObject.PartNameWuwaCSInfoMap[partName]; + int originalVertexCount = wwcsInfo.CalculateTime; + int originalOffset = wwcsInfo.Offset; + LOG.Info("CurrentVertexCount: " + std::to_string(currentVertexCount) + " OriginalVertexCount: " + std::to_string(originalVertexCount)); + outputIniFile << L";------------" + MMTString_ToWideString(partName) + L"-----------" << std::endl; + + if (originalVertexCount == currentVertexCount) { + //顶点数相同时,无需改变顶点数,但是如果偏移不同还是需要改偏移的。 + if (currentOffset != originalOffset) { + if (wwcsInfo.ComputeShaderHash == "4d0760c2c7406824") { + //修改3个偏移数 + outputIniFile << L"csreplace = cs-cb0, 1, " + std::to_wstring(originalOffset) + L"," + std::to_wstring(currentOffset) << std::endl; + outputIniFile << L"csreplace = cs-cb0, 2, " + std::to_wstring(originalOffset) + L"," + std::to_wstring(currentOffset) << std::endl; + outputIniFile << L"csreplace = cs-cb0, 3, " + std::to_wstring(originalOffset) + L"," + std::to_wstring(currentOffset) << std::endl; + } + else if (wwcsInfo.ComputeShaderHash == "1ff924db9d4048d1") { + //修改2个偏移数 + outputIniFile << L"csreplace = cs-cb0, 1, " + std::to_wstring(originalOffset) + L"," + std::to_wstring(currentOffset) << std::endl; + outputIniFile << L"csreplace = cs-cb0, 2, " + std::to_wstring(originalOffset) + L"," + std::to_wstring(currentOffset) << std::endl; + } + + } + } + else { + if (currentOffset != originalOffset) { + //顶点数不同,偏移也不同时全部都要修改 + if (wwcsInfo.ComputeShaderHash == "4d0760c2c7406824") { + //修改3个偏移数 + outputIniFile << L"csreplace = cs-cb0, 1, " + std::to_wstring(originalOffset) + L"," + std::to_wstring(currentOffset) << std::endl; + outputIniFile << L"csreplace = cs-cb0, 2, " + std::to_wstring(originalOffset) + L"," + std::to_wstring(currentOffset) << std::endl; + outputIniFile << L"csreplace = cs-cb0, 3, " + std::to_wstring(originalOffset) + L"," + std::to_wstring(currentOffset) << std::endl << std::endl; + //修改1个顶点数 + outputIniFile << L"csreplace = cs-cb0, 4, " + std::to_wstring(originalVertexCount) + L"," + std::to_wstring(currentVertexCount) << std::endl; + + } + else if (wwcsInfo.ComputeShaderHash == "1ff924db9d4048d1") { + //修改2个偏移数 + outputIniFile << L"csreplace = cs-cb0, 1, " + std::to_wstring(originalOffset) + L"," + std::to_wstring(currentOffset) << std::endl; + outputIniFile << L"csreplace = cs-cb0, 2, " + std::to_wstring(originalOffset) + L"," + std::to_wstring(currentOffset) << std::endl << std::endl; + //修改1个顶点数 + outputIniFile << L"csreplace = cs-cb0, 3, " + std::to_wstring(originalVertexCount) + L"," + std::to_wstring(currentVertexCount) << std::endl; + + } + } + else { + //顶点数不同,偏移相同时,只需要改顶点数 + if (wwcsInfo.ComputeShaderHash == "4d0760c2c7406824") { + //修改1个顶点数 + outputIniFile << L"csreplace = cs-cb0, 4, " + std::to_wstring(originalVertexCount) + L"," + std::to_wstring(currentVertexCount) << std::endl; + + } + else if (wwcsInfo.ComputeShaderHash == "1ff924db9d4048d1") { + //修改1个顶点数 + outputIniFile << L"csreplace = cs-cb0, 3, " + std::to_wstring(originalVertexCount) + L"," + std::to_wstring(currentVertexCount) << std::endl; + + } + } + } + + currentOffset = currentOffset + currentVertexCount; + } + + } + outputIniFile << std::endl; outputIniFile << L"; -------------- TextureOverride VB -----------------" << std::endl << std::endl; //1.写出VBResource部分 @@ -165,11 +253,9 @@ void Generate_CS_WW_Body() { int fileSize = MMTFile_GetFileSize(filePath); std::string categoryHash = extractConfig.CategoryHashMap[categoryName]; std::string categorySlot = d3d11GameType.CategorySlotMap[categoryName]; - if (categoryName != "UVTOP") { - outputIniFile << L"[TextureOverride_" + MMTString_ToWideString(categoryName) + L"_Replace]" << std::endl; - outputIniFile << L"hash = " << MMTString_ToWideString(categoryHash) << "" << std::endl; - outputIniFile << "this = " << L"Resource_VB_" + MMTString_ToWideString(categoryName) + L"" << std::endl << std::endl; - } + outputIniFile << L"[TextureOverride_" + MMTString_ToWideString(categoryName) + L"_Replace]" << std::endl; + outputIniFile << L"hash = " << MMTString_ToWideString(categoryHash) << "" << std::endl; + outputIniFile << "this = " << L"Resource_VB_" + MMTString_ToWideString(categoryName) + L"" << std::endl << std::endl; } outputIniFile << std::endl; diff --git a/MMT/MMTFileUtils.cpp b/MMT/MMTFileUtils.cpp index 1ae23ff..43e519d 100644 --- a/MMT/MMTFileUtils.cpp +++ b/MMT/MMTFileUtils.cpp @@ -244,28 +244,5 @@ bool MMTFile_IsValidFilename(std::string filename) { -//TODO 这个方法要优化掉 -std::unordered_map> MMTFile_ReadIBBufFromFile(std::wstring readPathW, std::wstring Format) { - std::unordered_map> BufMap; - - int stride = 0; - std::wstring lowerFormatStr = boost::algorithm::to_lower_copy(Format); - if (lowerFormatStr == L"dxgi_format_r16_uint") { - stride = 2; - } - if (lowerFormatStr == L"dxgi_format_r32_uint") { - stride = 4; - } - int size = MMTFile_GetFileSize(readPathW); - int vertexNumber = size / stride; - std::vector Buffer(size); - std::ifstream BufFile(readPathW, std::ifstream::binary); - BufFile.read(reinterpret_cast(Buffer.data()), size); - BufFile.close(); - for (int i = 0; i < vertexNumber; i++) { - BufMap[i] = MMTFormat_GetRange_Byte(Buffer, i * stride, i * stride + stride); - } - return BufMap; -} diff --git a/MMT/MMTFileUtils.h b/MMT/MMTFileUtils.h index 1451e41..c04c8fe 100644 --- a/MMT/MMTFileUtils.h +++ b/MMT/MMTFileUtils.h @@ -13,6 +13,7 @@ std::vector MMTFile_FindFileNameListWithCondition(std::wstring Sea std::vector MMTFile_ReadIniFileLineList(std::wstring filePath); + std::vector MMTFile_GetFilePathListRecursive(std::wstring directory); //读取文件的所有行,一般用于ini读取或分析 @@ -23,9 +24,10 @@ void MMTFile_DeleteFilesWithSuffix(std::wstring directory, std::wstring suffix); std::unordered_map> MMTFile_ReadBufMapFromFile(std::wstring readPathW, int vertexNumber); -std::unordered_map> MMTFile_ReadIBBufFromFile(std::wstring readPathW, std::wstring Format); - +//读取文件大小 int MMTFile_GetFileSize(std::wstring FileName); + +//读取特殊的结尾被填充特别多0的文件的真实的不为0部分的文件大小 int MMTFile_GetRealFileSize_NullTerminated(std::wstring FileName); std::wstring MMTFile_FindMaxPrefixedDirectory(const std::wstring& directoryPath, const std::wstring& prefix); @@ -33,6 +35,5 @@ std::wstring MMTFile_FindMaxPrefixedDirectory(const std::wstring& directoryPath, //在文件中查找指定3Dmigoto的ini类型属性,比如查找format,需提供绝对路径,比直接分析整个文件的其它方法更快 std::wstring MMTFile_FindMigotoIniAttributeInFile(const std::wstring& filePath, const std::wstring& attributeName); - bool MMTFile_IsValidFilename(std::string filename); diff --git a/MMT/WWUtil.cpp b/MMT/WWUtil.cpp index 1729fc6..419af1f 100644 --- a/MMT/WWUtil.cpp +++ b/MMT/WWUtil.cpp @@ -29,7 +29,27 @@ void WuwaCSInfoJsonObject::saveToJsonFile(std::wstring outputFolder) { } -void WuwaCSInfoJsonObject::readFromJsonFile(std::wstring jsonFilePath) { - -} \ No newline at end of file +WuwaCSInfoJsonObject::WuwaCSInfoJsonObject() { + +} + +WuwaCSInfoJsonObject::WuwaCSInfoJsonObject(std::wstring readFolderPath) { + std::wstring readJsonPath = readFolderPath + L"wwinfo.json"; + if (std::filesystem::exists(readJsonPath)) { + json wwcsinfoJson = MMTJson_ReadJsonFromFile(readJsonPath); + WuwaCSInfo wwcsInfo; + for (const auto& item : wwcsinfoJson.items()) { + std::string CalculateTime = item.value()["CalculateTime"]; + std::string Offset = item.value()["Offset"]; + std::string ComputeShaderHash = item.value()["ComputeShaderHash"]; + LOG.Info("CalculateTime: " + CalculateTime); + LOG.Info("Offset: " + Offset); + LOG.Info("ComputeShaderHash: " + ComputeShaderHash); + wwcsInfo.CalculateTime = std::stoi(CalculateTime); + wwcsInfo.Offset = std::stoi(Offset); + wwcsInfo.ComputeShaderHash = ComputeShaderHash; + this->PartNameWuwaCSInfoMap[item.key()] = wwcsInfo; + } + } +} diff --git a/MMT/WWUtil.h b/MMT/WWUtil.h index eb27151..a472598 100644 --- a/MMT/WWUtil.h +++ b/MMT/WWUtil.h @@ -20,5 +20,7 @@ class WuwaCSInfoJsonObject { void saveToJsonFile(std::wstring outputFolder); - void readFromJsonFile(std::wstring jsonFilePath); + WuwaCSInfoJsonObject(); + + WuwaCSInfoJsonObject(std::wstring readFolderPath); }; \ No newline at end of file