MethodConditionalRendering.cs 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using Ryujinx.Common.Logging;
  2. using Ryujinx.Graphics.Gpu.State;
  3. namespace Ryujinx.Graphics.Gpu.Engine
  4. {
  5. partial class Methods
  6. {
  7. /// <summary>
  8. /// Checks if draws and clears should be performed, according
  9. /// to currently set conditional rendering conditions.
  10. /// </summary>
  11. /// <param name="state">GPU state</param>
  12. /// <returns>True if rendering is enabled, false otherwise</returns>
  13. private bool GetRenderEnable(GpuState state)
  14. {
  15. ConditionState condState = state.Get<ConditionState>(MethodOffset.ConditionState);
  16. switch (condState.Condition)
  17. {
  18. case Condition.Always:
  19. return true;
  20. case Condition.Never:
  21. return false;
  22. case Condition.ResultNonZero:
  23. return CounterNonZero(condState.Address.Pack());
  24. case Condition.Equal:
  25. return CounterCompare(condState.Address.Pack(), true);
  26. case Condition.NotEqual:
  27. return CounterCompare(condState.Address.Pack(), false);
  28. }
  29. Logger.PrintWarning(LogClass.Gpu, $"Invalid conditional render condition \"{condState.Condition}\".");
  30. return true;
  31. }
  32. /// <summary>
  33. /// Checks if the counter value at a given GPU memory address is non-zero.
  34. /// </summary>
  35. /// <param name="gpuVa">GPU virtual address of the counter value</param>
  36. /// <returns>True if the value is not zero, false otherwise</returns>
  37. private bool CounterNonZero(ulong gpuVa)
  38. {
  39. if (!FindAndFlush(gpuVa))
  40. {
  41. return false;
  42. }
  43. return _context.MemoryAccessor.ReadUInt64(gpuVa) != 0;
  44. }
  45. /// <summary>
  46. /// Checks if the counter at a given GPU memory address passes a specified equality comparison.
  47. /// </summary>
  48. /// <param name="gpuVa">GPU virtual address</param>
  49. /// <param name="isEqual">True to check if the values are equal, false to check if they are not equal</param>
  50. /// <returns>True if the condition is met, false otherwise</returns>
  51. private bool CounterCompare(ulong gpuVa, bool isEqual)
  52. {
  53. if (!FindAndFlush(gpuVa) && !FindAndFlush(gpuVa + 16))
  54. {
  55. return false;
  56. }
  57. ulong x = _context.MemoryAccessor.ReadUInt64(gpuVa);
  58. ulong y = _context.MemoryAccessor.ReadUInt64(gpuVa + 16);
  59. return isEqual ? x == y : x != y;
  60. }
  61. /// <summary>
  62. /// Tries to find a counter that is supposed to be written at the specified address,
  63. /// flushing if necessary.
  64. /// </summary>
  65. /// <param name="gpuVa">GPU virtual address where the counter is supposed to be written</param>
  66. /// <returns>True if a counter value is found at the specified address, false otherwise</returns>
  67. private bool FindAndFlush(ulong gpuVa)
  68. {
  69. return _counterCache.Contains(gpuVa);
  70. }
  71. }
  72. }