mirror of
https://github.com/GreemDev/Ryujinx
synced 2024-12-01 14:02:27 +01:00
9f1cf6458c
* Initial implementation of migration between memory heaps - Missing OOM handling - Missing `_map` data safety when remapping - Copy may not have completed yet (needs some kind of fence) - Map may be unmapped before it is done being used. (needs scoped access) - SSBO accesses are all "writes" - maybe pass info in another way. - Missing keeping map type when resizing buffers (should this be done?) * Ensure migrated data is in place before flushing. * Fix issue where old waitable would be signalled. - There is a real issue where existing Auto<> references need to be replaced. * Swap bound Auto<> instances when swapping buffer backing * Fix conversion buffers * Don't try move buffers if the host has shared memory. * Make GPU methods return PinnedSpan with scope * Storage Hint * Fix stupidity * Fix rebase * Tweak rules Attempt to sidestep BOTW slowdown * Remove line * Migrate only when command buffers flush * Change backing swap log to debug * Address some feedback * Disallow backing swap when the flush lock is held by the current thread * Make PinnedSpan from ReadOnlySpan explicitly unsafe * Fix some small issues - Index buffer swap fixed - Allocate DeviceLocal buffers using a separate block list to images. * Remove alternative flags * Address feedback
127 lines
No EOL
4.5 KiB
C#
127 lines
No EOL
4.5 KiB
C#
using Ryujinx.Common;
|
|
using Ryujinx.Graphics.GAL;
|
|
using Ryujinx.Graphics.Shader;
|
|
using Ryujinx.Graphics.Shader.Translation;
|
|
using Silk.NET.Vulkan;
|
|
using System;
|
|
|
|
namespace Ryujinx.Graphics.Vulkan.Effects
|
|
{
|
|
internal partial class FxaaPostProcessingEffect : IPostProcessingEffect
|
|
{
|
|
private readonly VulkanRenderer _renderer;
|
|
private ISampler _samplerLinear;
|
|
private ShaderCollection _shaderProgram;
|
|
|
|
private PipelineHelperShader _pipeline;
|
|
private TextureView _texture;
|
|
|
|
public FxaaPostProcessingEffect(VulkanRenderer renderer, Device device)
|
|
{
|
|
_renderer = renderer;
|
|
_pipeline = new PipelineHelperShader(renderer, device);
|
|
|
|
Initialize();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_shaderProgram.Dispose();
|
|
_pipeline.Dispose();
|
|
_samplerLinear.Dispose();
|
|
_texture?.Dispose();
|
|
}
|
|
|
|
private void Initialize()
|
|
{
|
|
_pipeline.Initialize();
|
|
|
|
var shader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/Fxaa.spv");
|
|
|
|
var computeBindings = new ShaderBindings(
|
|
new[] { 2 },
|
|
Array.Empty<int>(),
|
|
new[] { 1 },
|
|
new[] { 0 });
|
|
|
|
_samplerLinear = _renderer.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
|
|
|
_shaderProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
|
{
|
|
new ShaderSource(shader, computeBindings, ShaderStage.Compute, TargetLanguage.Spirv)
|
|
});
|
|
}
|
|
|
|
public TextureView Run(TextureView view, CommandBufferScoped cbs, int width, int height)
|
|
{
|
|
if (_texture == null || _texture.Width != view.Width || _texture.Height != view.Height)
|
|
{
|
|
_texture?.Dispose();
|
|
|
|
var info = view.Info;
|
|
|
|
if (view.Info.Format.IsBgr())
|
|
{
|
|
info = new TextureCreateInfo(info.Width,
|
|
info.Height,
|
|
info.Depth,
|
|
info.Levels,
|
|
info.Samples,
|
|
info.BlockWidth,
|
|
info.BlockHeight,
|
|
info.BytesPerPixel,
|
|
info.Format,
|
|
info.DepthStencilMode,
|
|
info.Target,
|
|
info.SwizzleB,
|
|
info.SwizzleG,
|
|
info.SwizzleR,
|
|
info.SwizzleA);
|
|
}
|
|
_texture = _renderer.CreateTexture(info, view.ScaleFactor) as TextureView;
|
|
}
|
|
|
|
_pipeline.SetCommandBuffer(cbs);
|
|
_pipeline.SetProgram(_shaderProgram);
|
|
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 1, view, _samplerLinear);
|
|
|
|
ReadOnlySpan<float> resolutionBuffer = stackalloc float[] { view.Width, view.Height };
|
|
int rangeSize = resolutionBuffer.Length * sizeof(float);
|
|
var bufferHandle = _renderer.BufferManager.CreateWithHandle(_renderer, rangeSize);
|
|
|
|
_renderer.BufferManager.SetData(bufferHandle, 0, resolutionBuffer);
|
|
|
|
var bufferRanges = new BufferRange(bufferHandle, 0, rangeSize);
|
|
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(2, bufferRanges) });
|
|
|
|
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
|
|
|
viewports[0] = new GAL.Viewport(
|
|
new Rectangle<float>(0, 0, view.Width, view.Height),
|
|
ViewportSwizzle.PositiveX,
|
|
ViewportSwizzle.PositiveY,
|
|
ViewportSwizzle.PositiveZ,
|
|
ViewportSwizzle.PositiveW,
|
|
0f,
|
|
1f);
|
|
|
|
Span<Rectangle<int>> scissors = stackalloc Rectangle<int>[1];
|
|
|
|
var dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize);
|
|
var dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize);
|
|
|
|
_pipeline.SetScissors(stackalloc[] { new Rectangle<int>(0, 0, view.Width, view.Height) });
|
|
_pipeline.SetViewports(viewports, false);
|
|
|
|
_pipeline.SetImage(0, _texture, GAL.Format.R8G8B8A8Unorm);
|
|
_pipeline.DispatchCompute(dispatchX, dispatchY, 1);
|
|
|
|
_renderer.BufferManager.Delete(bufferHandle);
|
|
_pipeline.ComputeBarrier();
|
|
|
|
_pipeline.Finish();
|
|
|
|
return _texture;
|
|
}
|
|
}
|
|
} |