SupportBufferUpdater.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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. }
  19. private void MarkDirty(int startOffset, int byteSize)
  20. {
  21. int endOffset = startOffset + byteSize;
  22. if (_startOffset == -1)
  23. {
  24. _startOffset = startOffset;
  25. _endOffset = endOffset;
  26. }
  27. else
  28. {
  29. if (startOffset < _startOffset)
  30. {
  31. _startOffset = startOffset;
  32. }
  33. if (endOffset > _endOffset)
  34. {
  35. _endOffset = endOffset;
  36. }
  37. }
  38. }
  39. public void UpdateFragmentRenderScaleCount(int count)
  40. {
  41. if (Data.FragmentRenderScaleCount.X != count)
  42. {
  43. Data.FragmentRenderScaleCount.X = count;
  44. MarkDirty(SupportBuffer.FragmentRenderScaleCountOffset, sizeof(int));
  45. }
  46. }
  47. private void UpdateGenericField<T>(int baseOffset, ReadOnlySpan<T> data, Span<T> target, int offset, int count) where T : unmanaged
  48. {
  49. data.Slice(0, count).CopyTo(target.Slice(offset));
  50. int elemSize = Unsafe.SizeOf<T>();
  51. MarkDirty(baseOffset + offset * elemSize, count * elemSize);
  52. }
  53. public void UpdateRenderScale(ReadOnlySpan<Vector4<float>> data, int offset, int count)
  54. {
  55. UpdateGenericField(SupportBuffer.GraphicsRenderScaleOffset, data, Data.RenderScale.ToSpan(), offset, count);
  56. }
  57. public void UpdateFragmentIsBgra(ReadOnlySpan<Vector4<int>> data, int offset, int count)
  58. {
  59. UpdateGenericField(SupportBuffer.FragmentIsBgraOffset, data, Data.FragmentIsBgra.ToSpan(), offset, count);
  60. }
  61. public void Commit()
  62. {
  63. if (_startOffset != -1)
  64. {
  65. ReadOnlySpan<byte> data = MemoryMarshal.Cast<SupportBuffer, byte>(MemoryMarshal.CreateSpan(ref Data, 1));
  66. _renderer.SetBufferData(Handle, _startOffset, data.Slice(_startOffset, _endOffset - _startOffset));
  67. _startOffset = -1;
  68. _endOffset = -1;
  69. }
  70. }
  71. public void Dispose()
  72. {
  73. _renderer.DeleteBuffer(Handle);
  74. }
  75. }
  76. }