summaryrefslogtreecommitdiff
path: root/src/video_core/macro/macro.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/macro/macro.h')
-rw-r--r--src/video_core/macro/macro.h141
1 files changed, 141 insertions, 0 deletions
diff --git a/src/video_core/macro/macro.h b/src/video_core/macro/macro.h
new file mode 100644
index 000000000..4d00b84b0
--- /dev/null
+++ b/src/video_core/macro/macro.h
@@ -0,0 +1,141 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include <unordered_map>
9#include <vector>
10#include "common/bit_field.h"
11#include "common/common_types.h"
12
13namespace Tegra {
14
15namespace Engines {
16class Maxwell3D;
17}
18
19namespace Macro {
20constexpr std::size_t NUM_MACRO_REGISTERS = 8;
21enum class Operation : u32 {
22 ALU = 0,
23 AddImmediate = 1,
24 ExtractInsert = 2,
25 ExtractShiftLeftImmediate = 3,
26 ExtractShiftLeftRegister = 4,
27 Read = 5,
28 Unused = 6, // This operation doesn't seem to be a valid encoding.
29 Branch = 7,
30};
31
32enum class ALUOperation : u32 {
33 Add = 0,
34 AddWithCarry = 1,
35 Subtract = 2,
36 SubtractWithBorrow = 3,
37 // Operations 4-7 don't seem to be valid encodings.
38 Xor = 8,
39 Or = 9,
40 And = 10,
41 AndNot = 11,
42 Nand = 12
43};
44
45enum class ResultOperation : u32 {
46 IgnoreAndFetch = 0,
47 Move = 1,
48 MoveAndSetMethod = 2,
49 FetchAndSend = 3,
50 MoveAndSend = 4,
51 FetchAndSetMethod = 5,
52 MoveAndSetMethodFetchAndSend = 6,
53 MoveAndSetMethodSend = 7
54};
55
56enum class BranchCondition : u32 {
57 Zero = 0,
58 NotZero = 1,
59};
60
61union Opcode {
62 u32 raw;
63 BitField<0, 3, Operation> operation;
64 BitField<4, 3, ResultOperation> result_operation;
65 BitField<4, 1, BranchCondition> branch_condition;
66 // If set on a branch, then the branch doesn't have a delay slot.
67 BitField<5, 1, u32> branch_annul;
68 BitField<7, 1, u32> is_exit;
69 BitField<8, 3, u32> dst;
70 BitField<11, 3, u32> src_a;
71 BitField<14, 3, u32> src_b;
72 // The signed immediate overlaps the second source operand and the alu operation.
73 BitField<14, 18, s32> immediate;
74
75 BitField<17, 5, ALUOperation> alu_operation;
76
77 // Bitfield instructions data
78 BitField<17, 5, u32> bf_src_bit;
79 BitField<22, 5, u32> bf_size;
80 BitField<27, 5, u32> bf_dst_bit;
81
82 u32 GetBitfieldMask() const {
83 return (1 << bf_size) - 1;
84 }
85
86 s32 GetBranchTarget() const {
87 return static_cast<s32>(immediate * sizeof(u32));
88 }
89};
90
91union MethodAddress {
92 u32 raw;
93 BitField<0, 12, u32> address;
94 BitField<12, 6, u32> increment;
95};
96
97} // namespace Macro
98
99class HLEMacro;
100
101class CachedMacro {
102public:
103 virtual ~CachedMacro() = default;
104 /**
105 * Executes the macro code with the specified input parameters.
106 * @param code The macro byte code to execute
107 * @param parameters The parameters of the macro
108 */
109 virtual void Execute(const std::vector<u32>& parameters, u32 method) = 0;
110};
111
112class MacroEngine {
113public:
114 explicit MacroEngine(Engines::Maxwell3D& maxwell3d);
115 virtual ~MacroEngine();
116
117 // Store the uploaded macro code to compile them when they're called.
118 void AddCode(u32 method, u32 data);
119
120 // Compiles the macro if its not in the cache, and executes the compiled macro
121 void Execute(Engines::Maxwell3D& maxwell3d, u32 method, const std::vector<u32>& parameters);
122
123protected:
124 virtual std::unique_ptr<CachedMacro> Compile(const std::vector<u32>& code) = 0;
125
126private:
127 struct CacheInfo {
128 std::unique_ptr<CachedMacro> lle_program{};
129 std::unique_ptr<CachedMacro> hle_program{};
130 u64 hash{};
131 bool has_hle_program{};
132 };
133
134 std::unordered_map<u32, CacheInfo> macro_cache;
135 std::unordered_map<u32, std::vector<u32>> uploaded_macro_code;
136 std::unique_ptr<HLEMacro> hle_macros;
137};
138
139std::unique_ptr<MacroEngine> GetMacroEngine(Engines::Maxwell3D& maxwell3d);
140
141} // namespace Tegra