summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-04-09 23:39:44 -0400
committerGravatar bunnei2018-04-14 16:01:40 -0400
commit86135864da9bbbd5906e96862994bd24f3cd4da5 (patch)
tree6e8c52749b512101f9733314a40c1461d6f6c77b /src
parentshader_bytecode: Add FSETP and KIL to GetInfo. (diff)
downloadyuzu-86135864da9bbbd5906e96862994bd24f3cd4da5.tar.gz
yuzu-86135864da9bbbd5906e96862994bd24f3cd4da5.tar.xz
yuzu-86135864da9bbbd5906e96862994bd24f3cd4da5.zip
gl_shader_decompiler: Implement negate, abs, etc. and lots of cleanup.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/shader_bytecode.h59
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp77
2 files changed, 96 insertions, 40 deletions
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index a4d02e572..dbcd23755 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -56,15 +56,18 @@ union Attribute {
56 Attribute_0 = 8, 56 Attribute_0 = 8,
57 }; 57 };
58 58
59 constexpr Index GetIndex() const { 59 union {
60 return index; 60 BitField<22, 2, u64> element;
61 } 61 BitField<24, 6, Index> index;
62 BitField<47, 3, u64> size;
63 } fmt20;
64
65 union {
66 BitField<30, 2, u64> element;
67 BitField<32, 6, Index> index;
68 } fmt28;
62 69
63public:
64 BitField<24, 6, Index> index;
65 BitField<22, 2, u64> element;
66 BitField<39, 8, u64> reg; 70 BitField<39, 8, u64> reg;
67 BitField<47, 3, u64> size;
68 u64 value; 71 u64 value;
69}; 72};
70 73
@@ -104,6 +107,7 @@ union OpCode {
104 enum class Type { 107 enum class Type {
105 Trivial, 108 Trivial,
106 Arithmetic, 109 Arithmetic,
110 Ffma,
107 Flow, 111 Flow,
108 Memory, 112 Memory,
109 Unknown, 113 Unknown,
@@ -210,12 +214,11 @@ union OpCode {
210 info_table[Id::TEXS] = {Type::Memory, "texs"}; 214 info_table[Id::TEXS] = {Type::Memory, "texs"};
211 info_table[Id::LD_A] = {Type::Memory, "ld_a"}; 215 info_table[Id::LD_A] = {Type::Memory, "ld_a"};
212 info_table[Id::ST_A] = {Type::Memory, "st_a"}; 216 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"}; 217 info_table[Id::MUFU] = {Type::Arithmetic, "mufu"};
215 info_table[Id::FFMA_IMM] = {Type::Arithmetic, "ffma_imm"}; 218 info_table[Id::FFMA_IMM] = {Type::Ffma, "ffma_imm"};
216 info_table[Id::FFMA_CR] = {Type::Arithmetic, "ffma_cr"}; 219 info_table[Id::FFMA_CR] = {Type::Ffma, "ffma_cr"};
217 info_table[Id::FFMA_RC] = {Type::Arithmetic, "ffma_rc"}; 220 info_table[Id::FFMA_RC] = {Type::Ffma, "ffma_rc"};
218 info_table[Id::FFMA_RR] = {Type::Arithmetic, "ffma_rr"}; 221 info_table[Id::FFMA_RR] = {Type::Ffma, "ffma_rr"};
219 info_table[Id::FADD_R] = {Type::Arithmetic, "fadd_r"}; 222 info_table[Id::FADD_R] = {Type::Arithmetic, "fadd_r"};
220 info_table[Id::FADD_C] = {Type::Arithmetic, "fadd_c"}; 223 info_table[Id::FADD_C] = {Type::Arithmetic, "fadd_c"};
221 info_table[Id::FADD_IMM] = {Type::Arithmetic, "fadd_imm"}; 224 info_table[Id::FADD_IMM] = {Type::Arithmetic, "fadd_imm"};
@@ -225,6 +228,7 @@ union OpCode {
225 info_table[Id::FSETP_C] = {Type::Arithmetic, "fsetp_c"}; 228 info_table[Id::FSETP_C] = {Type::Arithmetic, "fsetp_c"};
226 info_table[Id::FSETP_R] = {Type::Arithmetic, "fsetp_r"}; 229 info_table[Id::FSETP_R] = {Type::Arithmetic, "fsetp_r"};
227 info_table[Id::EXIT] = {Type::Trivial, "exit"}; 230 info_table[Id::EXIT] = {Type::Trivial, "exit"};
231 info_table[Id::IPA] = {Type::Trivial, "ipa"};
228 info_table[Id::KIL] = {Type::Flow, "kil"}; 232 info_table[Id::KIL] = {Type::Flow, "kil"};
229 return info_table; 233 return info_table;
230 } 234 }
@@ -285,16 +289,31 @@ union Instruction {
285 } 289 }
286 290
287 OpCode opcode; 291 OpCode opcode;
288 BitField<0, 8, Register> gpr1; 292 BitField<0, 8, Register> gpr0;
289 BitField<8, 8, Register> gpr2; 293 BitField<8, 8, Register> gpr8;
290 BitField<16, 4, Pred> pred; 294 BitField<16, 4, Pred> pred;
295 BitField<20, 8, Register> gpr20;
291 BitField<20, 7, SubOp> sub_op; 296 BitField<20, 7, SubOp> sub_op;
292 BitField<39, 8, Register> gpr3; 297 BitField<28, 8, Register> gpr28;
293 BitField<45, 1, u64> nb; 298 BitField<36, 13, u64> imm36;
294 BitField<46, 1, u64> aa; 299 BitField<39, 8, Register> gpr39;
295 BitField<48, 1, u64> na; 300
296 BitField<49, 1, u64> ab; 301 union {
297 BitField<50, 1, u64> ad; 302 BitField<45, 1, u64> negate_b;
303 BitField<46, 1, u64> abs_a;
304 BitField<48, 1, u64> negate_a;
305 BitField<49, 1, u64> abs_b;
306 BitField<50, 1, u64> abs_d;
307 } alu;
308
309 union {
310 BitField<48, 1, u64> negate_b;
311 BitField<49, 1, u64> negate_c;
312 } ffma;
313
314 BitField<60, 1, u64> is_b_gpr;
315 BitField<59, 1, u64> is_c_gpr;
316
298 Attribute attribute; 317 Attribute attribute;
299 Uniform uniform; 318 Uniform uniform;
300 319
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 704b24307..792b4b12e 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -17,6 +17,7 @@ using Tegra::Shader::Attribute;
17using Tegra::Shader::Instruction; 17using Tegra::Shader::Instruction;
18using Tegra::Shader::OpCode; 18using Tegra::Shader::OpCode;
19using Tegra::Shader::Register; 19using Tegra::Shader::Register;
20using Tegra::Shader::SubOp;
20using Tegra::Shader::Uniform; 21using Tegra::Shader::Uniform;
21 22
22constexpr u32 PROGRAM_END = MAX_PROGRAM_CODE_LENGTH; 23constexpr u32 PROGRAM_END = MAX_PROGRAM_CODE_LENGTH;
@@ -235,31 +236,67 @@ private:
235 236
236 switch (OpCode::GetInfo(instr.opcode).type) { 237 switch (OpCode::GetInfo(instr.opcode).type) {
237 case OpCode::Type::Arithmetic: { 238 case OpCode::Type::Arithmetic: {
238 ASSERT(!instr.nb); 239 ASSERT(!instr.alu.abs_d, "unimplemented");
239 ASSERT(!instr.aa);
240 ASSERT(!instr.na);
241 ASSERT(!instr.ab);
242 ASSERT(!instr.ad);
243 240
244 std::string gpr1 = GetRegister(instr.gpr1); 241 std::string dest = GetRegister(instr.gpr0);
245 std::string gpr2 = GetRegister(instr.gpr2); 242 std::string op_a = instr.alu.negate_a ? "-" : "";
246 std::string uniform = GetUniform(instr.uniform); 243 op_a += GetRegister(instr.gpr8);
244 if (instr.alu.abs_a) {
245 op_a = "abs(" + op_a + ")";
246 }
247
248 std::string op_b = instr.alu.negate_b ? "-" : "";
249 if (instr.is_b_gpr) {
250 op_b += GetRegister(instr.gpr20);
251 } else {
252 op_b += GetUniform(instr.uniform);
253 }
254 if (instr.alu.abs_b) {
255 op_b = "abs(" + op_b + ")";
256 }
247 257
248 switch (instr.opcode.EffectiveOpCode()) { 258 switch (instr.opcode.EffectiveOpCode()) {
249 case OpCode::Id::FMUL_C: { 259 case OpCode::Id::FMUL_C:
250 SetDest(0, gpr1, gpr2 + " * " + uniform, 1, 1); 260 case OpCode::Id::FMUL_R: {
261 SetDest(0, dest, op_a + " * " + op_b, 1, 1);
262 break;
263 }
264 case OpCode::Id::FADD_C:
265 case OpCode::Id::FADD_R: {
266 SetDest(0, dest, op_a + " + " + op_b, 1, 1);
251 break; 267 break;
252 } 268 }
253 case OpCode::Id::FADD_C: { 269 default: {
254 SetDest(0, gpr1, gpr2 + " + " + uniform, 1, 1); 270 LOG_ERROR(HW_GPU, "Unhandled arithmetic instruction: 0x%02x (%s): 0x%08x",
271 (int)instr.opcode.EffectiveOpCode(), OpCode::GetInfo(instr.opcode).name,
272 instr.hex);
273 throw DecompileFail("Unhandled instruction");
255 break; 274 break;
256 } 275 }
276 }
277 break;
278 }
279 case OpCode::Type::Ffma: {
280 ASSERT_MSG(!instr.ffma.negate_b, "untested");
281 ASSERT_MSG(!instr.ffma.negate_c, "untested");
282
283 std::string dest = GetRegister(instr.gpr0);
284 std::string op_a = GetRegister(instr.gpr8);
285
286 std::string op_b = instr.ffma.negate_b ? "-" : "";
287 op_b += GetUniform(instr.uniform);
288
289 std::string op_c = instr.ffma.negate_c ? "-" : "";
290 op_c += GetRegister(instr.gpr39);
291
292 switch (instr.opcode.EffectiveOpCode()) {
257 case OpCode::Id::FFMA_CR: { 293 case OpCode::Id::FFMA_CR: {
258 SetDest(0, gpr1, gpr2 + " * " + uniform + " + " + GetRegister(instr.gpr3), 1, 1); 294 SetDest(0, dest, op_a + " * " + op_b + " + " + op_c, 1, 1);
259 break; 295 break;
260 } 296 }
297
261 default: { 298 default: {
262 LOG_ERROR(HW_GPU, "Unhandled arithmetic instruction: 0x%02x (%s): 0x%08x", 299 LOG_ERROR(HW_GPU, "Unhandled arithmetic FFMA instruction: 0x%02x (%s): 0x%08x",
263 (int)instr.opcode.EffectiveOpCode(), OpCode::GetInfo(instr.opcode).name, 300 (int)instr.opcode.EffectiveOpCode(), OpCode::GetInfo(instr.opcode).name,
264 instr.hex); 301 instr.hex);
265 throw DecompileFail("Unhandled instruction"); 302 throw DecompileFail("Unhandled instruction");
@@ -269,18 +306,18 @@ private:
269 break; 306 break;
270 } 307 }
271 case OpCode::Type::Memory: { 308 case OpCode::Type::Memory: {
272 ASSERT(instr.attribute.size == 0); 309 std::string gpr0 = GetRegister(instr.gpr0);
273 310 const Attribute::Index attribute = instr.attribute.fmt20.index;
274 std::string gpr1 = GetRegister(instr.gpr1);
275 const Attribute::Index attribute = instr.attribute.GetIndex();
276 311
277 switch (instr.opcode.EffectiveOpCode()) { 312 switch (instr.opcode.EffectiveOpCode()) {
278 case OpCode::Id::LD_A: { 313 case OpCode::Id::LD_A: {
279 SetDest(instr.attribute.element, gpr1, GetInputAttribute(attribute), 1, 4); 314 ASSERT(instr.attribute.fmt20.size == 0);
315 SetDest(instr.attribute.fmt20.element, gpr0, GetInputAttribute(attribute), 1, 4);
280 break; 316 break;
281 } 317 }
282 case OpCode::Id::ST_A: { 318 case OpCode::Id::ST_A: {
283 SetDest(instr.attribute.element, GetOutputAttribute(attribute), gpr1, 4, 1); 319 ASSERT(instr.attribute.fmt20.size == 0);
320 SetDest(instr.attribute.fmt20.element, GetOutputAttribute(attribute), gpr0, 4, 1);
284 break; 321 break;
285 } 322 }
286 default: { 323 default: {