diff options
| author | 2020-01-25 03:15:55 -0300 | |
|---|---|---|
| committer | 2020-01-25 03:15:55 -0300 | |
| commit | 96638f57c9e17c3427d1ec6b39f250268a29ddd3 (patch) | |
| tree | 03d29965333b1dc26854b9714b43c9cc594055b7 /src | |
| parent | Merge pull request #3343 from FearlessTobi/ui-tab (diff) | |
| download | yuzu-96638f57c9e17c3427d1ec6b39f250268a29ddd3.tar.gz yuzu-96638f57c9e17c3427d1ec6b39f250268a29ddd3.tar.xz yuzu-96638f57c9e17c3427d1ec6b39f250268a29ddd3.zip | |
shader/memory: Implement LDL.S16 and LDS.S16
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/shader/decode/memory.cpp | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index 7591a715f..3f3ef6e7c 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp | |||
| @@ -22,6 +22,7 @@ using Tegra::Shader::Attribute; | |||
| 22 | using Tegra::Shader::Instruction; | 22 | using Tegra::Shader::Instruction; |
| 23 | using Tegra::Shader::OpCode; | 23 | using Tegra::Shader::OpCode; |
| 24 | using Tegra::Shader::Register; | 24 | using Tegra::Shader::Register; |
| 25 | using Tegra::Shader::StoreType; | ||
| 25 | 26 | ||
| 26 | namespace { | 27 | namespace { |
| 27 | 28 | ||
| @@ -61,6 +62,13 @@ u32 GetMemorySize(Tegra::Shader::UniformType uniform_type) { | |||
| 61 | } | 62 | } |
| 62 | } | 63 | } |
| 63 | 64 | ||
| 65 | Node Sign16Extend(Node value) { | ||
| 66 | Node sign = Operation(OperationCode::UBitwiseAnd, value, Immediate(1U << 15)); | ||
| 67 | Node is_sign = Operation(OperationCode::LogicalUEqual, std::move(sign), Immediate(1U << 15)); | ||
| 68 | Node extend = Operation(OperationCode::Select, is_sign, Immediate(0xFFFF0000), Immediate(0)); | ||
| 69 | return Operation(OperationCode::UBitwiseOr, std::move(value), std::move(extend)); | ||
| 70 | } | ||
| 71 | |||
| 64 | } // Anonymous namespace | 72 | } // Anonymous namespace |
| 65 | 73 | ||
| 66 | u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { | 74 | u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { |
| @@ -139,23 +147,26 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { | |||
| 139 | const auto GetMemory = [&](s32 offset) { | 147 | const auto GetMemory = [&](s32 offset) { |
| 140 | ASSERT(offset % 4 == 0); | 148 | ASSERT(offset % 4 == 0); |
| 141 | const Node immediate_offset = Immediate(static_cast<s32>(instr.smem_imm) + offset); | 149 | const Node immediate_offset = Immediate(static_cast<s32>(instr.smem_imm) + offset); |
| 142 | const Node address = Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8), | 150 | const Node address = |
| 143 | immediate_offset); | 151 | Operation(OperationCode::IAdd, GetRegister(instr.gpr8), immediate_offset); |
| 144 | return opcode->get().GetId() == OpCode::Id::LD_S ? GetSharedMemory(address) | 152 | return opcode->get().GetId() == OpCode::Id::LD_S ? GetSharedMemory(address) |
| 145 | : GetLocalMemory(address); | 153 | : GetLocalMemory(address); |
| 146 | }; | 154 | }; |
| 147 | 155 | ||
| 148 | switch (instr.ldst_sl.type.Value()) { | 156 | switch (instr.ldst_sl.type.Value()) { |
| 149 | case Tegra::Shader::StoreType::Bits32: | 157 | case StoreType::Signed16: |
| 150 | case Tegra::Shader::StoreType::Bits64: | 158 | SetRegister(bb, instr.gpr0, Sign16Extend(GetMemory(0))); |
| 151 | case Tegra::Shader::StoreType::Bits128: { | 159 | break; |
| 152 | const u32 count = [&]() { | 160 | case StoreType::Bits32: |
| 161 | case StoreType::Bits64: | ||
| 162 | case StoreType::Bits128: { | ||
| 163 | const u32 count = [&] { | ||
| 153 | switch (instr.ldst_sl.type.Value()) { | 164 | switch (instr.ldst_sl.type.Value()) { |
| 154 | case Tegra::Shader::StoreType::Bits32: | 165 | case StoreType::Bits32: |
| 155 | return 1; | 166 | return 1; |
| 156 | case Tegra::Shader::StoreType::Bits64: | 167 | case StoreType::Bits64: |
| 157 | return 2; | 168 | return 2; |
| 158 | case Tegra::Shader::StoreType::Bits128: | 169 | case StoreType::Bits128: |
| 159 | return 4; | 170 | return 4; |
| 160 | default: | 171 | default: |
| 161 | UNREACHABLE(); | 172 | UNREACHABLE(); |
| @@ -274,14 +285,14 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { | |||
| 274 | : &ShaderIR::SetSharedMemory; | 285 | : &ShaderIR::SetSharedMemory; |
| 275 | 286 | ||
| 276 | switch (instr.ldst_sl.type.Value()) { | 287 | switch (instr.ldst_sl.type.Value()) { |
| 277 | case Tegra::Shader::StoreType::Bits128: | 288 | case StoreType::Bits128: |
| 278 | (this->*set_memory)(bb, GetAddress(12), GetRegister(instr.gpr0.Value() + 3)); | 289 | (this->*set_memory)(bb, GetAddress(12), GetRegister(instr.gpr0.Value() + 3)); |
| 279 | (this->*set_memory)(bb, GetAddress(8), GetRegister(instr.gpr0.Value() + 2)); | 290 | (this->*set_memory)(bb, GetAddress(8), GetRegister(instr.gpr0.Value() + 2)); |
| 280 | [[fallthrough]]; | 291 | [[fallthrough]]; |
| 281 | case Tegra::Shader::StoreType::Bits64: | 292 | case StoreType::Bits64: |
| 282 | (this->*set_memory)(bb, GetAddress(4), GetRegister(instr.gpr0.Value() + 1)); | 293 | (this->*set_memory)(bb, GetAddress(4), GetRegister(instr.gpr0.Value() + 1)); |
| 283 | [[fallthrough]]; | 294 | [[fallthrough]]; |
| 284 | case Tegra::Shader::StoreType::Bits32: | 295 | case StoreType::Bits32: |
| 285 | (this->*set_memory)(bb, GetAddress(0), GetRegister(instr.gpr0)); | 296 | (this->*set_memory)(bb, GetAddress(0), GetRegister(instr.gpr0)); |
| 286 | break; | 297 | break; |
| 287 | default: | 298 | default: |