aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2019-11-06 22:43:02 -0300
committerReinUsesLisp <reinuseslisp@airmail.cc>2019-11-22 21:28:47 -0300
commitdc9961f341be64dcbc13097d4eb7b95db45f9fb9 (patch)
tree623997e27be185a8b6f415ef1e749b823d98565a /src
parent32c1bc6a67820f9df21c8f64f4df078b015aa7da (diff)
shader/texture: Handle TLDS texture type mismatches
Some games like "Fire Emblem: Three Houses" bind 2D textures to offsets used by instructions of 1D textures. To handle the discrepancy this commit uses the the texture type from the binding and modifies the emitted code IR to build a valid backend expression. E.g.: Bound texture is 2D and instruction is 1D, the emitted IR samples a 2D texture in the coordinate ivec2(X, 0).
Diffstat (limited to 'src')
-rw-r--r--src/video_core/shader/decode/texture.cpp11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp
index 695fdbd243..b094e5a06f 100644
--- a/src/video_core/shader/decode/texture.cpp
+++ b/src/video_core/shader/decode/texture.cpp
@@ -616,6 +616,8 @@ Node4 ShaderIR::GetTldCode(Tegra::Shader::Instruction instr) {
}
Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is_array) {
+ const auto& sampler = GetSampler(instr.sampler);
+
const std::size_t type_coord_count = GetCoordCount(texture_type);
const bool lod_enabled = instr.tlds.GetTextureProcessMode() == TextureProcessMode::LL;
@@ -639,7 +641,14 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is
// When lod is used always is in gpr20
const Node lod = lod_enabled ? GetRegister(instr.gpr20) : Immediate(0);
- const auto& sampler = GetSampler(instr.sampler);
+ // Fill empty entries from the guest sampler.
+ const std::size_t entry_coord_count = GetCoordCount(sampler.GetType());
+ if (type_coord_count != entry_coord_count) {
+ LOG_WARNING(HW_GPU, "Bound and built texture types mismatch");
+ }
+ for (std::size_t i = type_coord_count; i < entry_coord_count; ++i) {
+ coords.push_back(GetRegister(Register::ZeroIndex));
+ }
Node4 values;
for (u32 element = 0; element < values.size(); ++element) {