summaryrefslogtreecommitdiff
path: root/src/video_core/shader
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-05-18 02:35:01 -0300
committerGravatar ReinUsesLisp2019-05-20 22:38:59 -0300
commitf78ef617b66e81b6095156fa0ff435cf8307aef7 (patch)
treec822e8d45e7b33bd36f8778bff56f67a8e461fec /src/video_core/shader
parentMerge pull request #2455 from lioncash/config (diff)
downloadyuzu-f78ef617b66e81b6095156fa0ff435cf8307aef7.tar.gz
yuzu-f78ef617b66e81b6095156fa0ff435cf8307aef7.tar.xz
yuzu-f78ef617b66e81b6095156fa0ff435cf8307aef7.zip
shader/memory: Implement LD (generic memory)
Diffstat (limited to 'src/video_core/shader')
-rw-r--r--src/video_core/shader/decode/memory.cpp28
-rw-r--r--src/video_core/shader/shader_ir.h6
2 files changed, 23 insertions, 11 deletions
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp
index 6a992c543..8ac2fd4ac 100644
--- a/src/video_core/shader/decode/memory.cpp
+++ b/src/video_core/shader/decode/memory.cpp
@@ -148,12 +148,25 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
148 } 148 }
149 break; 149 break;
150 } 150 }
151 case OpCode::Id::LD:
151 case OpCode::Id::LDG: { 152 case OpCode::Id::LDG: {
153 const auto type = [instr, &opcode]() -> Tegra::Shader::UniformType {
154 switch (opcode->get().GetId()) {
155 case OpCode::Id::LD:
156 UNIMPLEMENTED_IF_MSG(!instr.generic.extended, "Unextended LD is not implemented");
157 return instr.generic.type;
158 case OpCode::Id::LDG:
159 return instr.ldg.type;
160 default:
161 UNREACHABLE();
162 return {};
163 }
164 }();
165
152 const auto [real_address_base, base_address, descriptor] = 166 const auto [real_address_base, base_address, descriptor] =
153 TrackAndGetGlobalMemory(bb, GetRegister(instr.gpr8), 167 TrackAndGetGlobalMemory(bb, instr, false);
154 static_cast<u32>(instr.ldg.immediate_offset.Value()), false);
155 168
156 const u32 count = GetUniformTypeElementsCount(instr.ldg.type); 169 const u32 count = GetUniformTypeElementsCount(type);
157 for (u32 i = 0; i < count; ++i) { 170 for (u32 i = 0; i < count; ++i) {
158 const Node it_offset = Immediate(i * 4); 171 const Node it_offset = Immediate(i * 4);
159 const Node real_address = 172 const Node real_address =
@@ -169,8 +182,7 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
169 } 182 }
170 case OpCode::Id::STG: { 183 case OpCode::Id::STG: {
171 const auto [real_address_base, base_address, descriptor] = 184 const auto [real_address_base, base_address, descriptor] =
172 TrackAndGetGlobalMemory(bb, GetRegister(instr.gpr8), 185 TrackAndGetGlobalMemory(bb, instr, true);
173 static_cast<u32>(instr.stg.immediate_offset.Value()), true);
174 186
175 // Encode in temporary registers like this: real_base_address, {registers_to_be_written...} 187 // Encode in temporary registers like this: real_base_address, {registers_to_be_written...}
176 SetTemporal(bb, 0, real_address_base); 188 SetTemporal(bb, 0, real_address_base);
@@ -267,9 +279,11 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
267} 279}
268 280
269std::tuple<Node, Node, GlobalMemoryBase> ShaderIR::TrackAndGetGlobalMemory(NodeBlock& bb, 281std::tuple<Node, Node, GlobalMemoryBase> ShaderIR::TrackAndGetGlobalMemory(NodeBlock& bb,
270 Node addr_register, 282 Instruction instr,
271 u32 immediate_offset,
272 bool is_write) { 283 bool is_write) {
284 const auto addr_register{GetRegister(instr.gmem.gpr)};
285 const auto immediate_offset{static_cast<u32>(instr.gmem.offset)};
286
273 const Node base_address{ 287 const Node base_address{
274 TrackCbuf(addr_register, global_code, static_cast<s64>(global_code.size()))}; 288 TrackCbuf(addr_register, global_code, static_cast<s64>(global_code.size()))};
275 const auto cbuf = std::get_if<CbufNode>(base_address); 289 const auto cbuf = std::get_if<CbufNode>(base_address);
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index 0bf124252..0f769ed8d 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -818,10 +818,8 @@ private:
818 std::pair<Node, s64> TrackRegister(const GprNode* tracked, const NodeBlock& code, 818 std::pair<Node, s64> TrackRegister(const GprNode* tracked, const NodeBlock& code,
819 s64 cursor) const; 819 s64 cursor) const;
820 820
821 std::tuple<Node, Node, GlobalMemoryBase> TrackAndGetGlobalMemory(NodeBlock& bb, 821 std::tuple<Node, Node, GlobalMemoryBase> TrackAndGetGlobalMemory(
822 Node addr_register, 822 NodeBlock& bb, Tegra::Shader::Instruction instr, bool is_write);
823 u32 immediate_offset,
824 bool is_write);
825 823
826 template <typename... T> 824 template <typename... T>
827 Node Operation(OperationCode code, const T*... operands) { 825 Node Operation(OperationCode code, const T*... operands) {