ShaderHeader.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. using System;
  2. namespace Ryujinx.Graphics.Gal.Shader
  3. {
  4. struct OmapTarget
  5. {
  6. public bool Red;
  7. public bool Green;
  8. public bool Blue;
  9. public bool Alpha;
  10. public bool Enabled => Red || Green || Blue || Alpha;
  11. public bool ComponentEnabled(int Component)
  12. {
  13. switch (Component)
  14. {
  15. case 0: return Red;
  16. case 1: return Green;
  17. case 2: return Blue;
  18. case 3: return Alpha;
  19. }
  20. throw new ArgumentException(nameof(Component));
  21. }
  22. }
  23. class ShaderHeader
  24. {
  25. public const int PointList = 1;
  26. public const int LineStrip = 6;
  27. public const int TriangleStrip = 7;
  28. public int SphType { get; private set; }
  29. public int Version { get; private set; }
  30. public int ShaderType { get; private set; }
  31. public bool MrtEnable { get; private set; }
  32. public bool KillsPixels { get; private set; }
  33. public bool DoesGlobalStore { get; private set; }
  34. public int SassVersion { get; private set; }
  35. public bool DoesLoadOrStore { get; private set; }
  36. public bool DoesFp64 { get; private set; }
  37. public int StreamOutMask { get; private set; }
  38. public int ShaderLocalMemoryLowSize { get; private set; }
  39. public int PerPatchAttributeCount { get; private set; }
  40. public int ShaderLocalMemoryHighSize { get; private set; }
  41. public int ThreadsPerInputPrimitive { get; private set; }
  42. public int ShaderLocalMemoryCrsSize { get; private set; }
  43. public int OutputTopology { get; private set; }
  44. public int MaxOutputVertexCount { get; private set; }
  45. public int StoreReqStart { get; private set; }
  46. public int StoreReqEnd { get; private set; }
  47. public OmapTarget[] OmapTargets { get; private set; }
  48. public bool OmapSampleMask { get; private set; }
  49. public bool OmapDepth { get; private set; }
  50. public ShaderHeader(IGalMemory Memory, long Position)
  51. {
  52. uint CommonWord0 = (uint)Memory.ReadInt32(Position + 0);
  53. uint CommonWord1 = (uint)Memory.ReadInt32(Position + 4);
  54. uint CommonWord2 = (uint)Memory.ReadInt32(Position + 8);
  55. uint CommonWord3 = (uint)Memory.ReadInt32(Position + 12);
  56. uint CommonWord4 = (uint)Memory.ReadInt32(Position + 16);
  57. SphType = ReadBits(CommonWord0, 0, 5);
  58. Version = ReadBits(CommonWord0, 5, 5);
  59. ShaderType = ReadBits(CommonWord0, 10, 4);
  60. MrtEnable = ReadBits(CommonWord0, 14, 1) != 0;
  61. KillsPixels = ReadBits(CommonWord0, 15, 1) != 0;
  62. DoesGlobalStore = ReadBits(CommonWord0, 16, 1) != 0;
  63. SassVersion = ReadBits(CommonWord0, 17, 4);
  64. DoesLoadOrStore = ReadBits(CommonWord0, 26, 1) != 0;
  65. DoesFp64 = ReadBits(CommonWord0, 27, 1) != 0;
  66. StreamOutMask = ReadBits(CommonWord0, 28, 4);
  67. ShaderLocalMemoryLowSize = ReadBits(CommonWord1, 0, 24);
  68. PerPatchAttributeCount = ReadBits(CommonWord1, 24, 8);
  69. ShaderLocalMemoryHighSize = ReadBits(CommonWord2, 0, 24);
  70. ThreadsPerInputPrimitive = ReadBits(CommonWord2, 24, 8);
  71. ShaderLocalMemoryCrsSize = ReadBits(CommonWord3, 0, 24);
  72. OutputTopology = ReadBits(CommonWord3, 24, 4);
  73. MaxOutputVertexCount = ReadBits(CommonWord4, 0, 12);
  74. StoreReqStart = ReadBits(CommonWord4, 12, 8);
  75. StoreReqEnd = ReadBits(CommonWord4, 24, 8);
  76. //Type 2 (fragment?) reading
  77. uint Type2OmapTarget = (uint)Memory.ReadInt32(Position + 72);
  78. uint Type2Omap = (uint)Memory.ReadInt32(Position + 76);
  79. OmapTargets = new OmapTarget[8];
  80. for (int i = 0; i < OmapTargets.Length; i++)
  81. {
  82. int Offset = i * 4;
  83. OmapTargets[i] = new OmapTarget
  84. {
  85. Red = ReadBits(Type2OmapTarget, Offset + 0, 1) != 0,
  86. Green = ReadBits(Type2OmapTarget, Offset + 1, 1) != 0,
  87. Blue = ReadBits(Type2OmapTarget, Offset + 2, 1) != 0,
  88. Alpha = ReadBits(Type2OmapTarget, Offset + 3, 1) != 0
  89. };
  90. }
  91. OmapSampleMask = ReadBits(Type2Omap, 0, 1) != 0;
  92. OmapDepth = ReadBits(Type2Omap, 1, 1) != 0;
  93. }
  94. public int DepthRegister
  95. {
  96. get
  97. {
  98. int Count = 0;
  99. for (int Index = 0; Index < OmapTargets.Length; Index++)
  100. {
  101. for (int Component = 0; Component < 4; Component++)
  102. {
  103. if (OmapTargets[Index].ComponentEnabled(Component))
  104. {
  105. Count++;
  106. }
  107. }
  108. }
  109. // Depth register is always two registers after the last color output
  110. return Count + 1;
  111. }
  112. }
  113. private static int ReadBits(uint Word, int Offset, int BitWidth)
  114. {
  115. uint Mask = (1u << BitWidth) - 1u;
  116. return (int)((Word >> Offset) & Mask);
  117. }
  118. }
  119. }