Skip to content

Commit

Permalink
PixelShaderGen: Pass in LOD bias through PSBlock and use in texture()…
Browse files Browse the repository at this point in the history
… on some APIs
  • Loading branch information
OatmealDome committed Aug 8, 2021
1 parent f2f8575 commit 5edb8f8
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 12 deletions.
1 change: 1 addition & 0 deletions Source/Core/VideoCommon/ConstantManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct PixelShaderConstants
std::array<int4, 4> kcolors;
int4 alpha;
std::array<float4, 8> texdims;
std::array<float, 8> lodbias;
std::array<int4, 2> zbias;
std::array<int4, 2> indtexscale;
std::array<int4, 6> indtexmtx;
Expand Down
51 changes: 41 additions & 10 deletions Source/Core/VideoCommon/PixelShaderGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ enum : u32
C_KCOLORS = C_COLORS + 4, // 4
C_ALPHA = C_KCOLORS + 4, // 8
C_TEXDIMS = C_ALPHA + 1, // 9
C_ZBIAS = C_TEXDIMS + 8, // 17
C_INDTEXSCALE = C_ZBIAS + 2, // 19
C_INDTEXMTX = C_INDTEXSCALE + 2, // 21
C_FOGCOLOR = C_INDTEXMTX + 6, // 27
C_FOGI = C_FOGCOLOR + 1, // 28
C_FOGF = C_FOGI + 1, // 29
C_ZSLOPE = C_FOGF + 2, // 31
C_EFBSCALE = C_ZSLOPE + 1, // 32
C_LODBIAS = C_TEXDIMS + 8, // 17
C_ZBIAS = C_TEXDIMS + 8, // 25
C_INDTEXSCALE = C_ZBIAS + 2, // 27
C_INDTEXMTX = C_INDTEXSCALE + 2, // 29
C_FOGCOLOR = C_INDTEXMTX + 6, // 35
C_FOGI = C_FOGCOLOR + 1, // 36
C_FOGF = C_FOGI + 1, // 37
C_ZSLOPE = C_FOGF + 2, // 39
C_EFBSCALE = C_ZSLOPE + 1, // 40
C_PENVCONST_END = C_EFBSCALE + 1
};

Expand Down Expand Up @@ -403,6 +404,7 @@ void WritePixelShaderCommonHeader(ShaderCode& out, APIType api_type,
"\tint4 " I_KCOLORS "[4];\n"
"\tint4 " I_ALPHA ";\n"
"\tfloat4 " I_TEXDIMS "[8];\n"
"\tfloat4 " I_LODBIAS "[2];\n"
"\tint4 " I_ZBIAS "[2];\n"
"\tint4 " I_INDTEXSCALE "[2];\n"
"\tint4 " I_INDTEXMTX "[6];\n"
Expand Down Expand Up @@ -454,6 +456,33 @@ void WritePixelShaderCommonHeader(ShaderCode& out, APIType api_type,
out.Write("}};\n");
}

#ifdef __APPLE__
if (api_type == APIType::Vulkan) // Metal with MoltenVK
#else
if (api_type == APIType::OpenGL && !host_config.backend_sampler_lod_bias)
#endif
{
// Metal and OpenGL ES do not support setting the LOD bias value in the sampler, so we pass
// it to the fragment shader through the PSBlock and use it as the bias value in the call to
// texture().
//
// I_LODBIAS is defined as a two-element float4 array because SPIRV-Cross will transform an
// eight-element float array into an eight-element float4 array due to packing rules.
// See: https://github.com/KhronosGroup/SPIRV-Cross/issues/1313
//
// This helper function calculates the correct array and component indices and returns the
// correct lodbias value.
out.Write("float lodbias(uint i) {{\n"
"\treturn i < 4 ? " I_LODBIAS "[0][i] : " I_LODBIAS "[1][4 - i];\n"
"}}\n");
}
else
{
// Other APIs can pass in the LOD bias value directly to the sampler, so always return zero.
// This should be equivalent to not passing in the LOD bias value at all.
out.Write("#define lodbias(i) 0.0\n");
}

if (bounding_box)
{
if (api_type == APIType::D3D)
Expand Down Expand Up @@ -1451,6 +1480,7 @@ static void SampleTexture(ShaderCode& out, std::string_view texcoords, std::stri
int texmap, bool stereo, APIType api_type)
{
out.SetConstantsUsed(C_TEXDIMS + texmap, C_TEXDIMS + texmap);
out.SetConstantsUsed(C_LODBIAS + texmap, C_LODBIAS + texmap);

if (api_type == APIType::D3D)
{
Expand All @@ -1460,8 +1490,9 @@ static void SampleTexture(ShaderCode& out, std::string_view texcoords, std::stri
}
else
{
out.Write("iround(255.0 * texture(samp[{}], float3({}.xy * " I_TEXDIMS "[{}].xy, {}))).{};\n",
texmap, texcoords, texmap, stereo ? "layer" : "0.0", texswap);
out.Write("iround(255.0 * texture(samp[{}], float3({}.xy * " I_TEXDIMS
"[{}].xy, {}), lodbias({}u))).{};\n",
texmap, texcoords, texmap, stereo ? "layer" : "0.0", texmap, texswap);
}
}

Expand Down
6 changes: 6 additions & 0 deletions Source/Core/VideoCommon/PixelShaderManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,12 @@ void PixelShaderManager::SetTexDims(int texmapid, u32 width, u32 height)
constants.texdims[texmapid][1] = rheight;
}

void PixelShaderManager::SetLodBias(int texmapid, float bias)
{
constants.lodbias[texmapid] = bias;
dirty = true;
}

void PixelShaderManager::SetZTextureBias()
{
constants.zbias[1][3] = bpmem.ztex1.bias;
Expand Down
1 change: 1 addition & 0 deletions Source/Core/VideoCommon/PixelShaderManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class PixelShaderManager
static void SetAlphaTestChanged();
static void SetDestAlphaChanged();
static void SetTexDims(int texmapid, u32 width, u32 height);
static void SetLodBias(int texmapid, float bias);
static void SetZTextureBias();
static void SetViewportChanged();
static void SetEfbScaleChanged(float scalex, float scaley);
Expand Down
1 change: 1 addition & 0 deletions Source/Core/VideoCommon/ShaderGenCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ const char* GetInterpolationQualifier(bool msaa, bool ssaa, bool in_glsl_interfa
#define I_KCOLORS "k"
#define I_ALPHA "alphaRef"
#define I_TEXDIMS "texdim"
#define I_LODBIAS "clodbias"
#define I_ZBIAS "czbias"
#define I_INDTEXSCALE "cindscale"
#define I_INDTEXMTX "cindmtx"
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/VideoCommon/TextureCacheBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1025,6 +1025,8 @@ static void SetSamplerState(u32 index, float custom_tex_scale, bool custom_tex,
state.anisotropic_filtering = 0;
}

PixelShaderManager::SetLodBias(index, state.lod_bias / 256.0f);

g_renderer->SetSamplerState(index, state);
}

Expand Down
5 changes: 3 additions & 2 deletions Source/Core/VideoCommon/UberShaderPixel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
// supports this in the future.
out.Write("int4 sampleTexture(uint sampler_num, float3 uv) {{\n");
if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan)
out.Write(" return iround(texture(samp[sampler_num], uv) * 255.0);\n");
out.Write(" return iround(texture(samp[sampler_num], uv, lodbias(sampler_num)) * 255.0);\n");
else if (ApiType == APIType::D3D)
out.Write(" return iround(Tex[sampler_num].Sample(samp[sampler_num], uv) * 255.0);\n");
out.Write("}}\n\n");
Expand All @@ -275,7 +275,8 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
for (int i = 0; i < 8; i++)
{
if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan)
out.Write(" case {}u: return iround(texture(samp[{}], uv) * 255.0);\n", i, i);
out.Write(" case {}u: return iround(texture(samp[{}], uv, lodbias({}u)) * 255.0);\n", i, i,
i);
else if (ApiType == APIType::D3D)
out.Write(" case {}u: return iround(Tex[{}].Sample(samp[{}], uv) * 255.0);\n", i, i, i);
}
Expand Down

0 comments on commit 5edb8f8

Please sign in to comment.