From dc9961f341be64dcbc13097d4eb7b95db45f9fb9 Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Wed, 6 Nov 2019 22:43:02 -0300
Subject: [PATCH] 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).
---
 src/video_core/shader/decode/texture.cpp | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

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) {