mirror of
				https://github.com/hedge-dev/XenosRecomp.git
				synced 2025-10-30 07:12:17 +00:00 
			
		
		
		
	Compare commits
	
		
			2 commits
		
	
	
		
			5a81a69f9c
			...
			7be2b82bb3
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 7be2b82bb3 | ||
|   | a0e2d16fb0 | 
					 4 changed files with 247 additions and 117 deletions
				
			
		|  | @ -34,6 +34,11 @@ IDxcBlob* DxcCompiler::compile(const std::string& shaderSource, bool compilePixe | |||
|             target = L"-T vs_6_0"; | ||||
|     } | ||||
| 
 | ||||
|     if (!compileLibrary) | ||||
|     { | ||||
|         args[argCount++] = L"-E shaderMain"; | ||||
|     } | ||||
| 
 | ||||
|     args[argCount++] = target; | ||||
|     args[argCount++] = L"-HV 2021"; | ||||
|     args[argCount++] = L"-all-resources-bound"; | ||||
|  |  | |||
|  | @ -44,7 +44,8 @@ using namespace metal; | |||
| 
 | ||||
| constant uint G_SPEC_CONSTANT [[function_constant(0)]]; | ||||
| 
 | ||||
| uint g_SpecConstants() { | ||||
| uint g_SpecConstants() | ||||
| { | ||||
|     return G_SPEC_CONSTANT; | ||||
| } | ||||
| 
 | ||||
|  | @ -172,7 +173,7 @@ float rcp(T a) | |||
| template<typename T> | ||||
| float4x4 mul(T a, T b) | ||||
| { | ||||
|     a * b; | ||||
|     return a * b; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
|  |  | |||
|  | @ -130,14 +130,21 @@ static FetchDestinationSwizzle getDestSwizzle(uint32_t dstSwizzle, uint32_t inde | |||
|     return FetchDestinationSwizzle((dstSwizzle >> (index * 3)) & 0x7); | ||||
| } | ||||
| 
 | ||||
| void ShaderRecompiler::printDstSwizzle(uint32_t dstSwizzle, bool operand) | ||||
| uint32_t ShaderRecompiler::printDstSwizzle(uint32_t dstSwizzle, bool operand) | ||||
| { | ||||
|     uint32_t size = 0; | ||||
| 
 | ||||
|     for (size_t i = 0; i < 4; i++) | ||||
|     { | ||||
|         const auto swizzle = getDestSwizzle(dstSwizzle, i); | ||||
|         if (swizzle >= FetchDestinationSwizzle::X && swizzle <= FetchDestinationSwizzle::W) | ||||
|         { | ||||
|             out += SWIZZLES[operand ? uint32_t(swizzle) : i]; | ||||
|             size++; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return size; | ||||
| } | ||||
| 
 | ||||
| void ShaderRecompiler::printDstSwizzle01(uint32_t dstRegister, uint32_t dstSwizzle) | ||||
|  | @ -172,10 +179,15 @@ void ShaderRecompiler::recompile(const VertexFetchInstruction& instr, uint32_t a | |||
| 
 | ||||
|     indent(); | ||||
|     print("r{}.", instr.dstRegister); | ||||
|     printDstSwizzle(instr.dstSwizzle, false); | ||||
|     uint32_t size = printDstSwizzle(instr.dstSwizzle, false); | ||||
| 
 | ||||
|     out += " = "; | ||||
| 
 | ||||
|     if (size <= 1) | ||||
|         out += "(float)("; | ||||
|     else | ||||
|         print("(float{})(", size); | ||||
| 
 | ||||
|     auto findResult = vertexElements.find(address); | ||||
|     assert(findResult != vertexElements.end()); | ||||
| 
 | ||||
|  | @ -185,15 +197,15 @@ void ShaderRecompiler::recompile(const VertexFetchInstruction& instr, uint32_t a | |||
|     case DeclUsage::Tangent: | ||||
|     case DeclUsage::Binormal: | ||||
|         specConstantsMask |= SPEC_CONSTANT_R11G11B10_NORMAL; | ||||
|         print("tfetchR11G11B10("); | ||||
|         print("tfetchR11G11B10((uint4)"); | ||||
|         break; | ||||
| 
 | ||||
|     case DeclUsage::TexCoord: | ||||
|         print("tfetchTexcoord(g_SwappedTexcoords, "); | ||||
|         print("tfetchTexcoord(g_SwappedTexcoords, (float4)"); | ||||
|         break; | ||||
|     } | ||||
| 
 | ||||
|     print("i{}{}", USAGE_VARIABLES[uint32_t(findResult->second.usage)], uint32_t(findResult->second.usageIndex)); | ||||
|     print("(input.i{}{})", USAGE_VARIABLES[uint32_t(findResult->second.usage)], uint32_t(findResult->second.usageIndex)); | ||||
| 
 | ||||
|     switch (findResult->second.usage) | ||||
|     { | ||||
|  | @ -208,7 +220,7 @@ void ShaderRecompiler::recompile(const VertexFetchInstruction& instr, uint32_t a | |||
|         break; | ||||
|     } | ||||
| 
 | ||||
|     out += '.'; | ||||
|     out += ")."; | ||||
|     printDstSwizzle(instr.dstSwizzle, true); | ||||
| 
 | ||||
|     out += ";\n"; | ||||
|  | @ -356,7 +368,13 @@ void ShaderRecompiler::recompile(const TextureFetchInstruction& instr, bool bicu | |||
|         print(", float2({}, {})", instr.offsetX * 0.5f, instr.offsetY * 0.5f); | ||||
|         break; | ||||
|     case TextureDimension::TextureCube: | ||||
|         out += ", cubeMapData"; | ||||
|         println("\n#ifdef __air__"); | ||||
|         indent(); | ||||
|         println(", &cubeMapData"); | ||||
|         println("#else"); | ||||
|         indent(); | ||||
|         println(", cubeMapData"); | ||||
|         println("#endif"); | ||||
|         break; | ||||
|     } | ||||
| 
 | ||||
|  | @ -594,6 +612,8 @@ void ShaderRecompiler::recompile(const AluInstruction& instr) | |||
|     bool closeIfBracket = false; | ||||
| 
 | ||||
|     std::string_view exportRegister; | ||||
|     bool vectorRegister = true; | ||||
| 
 | ||||
|     if (instr.exportData) | ||||
|     { | ||||
|         if (isPixelShader) | ||||
|  | @ -601,19 +621,20 @@ void ShaderRecompiler::recompile(const AluInstruction& instr) | |||
|             switch (ExportRegister(instr.vectorDest)) | ||||
|             { | ||||
|             case ExportRegister::PSColor0: | ||||
|                 exportRegister = "oC0"; | ||||
|                 exportRegister = "output.oC0"; | ||||
|                 break;         | ||||
|             case ExportRegister::PSColor1: | ||||
|                 exportRegister = "oC1"; | ||||
|                 exportRegister = "output.oC1"; | ||||
|                 break;         | ||||
|             case ExportRegister::PSColor2: | ||||
|                 exportRegister = "oC2"; | ||||
|                 exportRegister = "output.oC2"; | ||||
|                 break;             | ||||
|             case ExportRegister::PSColor3: | ||||
|                 exportRegister = "oC3"; | ||||
|                 exportRegister = "output.oC3"; | ||||
|                 break;            | ||||
|             case ExportRegister::PSDepth: | ||||
|                 exportRegister = "oDepth"; | ||||
|                 exportRegister = "output.oDepth"; | ||||
|                 vectorRegister = false; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|  | @ -622,7 +643,7 @@ void ShaderRecompiler::recompile(const AluInstruction& instr) | |||
|             switch (ExportRegister(instr.vectorDest)) | ||||
|             { | ||||
|             case ExportRegister::VSPosition: | ||||
|                 exportRegister = "oPos"; | ||||
|                 exportRegister = "output.oPos"; | ||||
| 
 | ||||
|             #ifdef UNLEASHED_RECOMP | ||||
|                 if (hasMtxProjection) | ||||
|  | @ -689,7 +710,8 @@ void ShaderRecompiler::recompile(const AluInstruction& instr) | |||
|         if (!exportRegister.empty()) | ||||
|         { | ||||
|             out += exportRegister; | ||||
|             out += '.'; | ||||
|             if (vectorRegister) | ||||
|                 out += '.'; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|  | @ -700,19 +722,20 @@ void ShaderRecompiler::recompile(const AluInstruction& instr) | |||
| 
 | ||||
|         for (size_t i = 0; i < 4; i++) | ||||
|         { | ||||
|             if ((vectorWriteMask >> i) & 0x1) { | ||||
|                 out += SWIZZLES[i]; | ||||
|             if ((vectorWriteMask >> i) & 0x1) | ||||
|             { | ||||
|                 if (vectorRegister) | ||||
|                     out += SWIZZLES[i]; | ||||
|                 vectorWriteSize++; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         out += " = "; | ||||
| 
 | ||||
|         if (vectorWriteSize > 1) { | ||||
|         if (vectorWriteSize > 1) | ||||
|             print("(float{})(", vectorWriteSize); | ||||
|         } else { | ||||
|         else | ||||
|             out += "(float)("; | ||||
|         } | ||||
| 
 | ||||
|         if (instr.vectorSaturate) | ||||
|             out += "saturate("; | ||||
|  | @ -790,7 +813,13 @@ void ShaderRecompiler::recompile(const AluInstruction& instr) | |||
|             break; | ||||
| 
 | ||||
|         case AluVectorOpcode::Cube: | ||||
|             println("\n#ifdef __air__"); | ||||
|             indent(); | ||||
|             print("cube(r{}, &cubeMapData)", instr.src1Register); | ||||
|             println("\n#else"); | ||||
|             indent(); | ||||
|             print("cube(r{}, cubeMapData)", instr.src1Register); | ||||
|             println("\n#endif"); | ||||
|             break; | ||||
| 
 | ||||
|         case AluVectorOpcode::Max4: | ||||
|  | @ -1066,7 +1095,8 @@ void ShaderRecompiler::recompile(const AluInstruction& instr) | |||
|         if (!exportRegister.empty()) | ||||
|         { | ||||
|             out += exportRegister; | ||||
|             out += '.'; | ||||
|             if (vectorRegister) | ||||
|                 out += '.'; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|  | @ -1075,7 +1105,7 @@ void ShaderRecompiler::recompile(const AluInstruction& instr) | |||
| 
 | ||||
|         for (size_t i = 0; i < 4; i++) | ||||
|         { | ||||
|             if ((scalarWriteMask >> i) & 0x1) | ||||
|             if (((scalarWriteMask >> i) & 0x1) && vectorRegister) | ||||
|                 out += SWIZZLES[i]; | ||||
|         } | ||||
| 
 | ||||
|  | @ -1349,7 +1379,7 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi | |||
|         if (constantInfo->registerSet == RegisterSet::Bool) | ||||
|         { | ||||
|             const char* constantName = reinterpret_cast<const char*>(constantTableData + constantInfo->name); | ||||
|             println("\t#define {} (1 << {})", constantName, constantInfo->registerIndex + (isPixelShader ? 16 : 0)); | ||||
|             println("#define {} (1 << {})", constantName, constantInfo->registerIndex + (isPixelShader ? 16 : 0)); | ||||
|             boolConstants.emplace(constantInfo->registerIndex, constantName); | ||||
|         } | ||||
|     } | ||||
|  | @ -1358,17 +1388,164 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi | |||
| 
 | ||||
|     const auto shader = reinterpret_cast<const Shader*>(shaderData + shaderContainer->shaderOffset); | ||||
| 
 | ||||
|     out += "#if __air__\n"; | ||||
|     println("struct {}", isPixelShader ? "Interpolators" : "VertexShaderInput"); | ||||
|     out += "{\n"; | ||||
| 
 | ||||
|     if (isPixelShader) { | ||||
|         out += "struct StageIn\n"; | ||||
|         out += "{\n"; | ||||
|     if (isPixelShader) | ||||
|     { | ||||
|         out += "#if __air__\n"; | ||||
| 
 | ||||
|         for (auto& [usage, usageIndex] : INTERPOLATORS) | ||||
|             println("\tfloat4 i{}{};", USAGE_VARIABLES[uint32_t(usage)], usageIndex); | ||||
| 
 | ||||
|         out += "};\n"; | ||||
|         out += "#else\n"; | ||||
| 
 | ||||
|         for (auto& [usage, usageIndex] : INTERPOLATORS) | ||||
|             println("\tfloat4 i{0}{1} : {2}{1};", USAGE_VARIABLES[uint32_t(usage)], usageIndex, USAGE_SEMANTICS[uint32_t(usage)]); | ||||
| 
 | ||||
|         out += "#endif\n"; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         auto vertexShader = reinterpret_cast<const VertexShader*>(shader); | ||||
| 
 | ||||
|         out += "#if __air__\n"; | ||||
| 
 | ||||
|         for (uint32_t i = 0; i < vertexShader->vertexElementCount; i++) | ||||
|         { | ||||
|             union | ||||
|             { | ||||
|                 VertexElement vertexElement; | ||||
|                 uint32_t value; | ||||
|             }; | ||||
| 
 | ||||
|             value = vertexShader->vertexElementsAndInterpolators[vertexShader->field18 + i]; | ||||
| 
 | ||||
|             const char* usageType = USAGE_TYPES[uint32_t(vertexElement.usage)]; | ||||
| 
 | ||||
| #ifdef UNLEASHED_RECOMP | ||||
|             if ((vertexElement.usage == DeclUsage::TexCoord && vertexElement.usageIndex == 2 && isMetaInstancer) || | ||||
|                 (vertexElement.usage == DeclUsage::Position && vertexElement.usageIndex == 1)) | ||||
|             { | ||||
|                 usageType = "uint4"; | ||||
|             } | ||||
| #endif | ||||
| 
 | ||||
|             out += '\t'; | ||||
| 
 | ||||
|             print("{0} i{1}{2}", usageType, USAGE_VARIABLES[uint32_t(vertexElement.usage)], | ||||
|                 uint32_t(vertexElement.usageIndex)); | ||||
| 
 | ||||
|             for (auto& usageLocation : USAGE_LOCATIONS) | ||||
|             { | ||||
|                 if (usageLocation.usage == vertexElement.usage && usageLocation.usageIndex == vertexElement.usageIndex) | ||||
|                 { | ||||
|                     println(" [[attribute({})]];", usageLocation.location); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             vertexElements.emplace(uint32_t(vertexElement.address), vertexElement); | ||||
|         } | ||||
| 
 | ||||
|         out += "#else\n"; | ||||
| 
 | ||||
|         for (uint32_t i = 0; i < vertexShader->vertexElementCount; i++) | ||||
|         { | ||||
|             union | ||||
|             { | ||||
|                 VertexElement vertexElement; | ||||
|                 uint32_t value; | ||||
|             }; | ||||
| 
 | ||||
|             value = vertexShader->vertexElementsAndInterpolators[vertexShader->field18 + i]; | ||||
| 
 | ||||
|             const char* usageType = USAGE_TYPES[uint32_t(vertexElement.usage)]; | ||||
| 
 | ||||
| #ifdef UNLEASHED_RECOMP | ||||
|             if ((vertexElement.usage == DeclUsage::TexCoord && vertexElement.usageIndex == 2 && isMetaInstancer) || | ||||
|                 (vertexElement.usage == DeclUsage::Position && vertexElement.usageIndex == 1)) | ||||
|             { | ||||
|                 usageType = "uint4"; | ||||
|             } | ||||
| #endif | ||||
| 
 | ||||
|             out += '\t'; | ||||
| 
 | ||||
|             for (auto& usageLocation : USAGE_LOCATIONS) | ||||
|             { | ||||
|                 if (usageLocation.usage == vertexElement.usage && usageLocation.usageIndex == vertexElement.usageIndex) | ||||
|                 { | ||||
|                     print("[[vk::location({})]] ", usageLocation.location); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             println("{0} i{1}{2} : {3}{2};", usageType, USAGE_VARIABLES[uint32_t(vertexElement.usage)], | ||||
|                 uint32_t(vertexElement.usageIndex), USAGE_SEMANTICS[uint32_t(vertexElement.usage)]); | ||||
|         } | ||||
| 
 | ||||
|         out += "#endif\n"; | ||||
|     } | ||||
| 
 | ||||
|     out += "};\n"; | ||||
| 
 | ||||
|     println("struct {}", isPixelShader ? "PixelShaderOutput" : "Interpolators"); | ||||
|     out += "{\n"; | ||||
| 
 | ||||
|     if (isPixelShader) | ||||
|     { | ||||
|         out += "#if __air__\n"; | ||||
| 
 | ||||
|         auto pixelShader = reinterpret_cast<const PixelShader*>(shader); | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_COLOR0) | ||||
|             out += "\tfloat4 oC0 [[color(0)]];\n"; | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_COLOR1) | ||||
|             out += "\tfloat4 oC1 [[color(1)]];\n"; | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_COLOR2) | ||||
|             out += "\tfloat4 oC2 [[color(2)]];\n"; | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_COLOR3) | ||||
|             out += "\tfloat4 oC3 [[color(3)]];\n"; | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_DEPTH) | ||||
|             out += "\tfloat oDepth [[depth(any)]];\n"; | ||||
| 
 | ||||
|         out += "#else\n"; | ||||
| 
 | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_COLOR0) | ||||
|             out += "\tfloat4 oC0 : SV_Target0;\n"; | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_COLOR1) | ||||
|             out += "\tfloat4 oC1 : SV_Target1;\n"; | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_COLOR2) | ||||
|             out += "\tfloat4 oC2 : SV_Target2;\n"; | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_COLOR3) | ||||
|             out += "\tfloat4 oC3 : SV_Target3;\n"; | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_DEPTH) | ||||
|             out += "\tfloat oDepth : SV_Depth;\n"; | ||||
| 
 | ||||
|         out += "#endif\n"; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         out += "#if __air__\n"; | ||||
| 
 | ||||
|         out += "\tfloat4 oPos [[position]];\n"; | ||||
| 
 | ||||
|         for (auto& [usage, usageIndex] : INTERPOLATORS) | ||||
|             print("\tfloat4 o{0}{1};\n", USAGE_VARIABLES[uint32_t(usage)], usageIndex); | ||||
| 
 | ||||
|         out += "#else\n"; | ||||
| 
 | ||||
|         out += "\tfloat4 oPos : SV_Position;\n"; | ||||
| 
 | ||||
|         for (auto& [usage, usageIndex] : INTERPOLATORS) | ||||
|             print("\tfloat4 o{0}{1} : {2}{1};\n", USAGE_VARIABLES[uint32_t(usage)], usageIndex, USAGE_SEMANTICS[uint32_t(usage)]); | ||||
| 
 | ||||
|         out += "#endif\n"; | ||||
|     } | ||||
| 
 | ||||
|     out += "};\n"; | ||||
| 
 | ||||
|     out += "#ifdef __air__\n"; | ||||
| 
 | ||||
|     if (isPixelShader) | ||||
|         out += "[[fragment]]\n"; | ||||
|  | @ -1384,128 +1561,77 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi | |||
| 
 | ||||
|     out += "#endif\n"; | ||||
| 
 | ||||
|     out += "void shaderMain(\n"; | ||||
|     println("{} shaderMain(", isPixelShader ? "PixelShaderOutput" : "Interpolators"); | ||||
| 
 | ||||
|     if (isPixelShader) | ||||
|     { | ||||
|         out += "#ifdef __air__\n"; | ||||
| 
 | ||||
|         out += "\tStageIn iStageIn [[stage_in]],\n"; | ||||
|         out += "\tInterpolators input [[stage_in]],\n"; | ||||
|         out += "\tfloat4 iPos [[position]],\n"; | ||||
|         out += "\tbool iFace [[front_facing]],\n"; | ||||
| 
 | ||||
|         auto pixelShader = reinterpret_cast<const PixelShader*>(shader); | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_COLOR0) | ||||
|             out += "\tfloat4 oC0 [[color(0)]],\n"; | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_COLOR1) | ||||
|             out += "\tfloat4 oC1 [[color(1)]],\n"; | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_COLOR2) | ||||
|             out += "\tfloat4 oC2 [[color(2)]],\n"; | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_COLOR3) | ||||
|             out += "\tfloat4 oC3 [[color(3)]],\n"; | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_DEPTH) | ||||
|             out += "\tfloat oDepth [[depth(any)]],\n"; | ||||
| 
 | ||||
|         out += "\tconstant Texture2DDescriptorHeap& g_Texture2DDescriptorHeap [[buffer(0)]],\n"; | ||||
|         out += "\tconstant Texture3DDescriptorHeap& g_Texture3DDescriptorHeap [[buffer(1)]],\n"; | ||||
|         out += "\tconstant TextureCubeDescriptorHeap& g_TextureCubeDescriptorHeap [[buffer(2)]],\n"; | ||||
|         out += "\tconstant SamplerDescriptorHeap& g_SamplerDescriptorHeap [[buffer(3)]],\n"; | ||||
|         out += "\tconstant PushConstants& g_PushConstants [[buffer(4)]]\n"; | ||||
|         out += "\tconstant PushConstants& g_PushConstants [[buffer(8)]]\n"; | ||||
| 
 | ||||
|         out += "#else\n"; | ||||
| 
 | ||||
|         out += "\tInterpolators input,\n"; | ||||
|         out += "\tin float4 iPos : SV_Position,\n"; | ||||
| 
 | ||||
|         for (auto& [usage, usageIndex] : INTERPOLATORS) | ||||
|             println("\tin float4 i{0}{1} : {2}{1},", USAGE_VARIABLES[uint32_t(usage)], usageIndex, USAGE_SEMANTICS[uint32_t(usage)]); | ||||
| 
 | ||||
|         out += "#ifdef __spirv__\n"; | ||||
|         out += "\tin bool iFace : SV_IsFrontFace\n"; | ||||
|         out += "#else\n"; | ||||
|         out += "\tin uint iFace : SV_IsFrontFace\n"; | ||||
|         out += "#endif\n"; | ||||
| 
 | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_COLOR0) | ||||
|             out += ",\n\tout float4 oC0 : SV_Target0"; | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_COLOR1) | ||||
|             out += ",\n\tout float4 oC1 : SV_Target1"; | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_COLOR2) | ||||
|             out += ",\n\tout float4 oC2 : SV_Target2"; | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_COLOR3) | ||||
|             out += ",\n\tout float4 oC3 : SV_Target3"; | ||||
|         if (pixelShader->outputs & PIXEL_SHADER_OUTPUT_DEPTH) | ||||
|             out += ",\n\tout float oDepth : SV_Depth"; | ||||
| 
 | ||||
|         out += "\n#endif\n"; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         auto vertexShader = reinterpret_cast<const VertexShader*>(shader); | ||||
|         for (uint32_t i = 0; i < vertexShader->vertexElementCount; i++) | ||||
|         { | ||||
|             union | ||||
|             { | ||||
|                 VertexElement vertexElement; | ||||
|                 uint32_t value; | ||||
|             }; | ||||
| 
 | ||||
|             value = vertexShader->vertexElementsAndInterpolators[vertexShader->field18 + i]; | ||||
| 
 | ||||
|             const char* usageType = USAGE_TYPES[uint32_t(vertexElement.usage)]; | ||||
| 
 | ||||
|         #ifdef UNLEASHED_RECOMP | ||||
|             if ((vertexElement.usage == DeclUsage::TexCoord && vertexElement.usageIndex == 2 && isMetaInstancer) || | ||||
|                 (vertexElement.usage == DeclUsage::Position && vertexElement.usageIndex == 1)) | ||||
|             { | ||||
|                 usageType = "uint4"; | ||||
|             } | ||||
|         #endif | ||||
| 
 | ||||
|             out += '\t'; | ||||
| 
 | ||||
|             for (auto& usageLocation : USAGE_LOCATIONS) | ||||
|             { | ||||
|                 if (usageLocation.usage == vertexElement.usage && usageLocation.usageIndex == vertexElement.usageIndex) | ||||
|                 { | ||||
|                     print("[[vk::location({})]] ", usageLocation.location); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             println("in {0} i{1}{2} : {3}{2},", usageType, USAGE_VARIABLES[uint32_t(vertexElement.usage)], | ||||
|                 uint32_t(vertexElement.usageIndex), USAGE_SEMANTICS[uint32_t(vertexElement.usage)]); | ||||
| 
 | ||||
|             vertexElements.emplace(uint32_t(vertexElement.address), vertexElement); | ||||
|         } | ||||
|         out += "#ifdef __air__\n"; | ||||
|         out += "\tconstant PushConstants& g_PushConstants [[buffer(8)]],\n"; | ||||
|         out += "\tVertexShaderInput input [[stage_in]]\n"; | ||||
|         out += "#else\n"; | ||||
|         out += "\tVertexShaderInput input\n"; | ||||
|         out += "#endif\n"; | ||||
| 
 | ||||
|     #ifdef UNLEASHED_RECOMP | ||||
|         if (hasIndexCount) | ||||
|         { | ||||
|             out += "\t,\n"; | ||||
|             out += "#ifdef __air__\n"; | ||||
|             out += "\tuint iVertexId [[vertex_id]],\n"; | ||||
|             out += "\tuint iInstanceId [[instance_id]],\n"; | ||||
|             out += "\tuint iInstanceId [[instance_id]]\n"; | ||||
|             out += "#else\n"; | ||||
|             out += "\tin uint iVertexId : SV_VertexID,\n"; | ||||
|             out += "\tin uint iInstanceId : SV_InstanceID,\n"; | ||||
|             out += "\tin uint iInstanceId : SV_InstanceID\n"; | ||||
|             out += "#endif\n"; | ||||
|         } | ||||
|     #endif | ||||
| 
 | ||||
|         out += "\tout float4 oPos : SV_Position"; | ||||
| 
 | ||||
|         for (auto& [usage, usageIndex] : INTERPOLATORS) | ||||
|             print(",\n\tout float4 o{0}{1} : {2}{1}", USAGE_VARIABLES[uint32_t(usage)], usageIndex, USAGE_SEMANTICS[uint32_t(usage)]); | ||||
|     } | ||||
| 
 | ||||
|     out += ")\n"; | ||||
|     out += "{\n"; | ||||
| 
 | ||||
| #ifdef UNLEASHED_RECOMP | ||||
| 
 | ||||
|     std::string outputName = isPixelShader ? "PixelShaderOutput" : "Interpolators"; | ||||
| 
 | ||||
|     out += "#ifdef __air__\n"; | ||||
|     println("\t{0} output = {0}{{}};", outputName); | ||||
|     out += "#else\n"; | ||||
|     println("\t{0} output = ({0})0;", outputName); | ||||
|     out += "#endif\n"; | ||||
| 
 | ||||
|     if (hasMtxProjection) | ||||
|     { | ||||
|         specConstantsMask |= SPEC_CONSTANT_REVERSE_Z; | ||||
| 
 | ||||
|         out += "\toPos = 0.0;\n"; | ||||
|         out += "\toutput.oPos = 0.0;\n"; | ||||
| 
 | ||||
|         out += "\tfloat4x4 mtxProjection = float4x4(g_MtxProjection(0), g_MtxProjection(1), g_MtxProjection(2), g_MtxProjection(3));\n"; | ||||
|         out += "\tfloat4x4 mtxProjectionReverseZ = mul(mtxProjection, float4x4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 1, 1));\n"; | ||||
|  | @ -1582,18 +1708,14 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi | |||
|         if (isPixelShader) | ||||
|         { | ||||
|             value = reinterpret_cast<const PixelShader*>(shader)->interpolators[i]; | ||||
|             println("#ifdef __air__"); | ||||
|             println("\tfloat4 r{} = iStageIn.i{}{};", uint32_t(interpolator.reg), USAGE_VARIABLES[uint32_t(interpolator.usage)], uint32_t(interpolator.usageIndex)); | ||||
|             println("#else"); | ||||
|             println("\tfloat4 r{} = i{}{};", uint32_t(interpolator.reg), USAGE_VARIABLES[uint32_t(interpolator.usage)], uint32_t(interpolator.usageIndex)); | ||||
|             println("#endif"); | ||||
|             println("\tfloat4 r{} = input.i{}{};", uint32_t(interpolator.reg), USAGE_VARIABLES[uint32_t(interpolator.usage)], uint32_t(interpolator.usageIndex)); | ||||
|             printedRegisters[interpolator.reg] = true; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             auto vertexShader = reinterpret_cast<const VertexShader*>(shader); | ||||
|             value = vertexShader->vertexElementsAndInterpolators[vertexShader->field18 + vertexShader->vertexElementCount + i]; | ||||
|             interpolators.emplace(i, fmt::format("o{}{}", USAGE_VARIABLES[uint32_t(interpolator.usage)], uint32_t(interpolator.usageIndex))); | ||||
|             interpolators.emplace(i, fmt::format("output.o{}{}", USAGE_VARIABLES[uint32_t(interpolator.usage)], uint32_t(interpolator.usageIndex))); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -1601,11 +1723,11 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi | |||
|     { | ||||
|     #ifdef UNLEASHED_RECOMP | ||||
|         if (!hasMtxProjection) | ||||
|             out += "\toPos = 0.0;\n"; | ||||
|             out += "\toutput.oPos = 0.0;\n"; | ||||
|     #endif | ||||
| 
 | ||||
|         for (auto& [usage, usageIndex] : INTERPOLATORS) | ||||
|             println("\to{}{} = 0.0;", USAGE_VARIABLES[uint32_t(usage)], usageIndex); | ||||
|             println("\toutput.o{}{} = 0.0;", USAGE_VARIABLES[uint32_t(usage)], usageIndex); | ||||
| 
 | ||||
|         out += "\n"; | ||||
|     } | ||||
|  | @ -1642,7 +1764,7 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi | |||
|         out += "\tfloat2 pixelCoord = 0.0;\n"; | ||||
| #endif | ||||
|         out += "#ifdef __air__\n"; | ||||
|         out += "\tCubeMapData cubeMapdata = CubeMapData{};\n"; | ||||
|         out += "\tCubeMapData cubeMapData = CubeMapData{};\n"; | ||||
|         out += "#else\n"; | ||||
|         out += "\tCubeMapData cubeMapData = (CubeMapData)0;\n"; | ||||
|         out += "#endif\n"; | ||||
|  | @ -1961,7 +2083,7 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi | |||
|                     out += "{\n"; | ||||
| 
 | ||||
|                     indent(); | ||||
|                     out += "\tclip(oC0.w - g_AlphaThreshold);\n"; | ||||
|                     out += "\tclip(output.oC0.w - g_AlphaThreshold);\n"; | ||||
| 
 | ||||
|                     indent(); | ||||
|                     out += "}\n"; | ||||
|  | @ -1975,9 +2097,9 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi | |||
|                     out += "{\n"; | ||||
| 
 | ||||
|                     indent(); | ||||
|                     out += "\toC0.w *= 1.0 + computeMipLevel(pixelCoord) * 0.25;\n"; | ||||
|                     out += "\toutput.oC0.w *= 1.0 + computeMipLevel(pixelCoord) * 0.25;\n"; | ||||
|                     indent(); | ||||
|                     out += "\toC0.w = 0.5 + (oC0.w - g_AlphaThreshold) / max(fwidth(oC0.w), 1e-6);\n"; | ||||
|                     out += "\toutput.oC0.w = 0.5 + (output.oC0.w - g_AlphaThreshold) / max(fwidth(output.oC0.w), 1e-6);\n"; | ||||
| 
 | ||||
|                     indent(); | ||||
|                     out += "}\n"; | ||||
|  | @ -1995,7 +2117,7 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi | |||
|                     else | ||||
|                 #endif | ||||
|                     { | ||||
|                         out += "return;\n"; | ||||
|                         out += "return output;\n"; | ||||
|                     } | ||||
|                 } | ||||
|                 else | ||||
|  | @ -2029,5 +2151,7 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi | |||
|         out += "\t}\n"; | ||||
| #endif | ||||
| 
 | ||||
|     out += "\treturn output;\n"; | ||||
| 
 | ||||
|     out += "}"; | ||||
| } | ||||
|  |  | |||
|  | @ -45,7 +45,7 @@ struct ShaderRecompiler : StringBuffer | |||
|             out += '\t'; | ||||
|     } | ||||
| 
 | ||||
|     void printDstSwizzle(uint32_t dstSwizzle, bool operand); | ||||
|     uint32_t printDstSwizzle(uint32_t dstSwizzle, bool operand); | ||||
|     void printDstSwizzle01(uint32_t dstRegister, uint32_t dstSwizzle); | ||||
| 
 | ||||
|     void recompile(const VertexFetchInstruction& instr, uint32_t address); | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue