summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/shader/decode/image.cpp6
-rw-r--r--src/video_core/shader/decode/memory.cpp19
-rw-r--r--src/video_core/shader/decode/texture.cpp8
-rw-r--r--src/video_core/shader/shader_ir.cpp11
-rw-r--r--src/video_core/shader/shader_ir.h2
-rw-r--r--src/video_core/shader/track.cpp25
6 files changed, 36 insertions, 35 deletions
diff --git a/src/video_core/shader/decode/image.cpp b/src/video_core/shader/decode/image.cpp
index 24f022cc0..77151a24b 100644
--- a/src/video_core/shader/decode/image.cpp
+++ b/src/video_core/shader/decode/image.cpp
@@ -95,12 +95,8 @@ const Image& ShaderIR::GetImage(Tegra::Shader::Image image, Tegra::Shader::Image
95const Image& ShaderIR::GetBindlessImage(Tegra::Shader::Register reg, 95const Image& ShaderIR::GetBindlessImage(Tegra::Shader::Register reg,
96 Tegra::Shader::ImageType type) { 96 Tegra::Shader::ImageType type) {
97 const Node image_register{GetRegister(reg)}; 97 const Node image_register{GetRegister(reg)};
98 const Node base_image{ 98 const auto [base_image, cbuf_index, cbuf_offset]{
99 TrackCbuf(image_register, global_code, static_cast<s64>(global_code.size()))}; 99 TrackCbuf(image_register, global_code, static_cast<s64>(global_code.size()))};
100 const auto cbuf{std::get_if<CbufNode>(&*base_image)};
101 const auto cbuf_offset_imm{std::get_if<ImmediateNode>(&*cbuf->GetOffset())};
102 const auto cbuf_offset{cbuf_offset_imm->GetValue()};
103 const auto cbuf_index{cbuf->GetIndex()};
104 const auto cbuf_key{(static_cast<u64>(cbuf_index) << 32) | static_cast<u64>(cbuf_offset)}; 100 const auto cbuf_key{(static_cast<u64>(cbuf_index) << 32) | static_cast<u64>(cbuf_offset)};
105 101
106 // If this image has already been used, return the existing mapping. 102 // If this image has already been used, return the existing mapping.
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp
index 80fc0ccfc..ab207a33b 100644
--- a/src/video_core/shader/decode/memory.cpp
+++ b/src/video_core/shader/decode/memory.cpp
@@ -297,18 +297,13 @@ std::tuple<Node, Node, GlobalMemoryBase> ShaderIR::TrackAndGetGlobalMemory(NodeB
297 const auto addr_register{GetRegister(instr.gmem.gpr)}; 297 const auto addr_register{GetRegister(instr.gmem.gpr)};
298 const auto immediate_offset{static_cast<u32>(instr.gmem.offset)}; 298 const auto immediate_offset{static_cast<u32>(instr.gmem.offset)};
299 299
300 const Node base_address{ 300 const auto [base_address, index, offset] =
301 TrackCbuf(addr_register, global_code, static_cast<s64>(global_code.size()))}; 301 TrackCbuf(addr_register, global_code, static_cast<s64>(global_code.size()));
302 const auto cbuf = std::get_if<CbufNode>(&*base_address); 302 ASSERT(base_address != nullptr);
303 ASSERT(cbuf != nullptr); 303
304 const auto cbuf_offset_imm = std::get_if<ImmediateNode>(&*cbuf->GetOffset()); 304 bb.push_back(Comment(fmt::format("Base address is c[0x{:x}][0x{:x}]", index, offset)));
305 ASSERT(cbuf_offset_imm != nullptr); 305
306 const auto cbuf_offset = cbuf_offset_imm->GetValue(); 306 const GlobalMemoryBase descriptor{index, offset};
307
308 bb.push_back(
309 Comment(fmt::format("Base address is c[0x{:x}][0x{:x}]", cbuf->GetIndex(), cbuf_offset)));
310
311 const GlobalMemoryBase descriptor{cbuf->GetIndex(), cbuf_offset};
312 const auto& [entry, is_new] = used_global_memory.try_emplace(descriptor); 307 const auto& [entry, is_new] = used_global_memory.try_emplace(descriptor);
313 auto& usage = entry->second; 308 auto& usage = entry->second;
314 if (is_write) { 309 if (is_write) {
diff --git a/src/video_core/shader/decode/texture.cpp b/src/video_core/shader/decode/texture.cpp
index 323be3f14..e1ee5c190 100644
--- a/src/video_core/shader/decode/texture.cpp
+++ b/src/video_core/shader/decode/texture.cpp
@@ -308,13 +308,9 @@ const Sampler& ShaderIR::GetSampler(const Tegra::Shader::Sampler& sampler, Textu
308const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg, TextureType type, 308const Sampler& ShaderIR::GetBindlessSampler(const Tegra::Shader::Register& reg, TextureType type,
309 bool is_array, bool is_shadow) { 309 bool is_array, bool is_shadow) {
310 const Node sampler_register = GetRegister(reg); 310 const Node sampler_register = GetRegister(reg);
311 const Node base_sampler = 311 const auto [base_sampler, cbuf_index, cbuf_offset] =
312 TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size())); 312 TrackCbuf(sampler_register, global_code, static_cast<s64>(global_code.size()));
313 const auto cbuf = std::get_if<CbufNode>(&*base_sampler); 313 ASSERT(base_sampler != nullptr);
314 const auto cbuf_offset_imm = std::get_if<ImmediateNode>(&*cbuf->GetOffset());
315 ASSERT(cbuf_offset_imm != nullptr);
316 const auto cbuf_offset = cbuf_offset_imm->GetValue();
317 const auto cbuf_index = cbuf->GetIndex();
318 const auto cbuf_key = (static_cast<u64>(cbuf_index) << 32) | static_cast<u64>(cbuf_offset); 314 const auto cbuf_key = (static_cast<u64>(cbuf_index) << 32) | static_cast<u64>(cbuf_offset);
319 315
320 // If this sampler has already been used, return the existing mapping. 316 // If this sampler has already been used, return the existing mapping.
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index caa409788..78bd1cf1e 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -61,7 +61,16 @@ Node ShaderIR::GetConstBufferIndirect(u64 index_, u64 offset_, Node node) {
61 const auto [entry, is_new] = used_cbufs.try_emplace(index); 61 const auto [entry, is_new] = used_cbufs.try_emplace(index);
62 entry->second.MarkAsUsedIndirect(); 62 entry->second.MarkAsUsedIndirect();
63 63
64 const Node final_offset = Operation(OperationCode::UAdd, NO_PRECISE, node, Immediate(offset)); 64 const Node final_offset = [&]() {
65 // Attempt to inline constant buffer without a variable offset. This is done to allow
66 // tracking LDC calls.
67 if (const auto gpr = std::get_if<GprNode>(&*node)) {
68 if (gpr->GetIndex() == Register::ZeroIndex) {
69 return Immediate(offset);
70 }
71 }
72 return Operation(OperationCode::UAdd, NO_PRECISE, node, Immediate(offset));
73 }();
65 return MakeNode<CbufNode>(index, final_offset); 74 return MakeNode<CbufNode>(index, final_offset);
66} 75}
67 76
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index 03c888def..126c78136 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -328,7 +328,7 @@ private:
328 void WriteLop3Instruction(NodeBlock& bb, Tegra::Shader::Register dest, Node op_a, Node op_b, 328 void WriteLop3Instruction(NodeBlock& bb, Tegra::Shader::Register dest, Node op_a, Node op_b,
329 Node op_c, Node imm_lut, bool sets_cc); 329 Node op_c, Node imm_lut, bool sets_cc);
330 330
331 Node TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) const; 331 std::tuple<Node, u32, u32> TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) const;
332 332
333 std::optional<u32> TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const; 333 std::optional<u32> TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const;
334 334
diff --git a/src/video_core/shader/track.cpp b/src/video_core/shader/track.cpp
index fc957d980..dc132a4a3 100644
--- a/src/video_core/shader/track.cpp
+++ b/src/video_core/shader/track.cpp
@@ -32,39 +32,44 @@ std::pair<Node, s64> FindOperation(const NodeBlock& code, s64 cursor,
32 } 32 }
33 return {}; 33 return {};
34} 34}
35} // namespace 35} // Anonymous namespace
36 36
37Node ShaderIR::TrackCbuf(Node tracked, const NodeBlock& code, s64 cursor) const { 37std::tuple<Node, u32, u32> ShaderIR::TrackCbuf(Node tracked, const NodeBlock& code,
38 s64 cursor) const {
38 if (const auto cbuf = std::get_if<CbufNode>(&*tracked)) { 39 if (const auto cbuf = std::get_if<CbufNode>(&*tracked)) {
39 // Cbuf found, but it has to be immediate 40 // Constant buffer found, test if it's an immediate
40 return std::holds_alternative<ImmediateNode>(*cbuf->GetOffset()) ? tracked : nullptr; 41 const auto offset = cbuf->GetOffset();
42 if (const auto immediate = std::get_if<ImmediateNode>(&*offset)) {
43 return {tracked, cbuf->GetIndex(), immediate->GetValue()};
44 }
45 return {};
41 } 46 }
42 if (const auto gpr = std::get_if<GprNode>(&*tracked)) { 47 if (const auto gpr = std::get_if<GprNode>(&*tracked)) {
43 if (gpr->GetIndex() == Tegra::Shader::Register::ZeroIndex) { 48 if (gpr->GetIndex() == Tegra::Shader::Register::ZeroIndex) {
44 return nullptr; 49 return {};
45 } 50 }
46 // Reduce the cursor in one to avoid infinite loops when the instruction sets the same 51 // Reduce the cursor in one to avoid infinite loops when the instruction sets the same
47 // register that it uses as operand 52 // register that it uses as operand
48 const auto [source, new_cursor] = TrackRegister(gpr, code, cursor - 1); 53 const auto [source, new_cursor] = TrackRegister(gpr, code, cursor - 1);
49 if (!source) { 54 if (!source) {
50 return nullptr; 55 return {};
51 } 56 }
52 return TrackCbuf(source, code, new_cursor); 57 return TrackCbuf(source, code, new_cursor);
53 } 58 }
54 if (const auto operation = std::get_if<OperationNode>(&*tracked)) { 59 if (const auto operation = std::get_if<OperationNode>(&*tracked)) {
55 for (std::size_t i = 0; i < operation->GetOperandsCount(); ++i) { 60 for (std::size_t i = 0; i < operation->GetOperandsCount(); ++i) {
56 if (const auto found = TrackCbuf((*operation)[i], code, cursor)) { 61 if (auto found = TrackCbuf((*operation)[i], code, cursor); std::get<0>(found)) {
57 // Cbuf found in operand 62 // Cbuf found in operand.
58 return found; 63 return found;
59 } 64 }
60 } 65 }
61 return nullptr; 66 return {};
62 } 67 }
63 if (const auto conditional = std::get_if<ConditionalNode>(&*tracked)) { 68 if (const auto conditional = std::get_if<ConditionalNode>(&*tracked)) {
64 const auto& conditional_code = conditional->GetCode(); 69 const auto& conditional_code = conditional->GetCode();
65 return TrackCbuf(tracked, conditional_code, static_cast<s64>(conditional_code.size())); 70 return TrackCbuf(tracked, conditional_code, static_cast<s64>(conditional_code.size()));
66 } 71 }
67 return nullptr; 72 return {};
68} 73}
69 74
70std::optional<u32> ShaderIR::TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const { 75std::optional<u32> ShaderIR::TrackImmediate(Node tracked, const NodeBlock& code, s64 cursor) const {