GeometryShaderManager.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Copyright 2014 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "VideoCommon/GeometryShaderManager.h"
  4. #include <cstring>
  5. #include "Common/ChunkFile.h"
  6. #include "Common/CommonTypes.h"
  7. #include "VideoCommon/BPMemory.h"
  8. #include "VideoCommon/RenderState.h"
  9. #include "VideoCommon/VideoConfig.h"
  10. #include "VideoCommon/XFMemory.h"
  11. static constexpr int LINE_PT_TEX_OFFSETS[8] = {0, 16, 8, 4, 2, 1, 1, 1};
  12. void GeometryShaderManager::Init()
  13. {
  14. constants = {};
  15. // Init any intial constants which aren't zero when bpmem is zero.
  16. SetViewportChanged();
  17. SetProjectionChanged();
  18. dirty = true;
  19. }
  20. void GeometryShaderManager::Dirty()
  21. {
  22. // This function is called after a savestate is loaded.
  23. // Any constants that can changed based on settings should be re-calculated
  24. m_projection_changed = true;
  25. // Uses EFB scale config
  26. SetLinePtWidthChanged();
  27. dirty = true;
  28. }
  29. void GeometryShaderManager::SetVSExpand(VSExpand expand)
  30. {
  31. if (constants.vs_expand != expand)
  32. {
  33. constants.vs_expand = expand;
  34. dirty = true;
  35. }
  36. }
  37. void GeometryShaderManager::SetConstants(PrimitiveType prim)
  38. {
  39. if (m_projection_changed && g_ActiveConfig.stereo_mode != StereoMode::Off)
  40. {
  41. m_projection_changed = false;
  42. if (xfmem.projection.type == ProjectionType::Perspective)
  43. {
  44. float offset = (g_ActiveConfig.iStereoDepth / 1000.0f) *
  45. (g_ActiveConfig.iStereoDepthPercentage / 100.0f);
  46. constants.stereoparams[0] = g_ActiveConfig.bStereoSwapEyes ? offset : -offset;
  47. constants.stereoparams[1] = g_ActiveConfig.bStereoSwapEyes ? -offset : offset;
  48. }
  49. else
  50. {
  51. constants.stereoparams[0] = constants.stereoparams[1] = 0;
  52. }
  53. constants.stereoparams[2] = (float)(g_ActiveConfig.iStereoConvergence *
  54. (g_ActiveConfig.iStereoConvergencePercentage / 100.0f));
  55. dirty = true;
  56. }
  57. if (g_ActiveConfig.UseVSForLinePointExpand())
  58. {
  59. if (prim == PrimitiveType::Points)
  60. SetVSExpand(VSExpand::Point);
  61. else if (prim == PrimitiveType::Lines)
  62. SetVSExpand(VSExpand::Line);
  63. else
  64. SetVSExpand(VSExpand::None);
  65. }
  66. if (m_viewport_changed)
  67. {
  68. m_viewport_changed = false;
  69. constants.lineptparams[0] = 2.0f * xfmem.viewport.wd;
  70. constants.lineptparams[1] = -2.0f * xfmem.viewport.ht;
  71. dirty = true;
  72. }
  73. }
  74. void GeometryShaderManager::SetViewportChanged()
  75. {
  76. m_viewport_changed = true;
  77. }
  78. void GeometryShaderManager::SetProjectionChanged()
  79. {
  80. m_projection_changed = true;
  81. }
  82. void GeometryShaderManager::SetLinePtWidthChanged()
  83. {
  84. constants.lineptparams[2] = bpmem.lineptwidth.linesize / 6.f;
  85. constants.lineptparams[3] = bpmem.lineptwidth.pointsize / 6.f;
  86. constants.texoffset[2] = LINE_PT_TEX_OFFSETS[bpmem.lineptwidth.lineoff];
  87. constants.texoffset[3] = LINE_PT_TEX_OFFSETS[bpmem.lineptwidth.pointoff];
  88. dirty = true;
  89. }
  90. void GeometryShaderManager::SetTexCoordChanged(u8 texmapid)
  91. {
  92. TCoordInfo& tc = bpmem.texcoords[texmapid];
  93. int bitmask = 1 << texmapid;
  94. constants.texoffset[0] &= ~bitmask;
  95. constants.texoffset[0] |= tc.s.line_offset << texmapid;
  96. constants.texoffset[1] &= ~bitmask;
  97. constants.texoffset[1] |= tc.s.point_offset << texmapid;
  98. dirty = true;
  99. }
  100. void GeometryShaderManager::DoState(PointerWrap& p)
  101. {
  102. p.Do(m_projection_changed);
  103. p.Do(m_viewport_changed);
  104. p.Do(constants);
  105. if (p.IsReadMode())
  106. {
  107. // Fixup the current state from global GPU state
  108. // NOTE: This requires that all GPU memory has been loaded already.
  109. Dirty();
  110. }
  111. }