Move solution and projects to src
This commit is contained in:
parent
cd124bda58
commit
cee7121058
3466 changed files with 55 additions and 55 deletions
179
src/Ryujinx.Graphics.Vulkan/Effects/FsrScalingFilter.cs
Normal file
179
src/Ryujinx.Graphics.Vulkan/Effects/FsrScalingFilter.cs
Normal file
|
@ -0,0 +1,179 @@
|
|||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using Extent2D = Ryujinx.Graphics.GAL.Extents2D;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
{
|
||||
internal partial class FsrScalingFilter : IScalingFilter
|
||||
{
|
||||
private readonly VulkanRenderer _renderer;
|
||||
private PipelineHelperShader _pipeline;
|
||||
private ISampler _sampler;
|
||||
private ShaderCollection _scalingProgram;
|
||||
private ShaderCollection _sharpeningProgram;
|
||||
private float _sharpeningLevel = 1;
|
||||
private Device _device;
|
||||
private TextureView _intermediaryTexture;
|
||||
|
||||
public float Level
|
||||
{
|
||||
get => _sharpeningLevel;
|
||||
set
|
||||
{
|
||||
_sharpeningLevel = MathF.Max(0.01f, value);
|
||||
}
|
||||
}
|
||||
|
||||
public FsrScalingFilter(VulkanRenderer renderer, Device device)
|
||||
{
|
||||
_device = device;
|
||||
_renderer = renderer;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_pipeline.Dispose();
|
||||
_scalingProgram.Dispose();
|
||||
_sharpeningProgram.Dispose();
|
||||
_sampler.Dispose();
|
||||
_intermediaryTexture?.Dispose();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
_pipeline = new PipelineHelperShader(_renderer, _device);
|
||||
|
||||
_pipeline.Initialize();
|
||||
|
||||
var scalingShader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/FsrScaling.spv");
|
||||
var sharpeningShader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/FsrSharpening.spv");
|
||||
|
||||
var computeBindings = new ShaderBindings(
|
||||
new[] { 2 },
|
||||
Array.Empty<int>(),
|
||||
new[] { 1 },
|
||||
new[] { 0 });
|
||||
|
||||
var sharpeningBindings = new ShaderBindings(
|
||||
new[] { 2, 3, 4 },
|
||||
Array.Empty<int>(),
|
||||
new[] { 1 },
|
||||
new[] { 0 });
|
||||
|
||||
_sampler = _renderer.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
||||
|
||||
_scalingProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||
{
|
||||
new ShaderSource(scalingShader, computeBindings, ShaderStage.Compute, TargetLanguage.Spirv)
|
||||
});
|
||||
|
||||
_sharpeningProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||
{
|
||||
new ShaderSource(sharpeningShader, sharpeningBindings, ShaderStage.Compute, TargetLanguage.Spirv)
|
||||
});
|
||||
}
|
||||
|
||||
public void Run(
|
||||
TextureView view,
|
||||
CommandBufferScoped cbs,
|
||||
Auto<DisposableImageView> destinationTexture,
|
||||
Silk.NET.Vulkan.Format format,
|
||||
int width,
|
||||
int height,
|
||||
Extent2D source,
|
||||
Extent2D destination)
|
||||
{
|
||||
if (_intermediaryTexture == null
|
||||
|| _intermediaryTexture.Info.Width != width
|
||||
|| _intermediaryTexture.Info.Height != height
|
||||
|| !_intermediaryTexture.Info.Equals(view.Info))
|
||||
{
|
||||
var originalInfo = view.Info;
|
||||
|
||||
var swapRB = originalInfo.Format.IsBgr() && originalInfo.SwizzleR == SwizzleComponent.Red;
|
||||
|
||||
var info = new TextureCreateInfo(
|
||||
width,
|
||||
height,
|
||||
originalInfo.Depth,
|
||||
originalInfo.Levels,
|
||||
originalInfo.Samples,
|
||||
originalInfo.BlockWidth,
|
||||
originalInfo.BlockHeight,
|
||||
originalInfo.BytesPerPixel,
|
||||
originalInfo.Format,
|
||||
originalInfo.DepthStencilMode,
|
||||
originalInfo.Target,
|
||||
swapRB ? originalInfo.SwizzleB : originalInfo.SwizzleR,
|
||||
originalInfo.SwizzleG,
|
||||
swapRB ? originalInfo.SwizzleR : originalInfo.SwizzleB,
|
||||
originalInfo.SwizzleA);
|
||||
_intermediaryTexture?.Dispose();
|
||||
_intermediaryTexture = _renderer.CreateTexture(info, view.ScaleFactor) as TextureView;
|
||||
}
|
||||
|
||||
_pipeline.SetCommandBuffer(cbs);
|
||||
_pipeline.SetProgram(_scalingProgram);
|
||||
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 1, view, _sampler);
|
||||
|
||||
float srcWidth = Math.Abs(source.X2 - source.X1);
|
||||
float srcHeight = Math.Abs(source.Y2 - source.Y1);
|
||||
float scaleX = srcWidth / view.Width;
|
||||
float scaleY = srcHeight / view.Height;
|
||||
|
||||
ReadOnlySpan<float> dimensionsBuffer = stackalloc float[]
|
||||
{
|
||||
source.X1,
|
||||
source.X2,
|
||||
source.Y1,
|
||||
source.Y2,
|
||||
destination.X1,
|
||||
destination.X2,
|
||||
destination.Y1,
|
||||
destination.Y2,
|
||||
scaleX,
|
||||
scaleY
|
||||
};
|
||||
|
||||
int rangeSize = dimensionsBuffer.Length * sizeof(float);
|
||||
var bufferHandle = _renderer.BufferManager.CreateWithHandle(_renderer, rangeSize);
|
||||
_renderer.BufferManager.SetData(bufferHandle, 0, dimensionsBuffer);
|
||||
|
||||
ReadOnlySpan<float> sharpeningBuffer = stackalloc float[] { 1.5f - (Level * 0.01f * 1.5f)};
|
||||
var sharpeningBufferHandle = _renderer.BufferManager.CreateWithHandle(_renderer, sizeof(float));
|
||||
_renderer.BufferManager.SetData(sharpeningBufferHandle, 0, sharpeningBuffer);
|
||||
|
||||
int threadGroupWorkRegionDim = 16;
|
||||
int dispatchX = (width + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim;
|
||||
int dispatchY = (height + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim;
|
||||
|
||||
var bufferRanges = new BufferRange(bufferHandle, 0, rangeSize);
|
||||
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(2, bufferRanges) });
|
||||
_pipeline.SetImage(0, _intermediaryTexture, GAL.Format.R8G8B8A8Unorm);
|
||||
_pipeline.DispatchCompute(dispatchX, dispatchY, 1);
|
||||
_pipeline.ComputeBarrier();
|
||||
|
||||
// Sharpening pass
|
||||
_pipeline.SetCommandBuffer(cbs);
|
||||
_pipeline.SetProgram(_sharpeningProgram);
|
||||
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 1, _intermediaryTexture, _sampler);
|
||||
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(2, bufferRanges) });
|
||||
var sharpeningRange = new BufferRange(sharpeningBufferHandle, 0, sizeof(float));
|
||||
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(4, sharpeningRange) });
|
||||
_pipeline.SetImage(0, destinationTexture);
|
||||
_pipeline.DispatchCompute(dispatchX, dispatchY, 1);
|
||||
_pipeline.ComputeBarrier();
|
||||
|
||||
_pipeline.Finish();
|
||||
|
||||
_renderer.BufferManager.Delete(bufferHandle);
|
||||
_renderer.BufferManager.Delete(sharpeningBufferHandle);
|
||||
}
|
||||
}
|
||||
}
|
111
src/Ryujinx.Graphics.Vulkan/Effects/FxaaPostProcessingEffect.cs
Normal file
111
src/Ryujinx.Graphics.Vulkan/Effects/FxaaPostProcessingEffect.cs
Normal file
|
@ -0,0 +1,111 @@
|
|||
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) });
|
||||
|
||||
var dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize);
|
||||
var dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize);
|
||||
|
||||
_pipeline.SetImage(0, _texture, GAL.Format.R8G8B8A8Unorm);
|
||||
_pipeline.DispatchCompute(dispatchX, dispatchY, 1);
|
||||
|
||||
_renderer.BufferManager.Delete(bufferHandle);
|
||||
_pipeline.ComputeBarrier();
|
||||
|
||||
_pipeline.Finish();
|
||||
|
||||
return _texture;
|
||||
}
|
||||
}
|
||||
}
|
10
src/Ryujinx.Graphics.Vulkan/Effects/IPostProcessingEffect.cs
Normal file
10
src/Ryujinx.Graphics.Vulkan/Effects/IPostProcessingEffect.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
{
|
||||
internal interface IPostProcessingEffect : IDisposable
|
||||
{
|
||||
const int LocalGroupSize = 64;
|
||||
TextureView Run(TextureView view, CommandBufferScoped cbs, int width, int height);
|
||||
}
|
||||
}
|
20
src/Ryujinx.Graphics.Vulkan/Effects/IScalingFilter.cs
Normal file
20
src/Ryujinx.Graphics.Vulkan/Effects/IScalingFilter.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using Extent2D = Ryujinx.Graphics.GAL.Extents2D;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
{
|
||||
internal interface IScalingFilter : IDisposable
|
||||
{
|
||||
float Level { get; set; }
|
||||
void Run(
|
||||
TextureView view,
|
||||
CommandBufferScoped cbs,
|
||||
Auto<DisposableImageView> destinationTexture,
|
||||
Format format,
|
||||
int width,
|
||||
int height,
|
||||
Extent2D source,
|
||||
Extent2D destination);
|
||||
}
|
||||
}
|
3945
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/FsrScaling.glsl
Normal file
3945
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/FsrScaling.glsl
Normal file
File diff suppressed because it is too large
Load diff
BIN
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/FsrScaling.spv
Normal file
BIN
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/FsrScaling.spv
Normal file
Binary file not shown.
3904
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/FsrSharpening.glsl
Normal file
3904
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/FsrSharpening.glsl
Normal file
File diff suppressed because it is too large
Load diff
BIN
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/FsrSharpening.spv
Normal file
BIN
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/FsrSharpening.spv
Normal file
Binary file not shown.
1177
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/Fxaa.glsl
Normal file
1177
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/Fxaa.glsl
Normal file
File diff suppressed because it is too large
Load diff
BIN
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/Fxaa.spv
Normal file
BIN
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/Fxaa.spv
Normal file
Binary file not shown.
1404
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaBlend.glsl
Normal file
1404
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaBlend.glsl
Normal file
File diff suppressed because it is too large
Load diff
BIN
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaBlend.spv
Normal file
BIN
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaBlend.spv
Normal file
Binary file not shown.
1402
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaEdge.glsl
Normal file
1402
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaEdge.glsl
Normal file
File diff suppressed because it is too large
Load diff
BIN
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaEdge.spv
Normal file
BIN
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaEdge.spv
Normal file
Binary file not shown.
1403
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaNeighbour.glsl
Normal file
1403
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaNeighbour.glsl
Normal file
File diff suppressed because it is too large
Load diff
BIN
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaNeighbour.spv
Normal file
BIN
src/Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaNeighbour.spv
Normal file
Binary file not shown.
15
src/Ryujinx.Graphics.Vulkan/Effects/SmaaConstants.cs
Normal file
15
src/Ryujinx.Graphics.Vulkan/Effects/SmaaConstants.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
internal struct SmaaConstants
|
||||
{
|
||||
public int QualityLow;
|
||||
public int QualityMedium;
|
||||
public int QualityHigh;
|
||||
public int QualityUltra;
|
||||
public float Width;
|
||||
public float Height;
|
||||
}
|
||||
}
|
289
src/Ryujinx.Graphics.Vulkan/Effects/SmaaPostProcessingEffect.cs
Normal file
289
src/Ryujinx.Graphics.Vulkan/Effects/SmaaPostProcessingEffect.cs
Normal file
|
@ -0,0 +1,289 @@
|
|||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using Format = Ryujinx.Graphics.GAL.Format;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
{
|
||||
internal partial class SmaaPostProcessingEffect : IPostProcessingEffect
|
||||
{
|
||||
public const int AreaWidth = 160;
|
||||
public const int AreaHeight = 560;
|
||||
public const int SearchWidth = 64;
|
||||
public const int SearchHeight = 16;
|
||||
|
||||
private readonly VulkanRenderer _renderer;
|
||||
private ISampler _samplerLinear;
|
||||
private SmaaConstants _specConstants;
|
||||
private ShaderCollection _edgeProgram;
|
||||
private ShaderCollection _blendProgram;
|
||||
private ShaderCollection _neighbourProgram;
|
||||
|
||||
private PipelineHelperShader _pipeline;
|
||||
|
||||
private TextureView _outputTexture;
|
||||
private TextureView _edgeOutputTexture;
|
||||
private TextureView _blendOutputTexture;
|
||||
private TextureView _areaTexture;
|
||||
private TextureView _searchTexture;
|
||||
private Device _device;
|
||||
private bool _recreatePipelines;
|
||||
private int _quality;
|
||||
|
||||
public SmaaPostProcessingEffect(VulkanRenderer renderer, Device device, int quality)
|
||||
{
|
||||
_device = device;
|
||||
_renderer = renderer;
|
||||
_quality = quality;
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public int Quality
|
||||
{
|
||||
get => _quality;
|
||||
set
|
||||
{
|
||||
_quality = value;
|
||||
|
||||
_recreatePipelines = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
DeletePipelines();
|
||||
_samplerLinear?.Dispose();
|
||||
_outputTexture?.Dispose();
|
||||
_edgeOutputTexture?.Dispose();
|
||||
_blendOutputTexture?.Dispose();
|
||||
_areaTexture?.Dispose();
|
||||
_searchTexture?.Dispose();
|
||||
}
|
||||
|
||||
private unsafe void RecreateShaders(int width, int height)
|
||||
{
|
||||
_recreatePipelines = false;
|
||||
|
||||
DeletePipelines();
|
||||
_pipeline = new PipelineHelperShader(_renderer, _device);
|
||||
|
||||
_pipeline.Initialize();
|
||||
|
||||
var edgeShader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaEdge.spv");
|
||||
var blendShader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaBlend.spv");
|
||||
var neighbourShader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaNeighbour.spv");
|
||||
|
||||
var edgeBindings = new ShaderBindings(
|
||||
new[] { 2 },
|
||||
Array.Empty<int>(),
|
||||
new[] { 1 },
|
||||
new[] { 0 });
|
||||
|
||||
var blendBindings = new ShaderBindings(
|
||||
new[] { 2 },
|
||||
Array.Empty<int>(),
|
||||
new[] { 1, 3, 4 },
|
||||
new[] { 0 });
|
||||
|
||||
var neighbourBindings = new ShaderBindings(
|
||||
new[] { 2 },
|
||||
Array.Empty<int>(),
|
||||
new[] { 1, 3 },
|
||||
new[] { 0 });
|
||||
|
||||
_samplerLinear = _renderer.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
||||
|
||||
_specConstants = new SmaaConstants()
|
||||
{
|
||||
Width = width,
|
||||
Height = height,
|
||||
QualityLow = Quality == 0 ? 1 : 0,
|
||||
QualityMedium = Quality == 1 ? 1 : 0,
|
||||
QualityHigh = Quality == 2 ? 1 : 0,
|
||||
QualityUltra = Quality == 3 ? 1 : 0,
|
||||
};
|
||||
|
||||
var specInfo = new SpecDescription(
|
||||
(0, SpecConstType.Int32),
|
||||
(1, SpecConstType.Int32),
|
||||
(2, SpecConstType.Int32),
|
||||
(3, SpecConstType.Int32),
|
||||
(4, SpecConstType.Float32),
|
||||
(5, SpecConstType.Float32));
|
||||
|
||||
_edgeProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||
{
|
||||
new ShaderSource(edgeShader, edgeBindings, ShaderStage.Compute, TargetLanguage.Spirv)
|
||||
}, new[] { specInfo });
|
||||
|
||||
_blendProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||
{
|
||||
new ShaderSource(blendShader, blendBindings, ShaderStage.Compute, TargetLanguage.Spirv)
|
||||
}, new[] { specInfo });
|
||||
|
||||
_neighbourProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||
{
|
||||
new ShaderSource(neighbourShader, neighbourBindings, ShaderStage.Compute, TargetLanguage.Spirv)
|
||||
}, new[] { specInfo });
|
||||
}
|
||||
|
||||
public void DeletePipelines()
|
||||
{
|
||||
_pipeline?.Dispose();
|
||||
_edgeProgram?.Dispose();
|
||||
_blendProgram?.Dispose();
|
||||
_neighbourProgram?.Dispose();
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
var areaInfo = new TextureCreateInfo(AreaWidth,
|
||||
AreaHeight,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
Format.R8G8Unorm,
|
||||
DepthStencilMode.Depth,
|
||||
Target.Texture2D,
|
||||
SwizzleComponent.Red,
|
||||
SwizzleComponent.Green,
|
||||
SwizzleComponent.Blue,
|
||||
SwizzleComponent.Alpha);
|
||||
|
||||
var searchInfo = new TextureCreateInfo(SearchWidth,
|
||||
SearchHeight,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
Format.R8Unorm,
|
||||
DepthStencilMode.Depth,
|
||||
Target.Texture2D,
|
||||
SwizzleComponent.Red,
|
||||
SwizzleComponent.Green,
|
||||
SwizzleComponent.Blue,
|
||||
SwizzleComponent.Alpha);
|
||||
|
||||
var areaTexture = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Textures/SmaaAreaTexture.bin");
|
||||
var searchTexture = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Textures/SmaaSearchTexture.bin");
|
||||
|
||||
_areaTexture = _renderer.CreateTexture(areaInfo, 1) as TextureView;
|
||||
_searchTexture = _renderer.CreateTexture(searchInfo, 1) as TextureView;
|
||||
|
||||
_areaTexture.SetData(areaTexture);
|
||||
_searchTexture.SetData(searchTexture);
|
||||
}
|
||||
|
||||
public TextureView Run(TextureView view, CommandBufferScoped cbs, int width, int height)
|
||||
{
|
||||
if (_recreatePipelines || _outputTexture == null || _outputTexture.Info.Width != view.Width || _outputTexture.Info.Height != view.Height)
|
||||
{
|
||||
RecreateShaders(view.Width, view.Height);
|
||||
_outputTexture?.Dispose();
|
||||
_edgeOutputTexture?.Dispose();
|
||||
_blendOutputTexture?.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);
|
||||
}
|
||||
|
||||
_outputTexture = _renderer.CreateTexture(info, view.ScaleFactor) as TextureView;
|
||||
_edgeOutputTexture = _renderer.CreateTexture(info, view.ScaleFactor) as TextureView;
|
||||
_blendOutputTexture = _renderer.CreateTexture(info, view.ScaleFactor) as TextureView;
|
||||
}
|
||||
|
||||
_pipeline.SetCommandBuffer(cbs);
|
||||
|
||||
Clear(_edgeOutputTexture);
|
||||
Clear(_blendOutputTexture);
|
||||
|
||||
_renderer.Pipeline.TextureBarrier();
|
||||
|
||||
var dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize);
|
||||
var dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize);
|
||||
|
||||
// Edge pass
|
||||
_pipeline.SetProgram(_edgeProgram);
|
||||
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 1, view, _samplerLinear);
|
||||
_pipeline.Specialize(_specConstants);
|
||||
|
||||
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) });
|
||||
_pipeline.SetImage(0, _edgeOutputTexture, GAL.Format.R8G8B8A8Unorm);
|
||||
_pipeline.DispatchCompute(dispatchX, dispatchY, 1);
|
||||
_pipeline.ComputeBarrier();
|
||||
|
||||
// Blend pass
|
||||
_pipeline.SetProgram(_blendProgram);
|
||||
_pipeline.Specialize(_specConstants);
|
||||
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 1, _edgeOutputTexture, _samplerLinear);
|
||||
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 3, _areaTexture, _samplerLinear);
|
||||
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 4, _searchTexture, _samplerLinear);
|
||||
_pipeline.SetImage(0, _blendOutputTexture, GAL.Format.R8G8B8A8Unorm);
|
||||
_pipeline.DispatchCompute(dispatchX, dispatchY, 1);
|
||||
_pipeline.ComputeBarrier();
|
||||
|
||||
// Neighbour pass
|
||||
_pipeline.SetProgram(_neighbourProgram);
|
||||
_pipeline.Specialize(_specConstants);
|
||||
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 3, _blendOutputTexture, _samplerLinear);
|
||||
_pipeline.SetTextureAndSampler(ShaderStage.Compute, 1, view, _samplerLinear);
|
||||
_pipeline.SetImage(0, _outputTexture, GAL.Format.R8G8B8A8Unorm);
|
||||
_pipeline.DispatchCompute(dispatchX, dispatchY, 1);
|
||||
_pipeline.ComputeBarrier();
|
||||
|
||||
_pipeline.Finish();
|
||||
|
||||
_renderer.BufferManager.Delete(bufferHandle);
|
||||
|
||||
return _outputTexture;
|
||||
}
|
||||
|
||||
private void Clear(TextureView texture)
|
||||
{
|
||||
Span<uint> colorMasks = stackalloc uint[1];
|
||||
|
||||
colorMasks[0] = 0xf;
|
||||
|
||||
Span<Rectangle<int>> scissors = stackalloc Rectangle<int>[1];
|
||||
|
||||
scissors[0] = new Rectangle<int>(0, 0, texture.Width, texture.Height);
|
||||
|
||||
_pipeline.SetRenderTarget(texture.GetImageViewForAttachment(), (uint)texture.Width, (uint)texture.Height, false, texture.VkFormat);
|
||||
_pipeline.SetRenderTargetColorMasks(colorMasks);
|
||||
_pipeline.SetScissors(scissors);
|
||||
_pipeline.ClearRenderTargetColor(0, 0, 1, new ColorF(0f, 0f, 0f, 1f));
|
||||
}
|
||||
}
|
||||
}
|
BIN
src/Ryujinx.Graphics.Vulkan/Effects/Textures/SmaaAreaTexture.bin
Normal file
BIN
src/Ryujinx.Graphics.Vulkan/Effects/Textures/SmaaAreaTexture.bin
Normal file
Binary file not shown.
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue