summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorPokechu22 <Pokechu022@gmail.com>2021-04-18 19:51:02 -0700
committerPokechu22 <Pokechu022@gmail.com>2021-05-07 16:37:47 -0700
commite1d45e9ba66d3ba7d6769e36c0fc82ceb5028ecb (patch)
tree4502381e619088293b8c6d047f964269223edfd4 /Source/Core
parentb5844ab195a38303e5fb82a7f6804a726fa8fb7a (diff)
UberShaderPixel: always run indirect stage logic
Hardware testing has confirmed that fb_addprev and wrapping both run even when the indirect stage is disabled.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/VideoCommon/PixelShaderManager.cpp33
-rw-r--r--Source/Core/VideoCommon/UberShaderPixel.cpp6
2 files changed, 17 insertions, 22 deletions
diff --git a/Source/Core/VideoCommon/PixelShaderManager.cpp b/Source/Core/VideoCommon/PixelShaderManager.cpp
index 6d52d8ffc1..0ae1ced1e4 100644
--- a/Source/Core/VideoCommon/PixelShaderManager.cpp
+++ b/Source/Core/VideoCommon/PixelShaderManager.cpp
@@ -148,29 +148,18 @@ void PixelShaderManager::SetConstants()
for (u32 i = 0; i < (bpmem.genMode.numtevstages + 1); ++i)
{
+ // Note: a tevind of zero just happens to be a passthrough, so no need
+ // to set an extra bit. Furthermore, wrap and add to previous apply even if there is no
+ // indirect stage.
+ constants.pack1[i][2] = bpmem.tevind[i].hex;
+
u32 stage = bpmem.tevind[i].bt;
- if (stage < bpmem.genMode.numindstages)
- {
- // We set some extra bits so the ubershader can quickly check if these
- // features are in use.
- if (bpmem.tevind[i].IsActive())
- constants.pack1[stage][3] =
- bpmem.tevindref.getTexCoord(stage) | bpmem.tevindref.getTexMap(stage) << 8 | 1 << 16;
- // Note: a tevind of zero just happens to be a passthrough, so no need
- // to set an extra bit.
- constants.pack1[i][2] = bpmem.tevind[i].hex; // TODO: This match shadergen, but videosw
- // will always wrap.
-
- // The ubershader uses tevind != 0 as a condition whether to calculate texcoords,
- // even when texture is disabled, instead of the stage < bpmem.genMode.numindstages.
- // We set an unused bit here to indicate that the stage is active, even if it
- // is just a pass-through.
- constants.pack1[i][2] |= 0x80000000;
- }
- else
- {
- constants.pack1[i][2] = 0;
- }
+
+ // We use an extra bit (1 << 16) to provide a fast way of testing if this feature is in use.
+ // Note also that this is indexed by indirect stage, not by TEV stage.
+ if (bpmem.tevind[i].IsActive() && stage < bpmem.genMode.numindstages)
+ constants.pack1[stage][3] =
+ bpmem.tevindref.getTexCoord(stage) | bpmem.tevindref.getTexMap(stage) << 8 | 1 << 16;
}
dirty = true;
diff --git a/Source/Core/VideoCommon/UberShaderPixel.cpp b/Source/Core/VideoCommon/UberShaderPixel.cpp
index a029f58812..642896a3dc 100644
--- a/Source/Core/VideoCommon/UberShaderPixel.cpp
+++ b/Source/Core/VideoCommon/UberShaderPixel.cpp
@@ -287,6 +287,8 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
// ======================
const auto LookupIndirectTexture = [&out, stereo](std::string_view out_var_name,
std::string_view in_index_name) {
+ // in_index_name is the indirect stage, not the tev stage
+ // bpmem_iref is packed differently from RAS1_IREF
out.Write("{{\n"
" uint iref = bpmem_iref({});\n"
" if ( iref != 0u)\n"
@@ -304,6 +306,10 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
"[texmap].xy, {})).abg;\n",
in_index_name, in_index_name, in_index_name, in_index_name, out_var_name,
stereo ? "float(layer)" : "0.0");
+ // There is always a bit set in bpmem_iref if the data is valid (matrix is not off, and the
+ // indirect texture stage is enabled). If the matrix is off, the result doesn't matter; if the
+ // indirect texture stage is disabled, the result is undefined (and produces a glitchy pattern
+ // on hardware, different from this).
out.Write(" }}\n"
" else\n"
" {{\n"