diff options
| author | 2019-09-18 16:26:05 -0400 | |
|---|---|---|
| committer | 2019-09-18 16:26:05 -0400 | |
| commit | b31880dc5e0d9aab1171d3476453ad2db00cfd3a (patch) | |
| tree | b1ec38b1d4be6f1f61d987608d99d1f6ee428a83 /src/video_core/shader/decode | |
| parent | Merge pull request #2851 from ReinUsesLisp/srgb (diff) | |
| parent | gl_shader_decompiler: Implement shared memory (diff) | |
| download | yuzu-b31880dc5e0d9aab1171d3476453ad2db00cfd3a.tar.gz yuzu-b31880dc5e0d9aab1171d3476453ad2db00cfd3a.tar.xz yuzu-b31880dc5e0d9aab1171d3476453ad2db00cfd3a.zip | |
Merge pull request #2784 from ReinUsesLisp/smem
shader_ir: Implement shared memory
Diffstat (limited to 'src/video_core/shader/decode')
| -rw-r--r-- | src/video_core/shader/decode/memory.cpp | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index ed108bea8..7923d4d69 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp | |||
| @@ -35,7 +35,7 @@ u32 GetUniformTypeElementsCount(Tegra::Shader::UniformType uniform_type) { | |||
| 35 | return 1; | 35 | return 1; |
| 36 | } | 36 | } |
| 37 | } | 37 | } |
| 38 | } // namespace | 38 | } // Anonymous namespace |
| 39 | 39 | ||
| 40 | u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { | 40 | u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { |
| 41 | const Instruction instr = {program_code[pc]}; | 41 | const Instruction instr = {program_code[pc]}; |
| @@ -106,16 +106,17 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { | |||
| 106 | } | 106 | } |
| 107 | break; | 107 | break; |
| 108 | } | 108 | } |
| 109 | case OpCode::Id::LD_L: { | 109 | case OpCode::Id::LD_L: |
| 110 | LOG_DEBUG(HW_GPU, "LD_L cache management mode: {}", | 110 | LOG_DEBUG(HW_GPU, "LD_L cache management mode: {}", static_cast<u64>(instr.ld_l.unknown)); |
| 111 | static_cast<u64>(instr.ld_l.unknown.Value())); | 111 | [[fallthrough]]; |
| 112 | 112 | case OpCode::Id::LD_S: { | |
| 113 | const auto GetLmem = [&](s32 offset) { | 113 | const auto GetMemory = [&](s32 offset) { |
| 114 | ASSERT(offset % 4 == 0); | 114 | ASSERT(offset % 4 == 0); |
| 115 | const Node immediate_offset = Immediate(static_cast<s32>(instr.smem_imm) + offset); | 115 | const Node immediate_offset = Immediate(static_cast<s32>(instr.smem_imm) + offset); |
| 116 | const Node address = Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8), | 116 | const Node address = Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8), |
| 117 | immediate_offset); | 117 | immediate_offset); |
| 118 | return GetLocalMemory(address); | 118 | return opcode->get().GetId() == OpCode::Id::LD_S ? GetSharedMemory(address) |
| 119 | : GetLocalMemory(address); | ||
| 119 | }; | 120 | }; |
| 120 | 121 | ||
| 121 | switch (instr.ldst_sl.type.Value()) { | 122 | switch (instr.ldst_sl.type.Value()) { |
| @@ -135,14 +136,16 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { | |||
| 135 | return 0; | 136 | return 0; |
| 136 | } | 137 | } |
| 137 | }(); | 138 | }(); |
| 138 | for (u32 i = 0; i < count; ++i) | 139 | for (u32 i = 0; i < count; ++i) { |
| 139 | SetTemporary(bb, i, GetLmem(i * 4)); | 140 | SetTemporary(bb, i, GetMemory(i * 4)); |
| 140 | for (u32 i = 0; i < count; ++i) | 141 | } |
| 142 | for (u32 i = 0; i < count; ++i) { | ||
| 141 | SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i)); | 143 | SetRegister(bb, instr.gpr0.Value() + i, GetTemporary(i)); |
| 144 | } | ||
| 142 | break; | 145 | break; |
| 143 | } | 146 | } |
| 144 | default: | 147 | default: |
| 145 | UNIMPLEMENTED_MSG("LD_L Unhandled type: {}", | 148 | UNIMPLEMENTED_MSG("{} Unhandled type: {}", opcode->get().GetName(), |
| 146 | static_cast<u32>(instr.ldst_sl.type.Value())); | 149 | static_cast<u32>(instr.ldst_sl.type.Value())); |
| 147 | } | 150 | } |
| 148 | break; | 151 | break; |
| @@ -209,27 +212,34 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { | |||
| 209 | 212 | ||
| 210 | break; | 213 | break; |
| 211 | } | 214 | } |
| 212 | case OpCode::Id::ST_L: { | 215 | case OpCode::Id::ST_L: |
| 213 | LOG_DEBUG(HW_GPU, "ST_L cache management mode: {}", | 216 | LOG_DEBUG(HW_GPU, "ST_L cache management mode: {}", |
| 214 | static_cast<u64>(instr.st_l.cache_management.Value())); | 217 | static_cast<u64>(instr.st_l.cache_management.Value())); |
| 215 | 218 | [[fallthrough]]; | |
| 216 | const auto GetLmemAddr = [&](s32 offset) { | 219 | case OpCode::Id::ST_S: { |
| 220 | const auto GetAddress = [&](s32 offset) { | ||
| 217 | ASSERT(offset % 4 == 0); | 221 | ASSERT(offset % 4 == 0); |
| 218 | const Node immediate = Immediate(static_cast<s32>(instr.smem_imm) + offset); | 222 | const Node immediate = Immediate(static_cast<s32>(instr.smem_imm) + offset); |
| 219 | return Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8), immediate); | 223 | return Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8), immediate); |
| 220 | }; | 224 | }; |
| 221 | 225 | ||
| 226 | const auto set_memory = opcode->get().GetId() == OpCode::Id::ST_L | ||
| 227 | ? &ShaderIR::SetLocalMemory | ||
| 228 | : &ShaderIR::SetSharedMemory; | ||
| 229 | |||
| 222 | switch (instr.ldst_sl.type.Value()) { | 230 | switch (instr.ldst_sl.type.Value()) { |
| 223 | case Tegra::Shader::StoreType::Bits128: | 231 | case Tegra::Shader::StoreType::Bits128: |
| 224 | SetLocalMemory(bb, GetLmemAddr(12), GetRegister(instr.gpr0.Value() + 3)); | 232 | (this->*set_memory)(bb, GetAddress(12), GetRegister(instr.gpr0.Value() + 3)); |
| 225 | SetLocalMemory(bb, GetLmemAddr(8), GetRegister(instr.gpr0.Value() + 2)); | 233 | (this->*set_memory)(bb, GetAddress(8), GetRegister(instr.gpr0.Value() + 2)); |
| 234 | [[fallthrough]]; | ||
| 226 | case Tegra::Shader::StoreType::Bits64: | 235 | case Tegra::Shader::StoreType::Bits64: |
| 227 | SetLocalMemory(bb, GetLmemAddr(4), GetRegister(instr.gpr0.Value() + 1)); | 236 | (this->*set_memory)(bb, GetAddress(4), GetRegister(instr.gpr0.Value() + 1)); |
| 237 | [[fallthrough]]; | ||
| 228 | case Tegra::Shader::StoreType::Bits32: | 238 | case Tegra::Shader::StoreType::Bits32: |
| 229 | SetLocalMemory(bb, GetLmemAddr(0), GetRegister(instr.gpr0)); | 239 | (this->*set_memory)(bb, GetAddress(0), GetRegister(instr.gpr0)); |
| 230 | break; | 240 | break; |
| 231 | default: | 241 | default: |
| 232 | UNIMPLEMENTED_MSG("ST_L Unhandled type: {}", | 242 | UNIMPLEMENTED_MSG("{} unhandled type: {}", opcode->get().GetName(), |
| 233 | static_cast<u32>(instr.ldst_sl.type.Value())); | 243 | static_cast<u32>(instr.ldst_sl.type.Value())); |
| 234 | } | 244 | } |
| 235 | break; | 245 | break; |