Adjust DrawNodes to use UBOs

This commit is contained in:
Dan Balasescu
2023-02-25 01:21:37 +09:00
parent eb0c3ca174
commit dd9748a25c
7 changed files with 121 additions and 18 deletions

View File

@ -0,0 +1,16 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Runtime.InteropServices;
using osu.Framework.Graphics.Shaders.Types;
namespace osu.Game.Graphics.Backgrounds
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public record struct TriangleBorderData
{
public UniformFloat Thickness;
public UniformFloat TexelSize;
private readonly UniformPadding8 pad1;
}
}

View File

@ -284,6 +284,8 @@ namespace osu.Game.Graphics.Backgrounds
parts.AddRange(Source.parts);
}
private IUniformBuffer<TriangleBorderData> borderDataBuffer;
public override void Draw(IRenderer renderer)
{
base.Draw(renderer);
@ -294,14 +296,16 @@ namespace osu.Game.Graphics.Backgrounds
vertexBatch = renderer.CreateQuadBatch<TexturedVertex2D>(Source.AimCount, 1);
}
// Due to triangles having various sizes we would need to set a different "texelSize" value for each of them, which is insanely expensive, thus we should use one single value.
// texelSize computed for an average triangle (size 100) will result in big triangles becoming blurry, so we may just use 0 for all of them.
// But we still need to specify at least something, because otherwise other shader usages will override this value.
float texelSize = 0f;
borderDataBuffer ??= renderer.CreateUniformBuffer<TriangleBorderData>();
borderDataBuffer.Data = borderDataBuffer.Data with
{
Thickness = fill,
// Due to triangles having various sizes we would need to set a different "TexelSize" value for each of them, which is insanely expensive, thus we should use one single value.
// TexelSize computed for an average triangle (size 100) will result in big triangles becoming blurry, so we may just use 0 for all of them.
TexelSize = 0
};
shader.Bind();
shader.GetUniform<float>("thickness").UpdateValue(ref fill);
shader.GetUniform<float>("texelSize").UpdateValue(ref texelSize);
foreach (TriangleParticle particle in parts)
{
@ -352,6 +356,7 @@ namespace osu.Game.Graphics.Backgrounds
base.Dispose(isDisposing);
vertexBatch?.Dispose();
borderDataBuffer?.Dispose();
}
}

View File

@ -227,6 +227,8 @@ namespace osu.Game.Graphics.Backgrounds
parts.AddRange(Source.parts);
}
private IUniformBuffer<TriangleBorderData>? borderDataBuffer;
public override void Draw(IRenderer renderer)
{
base.Draw(renderer);
@ -240,9 +242,15 @@ namespace osu.Game.Graphics.Backgrounds
vertexBatch = renderer.CreateQuadBatch<TexturedVertex2D>(Source.AimCount, 1);
}
borderDataBuffer ??= renderer.CreateUniformBuffer<TriangleBorderData>();
borderDataBuffer.Data = borderDataBuffer.Data with
{
Thickness = thickness,
TexelSize = texelSize
};
shader.Bind();
shader.GetUniform<float>("thickness").UpdateValue(ref thickness);
shader.GetUniform<float>("texelSize").UpdateValue(ref texelSize);
shader.BindUniformBlock("m_BorderData", borderDataBuffer);
Vector2 relativeSize = Vector2.Divide(triangleSize, size);
@ -303,6 +311,7 @@ namespace osu.Game.Graphics.Backgrounds
base.Dispose(isDisposing);
vertexBatch?.Dispose();
borderDataBuffer?.Dispose();
}
}

View File

@ -3,10 +3,12 @@
#nullable disable
using System.Runtime.InteropServices;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Rendering;
using osu.Framework.Graphics.Shaders;
using osu.Framework.Graphics.Shaders.Types;
using osu.Framework.Graphics.Sprites;
namespace osu.Game.Graphics.Sprites
@ -55,14 +57,32 @@ namespace osu.Game.Graphics.Sprites
progress = source.animationProgress;
}
private IUniformBuffer<AnimationData> animationDataBuffer;
protected override void Blit(IRenderer renderer)
{
TextureShader.GetUniform<float>("progress").UpdateValue(ref progress);
animationDataBuffer ??= renderer.CreateUniformBuffer<AnimationData>();
animationDataBuffer.Data = animationDataBuffer.Data with { Progress = progress };
TextureShader.BindUniformBlock("m_AnimationData", animationDataBuffer);
base.Blit(renderer);
}
protected override bool CanDrawOpaqueInterior => false;
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
animationDataBuffer?.Dispose();
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private record struct AnimationData
{
public UniformFloat Progress;
private readonly UniformPadding12 pad1;
}
}
}
}