summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/PixelShaderGen.cpp
diff options
context:
space:
mode:
authorAnthony <Helios747@users.noreply.github.com>2017-07-30 01:00:16 -0700
committerGitHub <noreply@github.com>2017-07-30 01:00:16 -0700
commitba57605266b9ab178963bf56e146f355d1b93cd4 (patch)
tree0ddc89cfca6db3d343d317c18b7c07c9ab83e9c4 /Source/Core/VideoCommon/PixelShaderGen.cpp
parent5bad2ee4a4129e734ff4f4d861cedc4cd573df55 (diff)
parentb154edb4fbdb327920a33b44f35f34cdf2636d6f (diff)
Merge pull request #5702 from stenzek/ubershaders
Ubershaders 2.0
Diffstat (limited to 'Source/Core/VideoCommon/PixelShaderGen.cpp')
-rw-r--r--Source/Core/VideoCommon/PixelShaderGen.cpp139
1 files changed, 66 insertions, 73 deletions
diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp
index fe4ef11bb0..308807e7c8 100644
--- a/Source/Core/VideoCommon/PixelShaderGen.cpp
+++ b/Source/Core/VideoCommon/PixelShaderGen.cpp
@@ -179,7 +179,7 @@ PixelShaderUid GetPixelShaderUid()
u32 numStages = uid_data->genMode_numtevstages + 1;
const bool forced_early_z =
- g_ActiveConfig.backend_info.bSupportsEarlyZ && bpmem.UseEarlyDepthTest() &&
+ bpmem.UseEarlyDepthTest() &&
(g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED)
// We can't allow early_ztest for zfreeze because depth is overridden per-pixel.
// This means it's impossible for zcomploc to be emulated on a zfrozen polygon.
@@ -192,18 +192,6 @@ PixelShaderUid GetPixelShaderUid()
uid_data->per_pixel_depth = per_pixel_depth;
uid_data->forced_early_z = forced_early_z;
- if (!uid_data->forced_early_z && bpmem.UseEarlyDepthTest() &&
- (!g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED))
- {
- static bool warn_once = true;
- if (warn_once)
- WARN_LOG(VIDEO, "Early z test enabled but not possible to emulate with current "
- "configuration. Make sure to enable fast depth calculations. If this message "
- "still shows up your hardware isn't able to emulate the feature properly (a "
- "GPU with D3D 11.0 / OGL 4.2 support is required).");
- warn_once = false;
- }
-
if (g_ActiveConfig.bEnablePixelLighting)
{
// The lighting shader only needs the two color bits of the 23bit component bit array.
@@ -333,33 +321,9 @@ PixelShaderUid GetPixelShaderUid()
return out;
}
-static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, int n,
- APIType ApiType, bool stereo);
-static void WriteTevRegular(ShaderCode& out, const char* components, int bias, int op, int clamp,
- int shift, bool alpha);
-static void SampleTexture(ShaderCode& out, const char* texcoords, const char* texswap, int texmap,
- bool stereo, APIType ApiType);
-static void WriteAlphaTest(ShaderCode& out, const pixel_shader_uid_data* uid_data, APIType ApiType,
- bool per_pixel_depth, bool use_dual_source);
-static void WriteFog(ShaderCode& out, const pixel_shader_uid_data* uid_data);
-static void WriteColor(ShaderCode& out, const pixel_shader_uid_data* uid_data,
- bool use_dual_source);
-
-ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host_config,
- const pixel_shader_uid_data* uid_data)
+void WritePixelShaderCommonHeader(ShaderCode& out, APIType ApiType, u32 num_texgens,
+ bool per_pixel_lighting, bool bounding_box)
{
- ShaderCode out;
-
- const bool per_pixel_lighting = g_ActiveConfig.bEnablePixelLighting;
- const bool msaa = host_config.msaa;
- const bool ssaa = host_config.ssaa;
- const bool stereo = host_config.stereo;
- const u32 numStages = uid_data->genMode_numtevstages + 1;
-
- out.Write("//Pixel Shader for TEV stages\n");
- out.Write("//%i TEV stages, %i texgens, %i IND stages\n", numStages, uid_data->genMode_numtexgens,
- uid_data->genMode_numindstages);
-
// dot product for integer vectors
out.Write("int idot(int3 x, int3 y)\n"
"{\n"
@@ -379,21 +343,10 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host
"int3 iround(float3 x) { return int3(round(x)); }\n"
"int4 iround(float4 x) { return int4(round(x)); }\n\n");
- if (ApiType == APIType::OpenGL)
+ if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan)
{
out.Write("SAMPLER_BINDING(0) uniform sampler2DArray samp[8];\n");
}
- else if (ApiType == APIType::Vulkan)
- {
- out.Write("SAMPLER_BINDING(0) uniform sampler2DArray samp0;\n");
- out.Write("SAMPLER_BINDING(1) uniform sampler2DArray samp1;\n");
- out.Write("SAMPLER_BINDING(2) uniform sampler2DArray samp2;\n");
- out.Write("SAMPLER_BINDING(3) uniform sampler2DArray samp3;\n");
- out.Write("SAMPLER_BINDING(4) uniform sampler2DArray samp4;\n");
- out.Write("SAMPLER_BINDING(5) uniform sampler2DArray samp5;\n");
- out.Write("SAMPLER_BINDING(6) uniform sampler2DArray samp6;\n");
- out.Write("SAMPLER_BINDING(7) uniform sampler2DArray samp7;\n");
- }
else // D3D
{
// Declare samplers
@@ -419,8 +372,26 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host
"\tint4 " I_FOGI ";\n"
"\tfloat4 " I_FOGF "[2];\n"
"\tfloat4 " I_ZSLOPE ";\n"
- "\tfloat4 " I_EFBSCALE ";\n"
- "};\n");
+ "\tfloat2 " I_EFBSCALE ";\n"
+ "\tuint bpmem_genmode;\n"
+ "\tuint bpmem_alphaTest;\n"
+ "\tuint bpmem_fogParam3;\n"
+ "\tuint bpmem_fogRangeBase;\n"
+ "\tuint bpmem_dstalpha;\n"
+ "\tuint bpmem_ztex_op;\n"
+ "\tbool bpmem_early_ztest;\n"
+ "\tbool bpmem_rgba6_format;\n"
+ "\tbool bpmem_dither;\n"
+ "\tbool bpmem_bounding_box;\n"
+ "\tuint4 bpmem_pack1[16];\n" // .xy - combiners, .z - tevind
+ "\tuint4 bpmem_pack2[8];\n" // .x - tevorder, .y - tevksel
+ "\tint4 konstLookup[32];\n"
+ "};\n\n");
+ out.Write("#define bpmem_combiners(i) (bpmem_pack1[(i)].xy)\n"
+ "#define bpmem_tevind(i) (bpmem_pack1[(i)].z)\n"
+ "#define bpmem_iref(i) (bpmem_pack1[(i)].w)\n"
+ "#define bpmem_tevorder(i) (bpmem_pack2[(i)].x)\n"
+ "#define bpmem_tevksel(i) (bpmem_pack2[(i)].y)\n\n");
if (per_pixel_lighting)
{
@@ -435,7 +406,7 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host
out.Write("};\n");
}
- if (uid_data->bounding_box)
+ if (bounding_box)
{
if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan)
{
@@ -450,10 +421,42 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host
}
out.Write("struct VS_OUTPUT {\n");
- GenerateVSOutputMembers(out, ApiType, uid_data->genMode_numtexgens, per_pixel_lighting, "");
+ GenerateVSOutputMembers(out, ApiType, num_texgens, per_pixel_lighting, "");
out.Write("};\n");
+}
- if (uid_data->forced_early_z)
+static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, int n,
+ APIType ApiType, bool stereo);
+static void WriteTevRegular(ShaderCode& out, const char* components, int bias, int op, int clamp,
+ int shift, bool alpha);
+static void SampleTexture(ShaderCode& out, const char* texcoords, const char* texswap, int texmap,
+ bool stereo, APIType ApiType);
+static void WriteAlphaTest(ShaderCode& out, const pixel_shader_uid_data* uid_data, APIType ApiType,
+ bool per_pixel_depth, bool use_dual_source);
+static void WriteFog(ShaderCode& out, const pixel_shader_uid_data* uid_data);
+static void WriteColor(ShaderCode& out, const pixel_shader_uid_data* uid_data,
+ bool use_dual_source);
+
+ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host_config,
+ const pixel_shader_uid_data* uid_data)
+{
+ ShaderCode out;
+
+ const bool per_pixel_lighting = g_ActiveConfig.bEnablePixelLighting;
+ const bool msaa = host_config.msaa;
+ const bool ssaa = host_config.ssaa;
+ const bool stereo = host_config.stereo;
+ const u32 numStages = uid_data->genMode_numtevstages + 1;
+
+ out.Write("//Pixel Shader for TEV stages\n");
+ out.Write("//%i TEV stages, %i texgens, %i IND stages\n", numStages, uid_data->genMode_numtexgens,
+ uid_data->genMode_numindstages);
+
+ // Stuff that is shared between ubershaders and pixelgen.
+ WritePixelShaderCommonHeader(out, ApiType, uid_data->genMode_numtexgens, per_pixel_lighting,
+ uid_data->bounding_box);
+
+ if (uid_data->forced_early_z && g_ActiveConfig.backend_info.bSupportsEarlyZ)
{
// Zcomploc (aka early_ztest) is a way to control whether depth test is done before
// or after texturing and alpha test. PC graphics APIs used to provide no way to emulate
@@ -549,7 +552,7 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host
// Let's set up attributes
for (unsigned int i = 0; i < uid_data->genMode_numtexgens; ++i)
{
- out.Write("%s in float3 uv%d;\n", GetInterpolationQualifier(msaa, ssaa), i);
+ out.Write("%s in float3 tex%d;\n", GetInterpolationQualifier(msaa, ssaa), i);
}
out.Write("%s in float4 clipPos;\n", GetInterpolationQualifier(msaa, ssaa));
if (per_pixel_lighting)
@@ -560,13 +563,6 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host
}
out.Write("void main()\n{\n");
-
- if (host_config.backend_geometry_shaders || ApiType == APIType::Vulkan)
- {
- for (unsigned int i = 0; i < uid_data->genMode_numtexgens; ++i)
- out.Write("\tfloat3 uv%d = tex%d;\n", i, i);
- }
-
out.Write("\tfloat4 rawpos = gl_FragCoord;\n");
}
else // D3D
@@ -582,7 +578,8 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host
// compute window position if needed because binding semantic WPOS is not widely supported
for (unsigned int i = 0; i < uid_data->genMode_numtexgens; ++i)
- out.Write(",\n in %s float3 uv%d : TEXCOORD%d", GetInterpolationQualifier(msaa, ssaa), i, i);
+ out.Write(",\n in %s float3 tex%d : TEXCOORD%d", GetInterpolationQualifier(msaa, ssaa), i,
+ i);
out.Write(",\n in %s float4 clipPos : TEXCOORD%d", GetInterpolationQualifier(msaa, ssaa),
uid_data->genMode_numtexgens);
if (per_pixel_lighting)
@@ -645,7 +642,7 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host
for (unsigned int i = 0; i < uid_data->genMode_numtexgens; ++i)
{
out.Write("\tint2 fixpoint_uv%d = int2(", i);
- out.Write("(uv%d.z == 0.0 ? uv%d.xy : uv%d.xy / uv%d.z)", i, i, i, i);
+ out.Write("(tex%d.z == 0.0 ? tex%d.xy : tex%d.xy / tex%d.z)", i, i, i, i);
out.Write(" * " I_TEXDIMS "[%d].zw);\n", i);
// TODO: S24 overflows here?
}
@@ -824,7 +821,7 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
const char* tevIndAlphaSel[] = {"", "x", "y", "z"};
const char* tevIndAlphaMask[] = {"248", "224", "240",
"248"}; // 0b11111000, 0b11100000, 0b11110000, 0b11111000
- out.Write("alphabump = iindtex%d.%s & %s;\n", tevind.bt, tevIndAlphaSel[tevind.bs],
+ out.Write("alphabump = iindtex%d.%s & %s;\n", tevind.bt.Value(), tevIndAlphaSel[tevind.bs],
tevIndAlphaMask[tevind.fmt]);
}
else
@@ -836,7 +833,8 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
{
// format
const char* tevIndFmtMask[] = {"255", "31", "15", "7"};
- out.Write("\tint3 iindtevcrd%d = iindtex%d & %s;\n", n, tevind.bt, tevIndFmtMask[tevind.fmt]);
+ out.Write("\tint3 iindtevcrd%d = iindtex%d & %s;\n", n, tevind.bt.Value(),
+ tevIndFmtMask[tevind.fmt]);
// bias - TODO: Check if this needs to be this complicated..
const char* tevIndBiasField[] = {"", "x", "y", "xy",
@@ -1166,11 +1164,6 @@ static void SampleTexture(ShaderCode& out, const char* texcoords, const char* te
"[%d].xy, %s))).%s;\n",
texmap, texmap, texcoords, texmap, stereo ? "layer" : "0.0", texswap);
}
- else if (ApiType == APIType::Vulkan)
- {
- out.Write("iround(255.0 * texture(samp%d, float3(%s.xy * " I_TEXDIMS "[%d].xy, %s))).%s;\n",
- texmap, texcoords, texmap, stereo ? "layer" : "0.0", texswap);
- }
else
{
out.Write("iround(255.0 * texture(samp[%d], float3(%s.xy * " I_TEXDIMS "[%d].xy, %s))).%s;\n",