SupportBufferUpdater.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. using Ryujinx.Graphics.Shader;
  2. using System;
  3. using System.Runtime.CompilerServices;
  4. using System.Runtime.InteropServices;
  5. namespace Ryujinx.Graphics.GAL
  6. {
  7. public class SupportBufferUpdater : IDisposable
  8. {
  9. public SupportBuffer Data;
  10. public BufferHandle Handle;
  11. private IRenderer _renderer;
  12. private int _startOffset = -1;
  13. private int _endOffset = -1;
  14. public SupportBufferUpdater(IRenderer renderer)
  15. {
  16. _renderer = renderer;
  17. Handle = renderer.CreateBuffer(SupportBuffer.RequiredSize);
  18. renderer.Pipeline.ClearBuffer(Handle, 0, SupportBuffer.RequiredSize, 0);
  19. }
  20. private void MarkDirty(int startOffset, int byteSize)
  21. {
  22. int endOffset = startOffset + byteSize;
  23. if (_startOffset == -1)
  24. {
  25. _startOffset = startOffset;
  26. _endOffset = endOffset;
  27. }
  28. else
  29. {
  30. if (startOffset < _startOffset)
  31. {
  32. _startOffset = startOffset;
  33. }
  34. if (endOffset > _endOffset)
  35. {
  36. _endOffset = endOffset;
  37. }
  38. }
  39. }
  40. public void UpdateFragmentRenderScaleCount(int count)
  41. {
  42. if (Data.FragmentRenderScaleCount.X != count)
  43. {
  44. Data.FragmentRenderScaleCount.X = count;
  45. MarkDirty(SupportBuffer.FragmentRenderScaleCountOffset, sizeof(int));
  46. }
  47. }
  48. private void UpdateGenericField<T>(int baseOffset, ReadOnlySpan<T> data, Span<T> target, int offset, int count) where T : unmanaged
  49. {
  50. data.Slice(0, count).CopyTo(target.Slice(offset));
  51. int elemSize = Unsafe.SizeOf<T>();
  52. MarkDirty(baseOffset + offset * elemSize, count * elemSize);
  53. }
  54. public void UpdateRenderScale(ReadOnlySpan<Vector4<float>> data, int offset, int count)
  55. {
  56. UpdateGenericField(SupportBuffer.GraphicsRenderScaleOffset, data, Data.RenderScale.AsSpan(), offset, count);
  57. }
  58. public void UpdateFragmentIsBgra(ReadOnlySpan<Vector4<int>> data, int offset, int count)
  59. {
  60. UpdateGenericField(SupportBuffer.FragmentIsBgraOffset, data, Data.FragmentIsBgra.AsSpan(), offset, count);
  61. }
  62. public void UpdateViewportInverse(Vector4<float> data)
  63. {
  64. Data.ViewportInverse = data;
  65. MarkDirty(SupportBuffer.ViewportInverseOffset, SupportBuffer.FieldSize);
  66. }
  67. public void Commit()
  68. {
  69. if (_startOffset != -1)
  70. {
  71. ReadOnlySpan<byte> data = MemoryMarshal.Cast<SupportBuffer, byte>(MemoryMarshal.CreateSpan(ref Data, 1));
  72. _renderer.SetBufferData(Handle, _startOffset, data.Slice(_startOffset, _endOffset - _startOffset));
  73. _startOffset = -1;
  74. _endOffset = -1;
  75. }
  76. }
  77. public void Dispose()
  78. {
  79. _renderer.DeleteBuffer(Handle);
  80. }
  81. }
  82. }