mirror of
https://github.com/hedge-dev/XenosRecomp.git
synced 2025-10-30 07:12:17 +00:00
Add reverse Z implementation.
This commit is contained in:
parent
357d830adb
commit
11128441c6
3 changed files with 67 additions and 7 deletions
|
|
@ -6,6 +6,7 @@
|
||||||
#define SPEC_CONSTANT_BICUBIC_GI_FILTER (1 << 2)
|
#define SPEC_CONSTANT_BICUBIC_GI_FILTER (1 << 2)
|
||||||
#define SPEC_CONSTANT_ALPHA_TEST (1 << 3)
|
#define SPEC_CONSTANT_ALPHA_TEST (1 << 3)
|
||||||
#define SPEC_CONSTANT_ALPHA_TO_COVERAGE (1 << 4)
|
#define SPEC_CONSTANT_ALPHA_TO_COVERAGE (1 << 4)
|
||||||
|
#define SPEC_CONSTANT_REVERSE_Z (1 << 5)
|
||||||
|
|
||||||
#if !defined(__cplusplus) || defined(__INTELLISENSE__)
|
#if !defined(__cplusplus) || defined(__INTELLISENSE__)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -253,8 +253,7 @@ void ShaderRecompiler::recompile(const TextureFetchInstruction& instr, bool bicu
|
||||||
if (findResult != samplers.end())
|
if (findResult != samplers.end())
|
||||||
{
|
{
|
||||||
constNamePtr = findResult->second;
|
constNamePtr = findResult->second;
|
||||||
subtractFromOne = strcmp(constNamePtr, "sampZBuffer") == 0 ||
|
subtractFromOne = hasMtxPrevInvViewProjection && strcmp(constNamePtr, "sampZBuffer") == 0;
|
||||||
strcmp(constNamePtr, "g_DepthSampler") == 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -448,8 +447,16 @@ void ShaderRecompiler::recompile(const AluInstruction& instr)
|
||||||
const char* constantName = reinterpret_cast<const char*>(constantTableData + findResult->second->name);
|
const char* constantName = reinterpret_cast<const char*>(constantTableData + findResult->second->name);
|
||||||
if (findResult->second->registerCount > 1)
|
if (findResult->second->registerCount > 1)
|
||||||
{
|
{
|
||||||
regFormatted = std::format("{}({}{})", constantName,
|
if (hasMtxProjection && strcmp(constantName, "g_MtxProjection") == 0)
|
||||||
reg - findResult->second->registerIndex, instr.const0Relative ? (instr.constAddressRegisterRelative ? " + a0" : " + aL") : "");
|
{
|
||||||
|
regFormatted = std::format("(iterationIndex == 0 ? mtxProjectionReverseZ[{0}] : mtxProjection[{0}])",
|
||||||
|
reg - findResult->second->registerIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
regFormatted = std::format("{}({}{})", constantName,
|
||||||
|
reg - findResult->second->registerIndex, instr.const0Relative ? (instr.constAddressRegisterRelative ? " + a0" : " + aL") : "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -552,6 +559,8 @@ void ShaderRecompiler::recompile(const AluInstruction& instr)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool closeIfBracket = false;
|
||||||
|
|
||||||
std::string_view exportRegister;
|
std::string_view exportRegister;
|
||||||
if (instr.exportData)
|
if (instr.exportData)
|
||||||
{
|
{
|
||||||
|
|
@ -582,6 +591,18 @@ void ShaderRecompiler::recompile(const AluInstruction& instr)
|
||||||
{
|
{
|
||||||
case ExportRegister::VSPosition:
|
case ExportRegister::VSPosition:
|
||||||
exportRegister = "oPos";
|
exportRegister = "oPos";
|
||||||
|
|
||||||
|
if (hasMtxProjection)
|
||||||
|
{
|
||||||
|
indent();
|
||||||
|
out += "if ((g_SpecConstants() & SPEC_CONSTANT_REVERSE_Z) == 0 || iterationIndex == 0)\n";
|
||||||
|
indent();
|
||||||
|
out += "{\n";
|
||||||
|
++indentation;
|
||||||
|
|
||||||
|
closeIfBracket = true;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -1044,6 +1065,13 @@ void ShaderRecompiler::recompile(const AluInstruction& instr)
|
||||||
out += "clip(ps != 0.0 ? 1 : -1);\n";
|
out += "clip(ps != 0.0 ? 1 : -1);\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (closeIfBracket)
|
||||||
|
{
|
||||||
|
--indentation;
|
||||||
|
indent();
|
||||||
|
out += "}\n";
|
||||||
|
}
|
||||||
|
|
||||||
if (instr.isPredicated)
|
if (instr.isPredicated)
|
||||||
{
|
{
|
||||||
--indentation;
|
--indentation;
|
||||||
|
|
@ -1081,11 +1109,18 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi
|
||||||
|
|
||||||
if (!isPixelShader)
|
if (!isPixelShader)
|
||||||
{
|
{
|
||||||
if (strcmp(constantName, "g_InstanceTypes") == 0)
|
if (strcmp(constantName, "g_MtxProjection") == 0)
|
||||||
|
hasMtxProjection = true;
|
||||||
|
else if (strcmp(constantName, "g_InstanceTypes") == 0)
|
||||||
isMetaInstancer = true;
|
isMetaInstancer = true;
|
||||||
else if (strcmp(constantName, "g_IndexCount") == 0)
|
else if (strcmp(constantName, "g_IndexCount") == 0)
|
||||||
hasIndexCount = true;
|
hasIndexCount = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (strcmp(constantName, "g_MtxPrevInvViewProjection") == 0)
|
||||||
|
hasMtxPrevInvViewProjection = true;
|
||||||
|
}
|
||||||
|
|
||||||
switch (constantInfo->registerSet)
|
switch (constantInfo->registerSet)
|
||||||
{
|
{
|
||||||
|
|
@ -1285,6 +1320,20 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi
|
||||||
out += ")\n";
|
out += ")\n";
|
||||||
out += "{\n";
|
out += "{\n";
|
||||||
|
|
||||||
|
|
||||||
|
if (hasMtxProjection)
|
||||||
|
{
|
||||||
|
specConstantsMask |= SPEC_CONSTANT_REVERSE_Z;
|
||||||
|
|
||||||
|
out += "\toPos = 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";
|
||||||
|
|
||||||
|
out += "\t[unroll] for (int iterationIndex = 0; iterationIndex < 2; iterationIndex++)\n";
|
||||||
|
out += "\t{\n";
|
||||||
|
}
|
||||||
|
|
||||||
if (shaderContainer->definitionTableOffset != NULL)
|
if (shaderContainer->definitionTableOffset != NULL)
|
||||||
{
|
{
|
||||||
auto definitionTable = reinterpret_cast<const DefinitionTable*>(shaderData + shaderContainer->definitionTableOffset);
|
auto definitionTable = reinterpret_cast<const DefinitionTable*>(shaderData + shaderContainer->definitionTableOffset);
|
||||||
|
|
@ -1360,7 +1409,9 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi
|
||||||
|
|
||||||
if (!isPixelShader)
|
if (!isPixelShader)
|
||||||
{
|
{
|
||||||
out += "\toPos = 0.0;\n";
|
if (!hasMtxProjection)
|
||||||
|
out += "\toPos = 0.0;\n";
|
||||||
|
|
||||||
for (auto& [usage, usageIndex] : INTERPOLATORS)
|
for (auto& [usage, usageIndex] : INTERPOLATORS)
|
||||||
println("\to{}{} = 0.0;", USAGE_VARIABLES[uint32_t(usage)], usageIndex);
|
println("\to{}{} = 0.0;", USAGE_VARIABLES[uint32_t(usage)], usageIndex);
|
||||||
|
|
||||||
|
|
@ -1734,7 +1785,10 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi
|
||||||
if (simpleControlFlow)
|
if (simpleControlFlow)
|
||||||
{
|
{
|
||||||
indent();
|
indent();
|
||||||
out += "return;\n";
|
if (hasMtxProjection)
|
||||||
|
out += "continue;\n";
|
||||||
|
else
|
||||||
|
out += "return;\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1762,5 +1816,8 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi
|
||||||
out += "\t}\n";
|
out += "\t}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasMtxProjection)
|
||||||
|
out += "\t}\n";
|
||||||
|
|
||||||
out += "}";
|
out += "}";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,8 @@ struct ShaderRecompiler : StringBuffer
|
||||||
std::unordered_map<uint32_t, const char*> samplers;
|
std::unordered_map<uint32_t, const char*> samplers;
|
||||||
std::unordered_map<uint32_t, uint32_t> ifEndLabels;
|
std::unordered_map<uint32_t, uint32_t> ifEndLabels;
|
||||||
uint32_t specConstantsMask = 0;
|
uint32_t specConstantsMask = 0;
|
||||||
|
bool hasMtxProjection = false;
|
||||||
|
bool hasMtxPrevInvViewProjection = false;
|
||||||
|
|
||||||
void indent()
|
void indent()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue