summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/CMakeLists.txt1
-rw-r--r--src/video_core/engines/shader_bytecode.h297
2 files changed, 298 insertions, 0 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index a710c4bc5..4defb5786 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -9,6 +9,7 @@ add_library(video_core STATIC
9 engines/maxwell_3d.h 9 engines/maxwell_3d.h
10 engines/maxwell_compute.cpp 10 engines/maxwell_compute.cpp
11 engines/maxwell_compute.h 11 engines/maxwell_compute.h
12 engines/shader_bytecode.h
12 gpu.cpp 13 gpu.cpp
13 gpu.h 14 gpu.h
14 macro_interpreter.cpp 15 macro_interpreter.cpp
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
new file mode 100644
index 000000000..6660742cc
--- /dev/null
+++ b/src/video_core/engines/shader_bytecode.h
@@ -0,0 +1,297 @@
1// Copyright 2018 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 <map>
8#include <string>
9#include "common/bit_field.h"
10
11namespace Tegra {
12namespace Shader {
13
14struct Register {
15 constexpr Register() = default;
16
17 constexpr Register(u64 value) : value(value) {}
18
19 constexpr u64 GetIndex() const {
20 return value;
21 }
22
23 constexpr operator u64() const {
24 return value;
25 }
26
27 template <typename T>
28 constexpr u64 operator-(const T& oth) const {
29 return value - oth;
30 }
31
32 template <typename T>
33 constexpr u64 operator&(const T& oth) const {
34 return value & oth;
35 }
36
37 constexpr u64 operator&(const Register& oth) const {
38 return value & oth.value;
39 }
40
41 constexpr u64 operator~() const {
42 return ~value;
43 }
44
45private:
46 u64 value;
47};
48
49union Attribute {
50 constexpr Attribute() = default;
51
52 constexpr Attribute(u64 value) : value(value) {}
53
54 enum class Index : u64 {
55 Position = 7,
56 Attribute_0 = 8,
57 };
58
59 constexpr Index GetIndex() const {
60 return index;
61 }
62
63public:
64 BitField<24, 6, Index> index;
65 BitField<22, 2, u64> element;
66 BitField<39, 8, u64> reg;
67 BitField<47, 3, u64> size;
68 u64 value;
69};
70
71union Uniform {
72 BitField<20, 14, u64> offset;
73 BitField<34, 5, u64> index;
74};
75
76union OpCode {
77 enum class Id : u64 {
78 TEXS = 0x6C,
79 IPA = 0xE0,
80 FFMA_IMM = 0x65,
81 FFMA_CR = 0x93,
82 FFMA_RC = 0xA3,
83 FFMA_RR = 0xB3,
84
85 FADD_C = 0x98B,
86 FMUL_C = 0x98D,
87 MUFU = 0xA10,
88 FADD_R = 0xB8B,
89 FMUL_R = 0xB8D,
90 LD_A = 0x1DFB,
91 ST_A = 0x1DFE,
92
93 FSETP_R = 0x5BB,
94 FSETP_C = 0x4BB,
95 EXIT = 0xE30,
96 KIL = 0xE33,
97
98 FMUL_IMM = 0x70D,
99 FMUL_IMM_x = 0x72D,
100 FADD_IMM = 0x70B,
101 FADD_IMM_x = 0x72B,
102 };
103
104 enum class Type {
105 Trivial,
106 Arithmetic,
107 Flow,
108 Memory,
109 Unknown,
110 };
111
112 struct Info {
113 Type type;
114 std::string name;
115 };
116
117 constexpr OpCode() = default;
118
119 constexpr OpCode(Id value) : value(static_cast<u64>(value)) {}
120
121 constexpr OpCode(u64 value) : value{value} {}
122
123 constexpr Id EffectiveOpCode() const {
124 switch (op1) {
125 case Id::TEXS:
126 return op1;
127 }
128
129 switch (op2) {
130 case Id::IPA:
131 return op2;
132 }
133
134 switch (op3) {
135 case Id::FFMA_IMM:
136 case Id::FFMA_CR:
137 case Id::FFMA_RC:
138 case Id::FFMA_RR:
139 return op3;
140 }
141
142 switch (op4) {
143 case Id::EXIT:
144 case Id::FSETP_R:
145 case Id::FSETP_C:
146 case Id::KIL:
147 return op4;
148 }
149
150 switch (op5) {
151 case Id::MUFU:
152 case Id::LD_A:
153 case Id::ST_A:
154 case Id::FADD_R:
155 case Id::FADD_C:
156 case Id::FMUL_R:
157 case Id::FMUL_C:
158 return op5;
159
160 case Id::FMUL_IMM:
161 case Id::FMUL_IMM_x:
162 return Id::FMUL_IMM;
163
164 case Id::FADD_IMM:
165 case Id::FADD_IMM_x:
166 return Id::FADD_IMM;
167 }
168
169 return static_cast<Id>(value);
170 }
171
172 static const Info& GetInfo(const OpCode& opcode) {
173 static const std::map<Id, Info> info_table{BuildInfoTable()};
174 const auto& search{info_table.find(opcode.EffectiveOpCode())};
175 if (search != info_table.end()) {
176 return search->second;
177 }
178
179 static const Info unknown{Type::Unknown, "UNK"};
180 return unknown;
181 }
182
183 constexpr operator Id() const {
184 return static_cast<Id>(value);
185 }
186
187 constexpr OpCode operator<<(size_t bits) const {
188 return value << bits;
189 }
190
191 constexpr OpCode operator>>(size_t bits) const {
192 return value >> bits;
193 }
194
195 template <typename T>
196 constexpr u64 operator-(const T& oth) const {
197 return value - oth;
198 }
199
200 constexpr u64 operator&(const OpCode& oth) const {
201 return value & oth.value;
202 }
203
204 constexpr u64 operator~() const {
205 return ~value;
206 }
207
208 static std::map<Id, Info> BuildInfoTable() {
209 std::map<Id, Info> info_table;
210 info_table[Id::TEXS] = {Type::Memory, "texs"};
211 info_table[Id::LD_A] = {Type::Memory, "ld_a"};
212 info_table[Id::ST_A] = {Type::Memory, "st_a"};
213 info_table[Id::IPA] = {Type::Arithmetic, "ipa"};
214 info_table[Id::MUFU] = {Type::Arithmetic, "mufu"};
215 info_table[Id::FFMA_IMM] = {Type::Arithmetic, "ffma_imm"};
216 info_table[Id::FFMA_CR] = {Type::Arithmetic, "ffma_cr"};
217 info_table[Id::FFMA_RC] = {Type::Arithmetic, "ffma_rc"};
218 info_table[Id::FFMA_RR] = {Type::Arithmetic, "ffma_rr"};
219 info_table[Id::FADD_R] = {Type::Arithmetic, "fadd_r"};
220 info_table[Id::FADD_C] = {Type::Arithmetic, "fadd_c"};
221 info_table[Id::FADD_IMM] = {Type::Arithmetic, "fadd_imm"};
222 info_table[Id::FMUL_R] = {Type::Arithmetic, "fmul_r"};
223 info_table[Id::FMUL_C] = {Type::Arithmetic, "fmul_c"};
224 info_table[Id::FMUL_IMM] = {Type::Arithmetic, "fmul_imm"};
225 info_table[Id::EXIT] = {Type::Trivial, "exit"};
226 return info_table;
227 }
228
229 BitField<57, 7, Id> op1;
230 BitField<56, 8, Id> op2;
231 BitField<55, 9, Id> op3;
232 BitField<52, 12, Id> op4;
233 BitField<51, 13, Id> op5;
234 u64 value;
235};
236static_assert(sizeof(OpCode) == 0x8, "Incorrect structure size");
237
238} // namespace Shader
239} // namespace Tegra
240
241namespace std {
242
243template <>
244struct make_unsigned<Tegra::Shader::Attribute> {
245 using type = Tegra::Shader::Attribute;
246};
247
248template <>
249struct make_unsigned<Tegra::Shader::Register> {
250 using type = Tegra::Shader::Register;
251};
252
253template <>
254struct make_unsigned<Tegra::Shader::OpCode> {
255 using type = Tegra::Shader::OpCode;
256};
257
258} // namespace std
259
260namespace Tegra {
261namespace Shader {
262
263enum class Pred : u64 {
264 UnusedIndex = 0x7,
265 NeverExecute = 0xf,
266};
267
268#pragma pack(1)
269union Instruction {
270 Instruction& operator=(const Instruction& instr) {
271 hex = instr.hex;
272 return *this;
273 }
274
275 OpCode opcode;
276 BitField<0, 8, Register> gpr1;
277 BitField<8, 8, Register> gpr2;
278 BitField<16, 4, Pred> pred;
279 BitField<39, 8, Register> gpr3;
280 BitField<45, 1, u64> nb;
281 BitField<46, 1, u64> aa;
282 BitField<48, 1, u64> na;
283 BitField<49, 1, u64> ab;
284 BitField<50, 1, u64> ad;
285 Attribute attribute;
286 Uniform uniform;
287
288 u64 hex;
289};
290static_assert(sizeof(Instruction) == 0x8, "Incorrect structure size");
291static_assert(std::is_standard_layout<Instruction>::value,
292 "Structure does not have standard layout");
293
294#pragma pack()
295
296} // namespace Shader
297} // namespace Tegra