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. }