diff options
author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2019-11-06 22:43:02 -0300 |
---|---|---|
committer | ReinUsesLisp <reinuseslisp@airmail.cc> | 2019-11-22 21:28:47 -0300 |
commit | dc9961f341be64dcbc13097d4eb7b95db45f9fb9 (patch) | |
tree | 623997e27be185a8b6f415ef1e749b823d98565a /src | |
parent | 32c1bc6a67820f9df21c8f64f4df078b015aa7da (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.cpp | 11 |
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) { |