mirror of
https://github.com/hedge-dev/XenosRecomp.git
synced 2025-10-30 07:12:17 +00:00
Merge a0e2d16fb0 into b15b5e4728
This commit is contained in:
commit
7be2b82bb3
5 changed files with 607 additions and 95 deletions
|
|
@ -4,6 +4,10 @@ if (WIN32)
|
|||
option(XENOS_RECOMP_DXIL "Generate DXIL shader cache" ON)
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
option(XENOS_RECOMP_AIR "Generate Metal AIR shader cache" ON)
|
||||
endif()
|
||||
|
||||
set(SMOLV_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../thirdparty/smol-v/source")
|
||||
|
||||
add_executable(XenosRecomp
|
||||
|
|
@ -51,3 +55,7 @@ if (XENOS_RECOMP_DXIL)
|
|||
target_compile_definitions(XenosRecomp PRIVATE XENOS_RECOMP_DXIL)
|
||||
target_link_libraries(XenosRecomp PRIVATE Microsoft::DXIL)
|
||||
endif()
|
||||
|
||||
if (XENOS_RECOMP_AIR)
|
||||
target_compile_definitions(XenosRecomp PRIVATE XENOS_RECOMP_AIR)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -10,10 +10,12 @@
|
|||
#define SPEC_CONSTANT_REVERSE_Z (1 << 4)
|
||||
#endif
|
||||
|
||||
#if !defined(__cplusplus) || defined(__INTELLISENSE__)
|
||||
#if defined(__air__) || !defined(__cplusplus) || defined(__INTELLISENSE__)
|
||||
|
||||
#ifndef __air__
|
||||
#define FLT_MIN asfloat(0xff7fffff)
|
||||
#define FLT_MAX asfloat(0x7f7fffff)
|
||||
#endif
|
||||
|
||||
#ifdef __spirv__
|
||||
|
||||
|
|
@ -34,6 +36,30 @@ struct PushConstants
|
|||
|
||||
#define g_SpecConstants() g_SpecConstants
|
||||
|
||||
#elif __air__
|
||||
|
||||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
constant uint G_SPEC_CONSTANT [[function_constant(0)]];
|
||||
|
||||
uint g_SpecConstants()
|
||||
{
|
||||
return G_SPEC_CONSTANT;
|
||||
}
|
||||
|
||||
struct PushConstants
|
||||
{
|
||||
ulong VertexShaderConstants;
|
||||
ulong PixelShaderConstants;
|
||||
ulong SharedConstants;
|
||||
};
|
||||
|
||||
#define g_Booleans (*(reinterpret_cast<device uint*>(g_PushConstants.SharedConstants + 256)))
|
||||
#define g_SwappedTexcoords (*(reinterpret_cast<device uint*>(g_PushConstants.SharedConstants + 260)))
|
||||
#define g_AlphaThreshold (*(reinterpret_cast<device float*>(g_PushConstants.SharedConstants + 264)))
|
||||
|
||||
#else
|
||||
|
||||
#define DEFINE_SHARED_CONSTANTS() \
|
||||
|
|
@ -45,6 +71,56 @@ uint g_SpecConstants();
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef __air__
|
||||
|
||||
struct Texture2DDescriptorHeap
|
||||
{
|
||||
array<texture2d<float>, 1> g [[id(0)]];
|
||||
};
|
||||
|
||||
struct Texture3DDescriptorHeap
|
||||
{
|
||||
array<texture3d<float>, 1> g [[id(0)]];
|
||||
};
|
||||
|
||||
struct TextureCubeDescriptorHeap
|
||||
{
|
||||
array<texturecube<float>, 1> g [[id(0)]];
|
||||
};
|
||||
|
||||
struct SamplerDescriptorHeap
|
||||
{
|
||||
array<sampler, 1> g [[id(0)]];
|
||||
};
|
||||
|
||||
uint2 getTexture2DDimensions(texture2d<float> texture)
|
||||
{
|
||||
return uint2(texture.get_width(), texture.get_height());
|
||||
}
|
||||
|
||||
float4 tfetch2D(constant Texture2DDescriptorHeap& textureHeap,
|
||||
constant SamplerDescriptorHeap& samplerHeap,
|
||||
uint resourceDescriptorIndex,
|
||||
uint samplerDescriptorIndex,
|
||||
float2 texCoord, float2 offset)
|
||||
{
|
||||
texture2d<float> texture = textureHeap.g[resourceDescriptorIndex];
|
||||
sampler sampler = samplerHeap.g[samplerDescriptorIndex];
|
||||
return texture.sample(sampler, texCoord + offset / (float2)getTexture2DDimensions(texture));
|
||||
}
|
||||
|
||||
float2 getWeights2D(constant Texture2DDescriptorHeap& textureHeap,
|
||||
constant SamplerDescriptorHeap& samplerHeap,
|
||||
uint resourceDescriptorIndex,
|
||||
uint samplerDescriptorIndex,
|
||||
float2 texCoord, float2 offset)
|
||||
{
|
||||
texture2d<float> texture = textureHeap.g[resourceDescriptorIndex];
|
||||
return select(fract(texCoord * (float2)getTexture2DDimensions(texture) + offset - 0.5), 0.0, isnan(texCoord));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
Texture2D<float4> g_Texture2DDescriptorHeap[] : register(t0, space0);
|
||||
Texture3D<float4> g_Texture3DDescriptorHeap[] : register(t0, space1);
|
||||
TextureCube<float4> g_TextureCubeDescriptorHeap[] : register(t0, space2);
|
||||
|
|
@ -69,6 +145,46 @@ float2 getWeights2D(uint resourceDescriptorIndex, uint samplerDescriptorIndex, f
|
|||
return select(isnan(texCoord), 0.0, frac(texCoord * getTexture2DDimensions(texture) + offset - 0.5));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __air__
|
||||
#define selectWrapper(a, b, c) select(c, b, a)
|
||||
#else
|
||||
#define selectWrapper(a, b, c) select(a, b, c)
|
||||
#endif
|
||||
|
||||
#ifdef __air__
|
||||
#define frac(X) fract(X)
|
||||
|
||||
template<typename T>
|
||||
void clip(T a)
|
||||
{
|
||||
if (a < 0.0) {
|
||||
discard_fragment();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
float rcp(T a)
|
||||
{
|
||||
return 1.0 / a;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
float4x4 mul(T a, T b)
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __air__
|
||||
#define UNROLL
|
||||
#define BRANCH
|
||||
#else
|
||||
#define UNROLL [unroll]
|
||||
#define BRANCH [branch]
|
||||
#endif
|
||||
|
||||
float w0(float a)
|
||||
{
|
||||
return (1.0f / 6.0f) * (a * (a * (-a + 3.0f) - 3.0f) + 1.0f);
|
||||
|
|
@ -109,6 +225,74 @@ float h1(float a)
|
|||
return 1.0f + w3(a) / (w2(a) + w3(a)) + 0.5f;
|
||||
}
|
||||
|
||||
struct CubeMapData
|
||||
{
|
||||
float3 cubeMapDirections[2];
|
||||
uint cubeMapIndex;
|
||||
};
|
||||
|
||||
#ifdef __air__
|
||||
|
||||
float4 tfetch2DBicubic(constant Texture2DDescriptorHeap& textureHeap,
|
||||
constant SamplerDescriptorHeap& samplerHeap,
|
||||
uint resourceDescriptorIndex,
|
||||
uint samplerDescriptorIndex,
|
||||
float2 texCoord, float2 offset)
|
||||
{
|
||||
texture2d<float> texture = textureHeap.g[resourceDescriptorIndex];
|
||||
sampler sampler = samplerHeap.g[samplerDescriptorIndex];
|
||||
uint2 dimensions = getTexture2DDimensions(texture);
|
||||
|
||||
float x = texCoord.x * dimensions.x + offset.x;
|
||||
float y = texCoord.y * dimensions.y + offset.y;
|
||||
|
||||
x -= 0.5f;
|
||||
y -= 0.5f;
|
||||
float px = floor(x);
|
||||
float py = floor(y);
|
||||
float fx = x - px;
|
||||
float fy = y - py;
|
||||
|
||||
float g0x = g0(fx);
|
||||
float g1x = g1(fx);
|
||||
float h0x = h0(fx);
|
||||
float h1x = h1(fx);
|
||||
float h0y = h0(fy);
|
||||
float h1y = h1(fy);
|
||||
|
||||
float4 r =
|
||||
g0(fy) * (g0x * texture.sample(sampler, float2(px + h0x, py + h0y) / float2(dimensions)) +
|
||||
g1x * texture.sample(sampler, float2(px + h1x, py + h0y) / float2(dimensions))) +
|
||||
g1(fy) * (g0x * texture.sample(sampler, float2(px + h0x, py + h1y) / float2(dimensions)) +
|
||||
g1x * texture.sample(sampler, float2(px + h1x, py + h1y) / float2(dimensions)));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
float4 tfetch3D(constant Texture3DDescriptorHeap& textureHeap,
|
||||
constant SamplerDescriptorHeap& samplerHeap,
|
||||
uint resourceDescriptorIndex,
|
||||
uint samplerDescriptorIndex,
|
||||
float3 texCoord)
|
||||
{
|
||||
texture3d<float> texture = textureHeap.g[resourceDescriptorIndex];
|
||||
sampler sampler = samplerHeap.g[samplerDescriptorIndex];
|
||||
return texture.sample(sampler, texCoord);
|
||||
}
|
||||
|
||||
float4 tfetchCube(constant TextureCubeDescriptorHeap& textureHeap,
|
||||
constant SamplerDescriptorHeap& samplerHeap,
|
||||
uint resourceDescriptorIndex,
|
||||
uint samplerDescriptorIndex,
|
||||
float3 texCoord, thread CubeMapData* cubeMapData)
|
||||
{
|
||||
texturecube<float> texture = textureHeap.g[resourceDescriptorIndex];
|
||||
sampler sampler = samplerHeap.g[samplerDescriptorIndex];
|
||||
return texture.sample(sampler, cubeMapData->cubeMapDirections[(uint)texCoord.z]);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
float4 tfetch2DBicubic(uint resourceDescriptorIndex, uint samplerDescriptorIndex, float2 texCoord, float2 offset)
|
||||
{
|
||||
Texture2D<float4> texture = g_Texture2DDescriptorHeap[resourceDescriptorIndex];
|
||||
|
|
@ -146,17 +330,13 @@ float4 tfetch3D(uint resourceDescriptorIndex, uint samplerDescriptorIndex, float
|
|||
return g_Texture3DDescriptorHeap[resourceDescriptorIndex].Sample(g_SamplerDescriptorHeap[samplerDescriptorIndex], texCoord);
|
||||
}
|
||||
|
||||
struct CubeMapData
|
||||
{
|
||||
float3 cubeMapDirections[2];
|
||||
uint cubeMapIndex;
|
||||
};
|
||||
|
||||
float4 tfetchCube(uint resourceDescriptorIndex, uint samplerDescriptorIndex, float3 texCoord, inout CubeMapData cubeMapData)
|
||||
{
|
||||
return g_TextureCubeDescriptorHeap[resourceDescriptorIndex].Sample(g_SamplerDescriptorHeap[samplerDescriptorIndex], cubeMapData.cubeMapDirections[texCoord.z]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
float4 tfetchR11G11B10(uint4 value)
|
||||
{
|
||||
if (g_SpecConstants() & SPEC_CONSTANT_R11G11B10_NORMAL)
|
||||
|
|
@ -169,7 +349,11 @@ float4 tfetchR11G11B10(uint4 value)
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifdef __air__
|
||||
return as_type<float4>(value);
|
||||
#else
|
||||
return asfloat(value);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -178,6 +362,19 @@ float4 tfetchTexcoord(uint swappedTexcoords, float4 value, uint semanticIndex)
|
|||
return (swappedTexcoords & (1ull << semanticIndex)) != 0 ? value.yxwz : value;
|
||||
}
|
||||
|
||||
#ifdef __air__
|
||||
|
||||
float4 cube(float4 value, thread CubeMapData* cubeMapData)
|
||||
{
|
||||
uint index = cubeMapData->cubeMapIndex;
|
||||
cubeMapData->cubeMapDirections[index] = value.xyz;
|
||||
++cubeMapData->cubeMapIndex;
|
||||
|
||||
return float4(0.0, 0.0, 0.0, index);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
float4 cube(float4 value, inout CubeMapData cubeMapData)
|
||||
{
|
||||
uint index = cubeMapData.cubeMapIndex;
|
||||
|
|
@ -187,6 +384,8 @@ float4 cube(float4 value, inout CubeMapData cubeMapData)
|
|||
return float4(0.0, 0.0, 0.0, index);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
float4 dst(float4 src0, float4 src1)
|
||||
{
|
||||
float4 dest;
|
||||
|
|
@ -202,15 +401,34 @@ float4 max4(float4 src0)
|
|||
return max(max(src0.x, src0.y), max(src0.z, src0.w));
|
||||
}
|
||||
|
||||
#ifdef __air__
|
||||
|
||||
float2 getPixelCoord(constant Texture2DDescriptorHeap& textureHeap,
|
||||
uint resourceDescriptorIndex,
|
||||
float2 texCoord)
|
||||
{
|
||||
texture2d<float> texture = textureHeap.g[resourceDescriptorIndex];
|
||||
return (float2)getTexture2DDimensions(texture) * texCoord;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
float2 getPixelCoord(uint resourceDescriptorIndex, float2 texCoord)
|
||||
{
|
||||
return getTexture2DDimensions(g_Texture2DDescriptorHeap[resourceDescriptorIndex]) * texCoord;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
float computeMipLevel(float2 pixelCoord)
|
||||
{
|
||||
#ifdef __air__
|
||||
float2 dx = dfdx(pixelCoord);
|
||||
float2 dy = dfdy(pixelCoord);
|
||||
#else
|
||||
float2 dx = ddx(pixelCoord);
|
||||
float2 dy = ddy(pixelCoord);
|
||||
#endif
|
||||
float deltaMaxSqr = max(dot(dx, dx), dot(dy, dy));
|
||||
return max(0.0, 0.5 * log2(deltaMaxSqr));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
@ -271,7 +283,13 @@ void ShaderRecompiler::recompile(const TextureFetchInstruction& instr, bool bicu
|
|||
if (instr.constIndex == 0 && instr.dimension == TextureDimension::Texture2D)
|
||||
{
|
||||
indent();
|
||||
print("pixelCoord = getPixelCoord({}_Texture2DDescriptorIndex, ", constNamePtr);
|
||||
println("pixelCoord = getPixelCoord(");
|
||||
println("#ifdef __air__");
|
||||
indent();
|
||||
println("g_Texture2DDescriptorHeap,");
|
||||
println("#endif");
|
||||
indent();
|
||||
print("{}_Texture2DDescriptorIndex, ", constNamePtr);
|
||||
printSrcRegister(2);
|
||||
out += ");\n";
|
||||
}
|
||||
|
|
@ -331,7 +349,17 @@ void ShaderRecompiler::recompile(const TextureFetchInstruction& instr, bool bicu
|
|||
out += "Bicubic";
|
||||
#endif
|
||||
|
||||
print("({0}_Texture{1}DescriptorIndex, {0}_SamplerDescriptorIndex, ", constNamePtr, dimension);
|
||||
println("(");
|
||||
|
||||
println("#ifdef __air__");
|
||||
indent();
|
||||
println("\tg_Texture{}DescriptorHeap,", dimension);
|
||||
indent();
|
||||
println("\tg_SamplerDescriptorHeap,");
|
||||
println("#endif");
|
||||
|
||||
indent();
|
||||
print("\t{0}_Texture{1}DescriptorIndex, {0}_SamplerDescriptorIndex, ", constNamePtr, dimension);
|
||||
printSrcRegister(componentCount);
|
||||
|
||||
switch (instr.dimension)
|
||||
|
|
@ -340,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;
|
||||
}
|
||||
|
||||
|
|
@ -578,6 +612,8 @@ void ShaderRecompiler::recompile(const AluInstruction& instr)
|
|||
bool closeIfBracket = false;
|
||||
|
||||
std::string_view exportRegister;
|
||||
bool vectorRegister = true;
|
||||
|
||||
if (instr.exportData)
|
||||
{
|
||||
if (isPixelShader)
|
||||
|
|
@ -585,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -606,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)
|
||||
|
|
@ -673,21 +710,33 @@ void ShaderRecompiler::recompile(const AluInstruction& instr)
|
|||
if (!exportRegister.empty())
|
||||
{
|
||||
out += exportRegister;
|
||||
out += '.';
|
||||
if (vectorRegister)
|
||||
out += '.';
|
||||
}
|
||||
else
|
||||
{
|
||||
print("r{}.", instr.vectorDest);
|
||||
}
|
||||
|
||||
uint32_t vectorWriteSize = 0;
|
||||
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
{
|
||||
if ((vectorWriteMask >> i) & 0x1)
|
||||
out += SWIZZLES[i];
|
||||
{
|
||||
if (vectorRegister)
|
||||
out += SWIZZLES[i];
|
||||
vectorWriteSize++;
|
||||
}
|
||||
}
|
||||
|
||||
out += " = ";
|
||||
|
||||
if (vectorWriteSize > 1)
|
||||
print("(float{})(", vectorWriteSize);
|
||||
else
|
||||
out += "(float)(";
|
||||
|
||||
if (instr.vectorSaturate)
|
||||
out += "saturate(";
|
||||
|
||||
|
|
@ -743,15 +792,15 @@ void ShaderRecompiler::recompile(const AluInstruction& instr)
|
|||
break;
|
||||
|
||||
case AluVectorOpcode::CndEq:
|
||||
print("select({} == 0.0, {}, {})", op(VECTOR_0), op(VECTOR_1), op(VECTOR_2));
|
||||
print("selectWrapper({} == 0.0, {}, {})", op(VECTOR_0), op(VECTOR_1), op(VECTOR_2));
|
||||
break;
|
||||
|
||||
case AluVectorOpcode::CndGe:
|
||||
print("select({} >= 0.0, {}, {})", op(VECTOR_0), op(VECTOR_1), op(VECTOR_2));
|
||||
print("selectWrapper({} >= 0.0, {}, {})", op(VECTOR_0), op(VECTOR_1), op(VECTOR_2));
|
||||
break;
|
||||
|
||||
case AluVectorOpcode::CndGt:
|
||||
print("select({} > 0.0, {}, {})", op(VECTOR_0), op(VECTOR_1), op(VECTOR_2));
|
||||
print("selectWrapper({} > 0.0, {}, {})", op(VECTOR_0), op(VECTOR_1), op(VECTOR_2));
|
||||
break;
|
||||
|
||||
case AluVectorOpcode::Dp4:
|
||||
|
|
@ -764,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:
|
||||
|
|
@ -802,7 +857,7 @@ void ShaderRecompiler::recompile(const AluInstruction& instr)
|
|||
if (instr.vectorSaturate)
|
||||
out += ')';
|
||||
|
||||
out += ";\n";
|
||||
out += ");\n";
|
||||
}
|
||||
|
||||
if (instr.scalarOpcode != AluScalarOpcode::RetainPrev)
|
||||
|
|
@ -1040,7 +1095,8 @@ void ShaderRecompiler::recompile(const AluInstruction& instr)
|
|||
if (!exportRegister.empty())
|
||||
{
|
||||
out += exportRegister;
|
||||
out += '.';
|
||||
if (vectorRegister)
|
||||
out += '.';
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1049,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];
|
||||
}
|
||||
|
||||
|
|
@ -1154,7 +1210,7 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi
|
|||
{
|
||||
uint32_t tailCount = (isPixelShader ? 224 : 256) - constantInfo->registerIndex;
|
||||
|
||||
println("#define {}(INDEX) select((INDEX) < {}, vk::RawBufferLoad<float4>(g_PushConstants.{}ShaderConstants + ({} + min(INDEX, {})) * 16, 0x10), 0.0)",
|
||||
println("#define {}(INDEX) selectWrapper((INDEX) < {}, vk::RawBufferLoad<float4>(g_PushConstants.{}ShaderConstants + ({} + min(INDEX, {})) * 16, 0x10), 0.0)",
|
||||
constantName, tailCount, shaderName, constantInfo->registerIndex.get(), tailCount - 1);
|
||||
}
|
||||
else
|
||||
|
|
@ -1187,6 +1243,75 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi
|
|||
}
|
||||
}
|
||||
|
||||
out += "\n#elif __air__\n\n";
|
||||
|
||||
for (uint32_t i = 0; i < constantTableContainer->constantTable.constants; i++)
|
||||
{
|
||||
const auto constantInfo = reinterpret_cast<const ConstantInfo*>(
|
||||
constantTableData + constantTableContainer->constantTable.constantInfo + i * sizeof(ConstantInfo));
|
||||
|
||||
const char* constantName = reinterpret_cast<const char*>(constantTableData + constantInfo->name);
|
||||
|
||||
#ifdef UNLEASHED_RECOMP
|
||||
if (!isPixelShader)
|
||||
{
|
||||
if (strcmp(constantName, "g_MtxProjection") == 0)
|
||||
hasMtxProjection = true;
|
||||
else if (strcmp(constantName, "g_InstanceTypes") == 0)
|
||||
isMetaInstancer = true;
|
||||
else if (strcmp(constantName, "g_IndexCount") == 0)
|
||||
hasIndexCount = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strcmp(constantName, "g_MtxPrevInvViewProjection") == 0)
|
||||
hasMtxPrevInvViewProjection = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (constantInfo->registerSet)
|
||||
{
|
||||
case RegisterSet::Float4:
|
||||
{
|
||||
const char* shaderName = isPixelShader ? "Pixel" : "Vertex";
|
||||
|
||||
if (constantInfo->registerCount > 1)
|
||||
{
|
||||
uint32_t tailCount = (isPixelShader ? 224 : 256) - constantInfo->registerIndex;
|
||||
|
||||
println("#define {}(INDEX) selectWrapper((INDEX) < {}, (*(reinterpret_cast<device float4*>(g_PushConstants.{}ShaderConstants + ({} + min(INDEX, {})) * 16))), 0.0)",
|
||||
constantName, tailCount, shaderName, constantInfo->registerIndex.get(), tailCount - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
println("#define {} (*(reinterpret_cast<device float4*>(g_PushConstants.{}ShaderConstants + {})))",
|
||||
constantName, shaderName, constantInfo->registerIndex * 16);
|
||||
}
|
||||
|
||||
for (uint16_t j = 0; j < constantInfo->registerCount; j++)
|
||||
float4Constants.emplace(constantInfo->registerIndex + j, constantInfo);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case RegisterSet::Sampler:
|
||||
{
|
||||
for (size_t j = 0; j < std::size(TEXTURE_DIMENSIONS); j++)
|
||||
{
|
||||
println("#define {}_Texture{}DescriptorIndex (*(reinterpret_cast<device uint*>(g_PushConstants.SharedConstants + {})))",
|
||||
constantName, TEXTURE_DIMENSIONS[j], j * 64 + constantInfo->registerIndex * 4);
|
||||
}
|
||||
|
||||
println("#define {}_SamplerDescriptorIndex (*(reinterpret_cast<device uint*>(g_PushConstants.SharedConstants + {})))",
|
||||
constantName, std::size(TEXTURE_DIMENSIONS) * 64 + constantInfo->registerIndex * 4);
|
||||
|
||||
samplers.emplace(constantInfo->registerIndex, constantName);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
out += "\n#else\n\n";
|
||||
|
||||
println("cbuffer {}ShaderConstants : register(b{}, space4)", isPixelShader ? "Pixel" : "Vertex", isPixelShader ? 1 : 0);
|
||||
|
|
@ -1211,7 +1336,7 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi
|
|||
if (constantInfo->registerCount > 1)
|
||||
{
|
||||
uint32_t tailCount = (isPixelShader ? 224 : 256) - constantInfo->registerIndex;
|
||||
println("#define {0}(INDEX) select((INDEX) < {1}, {0}[min(INDEX, {2})], 0.0)", constantName, tailCount, tailCount - 1);
|
||||
println("#define {0}(INDEX) selectWrapper((INDEX) < {1}, {0}[min(INDEX, {2})], 0.0)", constantName, tailCount, tailCount - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1254,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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1263,45 +1388,29 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi
|
|||
|
||||
const auto shader = reinterpret_cast<const Shader*>(shaderData + shaderContainer->shaderOffset);
|
||||
|
||||
out += "#ifndef __spirv__\n";
|
||||
|
||||
if (isPixelShader)
|
||||
out += "[shader(\"pixel\")]\n";
|
||||
else
|
||||
out += "[shader(\"vertex\")]\n";
|
||||
|
||||
out += "#endif\n";
|
||||
|
||||
out += "void main(\n";
|
||||
println("struct {}", isPixelShader ? "Interpolators" : "VertexShaderInput");
|
||||
out += "{\n";
|
||||
|
||||
if (isPixelShader)
|
||||
{
|
||||
out += "\tin float4 iPos : SV_Position,\n";
|
||||
out += "#if __air__\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)]);
|
||||
println("\tfloat4 i{}{};", USAGE_VARIABLES[uint32_t(usage)], usageIndex);
|
||||
|
||||
out += "#ifdef __spirv__\n";
|
||||
out += "\tin bool iFace : SV_IsFrontFace\n";
|
||||
out += "#else\n";
|
||||
out += "\tin uint iFace : SV_IsFrontFace\n";
|
||||
out += "#endif\n";
|
||||
|
||||
auto pixelShader = reinterpret_cast<const PixelShader*>(shader);
|
||||
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";
|
||||
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
|
||||
|
|
@ -1314,13 +1423,52 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi
|
|||
|
||||
const char* usageType = USAGE_TYPES[uint32_t(vertexElement.usage)];
|
||||
|
||||
#ifdef UNLEASHED_RECOMP
|
||||
#ifdef UNLEASHED_RECOMP
|
||||
if ((vertexElement.usage == DeclUsage::TexCoord && vertexElement.usageIndex == 2 && isMetaInstancer) ||
|
||||
(vertexElement.usage == DeclUsage::Position && vertexElement.usageIndex == 1))
|
||||
{
|
||||
usageType = "uint4";
|
||||
}
|
||||
#endif
|
||||
#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';
|
||||
|
||||
|
|
@ -1333,40 +1481,162 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi
|
|||
}
|
||||
}
|
||||
|
||||
println("in {0} i{1}{2} : {3}{2},", usageType, USAGE_VARIABLES[uint32_t(vertexElement.usage)],
|
||||
println("{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 += "#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";
|
||||
else
|
||||
out += "[[vertex]]\n";
|
||||
|
||||
out += "#elifndef __spirv__\n";
|
||||
|
||||
if (isPixelShader)
|
||||
out += "[shader(\"pixel\")]\n";
|
||||
else
|
||||
out += "[shader(\"vertex\")]\n";
|
||||
|
||||
out += "#endif\n";
|
||||
|
||||
println("{} shaderMain(", isPixelShader ? "PixelShaderOutput" : "Interpolators");
|
||||
|
||||
if (isPixelShader)
|
||||
{
|
||||
out += "#ifdef __air__\n";
|
||||
|
||||
out += "\tInterpolators input [[stage_in]],\n";
|
||||
out += "\tfloat4 iPos [[position]],\n";
|
||||
out += "\tbool iFace [[front_facing]],\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(8)]]\n";
|
||||
|
||||
out += "#else\n";
|
||||
|
||||
out += "\tInterpolators input,\n";
|
||||
out += "\tin float4 iPos : SV_Position,\n";
|
||||
|
||||
out += "#ifdef __spirv__\n";
|
||||
out += "\tin bool iFace : SV_IsFrontFace\n";
|
||||
out += "#else\n";
|
||||
out += "\tin uint iFace : SV_IsFrontFace\n";
|
||||
out += "#endif\n";
|
||||
|
||||
out += "\n#endif\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
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 += "#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";
|
||||
|
||||
out += "\t[unroll] for (int iterationIndex = 0; iterationIndex < 2; iterationIndex++)\n";
|
||||
out += "\tUNROLL for (int iterationIndex = 0; iterationIndex < 2; iterationIndex++)\n";
|
||||
out += "\t{\n";
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1381,8 +1651,13 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi
|
|||
auto value = reinterpret_cast<const be<uint32_t>*>(shaderData + shaderContainer->virtualSize + definition->physicalOffset);
|
||||
for (uint16_t i = 0; i < (definition->count + 3) / 4; i++)
|
||||
{
|
||||
println("#ifdef __air__");
|
||||
println("\tfloat4 c{} = as_type<float4>(uint4(0x{:X}, 0x{:X}, 0x{:X}, 0x{:X}));",
|
||||
definition->registerIndex + i - (isPixelShader ? 256 : 0), value[0].get(), value[1].get(), value[2].get(), value[3].get());
|
||||
println("#else");
|
||||
println("\tfloat4 c{} = asfloat(uint4(0x{:X}, 0x{:X}, 0x{:X}, 0x{:X}));",
|
||||
definition->registerIndex + i - (isPixelShader ? 256 : 0), value[0].get(), value[1].get(), value[2].get(), value[3].get());
|
||||
println("#endif");
|
||||
|
||||
value += 4;
|
||||
}
|
||||
|
|
@ -1433,14 +1708,14 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi
|
|||
if (isPixelShader)
|
||||
{
|
||||
value = reinterpret_cast<const PixelShader*>(shader)->interpolators[i];
|
||||
println("\tfloat4 r{} = i{}{};", uint32_t(interpolator.reg), USAGE_VARIABLES[uint32_t(interpolator.usage)], uint32_t(interpolator.usageIndex));
|
||||
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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1448,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";
|
||||
}
|
||||
|
|
@ -1488,7 +1763,11 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi
|
|||
#ifdef UNLEASHED_RECOMP
|
||||
out += "\tfloat2 pixelCoord = 0.0;\n";
|
||||
#endif
|
||||
out += "#ifdef __air__\n";
|
||||
out += "\tCubeMapData cubeMapData = CubeMapData{};\n";
|
||||
out += "#else\n";
|
||||
out += "\tCubeMapData cubeMapData = (CubeMapData)0;\n";
|
||||
out += "#endif\n";
|
||||
}
|
||||
|
||||
const be<uint32_t>* code = reinterpret_cast<const be<uint32_t>*>(shaderData + shaderContainer->virtualSize + shader->physicalOffset);
|
||||
|
|
@ -1646,7 +1925,7 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi
|
|||
{
|
||||
indent();
|
||||
#ifdef UNLEASHED_RECOMP
|
||||
print("[unroll] ");
|
||||
print("UNROLL ");
|
||||
#endif
|
||||
println("for (aL = 0; aL < i{}.x; aL++)", uint32_t(cfInstr.loopStart.loopId));
|
||||
indent();
|
||||
|
|
@ -1754,27 +2033,27 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi
|
|||
specConstantsMask |= SPEC_CONSTANT_BICUBIC_GI_FILTER;
|
||||
|
||||
indent();
|
||||
out += "if (g_SpecConstants() & SPEC_CONSTANT_BICUBIC_GI_FILTER)";
|
||||
out += "if (g_SpecConstants() & SPEC_CONSTANT_BICUBIC_GI_FILTER)\n";
|
||||
indent();
|
||||
out += '{';
|
||||
out += "{\n";
|
||||
|
||||
++indentation;
|
||||
recompile(textureFetch, true);
|
||||
--indentation;
|
||||
|
||||
indent();
|
||||
out += "}";
|
||||
out += "}\n";
|
||||
indent();
|
||||
out += "else";
|
||||
out += "else\n";
|
||||
indent();
|
||||
out += '{';
|
||||
out += "{\n";
|
||||
|
||||
++indentation;
|
||||
recompile(textureFetch, false);
|
||||
--indentation;
|
||||
|
||||
indent();
|
||||
out += '}';
|
||||
out += "}\n";
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
|
@ -1799,31 +2078,31 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi
|
|||
specConstantsMask |= SPEC_CONSTANT_ALPHA_TEST;
|
||||
|
||||
indent();
|
||||
out += "[branch] if (g_SpecConstants() & SPEC_CONSTANT_ALPHA_TEST)";
|
||||
out += "BRANCH if (g_SpecConstants() & SPEC_CONSTANT_ALPHA_TEST)\n";
|
||||
indent();
|
||||
out += '{';
|
||||
out += "{\n";
|
||||
|
||||
indent();
|
||||
out += "\tclip(oC0.w - g_AlphaThreshold);\n";
|
||||
out += "\tclip(output.oC0.w - g_AlphaThreshold);\n";
|
||||
|
||||
indent();
|
||||
out += "}";
|
||||
out += "}\n";
|
||||
|
||||
#ifdef UNLEASHED_RECOMP
|
||||
specConstantsMask |= SPEC_CONSTANT_ALPHA_TO_COVERAGE;
|
||||
|
||||
indent();
|
||||
out += "else if (g_SpecConstants() & SPEC_CONSTANT_ALPHA_TO_COVERAGE)";
|
||||
out += "else if (g_SpecConstants() & SPEC_CONSTANT_ALPHA_TO_COVERAGE)\n";
|
||||
indent();
|
||||
out += '{';
|
||||
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 += '}';
|
||||
out += "}\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -1838,7 +2117,7 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_vi
|
|||
else
|
||||
#endif
|
||||
{
|
||||
out += "return;\n";
|
||||
out += "return output;\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1872,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