FxaaPostProcessingEffect.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. using Ryujinx.Common;
  2. using Ryujinx.Graphics.GAL;
  3. using Ryujinx.Graphics.Shader;
  4. using Ryujinx.Graphics.Shader.Translation;
  5. using Silk.NET.Vulkan;
  6. using System;
  7. namespace Ryujinx.Graphics.Vulkan.Effects
  8. {
  9. internal partial class FxaaPostProcessingEffect : IPostProcessingEffect
  10. {
  11. private readonly VulkanRenderer _renderer;
  12. private ISampler _samplerLinear;
  13. private ShaderCollection _shaderProgram;
  14. private PipelineHelperShader _pipeline;
  15. private TextureView _texture;
  16. public FxaaPostProcessingEffect(VulkanRenderer renderer, Device device)
  17. {
  18. _renderer = renderer;
  19. _pipeline = new PipelineHelperShader(renderer, device);
  20. Initialize();
  21. }
  22. public void Dispose()
  23. {
  24. _shaderProgram.Dispose();
  25. _pipeline.Dispose();
  26. _samplerLinear.Dispose();
  27. _texture?.Dispose();
  28. }
  29. private void Initialize()
  30. {
  31. _pipeline.Initialize();
  32. var shader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/Fxaa.spv");
  33. var computeBindings = new ShaderBindings(
  34. new[] { 2 },
  35. Array.Empty<int>(),
  36. new[] { 1 },
  37. new[] { 0 });
  38. _samplerLinear = _renderer.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
  39. _shaderProgram = _renderer.CreateProgramWithMinimalLayout(new[]
  40. {
  41. new ShaderSource(shader, computeBindings, ShaderStage.Compute, TargetLanguage.Spirv)
  42. });
  43. }
  44. public TextureView Run(TextureView view, CommandBufferScoped cbs, int width, int height)
  45. {
  46. if (_texture == null || _texture.Width != view.Width || _texture.Height != view.Height)
  47. {
  48. _texture?.Dispose();
  49. var info = view.Info;
  50. if (view.Info.Format.IsBgr())
  51. {
  52. info = new TextureCreateInfo(info.Width,
  53. info.Height,
  54. info.Depth,
  55. info.Levels,
  56. info.Samples,
  57. info.BlockWidth,
  58. info.BlockHeight,
  59. info.BytesPerPixel,
  60. info.Format,
  61. info.DepthStencilMode,
  62. info.Target,
  63. info.SwizzleB,
  64. info.SwizzleG,
  65. info.SwizzleR,
  66. info.SwizzleA);
  67. }
  68. _texture = _renderer.CreateTexture(info, view.ScaleFactor) as TextureView;
  69. }
  70. _pipeline.SetCommandBuffer(cbs);
  71. _pipeline.SetProgram(_shaderProgram);
  72. _pipeline.SetTextureAndSampler(ShaderStage.Compute, 1, view, _samplerLinear);
  73. ReadOnlySpan<float> resolutionBuffer = stackalloc float[] { view.Width, view.Height };
  74. int rangeSize = resolutionBuffer.Length * sizeof(float);
  75. var bufferHandle = _renderer.BufferManager.CreateWithHandle(_renderer, rangeSize, false);
  76. _renderer.BufferManager.SetData(bufferHandle, 0, resolutionBuffer);
  77. var bufferRanges = new BufferRange(bufferHandle, 0, rangeSize);
  78. _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(2, bufferRanges) });
  79. Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
  80. viewports[0] = new GAL.Viewport(
  81. new Rectangle<float>(0, 0, view.Width, view.Height),
  82. ViewportSwizzle.PositiveX,
  83. ViewportSwizzle.PositiveY,
  84. ViewportSwizzle.PositiveZ,
  85. ViewportSwizzle.PositiveW,
  86. 0f,
  87. 1f);
  88. Span<Rectangle<int>> scissors = stackalloc Rectangle<int>[1];
  89. var dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize);
  90. var dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize);
  91. _pipeline.SetScissors(stackalloc[] { new Rectangle<int>(0, 0, view.Width, view.Height) });
  92. _pipeline.SetViewports(viewports, false);
  93. _pipeline.SetImage(0, _texture, GAL.Format.R8G8B8A8Unorm);
  94. _pipeline.DispatchCompute(dispatchX, dispatchY, 1);
  95. _renderer.BufferManager.Delete(bufferHandle);
  96. _pipeline.ComputeBarrier();
  97. _pipeline.Finish();
  98. return _texture;
  99. }
  100. }
  101. }