1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-13 13:32:54 +08:00

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

@ -13,6 +13,7 @@ using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Rendering; using osu.Framework.Graphics.Rendering;
using osu.Framework.Graphics.Rendering.Vertices; using osu.Framework.Graphics.Rendering.Vertices;
using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Shaders;
using osu.Framework.Graphics.Shaders.Types;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Framework.Input; using osu.Framework.Input;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
@ -255,15 +256,23 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
Source.parts.CopyTo(parts, 0); Source.parts.CopyTo(parts, 0);
} }
private IUniformBuffer<CursorTrailParameters> cursorTrailParameters;
public override void Draw(IRenderer renderer) public override void Draw(IRenderer renderer)
{ {
base.Draw(renderer); base.Draw(renderer);
vertexBatch ??= renderer.CreateQuadBatch<TexturedTrailVertex>(max_sprites, 1); vertexBatch ??= renderer.CreateQuadBatch<TexturedTrailVertex>(max_sprites, 1);
cursorTrailParameters ??= renderer.CreateUniformBuffer<CursorTrailParameters>();
cursorTrailParameters.Data = cursorTrailParameters.Data with
{
FadeClock = time,
FadeExponent = fadeExponent
};
shader.Bind(); shader.Bind();
shader.GetUniform<float>("g_FadeClock").UpdateValue(ref time); shader.BindUniformBlock("m_CursorTrailParameters", cursorTrailParameters);
shader.GetUniform<float>("g_FadeExponent").UpdateValue(ref fadeExponent);
texture.Bind(); texture.Bind();
@ -323,6 +332,15 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
base.Dispose(isDisposing); base.Dispose(isDisposing);
vertexBatch?.Dispose(); vertexBatch?.Dispose();
cursorTrailParameters?.Dispose();
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private record struct CursorTrailParameters
{
public UniformFloat FadeClock;
public UniformFloat FadeExponent;
private readonly UniformPadding8 pad1;
} }
} }

View File

@ -9,6 +9,7 @@ using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Rendering; using osu.Framework.Graphics.Rendering;
using osu.Game.Graphics.Backgrounds;
namespace osu.Game.Tests.Visual.Background namespace osu.Game.Tests.Visual.Background
{ {
@ -97,15 +98,29 @@ namespace osu.Game.Tests.Visual.Background
texelSize = Source.texelSize; texelSize = Source.texelSize;
} }
private IUniformBuffer<TriangleBorderData>? borderDataBuffer;
public override void Draw(IRenderer renderer) public override void Draw(IRenderer renderer)
{ {
TextureShader.GetUniform<float>("thickness").UpdateValue(ref thickness); borderDataBuffer ??= renderer.CreateUniformBuffer<TriangleBorderData>();
TextureShader.GetUniform<float>("texelSize").UpdateValue(ref texelSize); borderDataBuffer.Data = borderDataBuffer.Data with
{
Thickness = thickness,
TexelSize = texelSize
};
TextureShader.BindUniformBlock("m_BorderData", borderDataBuffer);
base.Draw(renderer); base.Draw(renderer);
} }
protected override bool CanDrawOpaqueInterior => false; protected override bool CanDrawOpaqueInterior => false;
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
borderDataBuffer?.Dispose();
}
} }
} }
} }

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); parts.AddRange(Source.parts);
} }
private IUniformBuffer<TriangleBorderData> borderDataBuffer;
public override void Draw(IRenderer renderer) public override void Draw(IRenderer renderer)
{ {
base.Draw(renderer); base.Draw(renderer);
@ -294,14 +296,16 @@ namespace osu.Game.Graphics.Backgrounds
vertexBatch = renderer.CreateQuadBatch<TexturedVertex2D>(Source.AimCount, 1); 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. borderDataBuffer ??= renderer.CreateUniformBuffer<TriangleBorderData>();
// 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. borderDataBuffer.Data = borderDataBuffer.Data with
// But we still need to specify at least something, because otherwise other shader usages will override this value. {
float texelSize = 0f; 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.Bind();
shader.GetUniform<float>("thickness").UpdateValue(ref fill);
shader.GetUniform<float>("texelSize").UpdateValue(ref texelSize);
foreach (TriangleParticle particle in parts) foreach (TriangleParticle particle in parts)
{ {
@ -352,6 +356,7 @@ namespace osu.Game.Graphics.Backgrounds
base.Dispose(isDisposing); base.Dispose(isDisposing);
vertexBatch?.Dispose(); vertexBatch?.Dispose();
borderDataBuffer?.Dispose();
} }
} }

View File

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

View File

@ -3,10 +3,12 @@
#nullable disable #nullable disable
using System.Runtime.InteropServices;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Rendering; using osu.Framework.Graphics.Rendering;
using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Shaders;
using osu.Framework.Graphics.Shaders.Types;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
namespace osu.Game.Graphics.Sprites namespace osu.Game.Graphics.Sprites
@ -55,14 +57,32 @@ namespace osu.Game.Graphics.Sprites
progress = source.animationProgress; progress = source.animationProgress;
} }
private IUniformBuffer<AnimationData> animationDataBuffer;
protected override void Blit(IRenderer renderer) 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); base.Blit(renderer);
} }
protected override bool CanDrawOpaqueInterior => false; 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;
}
} }
} }
} }

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Runtime.InteropServices;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
@ -9,6 +10,7 @@ using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Rendering; using osu.Framework.Graphics.Rendering;
using osu.Framework.Graphics.Rendering.Vertices; using osu.Framework.Graphics.Rendering.Vertices;
using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Shaders;
using osu.Framework.Graphics.Shaders.Types;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation; using osu.Framework.Localisation;
using osu.Game.Configuration; using osu.Game.Configuration;
@ -245,6 +247,8 @@ namespace osu.Game.Rulesets.Mods
flashlightSmoothness = Source.flashlightSmoothness; flashlightSmoothness = Source.flashlightSmoothness;
} }
private IUniformBuffer<FlashlightParameters>? flashlightParametersBuffer;
public override void Draw(IRenderer renderer) public override void Draw(IRenderer renderer)
{ {
base.Draw(renderer); base.Draw(renderer);
@ -259,12 +263,17 @@ namespace osu.Game.Rulesets.Mods
}); });
} }
shader.Bind(); flashlightParametersBuffer ??= renderer.CreateUniformBuffer<FlashlightParameters>();
flashlightParametersBuffer.Data = flashlightParametersBuffer.Data with
{
Position = flashlightPosition,
Size = flashlightSize,
Dim = flashlightDim,
Smoothness = flashlightSmoothness
};
shader.GetUniform<Vector2>("flashlightPos").UpdateValue(ref flashlightPosition); shader.Bind();
shader.GetUniform<Vector2>("flashlightSize").UpdateValue(ref flashlightSize); shader.BindUniformBlock("m_FlashlightParameters", flashlightParametersBuffer);
shader.GetUniform<float>("flashlightDim").UpdateValue(ref flashlightDim);
shader.GetUniform<float>("flashlightSmoothness").UpdateValue(ref flashlightSmoothness);
renderer.DrawQuad(renderer.WhitePixel, screenSpaceDrawQuad, DrawColourInfo.Colour, vertexAction: addAction); renderer.DrawQuad(renderer.WhitePixel, screenSpaceDrawQuad, DrawColourInfo.Colour, vertexAction: addAction);
@ -275,6 +284,17 @@ namespace osu.Game.Rulesets.Mods
{ {
base.Dispose(isDisposing); base.Dispose(isDisposing);
quadBatch?.Dispose(); quadBatch?.Dispose();
flashlightParametersBuffer?.Dispose();
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private record struct FlashlightParameters
{
public UniformVector2 Position;
public UniformVector2 Size;
public UniformFloat Dim;
public UniformFloat Smoothness;
private readonly UniformPadding8 pad1;
} }
} }
} }