Merge pull request #5901 from peppy/contextual-initialise-levels

Avoid initialising textures when unnecessary
This commit is contained in:
Dan Balasescu
2023-07-07 19:02:10 +09:00
committed by GitHub
7 changed files with 41 additions and 30 deletions

View File

@@ -434,7 +434,7 @@ namespace osu.Framework.Graphics.OpenGL
protected override IUniformBuffer<TData> CreateUniformBuffer<TData>() => new GLUniformBuffer<TData>(this);
protected override INativeTexture CreateNativeTexture(int width, int height, bool manualMipmaps = false, TextureFilteringMode filteringMode = TextureFilteringMode.Linear,
Color4 initialisationColour = default)
Color4? initialisationColour = null)
{
All glFilteringMode;

View File

@@ -69,7 +69,7 @@ namespace osu.Framework.Graphics.OpenGL.Textures
private readonly List<RectangleI> uploadedRegions = new List<RectangleI>();
private readonly All filteringMode;
private readonly Color4 initialisationColour;
private readonly Color4? initialisationColour;
/// <summary>
/// Creates a new <see cref="GLTexture"/>.
@@ -79,8 +79,8 @@ namespace osu.Framework.Graphics.OpenGL.Textures
/// <param name="height">The height of the texture.</param>
/// <param name="manualMipmaps">Whether manual mipmaps will be uploaded to the texture. If false, the texture will compute mipmaps automatically.</param>
/// <param name="filteringMode">The filtering mode.</param>
/// <param name="initialisationColour">The colour to initialise texture levels with (in the case of sub region initial uploads).</param>
public GLTexture(GLRenderer renderer, int width, int height, bool manualMipmaps = false, All filteringMode = All.Linear, Color4 initialisationColour = default)
/// <param name="initialisationColour">The colour to initialise texture levels with (in the case of sub region initial uploads). If null, no initialisation is provided out-of-the-box.</param>
public GLTexture(GLRenderer renderer, int width, int height, bool manualMipmaps = false, All filteringMode = All.Linear, Color4? initialisationColour = null)
{
Renderer = renderer;
Width = width;
@@ -470,7 +470,15 @@ namespace osu.Framework.Graphics.OpenGL.Textures
private void initializeLevel(int level, int width, int height)
{
using (var image = createBackingImage(width, height))
if (initialisationColour == null)
return;
var rgbaColour = new Rgba32(new Vector4(initialisationColour.Value.R, initialisationColour.Value.G, initialisationColour.Value.B, initialisationColour.Value.A));
using var image = initialisationColour == default
? new Image<Rgba32>(width, height)
: new Image<Rgba32>(width, height, rgbaColour);
using (var pixels = image.CreateReadOnlyPixelSpan())
{
updateMemoryUsage(level, (long)width * height * 4);
@@ -478,13 +486,5 @@ namespace osu.Framework.Graphics.OpenGL.Textures
ref MemoryMarshal.GetReference(pixels.Span));
}
}
private Image<Rgba32> createBackingImage(int width, int height)
{
// it is faster to initialise without a background specification if transparent black is all that's required.
return initialisationColour == default
? new Image<Rgba32>(width, height)
: new Image<Rgba32>(width, height, new Rgba32(new Vector4(initialisationColour.R, initialisationColour.G, initialisationColour.B, initialisationColour.A)));
}
}
}

View File

@@ -195,7 +195,7 @@ namespace osu.Framework.Graphics.Rendering.Dummy
=> new DummyFrameBuffer(this);
public Texture CreateTexture(int width, int height, bool manualMipmaps = false, TextureFilteringMode filteringMode = TextureFilteringMode.Linear, WrapMode wrapModeS = WrapMode.None,
WrapMode wrapModeT = WrapMode.None, Color4 initialisationColour = default)
WrapMode wrapModeT = WrapMode.None, Color4? initialisationColour = null)
=> new Texture(new DummyNativeTexture(this) { Width = width, Height = height }, wrapModeS, wrapModeT);
public Texture CreateVideoTexture(int width, int height)

View File

@@ -372,10 +372,18 @@ namespace osu.Framework.Graphics.Rendering
IFrameBuffer CreateFrameBuffer(RenderBufferFormat[]? renderBufferFormats = null, TextureFilteringMode filteringMode = TextureFilteringMode.Linear);
/// <summary>
/// Creates a new texture.
/// Creates a new <see cref="Texture"/>.
/// </summary>
/// <param name="width">The width of the texture.</param>
/// <param name="height">The height of the texture.</param>
/// <param name="manualMipmaps">Whether manual mipmaps will be uploaded to the texture. If false, the texture will compute mipmaps automatically.</param>
/// <param name="filteringMode">The filtering mode.</param>
/// <param name="initialisationColour">The colour to initialise texture levels with (in the case of sub region initial uploads). If null, no initialisation is provided out-of-the-box.</param>
/// <param name="wrapModeS">The texture's horizontal wrap mode.</param>
/// <param name="wrapModeT">The texture's vertex wrap mode.</param>
/// <returns>The <see cref="Texture"/>.</returns>
Texture CreateTexture(int width, int height, bool manualMipmaps = false, TextureFilteringMode filteringMode = TextureFilteringMode.Linear, WrapMode wrapModeS = WrapMode.None,
WrapMode wrapModeT = WrapMode.None, Color4 initialisationColour = default);
WrapMode wrapModeT = WrapMode.None, Color4? initialisationColour = null);
/// <summary>
/// Creates a new video texture.

View File

@@ -1084,10 +1084,10 @@ namespace osu.Framework.Graphics.Rendering
/// <param name="height">The height of the texture.</param>
/// <param name="manualMipmaps">Whether manual mipmaps will be uploaded to the texture. If false, the texture will compute mipmaps automatically.</param>
/// <param name="filteringMode">The filtering mode.</param>
/// <param name="initialisationColour">The colour to initialise texture levels with (in the case of sub region initial uploads).</param>
/// <param name="initialisationColour">The colour to initialise texture levels with (in the case of sub region initial uploads). If null, no initialisation is provided out-of-the-box.</param>
/// <returns>The <see cref="INativeTexture"/>.</returns>
protected abstract INativeTexture CreateNativeTexture(int width, int height, bool manualMipmaps = false, TextureFilteringMode filteringMode = TextureFilteringMode.Linear,
Color4 initialisationColour = default);
Color4? initialisationColour = null);
/// <summary>
/// Creates a new <see cref="INativeTexture"/> for video sprites.
@@ -1097,7 +1097,7 @@ namespace osu.Framework.Graphics.Rendering
/// <returns>The video <see cref="INativeTexture"/>.</returns>
protected abstract INativeTexture CreateNativeVideoTexture(int width, int height);
public Texture CreateTexture(int width, int height, bool manualMipmaps, TextureFilteringMode filteringMode, WrapMode wrapModeS, WrapMode wrapModeT, Color4 initialisationColour)
public Texture CreateTexture(int width, int height, bool manualMipmaps, TextureFilteringMode filteringMode, WrapMode wrapModeS, WrapMode wrapModeT, Color4? initialisationColour)
=> CreateTexture(CreateNativeTexture(width, height, manualMipmaps, filteringMode, initialisationColour), wrapModeS, wrapModeT);
public Texture CreateVideoTexture(int width, int height) => CreateTexture(CreateNativeVideoTexture(width, height));

View File

@@ -54,7 +54,7 @@ namespace osu.Framework.Graphics.Veldrid.Textures
private readonly List<RectangleI> uploadedRegions = new List<RectangleI>();
private readonly SamplerFilter filteringMode;
private readonly Color4 initialisationColour;
private readonly Color4? initialisationColour;
public ulong BindCount { get; protected set; }
@@ -83,9 +83,9 @@ namespace osu.Framework.Graphics.Veldrid.Textures
/// <param name="height">The height of the texture.</param>
/// <param name="manualMipmaps">Whether manual mipmaps will be uploaded to the texture. If false, the texture will compute mipmaps automatically.</param>
/// <param name="filteringMode">The filtering mode.</param>
/// <param name="initialisationColour">The colour to initialise texture levels with (in the case of sub region initial uploads).</param>
/// <param name="initialisationColour">The colour to initialise texture levels with (in the case of sub region initial uploads). If null, no initialisation is provided out-of-the-box.</param>
public VeldridTexture(VeldridRenderer renderer, int width, int height, bool manualMipmaps = false, SamplerFilter filteringMode = SamplerFilter.MinLinear_MagLinear_MipLinear,
Color4 initialisationColour = default)
Color4? initialisationColour = null)
{
this.manualMipmaps = manualMipmaps;
this.filteringMode = filteringMode;
@@ -485,6 +485,7 @@ namespace osu.Framework.Graphics.Veldrid.Textures
if (!upload.Data.IsEmpty)
{
// ensure all mip levels up to the target level are initialised.
// generally we always upload at level 0, so this won't run.
if (upload.Level > maximumUploadedLod)
{
for (int i = maximumUploadedLod + 1; i <= upload.Level; i++)
@@ -508,20 +509,22 @@ namespace osu.Framework.Graphics.Veldrid.Textures
private unsafe void initialiseLevel(Texture texture, int level, int width, int height)
{
using (var image = createBackingImage(width, height))
if (initialisationColour == null)
return;
var rgbaColour = new Rgba32(new Vector4(initialisationColour.Value.R, initialisationColour.Value.G, initialisationColour.Value.B, initialisationColour.Value.A));
using var image = initialisationColour == default
? new Image<Rgba32>(width, height)
: new Image<Rgba32>(width, height, rgbaColour);
using (var pixels = image.CreateReadOnlyPixelSpan())
{
updateMemoryUsage(level, (long)width * height * sizeof(Rgba32));
Renderer.UpdateTexture(texture, 0, 0, width, height, level, pixels.Span);
}
}
private Image<Rgba32> createBackingImage(int width, int height)
{
// it is faster to initialise without a background specification if transparent black is all that's required.
return initialisationColour == default
? new Image<Rgba32>(width, height)
: new Image<Rgba32>(width, height, new Rgba32(new Vector4(initialisationColour.R, initialisationColour.G, initialisationColour.B, initialisationColour.A)));
}
// todo: should this be limited to MAX_MIPMAP_LEVELS or was that constant supposed to be for automatic mipmap generation only?

View File

@@ -594,7 +594,7 @@ namespace osu.Framework.Graphics.Veldrid
=> new VeldridUniformBuffer<TData>(this);
protected override INativeTexture CreateNativeTexture(int width, int height, bool manualMipmaps = false, TextureFilteringMode filteringMode = TextureFilteringMode.Linear,
Color4 initialisationColour = default)
Color4? initialisationColour = null)
=> new VeldridTexture(this, width, height, manualMipmaps, filteringMode.ToSamplerFilter(), initialisationColour);
protected override INativeTexture CreateNativeVideoTexture(int width, int height)