phase(N.5) Task 9 fixup: layout assertion + DrawCommandStride const

Code quality review caught:
- sizeofDEIC was a local; promoted to public const DrawCommandStride
  so tests can reference it symbolically.
- BatchDataPublic layout invariant (size + field offsets) wasn't
  asserted in tests. Added BatchDataPublic_LayoutMatchesPrivateBatchData
  + DrawCommandStride_MatchesStructSize tests to gate Task 10's
  MemoryMarshal.Cast<BatchData, BatchDataPublic> safety.
- Plan doc updated: BatchDataPublic spec was Pack=4 (wrong — must
  match private BatchData's Pack=8 for the cast to work). Implementation
  was already correct; plan now matches.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-08 20:42:49 +02:00
parent 9a7a250b62
commit b163c53622
3 changed files with 30 additions and 5 deletions

View file

@ -91,4 +91,23 @@ public sealed class WbDrawDispatcherIndirectBuilderTests
Assert.Equal(1, result.OpaqueCount);
Assert.Equal(0, result.TransparentCount);
}
[Fact]
public void BatchDataPublic_LayoutMatchesPrivateBatchData()
{
// Task 10 will use MemoryMarshal.Cast<BatchData, BatchDataPublic> to
// expose the dispatcher's per-frame BatchData[] scratch to BuildIndirectArrays
// without copying. The cast is only safe if the structs have identical
// layout (size, field offsets). Both use [StructLayout(Sequential, Pack=8)].
Assert.Equal(16, System.Runtime.CompilerServices.Unsafe.SizeOf<WbDrawDispatcher.BatchDataPublic>());
Assert.Equal(0, (int)System.Runtime.InteropServices.Marshal.OffsetOf<WbDrawDispatcher.BatchDataPublic>(nameof(WbDrawDispatcher.BatchDataPublic.TextureHandle)));
Assert.Equal(8, (int)System.Runtime.InteropServices.Marshal.OffsetOf<WbDrawDispatcher.BatchDataPublic>(nameof(WbDrawDispatcher.BatchDataPublic.TextureLayer)));
Assert.Equal(12, (int)System.Runtime.InteropServices.Marshal.OffsetOf<WbDrawDispatcher.BatchDataPublic>(nameof(WbDrawDispatcher.BatchDataPublic.Flags)));
}
[Fact]
public void DrawCommandStride_MatchesStructSize()
{
Assert.Equal(WbDrawDispatcher.DrawCommandStride, System.Runtime.CompilerServices.Unsafe.SizeOf<DrawElementsIndirectCommand>());
}
}