summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar FernandoS272018-09-17 18:16:06 -0400
committerGravatar FernandoS272018-09-17 20:50:54 -0400
commit567a5524b9b5d77153f580bf1b548430d368e2f2 (patch)
treed5b086a4242e8cdd79e54de52256be64af524fe4 /src
parentImplemented I2I.CC on the NEU control code, used by SMO (diff)
downloadyuzu-567a5524b9b5d77153f580bf1b548430d368e2f2.tar.gz
yuzu-567a5524b9b5d77153f580bf1b548430d368e2f2.tar.xz
yuzu-567a5524b9b5d77153f580bf1b548430d368e2f2.zip
Implemented Internal Flags
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp48
1 files changed, 35 insertions, 13 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 2f1d6de3c..f5425c31e 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -235,6 +235,14 @@ private:
235 const std::string& suffix; 235 const std::string& suffix;
236}; 236};
237 237
238enum class InternalFlag : u64 {
239 ZeroFlag = 0,
240 CarryFlag = 1,
241 OverflowFlag = 2,
242 NaNFlag = 3,
243 Amount
244};
245
238/** 246/**
239 * Used to manage shader registers that are emulated with GLSL. This class keeps track of the state 247 * Used to manage shader registers that are emulated with GLSL. This class keeps track of the state
240 * of all registers (e.g. whether they are currently being used as Floats or Integers), and 248 * of all registers (e.g. whether they are currently being used as Floats or Integers), and
@@ -328,13 +336,19 @@ public:
328 void SetRegisterToInteger(const Register& reg, bool is_signed, u64 elem, 336 void SetRegisterToInteger(const Register& reg, bool is_signed, u64 elem,
329 const std::string& value, u64 dest_num_components, 337 const std::string& value, u64 dest_num_components,
330 u64 value_num_components, bool is_saturated = false, 338 u64 value_num_components, bool is_saturated = false,
331 u64 dest_elem = 0, Register::Size size = Register::Size::Word) { 339 u64 dest_elem = 0, Register::Size size = Register::Size::Word,
340 bool sets_cc = false) {
332 ASSERT_MSG(!is_saturated, "Unimplemented"); 341 ASSERT_MSG(!is_saturated, "Unimplemented");
333 342
334 const std::string func{is_signed ? "intBitsToFloat" : "uintBitsToFloat"}; 343 const std::string func{is_signed ? "intBitsToFloat" : "uintBitsToFloat"};
335 344
336 SetRegister(reg, elem, func + '(' + ConvertIntegerSize(value, size) + ')', 345 SetRegister(reg, elem, func + '(' + ConvertIntegerSize(value, size) + ')',
337 dest_num_components, value_num_components, dest_elem); 346 dest_num_components, value_num_components, dest_elem);
347
348 if (sets_cc) {
349 const std::string zero_condition = "( " + ConvertIntegerSize(value, size) + " == 0 )";
350 SetInternalFlag(InternalFlag::ZeroFlag, zero_condition);
351 }
338 } 352 }
339 353
340 /** 354 /**
@@ -352,12 +366,23 @@ public:
352 } 366 }
353 367
354 std::string GetControlCode(const Tegra::Shader::ControlCode cc) const { 368 std::string GetControlCode(const Tegra::Shader::ControlCode cc) const {
355 const u32 code = static_cast<u32>(cc); 369 switch (cc) {
356 return "controlCode_" + std::to_string(code) + suffix; 370 case Tegra::Shader::ControlCode::NEU:
371 return "!(" + GetInternalFlag(InternalFlag::ZeroFlag) + ')';
372 default:
373 LOG_CRITICAL(HW_GPU, "Unimplemented Control Code {}", static_cast<u32>(cc));
374 UNREACHABLE();
375 return "false";
376 }
357 } 377 }
358 378
359 void SetControlCode(const Tegra::Shader::ControlCode cc, const std::string& value) const { 379 std::string GetInternalFlag(const InternalFlag ii) const {
360 shader.AddLine(GetControlCode(cc) + " = " + value + ';'); 380 const u32 code = static_cast<u32>(ii);
381 return "internalFlag_" + std::to_string(code) + suffix;
382 }
383
384 void SetInternalFlag(const InternalFlag ii, const std::string& value) const {
385 shader.AddLine(GetInternalFlag(ii) + " = " + value + ';');
361 } 386 }
362 387
363 /** 388 /**
@@ -423,9 +448,9 @@ public:
423 } 448 }
424 declarations.AddNewLine(); 449 declarations.AddNewLine();
425 450
426 for (u32 cc = 0; cc < 32; cc++) { 451 for (u32 ii = 0; ii < static_cast<u64>(InternalFlag::Amount); ii++) {
427 const Tegra::Shader::ControlCode code = static_cast<Tegra::Shader::ControlCode>(cc); 452 const InternalFlag code = static_cast<InternalFlag>(ii);
428 declarations.AddLine("bool " + GetControlCode(code) + " = false;"); 453 declarations.AddLine("bool " + GetInternalFlag(code) + " = false;");
429 } 454 }
430 declarations.AddNewLine(); 455 declarations.AddNewLine();
431 456
@@ -1655,11 +1680,8 @@ private:
1655 } 1680 }
1656 1681
1657 regs.SetRegisterToInteger(instr.gpr0, instr.conversion.is_output_signed, 0, op_a, 1, 1682 regs.SetRegisterToInteger(instr.gpr0, instr.conversion.is_output_signed, 0, op_a, 1,
1658 1, instr.alu.saturate_d, 0, instr.conversion.dest_size); 1683 1, instr.alu.saturate_d, 0, instr.conversion.dest_size,
1659 if (instr.generates_cc.Value() != 0) { 1684 instr.generates_cc.Value() != 0);
1660 const std::string neucondition = "( " + op_a + " != 0 )";
1661 regs.SetControlCode(Tegra::Shader::ControlCode::NEU, neucondition);
1662 }
1663 break; 1685 break;
1664 } 1686 }
1665 case OpCode::Id::I2F_R: 1687 case OpCode::Id::I2F_R: