From f48a6cf65c0077bfbe2d940d5ccd01a8597e9043 Mon Sep 17 00:00:00 2001 From: Erik Date: Fri, 8 May 2026 19:44:10 +0200 Subject: [PATCH] phase(N.5) Task 2: parallel Texture2DArray upload path in TextureCache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds UploadRgba8AsLayer1Array — uploads pixel data as a 1-layer Texture2DArray. Existing UploadRgba8 (Texture2D) untouched, so legacy callers (StaticMeshRenderer, InstancedMeshRenderer, ParticleRenderer, WbDrawDispatcher's pre-rewrite path) keep working unchanged. Required for Task 3's Bindless* methods which need the Texture2DArray target so the WB modern shader can sample via sampler2DArray. Same surface may be uploaded both ways during the N.5/N.6 transition; doubling is bounded and acceptable. After N.6 retires legacy renderers entirely, the legacy UploadRgba8 becomes unused and is deleted. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/AcDream.App/Rendering/TextureCache.cs | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/AcDream.App/Rendering/TextureCache.cs b/src/AcDream.App/Rendering/TextureCache.cs index 6d10200..a53dfd7 100644 --- a/src/AcDream.App/Rendering/TextureCache.cs +++ b/src/AcDream.App/Rendering/TextureCache.cs @@ -279,6 +279,38 @@ public sealed unsafe class TextureCache : Wb.ITextureCachePerInstance, IDisposab return tex; } + /// + /// Variant of that uploads pixel data as a 1-layer + /// Texture2DArray. Required by the WB modern rendering path which samples via + /// sampler2DArray in its bindless shader. Pixel data is identical. + /// + private uint UploadRgba8AsLayer1Array(DecodedTexture decoded) + { + uint tex = _gl.GenTexture(); + _gl.BindTexture(TextureTarget.Texture2DArray, tex); + + fixed (byte* p = decoded.Rgba8) + _gl.TexImage3D( + TextureTarget.Texture2DArray, + 0, + InternalFormat.Rgba8, + (uint)decoded.Width, + (uint)decoded.Height, + 1, + 0, + PixelFormat.Rgba, + PixelType.UnsignedByte, + p); + + _gl.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); + _gl.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); + _gl.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); + _gl.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); + + _gl.BindTexture(TextureTarget.Texture2DArray, 0); + return tex; + } + public void Dispose() { foreach (var h in _handlesBySurfaceId.Values)