diff options
| author | 2021-03-26 20:51:05 +0100 | |
|---|---|---|
| committer | 2021-07-22 21:51:25 -0400 | |
| commit | dc1a9a3bed2aa9b0851f07976b0c687172aa3edc (patch) | |
| tree | 8bfc0b3afc76b1b9a6100dfe8fb60b013927932b /src/shader_recompiler/frontend | |
| parent | spirv: Add fixed pipeline point size (diff) | |
| download | yuzu-dc1a9a3bed2aa9b0851f07976b0c687172aa3edc.tar.gz yuzu-dc1a9a3bed2aa9b0851f07976b0c687172aa3edc.tar.xz yuzu-dc1a9a3bed2aa9b0851f07976b0c687172aa3edc.zip | |
shader: Implement TLD
Diffstat (limited to 'src/shader_recompiler/frontend')
4 files changed, 170 insertions, 13 deletions
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index 717aa71ca..302b8471d 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc | |||
| @@ -378,7 +378,7 @@ OPCODE(BindlessImageSampleDrefImplicitLod, F32, U32, | |||
| 378 | OPCODE(BindlessImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) | 378 | OPCODE(BindlessImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) |
| 379 | OPCODE(BindlessImageGather, F32x4, U32, Opaque, Opaque, Opaque, ) | 379 | OPCODE(BindlessImageGather, F32x4, U32, Opaque, Opaque, Opaque, ) |
| 380 | OPCODE(BindlessImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) | 380 | OPCODE(BindlessImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) |
| 381 | OPCODE(BindlessImageFetch, F32x4, U32, Opaque, U32, U32, ) | 381 | OPCODE(BindlessImageFetch, F32x4, U32, Opaque, Opaque, Opaque, Opaque, ) |
| 382 | OPCODE(BindlessImageQueryDimensions, U32x4, U32, U32, ) | 382 | OPCODE(BindlessImageQueryDimensions, U32x4, U32, U32, ) |
| 383 | 383 | ||
| 384 | OPCODE(BoundImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) | 384 | OPCODE(BoundImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) |
| @@ -387,7 +387,7 @@ OPCODE(BoundImageSampleDrefImplicitLod, F32, U32, | |||
| 387 | OPCODE(BoundImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) | 387 | OPCODE(BoundImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) |
| 388 | OPCODE(BoundImageGather, F32x4, U32, Opaque, Opaque, Opaque, ) | 388 | OPCODE(BoundImageGather, F32x4, U32, Opaque, Opaque, Opaque, ) |
| 389 | OPCODE(BoundImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) | 389 | OPCODE(BoundImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) |
| 390 | OPCODE(BoundImageFetch, F32x4, U32, Opaque, U32, U32, ) | 390 | OPCODE(BoundImageFetch, F32x4, U32, Opaque, Opaque, Opaque, Opaque, ) |
| 391 | OPCODE(BoundImageQueryDimensions, U32x4, U32, U32, ) | 391 | OPCODE(BoundImageQueryDimensions, U32x4, U32, U32, ) |
| 392 | 392 | ||
| 393 | OPCODE(ImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) | 393 | OPCODE(ImageSampleImplicitLod, F32x4, U32, Opaque, Opaque, Opaque, ) |
| @@ -396,7 +396,7 @@ OPCODE(ImageSampleDrefImplicitLod, F32, U32, | |||
| 396 | OPCODE(ImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) | 396 | OPCODE(ImageSampleDrefExplicitLod, F32, U32, Opaque, F32, Opaque, Opaque, ) |
| 397 | OPCODE(ImageGather, F32x4, U32, Opaque, Opaque, Opaque, ) | 397 | OPCODE(ImageGather, F32x4, U32, Opaque, Opaque, Opaque, ) |
| 398 | OPCODE(ImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) | 398 | OPCODE(ImageGatherDref, F32x4, U32, Opaque, Opaque, Opaque, F32, ) |
| 399 | OPCODE(ImageFetch, F32x4, U32, Opaque, U32, U32, ) | 399 | OPCODE(ImageFetch, F32x4, U32, Opaque, Opaque, Opaque, Opaque, ) |
| 400 | OPCODE(ImageQueryDimensions, U32x4, U32, U32, ) | 400 | OPCODE(ImageQueryDimensions, U32x4, U32, U32, ) |
| 401 | 401 | ||
| 402 | // Warp operations | 402 | // Warp operations |
diff --git a/src/shader_recompiler/frontend/maxwell/maxwell.inc b/src/shader_recompiler/frontend/maxwell/maxwell.inc index d668dc1aa..b47fb9c2e 100644 --- a/src/shader_recompiler/frontend/maxwell/maxwell.inc +++ b/src/shader_recompiler/frontend/maxwell/maxwell.inc | |||
| @@ -252,8 +252,8 @@ INST(SYNC, "SYNC", "1111 0000 1111 1---") | |||
| 252 | INST(TEX, "TEX", "1100 0--- ---- ----") | 252 | INST(TEX, "TEX", "1100 0--- ---- ----") |
| 253 | INST(TEX_b, "TEX (b)", "1101 1110 10-- ----") | 253 | INST(TEX_b, "TEX (b)", "1101 1110 10-- ----") |
| 254 | INST(TEXS, "TEXS", "1101 -00- ---- ----") | 254 | INST(TEXS, "TEXS", "1101 -00- ---- ----") |
| 255 | INST(TLD, "TLD", "1101 1100 --11 1---") | 255 | INST(TLD, "TLD", "1101 1100 ---- ----") |
| 256 | INST(TLD_b, "TLD (b)", "1101 1101 --11 1---") | 256 | INST(TLD_b, "TLD (b)", "1101 1101 ---- ----") |
| 257 | INST(TLD4, "TLD4", "1100 10-- ---- ----") | 257 | INST(TLD4, "TLD4", "1100 10-- ---- ----") |
| 258 | INST(TLD4_b, "TLD4 (b)", "1101 1110 11-- ----") | 258 | INST(TLD4_b, "TLD4 (b)", "1101 1110 11-- ----") |
| 259 | INST(TLD4S, "TLD4S", "1101 1111 -0-- ----") | 259 | INST(TLD4S, "TLD4S", "1101 1111 -0-- ----") |
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 6a580f831..60d61ec6e 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::TLD(u64) { | ||
| 317 | ThrowNotImplemented(Opcode::TLD); | ||
| 318 | } | ||
| 319 | |||
| 320 | void TranslatorVisitor::TLD_b(u64) { | ||
| 321 | ThrowNotImplemented(Opcode::TLD_b); | ||
| 322 | } | ||
| 323 | |||
| 324 | void TranslatorVisitor::TLDS(u64) { | 316 | void TranslatorVisitor::TLDS(u64) { |
| 325 | ThrowNotImplemented(Opcode::TLDS); | 317 | ThrowNotImplemented(Opcode::TLDS); |
| 326 | } | 318 | } |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load.cpp new file mode 100644 index 000000000..b4063fa6e --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load.cpp | |||
| @@ -0,0 +1,165 @@ | |||
| 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{ | ||
| 50 | [&]() -> IR::U32 { return v.ir.BitFieldExtract(v.X(reg), v.ir.Imm32(0), v.ir.Imm32(16)); }}; | ||
| 51 | switch (type) { | ||
| 52 | case TextureType::_1D: | ||
| 53 | return v.X(reg); | ||
| 54 | case TextureType::ARRAY_1D: | ||
| 55 | return v.ir.CompositeConstruct(v.X(reg + 1), read_array()); | ||
| 56 | case TextureType::_2D: | ||
| 57 | return v.ir.CompositeConstruct(v.X(reg), v.X(reg + 1)); | ||
| 58 | case TextureType::ARRAY_2D: | ||
| 59 | return v.ir.CompositeConstruct(v.X(reg + 1), v.X(reg + 2), read_array()); | ||
| 60 | case TextureType::_3D: | ||
| 61 | return v.ir.CompositeConstruct(v.X(reg), v.X(reg + 1), v.X(reg + 2)); | ||
| 62 | case TextureType::ARRAY_3D: | ||
| 63 | throw NotImplementedException("3D array texture type"); | ||
| 64 | case TextureType::CUBE: | ||
| 65 | return v.ir.CompositeConstruct(v.X(reg), v.X(reg + 1), v.X(reg + 2)); | ||
| 66 | case TextureType::ARRAY_CUBE: | ||
| 67 | return v.ir.CompositeConstruct(v.X(reg + 1), v.X(reg + 2), v.X(reg + 3), read_array()); | ||
| 68 | } | ||
| 69 | throw NotImplementedException("Invalid texture type {}", type); | ||
| 70 | } | ||
| 71 | |||
| 72 | IR::Value MakeOffset(TranslatorVisitor& v, IR::Reg& reg, TextureType type) { | ||
| 73 | const IR::U32 value{v.X(reg++)}; | ||
| 74 | switch (type) { | ||
| 75 | case TextureType::_1D: | ||
| 76 | case TextureType::ARRAY_1D: | ||
| 77 | return v.ir.BitFieldExtract(value, v.ir.Imm32(0), v.ir.Imm32(4), true); | ||
| 78 | case TextureType::_2D: | ||
| 79 | case TextureType::ARRAY_2D: | ||
| 80 | return v.ir.CompositeConstruct( | ||
| 81 | v.ir.BitFieldExtract(value, v.ir.Imm32(0), v.ir.Imm32(4), true), | ||
| 82 | v.ir.BitFieldExtract(value, v.ir.Imm32(4), v.ir.Imm32(4), true)); | ||
| 83 | case TextureType::_3D: | ||
| 84 | case TextureType::ARRAY_3D: | ||
| 85 | return v.ir.CompositeConstruct( | ||
| 86 | v.ir.BitFieldExtract(value, v.ir.Imm32(0), v.ir.Imm32(4), true), | ||
| 87 | v.ir.BitFieldExtract(value, v.ir.Imm32(4), v.ir.Imm32(4), true), | ||
| 88 | v.ir.BitFieldExtract(value, v.ir.Imm32(8), v.ir.Imm32(4), true)); | ||
| 89 | case TextureType::CUBE: | ||
| 90 | case TextureType::ARRAY_CUBE: | ||
| 91 | throw NotImplementedException("Illegal offset on CUBE sample"); | ||
| 92 | } | ||
| 93 | throw NotImplementedException("Invalid texture type {}", type); | ||
| 94 | } | ||
| 95 | |||
| 96 | void Impl(TranslatorVisitor& v, u64 insn, bool is_bindless) { | ||
| 97 | union { | ||
| 98 | u64 raw; | ||
| 99 | BitField<49, 1, u64> nodep; | ||
| 100 | BitField<55, 1, u64> lod; | ||
| 101 | BitField<50, 1, u64> multisample; | ||
| 102 | BitField<35, 1, u64> aoffi; | ||
| 103 | BitField<54, 1, u64> clamp; | ||
| 104 | BitField<51, 3, IR::Pred> sparse_pred; | ||
| 105 | BitField<0, 8, IR::Reg> dest_reg; | ||
| 106 | BitField<8, 8, IR::Reg> coord_reg; | ||
| 107 | BitField<20, 8, IR::Reg> meta_reg; | ||
| 108 | BitField<28, 3, TextureType> type; | ||
| 109 | BitField<31, 4, u64> mask; | ||
| 110 | BitField<36, 13, u64> cbuf_offset; | ||
| 111 | } const tld{insn}; | ||
| 112 | |||
| 113 | const IR::Value coords{MakeCoords(v, tld.coord_reg, tld.type)}; | ||
| 114 | |||
| 115 | IR::Reg meta_reg{tld.meta_reg}; | ||
| 116 | IR::Value handle; | ||
| 117 | IR::Value offset; | ||
| 118 | IR::U32 lod; | ||
| 119 | IR::U32 multisample; | ||
| 120 | if (!is_bindless) { | ||
| 121 | handle = v.ir.Imm32(static_cast<u32>(tld.cbuf_offset.Value() * 4)); | ||
| 122 | } else { | ||
| 123 | handle = v.X(meta_reg++); | ||
| 124 | } | ||
| 125 | if (tld.lod != 0) { | ||
| 126 | lod = v.X(meta_reg++); | ||
| 127 | } | ||
| 128 | if (tld.aoffi != 0) { | ||
| 129 | offset = MakeOffset(v, meta_reg, tld.type); | ||
| 130 | } | ||
| 131 | if (tld.multisample != 0) { | ||
| 132 | multisample = v.X(meta_reg++); | ||
| 133 | } | ||
| 134 | if (tld.clamp != 0) { | ||
| 135 | throw NotImplementedException("TLD.CL - CLAMP is not implmented"); | ||
| 136 | } | ||
| 137 | IR::TextureInstInfo info{}; | ||
| 138 | info.type.Assign(GetType(tld.type, false)); | ||
| 139 | const IR::Value sample{[&]() -> IR::Value { | ||
| 140 | return v.ir.ImageFetch(handle, coords, offset, lod, multisample, info); | ||
| 141 | }()}; | ||
| 142 | |||
| 143 | IR::Reg dest_reg{tld.dest_reg}; | ||
| 144 | for (size_t element = 0; element < 4; ++element) { | ||
| 145 | if (((tld.mask >> element) & 1) == 0) { | ||
| 146 | continue; | ||
| 147 | } | ||
| 148 | v.F(dest_reg, IR::F32{v.ir.CompositeExtract(sample, element)}); | ||
| 149 | ++dest_reg; | ||
| 150 | } | ||
| 151 | if (tld.sparse_pred != IR::Pred::PT) { | ||
| 152 | v.ir.SetPred(tld.sparse_pred, v.ir.LogicalNot(v.ir.GetSparseFromOp(sample))); | ||
| 153 | } | ||
| 154 | } | ||
| 155 | } // Anonymous namespace | ||
| 156 | |||
| 157 | void TranslatorVisitor::TLD(u64 insn) { | ||
| 158 | Impl(*this, insn, false); | ||
| 159 | } | ||
| 160 | |||
| 161 | void TranslatorVisitor::TLD_b(u64 insn) { | ||
| 162 | Impl(*this, insn, true); | ||
| 163 | } | ||
| 164 | |||
| 165 | } // namespace Shader::Maxwell | ||