diff options
| author | 2021-03-28 21:25:08 +0200 | |
|---|---|---|
| committer | 2021-07-22 21:51:25 -0400 | |
| commit | be3e94ae55184933e0f1f5fb55698513f7936382 (patch) | |
| tree | 87dcf2bafc3da1966470de424f5f14bf662d1aa1 /src/shader_recompiler/frontend/maxwell | |
| parent | shader,spirv: Implement ImageQueryLod. (diff) | |
| download | yuzu-be3e94ae55184933e0f1f5fb55698513f7936382.tar.gz yuzu-be3e94ae55184933e0f1f5fb55698513f7936382.tar.xz yuzu-be3e94ae55184933e0f1f5fb55698513f7936382.zip | |
shader: Implement TMML partially
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp | 8 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/texture_mipmap_level.cpp | 130 |
2 files changed, 130 insertions, 8 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp index 7e1ad63e1..9f5ea7775 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp | |||
| @@ -313,14 +313,6 @@ void TranslatorVisitor::SYNC(u64) { | |||
| 313 | ThrowNotImplemented(Opcode::SYNC); | 313 | ThrowNotImplemented(Opcode::SYNC); |
| 314 | } | 314 | } |
| 315 | 315 | ||
| 316 | void TranslatorVisitor::TMML(u64) { | ||
| 317 | ThrowNotImplemented(Opcode::TMML); | ||
| 318 | } | ||
| 319 | |||
| 320 | void TranslatorVisitor::TMML_b(u64) { | ||
| 321 | ThrowNotImplemented(Opcode::TMML_b); | ||
| 322 | } | ||
| 323 | |||
| 324 | void TranslatorVisitor::TXA(u64) { | 316 | void TranslatorVisitor::TXA(u64) { |
| 325 | ThrowNotImplemented(Opcode::TXA); | 317 | ThrowNotImplemented(Opcode::TXA); |
| 326 | } | 318 | } |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_mipmap_level.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_mipmap_level.cpp new file mode 100644 index 000000000..ee13ede30 --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_mipmap_level.cpp | |||
| @@ -0,0 +1,130 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <optional> | ||
| 6 | |||
| 7 | #include "common/bit_field.h" | ||
| 8 | #include "common/common_types.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/modifiers.h" | ||
| 10 | #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | ||
| 11 | |||
| 12 | namespace Shader::Maxwell { | ||
| 13 | namespace { | ||
| 14 | |||
| 15 | enum class TextureType : u64 { | ||
| 16 | _1D, | ||
| 17 | ARRAY_1D, | ||
| 18 | _2D, | ||
| 19 | ARRAY_2D, | ||
| 20 | _3D, | ||
| 21 | ARRAY_3D, | ||
| 22 | CUBE, | ||
| 23 | ARRAY_CUBE, | ||
| 24 | }; | ||
| 25 | |||
| 26 | Shader::TextureType GetType(TextureType type, bool dc) { | ||
| 27 | switch (type) { | ||
| 28 | case TextureType::_1D: | ||
| 29 | return dc ? Shader::TextureType::Shadow1D : Shader::TextureType::Color1D; | ||
| 30 | case TextureType::ARRAY_1D: | ||
| 31 | return dc ? Shader::TextureType::ShadowArray1D : Shader::TextureType::ColorArray1D; | ||
| 32 | case TextureType::_2D: | ||
| 33 | return dc ? Shader::TextureType::Shadow2D : Shader::TextureType::Color2D; | ||
| 34 | case TextureType::ARRAY_2D: | ||
| 35 | return dc ? Shader::TextureType::ShadowArray2D : Shader::TextureType::ColorArray2D; | ||
| 36 | case TextureType::_3D: | ||
| 37 | return dc ? Shader::TextureType::Shadow3D : Shader::TextureType::Color3D; | ||
| 38 | case TextureType::ARRAY_3D: | ||
| 39 | throw NotImplementedException("3D array texture type"); | ||
| 40 | case TextureType::CUBE: | ||
| 41 | return dc ? Shader::TextureType::ShadowCube : Shader::TextureType::ColorCube; | ||
| 42 | case TextureType::ARRAY_CUBE: | ||
| 43 | return dc ? Shader::TextureType::ShadowArrayCube : Shader::TextureType::ColorArrayCube; | ||
| 44 | } | ||
| 45 | throw NotImplementedException("Invalid texture type {}", type); | ||
| 46 | } | ||
| 47 | |||
| 48 | IR::Value MakeCoords(TranslatorVisitor& v, IR::Reg reg, TextureType type) { | ||
| 49 | const auto read_array{[&]() -> IR::F32 { return v.ir.ConvertUToF(32, 16, v.X(reg)); }}; | ||
| 50 | switch (type) { | ||
| 51 | case TextureType::_1D: | ||
| 52 | return v.F(reg); | ||
| 53 | case TextureType::ARRAY_1D: | ||
| 54 | return v.ir.CompositeConstruct(v.F(reg + 1), read_array()); | ||
| 55 | case TextureType::_2D: | ||
| 56 | return v.ir.CompositeConstruct(v.F(reg), v.F(reg + 1)); | ||
| 57 | case TextureType::ARRAY_2D: | ||
| 58 | return v.ir.CompositeConstruct(v.F(reg + 1), v.F(reg + 2), read_array()); | ||
| 59 | case TextureType::_3D: | ||
| 60 | return v.ir.CompositeConstruct(v.F(reg), v.F(reg + 1), v.F(reg + 2)); | ||
| 61 | case TextureType::ARRAY_3D: | ||
| 62 | throw NotImplementedException("3D array texture type"); | ||
| 63 | case TextureType::CUBE: | ||
| 64 | return v.ir.CompositeConstruct(v.F(reg), v.F(reg + 1), v.F(reg + 2)); | ||
| 65 | case TextureType::ARRAY_CUBE: | ||
| 66 | return v.ir.CompositeConstruct(v.F(reg + 1), v.F(reg + 2), v.F(reg + 3), read_array()); | ||
| 67 | } | ||
| 68 | throw NotImplementedException("Invalid texture type {}", type); | ||
| 69 | } | ||
| 70 | |||
| 71 | void Impl(TranslatorVisitor& v, u64 insn, bool is_bindless) { | ||
| 72 | union { | ||
| 73 | u64 raw; | ||
| 74 | BitField<49, 1, u64> nodep; | ||
| 75 | BitField<35, 1, u64> ndv; | ||
| 76 | BitField<0, 8, IR::Reg> dest_reg; | ||
| 77 | BitField<8, 8, IR::Reg> coord_reg; | ||
| 78 | BitField<20, 8, IR::Reg> meta_reg; | ||
| 79 | BitField<28, 3, TextureType> type; | ||
| 80 | BitField<31, 4, u64> mask; | ||
| 81 | BitField<36, 13, u64> cbuf_offset; | ||
| 82 | } const tmml{insn}; | ||
| 83 | |||
| 84 | if ((tmml.mask & 0xC) != 0) { | ||
| 85 | throw NotImplementedException("TMML BA results are not implmented"); | ||
| 86 | } | ||
| 87 | |||
| 88 | IR::F32 transform_constant = v.ir.Imm32(256.0f); | ||
| 89 | |||
| 90 | const IR::Value coords{MakeCoords(v, tmml.coord_reg, tmml.type)}; | ||
| 91 | |||
| 92 | IR::U32 handle; | ||
| 93 | IR::Reg meta_reg{tmml.meta_reg}; | ||
| 94 | if (!is_bindless) { | ||
| 95 | handle = v.ir.Imm32(static_cast<u32>(tmml.cbuf_offset.Value() * 4)); | ||
| 96 | } else { | ||
| 97 | handle = v.X(meta_reg++); | ||
| 98 | } | ||
| 99 | IR::TextureInstInfo info{}; | ||
| 100 | info.type.Assign(GetType(tmml.type, false)); | ||
| 101 | const IR::Value sample{ | ||
| 102 | [&]() -> IR::Value { return v.ir.ImageQueryLod(handle, coords, info); }()}; | ||
| 103 | |||
| 104 | const IR::FpControl fp_control{ | ||
| 105 | .no_contraction{false}, | ||
| 106 | .rounding{IR::FpRounding::RP}, | ||
| 107 | .fmz_mode{IR::FmzMode::FTZ}, | ||
| 108 | }; | ||
| 109 | IR::Reg dest_reg{tmml.dest_reg}; | ||
| 110 | for (size_t element = 0; element < 4; ++element) { | ||
| 111 | if (((tmml.mask >> element) & 1) == 0) { | ||
| 112 | continue; | ||
| 113 | } | ||
| 114 | IR::F32 value = IR::F32{v.ir.CompositeExtract(sample, element)}; | ||
| 115 | v.F(dest_reg, | ||
| 116 | element < 2 ? IR::F32{v.ir.FPMul(value, transform_constant, fp_control)} : value); | ||
| 117 | ++dest_reg; | ||
| 118 | } | ||
| 119 | } | ||
| 120 | } // Anonymous namespace | ||
| 121 | |||
| 122 | void TranslatorVisitor::TMML(u64 insn) { | ||
| 123 | Impl(*this, insn, false); | ||
| 124 | } | ||
| 125 | |||
| 126 | void TranslatorVisitor::TMML_b(u64 insn) { | ||
| 127 | Impl(*this, insn, true); | ||
| 128 | } | ||
| 129 | |||
| 130 | } // namespace Shader::Maxwell | ||