Implement alpha to coverage.

This commit is contained in:
Skyth 2024-10-24 14:56:26 +03:00
parent f315ae49ba
commit 2489145820
2 changed files with 78 additions and 26 deletions

View file

@ -43,24 +43,23 @@ Texture3D<float4> g_Texture3DDescriptorHeap[] : register(t0, space1);
TextureCube<float4> g_TextureCubeDescriptorHeap[] : register(t0, space2);
SamplerState g_SamplerDescriptorHeap[] : register(s0, space3);
uint2 getTexture2DDimensions(Texture2D<float4> texture)
{
uint2 dimensions;
texture.GetDimensions(dimensions.x, dimensions.y);
return dimensions;
}
float4 tfetch2D(uint resourceDescriptorIndex, uint samplerDescriptorIndex, float2 texCoord, float2 offset)
{
Texture2D<float4> texture = g_Texture2DDescriptorHeap[resourceDescriptorIndex];
uint2 dimensions;
texture.GetDimensions(dimensions.x, dimensions.y);
return texture.Sample(g_SamplerDescriptorHeap[samplerDescriptorIndex], texCoord + offset / dimensions);
return texture.Sample(g_SamplerDescriptorHeap[samplerDescriptorIndex], texCoord + offset / getTexture2DDimensions(texture));
}
float2 getWeights2D(uint resourceDescriptorIndex, uint samplerDescriptorIndex, float2 texCoord, float2 offset)
{
Texture2D<float4> texture = g_Texture2DDescriptorHeap[resourceDescriptorIndex];
uint2 dimensions;
texture.GetDimensions(dimensions.x, dimensions.y);
return frac(texCoord * dimensions + offset - 0.5);
return frac(texCoord * getTexture2DDimensions(texture) + offset - 0.5);
}
float w0(float a)
@ -107,9 +106,7 @@ float4 tfetch2DBicubic(uint resourceDescriptorIndex, uint samplerDescriptorIndex
{
Texture2D<float4> texture = g_Texture2DDescriptorHeap[resourceDescriptorIndex];
SamplerState samplerState = g_SamplerDescriptorHeap[samplerDescriptorIndex];
uint2 dimensions;
texture.GetDimensions(dimensions.x, dimensions.y);
uint2 dimensions = getTexture2DDimensions(texture);
float x = texCoord.x * dimensions.x + offset.x;
float y = texCoord.y * dimensions.y + offset.y;
@ -198,3 +195,15 @@ float4 max4(float4 src0)
return max(max(src0.x, src0.y), max(src0.z, src0.w));
}
float2 getPixelCoord(uint resourceDescriptorIndex, float2 texCoord)
{
return getTexture2DDimensions(g_Texture2DDescriptorHeap[resourceDescriptorIndex]) * texCoord;
}
float computeMipLevel(float2 pixelCoord)
{
float2 dx = ddx(pixelCoord);
float2 dy = ddy(pixelCoord);
float deltaMaxSqr = max(dot(dx, dx), dot(dy, dy));
return max(0.0, 0.5 * log2(deltaMaxSqr));
}

View file

@ -229,6 +229,36 @@ void ShaderRecompiler::recompile(const TextureFetchInstruction& instr, bool bicu
++indentation;
}
auto printSrcRegister = [&](size_t componentCount)
{
print("r{}.", instr.srcRegister);
for (size_t i = 0; i < componentCount; i++)
out += SWIZZLES[((instr.srcSwizzle >> (i * 2))) & 0x3];
};
std::string constName;
const char* constNamePtr = nullptr;
auto findResult = samplers.find(instr.constIndex);
if (findResult != samplers.end())
{
constNamePtr = findResult->second;
}
else
{
constName = std::format("s{}", instr.constIndex);
constNamePtr = constName.c_str();
}
if (instr.constIndex == 0 && instr.dimension == TextureDimension::Texture2D)
{
indent();
print("pixelCoord = getPixelCoord(GET_SHARED_CONSTANT({}_ResourceDescriptorIndex), ", constNamePtr);
printSrcRegister(2);
out += ");\n";
}
indent();
print("r{}.", instr.dstRegister);
printDstSwizzle(instr.dstSwizzle, false);
@ -268,18 +298,8 @@ void ShaderRecompiler::recompile(const TextureFetchInstruction& instr, bool bicu
if (bicubic)
out += "Bicubic";
out += '(';
auto findResult = samplers.find(instr.constIndex);
if (findResult != samplers.end())
print("GET_SHARED_CONSTANT({}_ResourceDescriptorIndex), GET_SHARED_CONSTANT({}_SamplerDescriptorIndex)", findResult->second, findResult->second);
else
print("GET_SHARED_CONSTANT(s{}_ResourceDescriptorIndex), GET_SHARED_CONSTANT(s{}_SamplerDescriptorIndex)", instr.constIndex, instr.constIndex);
print(", r{}.", instr.srcRegister);
for (size_t i = 0; i < componentCount; i++)
out += SWIZZLES[((instr.srcSwizzle >> (i * 2))) & 0x3];
print("(GET_SHARED_CONSTANT({0}_ResourceDescriptorIndex), GET_SHARED_CONSTANT({0}_SamplerDescriptorIndex), ", constNamePtr);
printSrcRegister(componentCount);
switch (instr.dimension)
{
@ -1290,7 +1310,10 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData)
out += "\tbool p0 = false;\n";
out += "\tfloat ps = 0.0;\n";
if (isPixelShader)
{
out += "\tfloat2 pixelCoord = 0.0;\n";
out += "\tCubeMapData cubeMapData = (CubeMapData)0;\n";
}
const be<uint32_t>* code = reinterpret_cast<const be<uint32_t>*>(shaderData + shaderContainer->virtualSize + shader->physicalOffset);
@ -1591,7 +1614,27 @@ void ShaderRecompiler::recompile(const uint8_t* shaderData)
if (isPixelShader)
{
indent();
out += "[branch] if (GET_SHARED_CONSTANT(g_AlphaTestMode) != 0) clip(oC0.w - GET_SHARED_CONSTANT(g_AlphaThreshold));\n";
out += "[branch] if (GET_SHARED_CONSTANT(g_AlphaTestMode) == 1)";
indent();
out += '{';
indent();
out += "\tclip(oC0.w - GET_SHARED_CONSTANT(g_AlphaThreshold));\n";
indent();
out += "}";
indent();
out += "else if (GET_SHARED_CONSTANT(g_AlphaTestMode) == 2)";
indent();
out += '{';
indent();
out += "\toC0.w *= 1.0 + computeMipLevel(pixelCoord) * 0.25;\n";
indent();
out += "\toC0.w = 0.5 + (oC0.w - GET_SHARED_CONSTANT(g_AlphaThreshold)) / max(fwidth(oC0.w), 1e-6);\n";
indent();
out += '}';
}
else if (isCsdShader)
{