TextureConversionShader: Use integer math for truncating EFB format

This commit is contained in:
Stenzek 2017-04-25 13:02:34 +10:00
parent 335f54cac6
commit adebe2239e
1 changed files with 49 additions and 33 deletions

View File

@ -78,11 +78,6 @@ u16 GetEncodedSampleCount(u32 format)
} }
} }
static bool EFBFormatHasAlpha(u32 format)
{
return format == PEControl::RGBA6_Z24;
}
// block dimensions : widthStride, heightStride // block dimensions : widthStride, heightStride
// texture dims : width, height, x offset, y offset // texture dims : width, height, x offset, y offset
static void WriteSwizzler(char*& p, u32 format, APIType ApiType) static void WriteSwizzler(char*& p, u32 format, APIType ApiType)
@ -94,6 +89,25 @@ static void WriteSwizzler(char*& p, u32 format, APIType ApiType)
else else
WRITE(p, "uniform int4 position;\n"); WRITE(p, "uniform int4 position;\n");
// Alpha channel in the copy is set to 1 the EFB format does not have an alpha channel.
WRITE(p, "float4 RGBA8ToRGB8(float4 src)\n");
WRITE(p, "{\n");
WRITE(p, " return float4(src.xyz, 1.0);\n");
WRITE(p, "}\n");
WRITE(p, "float4 RGBA8ToRGBA6(float4 src)\n");
WRITE(p, "{\n");
WRITE(p, " int4 val = int4(src * 255.0) >> 2;\n");
WRITE(p, " return float4(val) / 63.0;\n");
WRITE(p, "}\n");
WRITE(p, "float4 RGBA8ToRGB565(float4 src)\n");
WRITE(p, "{\n");
WRITE(p, " int4 val = int4(src * 255.0);\n");
WRITE(p, " val = int4(val.r >> 3, val.g >> 2, val.b >> 3, 1);\n");
WRITE(p, " return float4(val) / float4(31.0, 63.0, 31.0, 1.0);\n");
WRITE(p, "}\n");
int blkW = TexDecoder_GetBlockWidthInTexels(format); int blkW = TexDecoder_GetBlockWidthInTexels(format);
int blkH = TexDecoder_GetBlockHeightInTexels(format); int blkH = TexDecoder_GetBlockHeightInTexels(format);
int samples = GetEncodedSampleCount(format); int samples = GetEncodedSampleCount(format);
@ -168,42 +182,45 @@ static void WriteSwizzler(char*& p, u32 format, APIType ApiType)
static void WriteSampleColor(char*& p, const char* colorComp, const char* dest, int xoffset, static void WriteSampleColor(char*& p, const char* colorComp, const char* dest, int xoffset,
APIType ApiType, const EFBCopyFormat& format, bool depth) APIType ApiType, const EFBCopyFormat& format, bool depth)
{ {
if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) WRITE(p, " %s = ", dest);
if (!depth)
{ {
WRITE(p, " %s = texture(samp0, float3(uv0 + float2(%d, 0) * sample_offset, 0.0)).%s;\n", dest, switch (format.efb_format)
xoffset, colorComp); {
case PEControl::RGB8_Z24:
WRITE(p, "RGBA8ToRGB8(");
break;
case PEControl::RGBA6_Z24:
WRITE(p, "RGBA8ToRGBA6(");
break;
case PEControl::RGB565_Z16:
WRITE(p, "RGBA8ToRGB565(");
break;
default:
WRITE(p, "(");
break;
}
} }
else else
{
WRITE(p, " %s = Tex0.Sample(samp0, float3(uv0 + float2(%d, 0) * sample_offset, 0.0)).%s;\n",
dest, xoffset, colorComp);
}
if (ApiType == APIType::D3D || ApiType == APIType::Vulkan)
{ {
// Handle D3D depth inversion. // Handle D3D depth inversion.
if (depth) if (ApiType == APIType::D3D || ApiType == APIType::Vulkan)
WRITE(p, " %s = 1.0 - %s;\n", dest, dest); WRITE(p, "1.0 - (");
else
WRITE(p, "(");
} }
// Truncate 8-bits to 5/6-bits per channel. if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan)
switch (format.efb_format)
{ {
case PEControl::RGBA6_Z24: WRITE(p, "texture(samp0, float3(uv0 + float2(%d, 0) * sample_offset, 0.0))).%s;\n", xoffset,
WRITE(p, " %s = floor(%s * 63.0) / 63.0;\n", dest, dest); colorComp);
break; }
else
case PEControl::RGB565_Z16: {
WRITE( WRITE(p, "Tex0.Sample(samp0, float3(uv0 + float2(%d, 0) * sample_offset, 0.0))).%s;\n", xoffset,
p, colorComp);
" %s = floor(%s * float4(31.0, 63.0, 31.0, 1.0).%s) / float4(31.0, 63.0, 31.0, 1.0).%s;\n",
dest, dest, colorComp, colorComp);
break;
} }
// Alpha channel is set to 1 in the copy if the EFB does not have an alpha channel.
if (std::strchr(colorComp, 'a') && !EFBFormatHasAlpha(format.efb_format))
WRITE(p, " %s.a = 1.0;\n", dest);
} }
static void WriteColorToIntensity(char*& p, const char* src, const char* dest) static void WriteColorToIntensity(char*& p, const char* src, const char* dest)
@ -403,7 +420,6 @@ static void WriteRGB5A3Encoder(char*& p, APIType ApiType, const EFBCopyFormat& f
WRITE(p, "}\n"); WRITE(p, "}\n");
WriteSampleColor(p, "rgba", "texSample", 1, ApiType, format, false); WriteSampleColor(p, "rgba", "texSample", 1, ApiType, format, false);
WRITE(p, " texSample.a = 1.0;\n");
WRITE(p, "if(texSample.a > 0.878f) {\n"); WRITE(p, "if(texSample.a > 0.878f) {\n");