summaryrefslogtreecommitdiff
path: root/src/video_core/shader/decode
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2018-12-29 02:44:54 -0300
committerGravatar ReinUsesLisp2019-01-30 00:00:15 -0300
commit3b84e04af1ce2f9e218e7bcf225dd3eff1ddc61d (patch)
treee73cb322fea7179d4dd620438ad16290feb14b0e /src/video_core/shader/decode
parentvideo_core/GPU Implemented the GPU PFIFO puller semaphore operations. (#1908) (diff)
downloadyuzu-3b84e04af1ce2f9e218e7bcf225dd3eff1ddc61d.tar.gz
yuzu-3b84e04af1ce2f9e218e7bcf225dd3eff1ddc61d.tar.xz
yuzu-3b84e04af1ce2f9e218e7bcf225dd3eff1ddc61d.zip
shader_decode: Implement LDG and basic cbuf tracking
Diffstat (limited to 'src/video_core/shader/decode')
-rw-r--r--src/video_core/shader/decode/memory.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp
index ae71672d6..04cb386b7 100644
--- a/src/video_core/shader/decode/memory.cpp
+++ b/src/video_core/shader/decode/memory.cpp
@@ -4,6 +4,7 @@
4 4
5#include <algorithm> 5#include <algorithm>
6#include <vector> 6#include <vector>
7#include <fmt/format.h>
7 8
8#include "common/assert.h" 9#include "common/assert.h"
9#include "common/common_types.h" 10#include "common/common_types.h"
@@ -119,6 +120,54 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) {
119 } 120 }
120 break; 121 break;
121 } 122 }
123 case OpCode::Id::LDG: {
124 const u32 count = [&]() {
125 switch (instr.ldg.type) {
126 case Tegra::Shader::UniformType::Single:
127 return 1;
128 case Tegra::Shader::UniformType::Double:
129 return 2;
130 case Tegra::Shader::UniformType::Quad:
131 case Tegra::Shader::UniformType::UnsignedQuad:
132 return 4;
133 default:
134 UNIMPLEMENTED_MSG("Unimplemented LDG size!");
135 return 1;
136 }
137 }();
138
139 const Node addr_register = GetRegister(instr.gpr8);
140 const Node base_address = TrackCbuf(addr_register, code, static_cast<s64>(code.size()));
141 const auto cbuf = std::get_if<CbufNode>(base_address);
142 ASSERT(cbuf != nullptr);
143 const auto cbuf_offset_imm = std::get_if<ImmediateNode>(cbuf->GetOffset());
144 ASSERT(cbuf_offset_imm != nullptr);
145 const auto cbuf_offset = cbuf_offset_imm->GetValue() * 4;
146
147 bb.push_back(Comment(
148 fmt::format("Base address is c[0x{:x}][0x{:x}]", cbuf->GetIndex(), cbuf_offset)));
149
150 const GlobalMemoryBase descriptor{cbuf->GetIndex(), cbuf_offset};
151 used_global_memory_bases.insert(descriptor);
152
153 const Node immediate_offset =
154 Immediate(static_cast<u32>(instr.ldg.immediate_offset.Value()));
155 const Node base_real_address =
156 Operation(OperationCode::UAdd, NO_PRECISE, immediate_offset, addr_register);
157
158 for (u32 i = 0; i < count; ++i) {
159 const Node it_offset = Immediate(i * 4);
160 const Node real_address =
161 Operation(OperationCode::UAdd, NO_PRECISE, base_real_address, it_offset);
162 const Node gmem = StoreNode(GmemNode(real_address, base_address, descriptor));
163
164 SetTemporal(bb, i, gmem);
165 }
166 for (u32 i = 0; i < count; ++i) {
167 SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i));
168 }
169 break;
170 }
122 case OpCode::Id::ST_A: { 171 case OpCode::Id::ST_A: {
123 UNIMPLEMENTED_IF_MSG(instr.gpr8.Value() != Register::ZeroIndex, 172 UNIMPLEMENTED_IF_MSG(instr.gpr8.Value() != Register::ZeroIndex,
124 "Indirect attribute loads are not supported"); 173 "Indirect attribute loads are not supported");