diff options
| author | 2018-09-17 18:16:06 -0400 | |
|---|---|---|
| committer | 2018-09-17 20:50:54 -0400 | |
| commit | 567a5524b9b5d77153f580bf1b548430d368e2f2 (patch) | |
| tree | d5b086a4242e8cdd79e54de52256be64af524fe4 /src | |
| parent | Implemented I2I.CC on the NEU control code, used by SMO (diff) | |
| download | yuzu-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.cpp | 48 |
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 | ||
| 238 | enum 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: |