Skip to content

Commit 529615b

Browse files
Align chunk tile heights to 16-row bins
1 parent acca457 commit 529615b

File tree

1 file changed

+18
-9
lines changed

1 file changed

+18
-9
lines changed

src/ImageSharp.Drawing.WebGPU/WebGPUSceneDispatch.cs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,11 +1317,24 @@ private static uint ScaleCount(uint value, uint numerator, uint denominator)
13171317
=> Math.Max(1U, checked((uint)Math.Max(1UL, ((ulong)Math.Max(value, 1U) * numerator) / Math.Max(denominator, 1U))));
13181318

13191319
/// <summary>
1320-
/// Aligns a chunk height down to one coarse bin when possible so tile-local scratch buffers stay bin-shaped.
1320+
/// Aligns a chunk height to one coarse bin (16 tile rows) so the next chunk's tile-y start stays bin-aligned.
13211321
/// </summary>
13221322
/// <param name="tileHeight">The candidate real chunk height, in tile rows.</param>
13231323
/// <param name="maximumTileHeight">The maximum tile height allowed for this chunk.</param>
1324-
/// <returns>The aligned chunk height, preserving short tail chunks when necessary.</returns>
1324+
/// <returns>The aligned chunk height, preserving short tail chunks only when there are no further rows to render.</returns>
1325+
/// <remarks>
1326+
/// <para>
1327+
/// Coarse rasterization reads the global binning grid using <c>chunk_tile_y_start / N_TILE_Y</c> and lays its
1328+
/// per-bin tiles out starting at <c>chunk_tile_y_start</c>. If a chunk's height is not a multiple of
1329+
/// <c>N_TILE_Y</c> (16), the next chunk's <c>chunk_tile_y_start</c> ends up bin-misaligned and the coarse
1330+
/// dispatch reads the wrong bin's content for the misaligned rows, dropping coverage in those rows.
1331+
/// </para>
1332+
/// <para>
1333+
/// This method therefore rounds non-final chunks up to the next multiple of 16 (the smallest legal chunk size
1334+
/// that preserves bin alignment) and only permits a sub-bin tail when <paramref name="maximumTileHeight"/>
1335+
/// itself is a sub-bin remainder — i.e., this is the final chunk and there are no further rows to render.
1336+
/// </para>
1337+
/// </remarks>
13251338
[MethodImpl(MethodImplOptions.AggressiveInlining)]
13261339
private static uint AlignChunkTileHeight(uint tileHeight, uint maximumTileHeight)
13271340
{
@@ -1330,13 +1343,9 @@ private static uint AlignChunkTileHeight(uint tileHeight, uint maximumTileHeight
13301343
return maximumTileHeight;
13311344
}
13321345

1333-
if (tileHeight <= 16U)
1334-
{
1335-
return tileHeight;
1336-
}
1337-
1338-
uint alignedTileHeight = tileHeight & ~15U;
1339-
return alignedTileHeight > 0U ? alignedTileHeight : 16U;
1346+
// Round up to a full bin row so the next chunk starts on a bin boundary.
1347+
uint alignedTileHeight = AlignUp(Math.Max(tileHeight, 1U), 16U);
1348+
return alignedTileHeight >= maximumTileHeight ? maximumTileHeight : alignedTileHeight;
13401349
}
13411350

13421351
/// <summary>

0 commit comments

Comments
 (0)