using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using AcDream.App.Rendering.Wb;
using Xunit;
namespace AcDream.App.Tests.Rendering.Wb;
///
/// Campaign V slice V2 (2026-07-27): CPU-side proof that
/// — EnvCellRenderer's per-batch GPU struct,
/// sharing mesh_modern.vert's BatchData shader-side layout with
/// WbDrawDispatcher — packs at the exact std430 offsets the shader expects
/// after TextureHandle (a raw 64-bit ARB_bindless_texture handle) became
/// TextureTableIndex (a slot into the binding=9 handle table). Mirrors
/// ClipFrameLayoutTests' role for ClipFrame and
/// WbDrawDispatcherIndirectBuilderTests.BatchDataPublic_LayoutMatchesPrivateBatchData
/// for WbDrawDispatcher's own BatchData — a silent layout drift here would
/// desync EnvCellRenderer's uploaded bytes from what mesh_modern.vert reads,
/// with no build error.
///
/// Layout under test (std430, 16 bytes total):
/// offset 0 : uint TextureTableIndex
/// offset 4 : uint Reserved (pad)
/// offset 8 : uint TextureIndex (layer within the texture array)
/// offset 12 : uint Flags
///
public class ModernBatchDataLayoutTests
{
[Fact]
public void Size_Is16Bytes_MatchingGpuBatchDataStride()
{
Assert.Equal(16, Unsafe.SizeOf());
}
[Fact]
public void FieldOffsets_MatchStd430Layout()
{
Assert.Equal(0, (int)Marshal.OffsetOf(nameof(ModernBatchData.TextureTableIndex)));
Assert.Equal(4, (int)Marshal.OffsetOf(nameof(ModernBatchData.Reserved)));
Assert.Equal(8, (int)Marshal.OffsetOf(nameof(ModernBatchData.TextureIndex)));
Assert.Equal(12, (int)Marshal.OffsetOf(nameof(ModernBatchData.Flags)));
}
[Fact]
public void FieldValues_RoundTripThroughTheStruct()
{
var data = new ModernBatchData
{
TextureTableIndex = 7u,
TextureIndex = 3u,
};
Assert.Equal(7u, data.TextureTableIndex);
Assert.Equal(0u, data.Reserved);
Assert.Equal(3u, data.TextureIndex);
Assert.Equal(0u, data.Flags);
}
}