diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/shader_bytecode.h | 6 | ||||
| -rw-r--r-- | src/video_core/shader/decode/memory.cpp | 55 |
2 files changed, 46 insertions, 15 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index 8e915e2ae..269df9437 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -217,9 +217,9 @@ enum class StoreType : u64 { | |||
| 217 | Signed8 = 1, | 217 | Signed8 = 1, |
| 218 | Unsigned16 = 2, | 218 | Unsigned16 = 2, |
| 219 | Signed16 = 3, | 219 | Signed16 = 3, |
| 220 | Bytes32 = 4, | 220 | Bits32 = 4, |
| 221 | Bytes64 = 5, | 221 | Bits64 = 5, |
| 222 | Bytes128 = 6, | 222 | Bits128 = 6, |
| 223 | }; | 223 | }; |
| 224 | 224 | ||
| 225 | enum class IMinMaxExchange : u64 { | 225 | enum class IMinMaxExchange : u64 { |
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index 1f418b4e6..3dd26da20 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp | |||
| @@ -104,19 +104,42 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) { | |||
| 104 | } | 104 | } |
| 105 | case OpCode::Id::LD_L: { | 105 | case OpCode::Id::LD_L: { |
| 106 | UNIMPLEMENTED_IF_MSG(instr.ld_l.unknown == 1, "LD_L Unhandled mode: {}", | 106 | UNIMPLEMENTED_IF_MSG(instr.ld_l.unknown == 1, "LD_L Unhandled mode: {}", |
| 107 | static_cast<unsigned>(instr.ld_l.unknown.Value())); | 107 | static_cast<u32>(instr.ld_l.unknown.Value())); |
| 108 | 108 | ||
| 109 | const Node index = Operation(OperationCode::IAdd, GetRegister(instr.gpr8), | 109 | const auto GetLmem = [&](s32 offset) { |
| 110 | Immediate(static_cast<s32>(instr.smem_imm))); | 110 | ASSERT(offset % 4 == 0); |
| 111 | const Node lmem = GetLocalMemory(index); | 111 | const Node immediate_offset = Immediate(static_cast<s32>(instr.smem_imm) + offset); |
| 112 | const Node address = Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8), | ||
| 113 | immediate_offset); | ||
| 114 | return GetLocalMemory(address); | ||
| 115 | }; | ||
| 112 | 116 | ||
| 113 | switch (instr.ldst_sl.type.Value()) { | 117 | switch (instr.ldst_sl.type.Value()) { |
| 114 | case Tegra::Shader::StoreType::Bytes32: | 118 | case Tegra::Shader::StoreType::Bits32: |
| 115 | SetRegister(bb, instr.gpr0, lmem); | 119 | case Tegra::Shader::StoreType::Bits64: |
| 120 | case Tegra::Shader::StoreType::Bits128: { | ||
| 121 | const u32 count = [&]() { | ||
| 122 | switch (instr.ldst_sl.type.Value()) { | ||
| 123 | case Tegra::Shader::StoreType::Bits32: | ||
| 124 | return 1; | ||
| 125 | case Tegra::Shader::StoreType::Bits64: | ||
| 126 | return 2; | ||
| 127 | case Tegra::Shader::StoreType::Bits128: | ||
| 128 | return 4; | ||
| 129 | default: | ||
| 130 | UNREACHABLE(); | ||
| 131 | return 0; | ||
| 132 | } | ||
| 133 | }(); | ||
| 134 | for (u32 i = 0; i < count; ++i) | ||
| 135 | SetTemporal(bb, i, GetLmem(i * 4)); | ||
| 136 | for (u32 i = 0; i < count; ++i) | ||
| 137 | SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i)); | ||
| 116 | break; | 138 | break; |
| 139 | } | ||
| 117 | default: | 140 | default: |
| 118 | UNIMPLEMENTED_MSG("LD_L Unhandled type: {}", | 141 | UNIMPLEMENTED_MSG("LD_L Unhandled type: {}", |
| 119 | static_cast<unsigned>(instr.ldst_sl.type.Value())); | 142 | static_cast<u32>(instr.ldst_sl.type.Value())); |
| 120 | } | 143 | } |
| 121 | break; | 144 | break; |
| 122 | } | 145 | } |
| @@ -202,12 +225,20 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) { | |||
| 202 | UNIMPLEMENTED_IF_MSG(instr.st_l.unknown == 0, "ST_L Unhandled mode: {}", | 225 | UNIMPLEMENTED_IF_MSG(instr.st_l.unknown == 0, "ST_L Unhandled mode: {}", |
| 203 | static_cast<u32>(instr.st_l.unknown.Value())); | 226 | static_cast<u32>(instr.st_l.unknown.Value())); |
| 204 | 227 | ||
| 205 | const Node index = Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8), | 228 | const auto GetLmemAddr = [&](s32 offset) { |
| 206 | Immediate(static_cast<s32>(instr.smem_imm))); | 229 | ASSERT(offset % 4 == 0); |
| 230 | const Node immediate = Immediate(static_cast<s32>(instr.smem_imm) + offset); | ||
| 231 | return Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8), immediate); | ||
| 232 | }; | ||
| 207 | 233 | ||
| 208 | switch (instr.ldst_sl.type.Value()) { | 234 | switch (instr.ldst_sl.type.Value()) { |
| 209 | case Tegra::Shader::StoreType::Bytes32: | 235 | case Tegra::Shader::StoreType::Bits128: |
| 210 | SetLocalMemory(bb, index, GetRegister(instr.gpr0)); | 236 | SetLocalMemory(bb, GetLmemAddr(12), GetRegister(instr.gpr0.Value() + 3)); |
| 237 | SetLocalMemory(bb, GetLmemAddr(8), GetRegister(instr.gpr0.Value() + 2)); | ||
| 238 | case Tegra::Shader::StoreType::Bits64: | ||
| 239 | SetLocalMemory(bb, GetLmemAddr(4), GetRegister(instr.gpr0.Value() + 1)); | ||
| 240 | case Tegra::Shader::StoreType::Bits32: | ||
| 241 | SetLocalMemory(bb, GetLmemAddr(0), GetRegister(instr.gpr0)); | ||
| 211 | break; | 242 | break; |
| 212 | default: | 243 | default: |
| 213 | UNIMPLEMENTED_MSG("ST_L Unhandled type: {}", | 244 | UNIMPLEMENTED_MSG("ST_L Unhandled type: {}", |