Support arbitrary mipmap level selection on Veldrid

This commit is contained in:
Salman Ahmed
2023-04-16 00:49:21 +03:00
parent 79b06df633
commit 0c66497c61
7 changed files with 81 additions and 26 deletions

View File

@@ -45,6 +45,19 @@ namespace osu.Framework.Graphics.OpenGL.Textures
public virtual int GetByteSize() => Width * Height * 4;
public bool Available { get; private set; } = true;
private int? mipLevel;
public int? MipLevel
{
get => mipLevel;
set
{
mipLevel = value;
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinLod, mipLevel ?? 0);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMaxLod, mipLevel ?? IRenderer.MAX_MIPMAP_LEVELS);
}
}
ulong INativeTexture.TotalBindCount { get; set; }
public bool BypassTextureUploadQueueing { get; set; }

View File

@@ -16,6 +16,7 @@ namespace osu.Framework.Graphics.Rendering.Dummy
public int MaxSize => 4096; // Sane default for testing purposes.
public int Width { get; set; } = 1;
public int Height { get; set; } = 1;
public int? MipLevel { get; set; }
public bool Available => true;
public bool BypassTextureUploadQueueing { get; set; }
public bool UploadComplete => true;

View File

@@ -34,6 +34,12 @@ namespace osu.Framework.Graphics.Rendering
/// </summary>
int Height { get; set; }
/// <summary>
/// The level of the texture to display, or null to display all levels automatically.
/// This is used by the texture visualiser tool for viewing textures on a specific mipmap level.
/// </summary>
int? MipLevel { get; set; }
/// <summary>
/// Whether the texture is in a usable state.
/// </summary>

View File

@@ -153,6 +153,12 @@ namespace osu.Framework.Graphics.Textures
/// </summary>
public Vector2 Size => new Vector2(Width, Height);
internal int? MipLevel
{
get => NativeTexture.MipLevel;
set => NativeTexture.MipLevel = value;
}
/// <summary>
/// Binds this texture for drawing.
/// </summary>

View File

@@ -387,11 +387,47 @@ namespace osu.Framework.Graphics.Veldrid.Textures
}
}
private int? mipLevel;
public int? MipLevel
{
get => mipLevel;
set
{
if (mipLevel == value)
return;
mipLevel = value;
if (resources != null)
resources.Sampler = createSampler();
}
}
/// <summary>
/// The maximum number of mip levels provided by an <see cref="ITextureUpload"/>.
/// </summary>
private int maximumUploadedLod;
private Sampler createSampler()
{
bool useUploadMipmaps = manualMipmaps || maximumUploadedLod > 0;
int maximumLod = useUploadMipmaps ? maximumUploadedLod : IRenderer.MAX_MIPMAP_LEVELS;
var samplerDescription = new SamplerDescription
{
AddressModeU = SamplerAddressMode.Clamp,
AddressModeV = SamplerAddressMode.Clamp,
AddressModeW = SamplerAddressMode.Clamp,
Filter = filteringMode,
MinimumLod = (uint)(MipLevel ?? 0),
MaximumLod = (uint)(MipLevel ?? maximumLod),
MaximumAnisotropy = 0,
};
return Renderer.Factory.CreateSampler(ref samplerDescription);
}
protected virtual void DoUpload(ITextureUpload upload)
{
Texture? texture = resources?.Texture;
@@ -415,24 +451,7 @@ namespace osu.Framework.Graphics.Veldrid.Textures
maximumUploadedLod = upload.Level;
if (sampler == null || maximumUploadedLod > lastMaximumUploadedLod)
{
sampler?.Dispose();
bool useUploadMipmaps = manualMipmaps || maximumUploadedLod > 0;
var samplerDescription = new SamplerDescription
{
AddressModeU = SamplerAddressMode.Clamp,
AddressModeV = SamplerAddressMode.Clamp,
AddressModeW = SamplerAddressMode.Clamp,
Filter = filteringMode,
MinimumLod = 0,
MaximumLod = useUploadMipmaps ? (uint)maximumUploadedLod : IRenderer.MAX_MIPMAP_LEVELS,
MaximumAnisotropy = 0,
};
sampler = Renderer.Factory.CreateSampler(ref samplerDescription);
}
sampler = createSampler();
resources = new VeldridTextureResources(texture, sampler);

View File

@@ -12,7 +12,21 @@ namespace osu.Framework.Graphics.Veldrid.Textures
internal class VeldridTextureResources : IDisposable
{
public readonly Texture Texture;
public readonly Sampler Sampler;
private Sampler sampler;
public Sampler Sampler
{
get => sampler;
set
{
sampler = value;
Set?.Dispose();
Set = null;
}
}
private readonly bool disposeResources;
public ResourceSet? Set { get; private set; }
@@ -20,9 +34,9 @@ namespace osu.Framework.Graphics.Veldrid.Textures
public VeldridTextureResources(Texture texture, Sampler sampler, bool disposeResources = true)
{
this.disposeResources = disposeResources;
this.sampler = sampler;
Texture = texture;
Sampler = sampler;
}
/// <summary>

View File

@@ -300,18 +300,14 @@ namespace osu.Framework.Graphics.Visualisation
texture.Bind();
if (visualisedMipLevel != -1)
{
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinLod, visualisedMipLevel);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMaxLod, visualisedMipLevel);
}
texture.MipLevel = visualisedMipLevel;
renderer.DrawQuad(texture, shrunkenQuad, Color4.White);
if (visualisedMipLevel != -1)
{
renderer.FlushCurrentBatch(null);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinLod, 0);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMaxLod, IRenderer.MAX_MIPMAP_LEVELS);
texture.MipLevel = null;
}
}