phase(N.5) Task 1: ArbBindlessTexture wrapper + capability detection

Adds Silk.NET.OpenGL.Extensions.ARB 2.23.0 package and a thin
BindlessSupport wrapper exposing GetResidentHandle / MakeNonResident /
HasShaderDrawParameters. TryCreate returns false if the bindless
extension isn't present, letting WbFoundationFlag fall back to legacy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-08 19:31:02 +02:00
parent 69c6c03d10
commit 4d1a7977cb
2 changed files with 68 additions and 0 deletions

View file

@ -14,6 +14,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Silk.NET.OpenGL" Version="2.23.0" />
<PackageReference Include="Silk.NET.OpenGL.Extensions.ARB" Version="2.23.0" />
<PackageReference Include="Silk.NET.Windowing" Version="2.23.0" />
<PackageReference Include="Silk.NET.Input" Version="2.23.0" />
<PackageReference Include="Silk.NET.OpenAL" Version="2.23.0" />

View file

@ -0,0 +1,67 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Extensions.ARB;
namespace AcDream.App.Rendering.Wb;
/// <summary>
/// Thin wrapper around <see cref="ArbBindlessTexture"/> + capability detection
/// for the modern rendering path. Constructed once at startup. Throws if the
/// extension isn't available — callers must check <see cref="IsAvailable"/>
/// before constructing for production use.
/// </summary>
public sealed class BindlessSupport
{
private readonly GL _gl;
private readonly ArbBindlessTexture _ext;
public bool IsAvailable => true; // Construction succeeded
public BindlessSupport(GL gl, ArbBindlessTexture extension)
{
_gl = gl;
_ext = extension;
}
public static bool TryCreate(GL gl, out BindlessSupport? support)
{
if (gl.TryGetExtension<ArbBindlessTexture>(out var ext))
{
support = new BindlessSupport(gl, ext);
return true;
}
support = null;
return false;
}
/// <summary>Get a 64-bit bindless handle for the texture and make it resident.
/// Idempotent: handle is the same for a given texture name.</summary>
public ulong GetResidentHandle(uint textureName)
{
ulong h = _ext.GetTextureHandle(textureName);
if (!_ext.IsTextureHandleResident(h))
_ext.MakeTextureHandleResident(h);
return h;
}
/// <summary>Release residency for a handle. Call before deleting the underlying texture.</summary>
public void MakeNonResident(ulong handle)
{
if (_ext.IsTextureHandleResident(handle))
_ext.MakeTextureHandleNonResident(handle);
}
/// <summary>Detect <c>GL_ARB_shader_draw_parameters</c> in addition to bindless.
/// N.5's vertex shader uses <c>gl_BaseInstanceARB</c> and <c>gl_DrawIDARB</c>
/// from this extension.</summary>
public bool HasShaderDrawParameters(GL gl)
{
int n = 0;
gl.GetInteger(GLEnum.NumExtensions, out n);
for (int i = 0; i < n; i++)
{
string ext = gl.GetStringS(StringName.Extensions, (uint)i);
if (ext == "GL_ARB_shader_draw_parameters") return true;
}
return false;
}
}