[Gpu] Upload complete unchecked constant vertex attributes
This commit is contained in:
parent
44e223c5c8
commit
d5de44b6fb
|
|
@ -360,7 +360,24 @@ public static class VertexInputResolver
|
|||
for (var bufferIndex = 0; bufferIndex < buffers.Count; bufferIndex++)
|
||||
{
|
||||
var buffer = buffers[bufferIndex];
|
||||
result[bufferIndex] = new VertexInputBuffer(buffer.Address, buffer.Stride, buffer.RecordCount, buffer.FetchIndex != 0);
|
||||
uint minimumFetchBytes = 0;
|
||||
foreach (var resourceIndex in buffer.AttributeIndices)
|
||||
{
|
||||
var resource = resources[resourceIndex];
|
||||
var descriptor = resource.Descriptor;
|
||||
// OOB_SELECT=2 only tests for an unbound (zero-record) descriptor.
|
||||
// A constant stream still reads the whole formatted element, even
|
||||
// when NUM_RECORDS is smaller than that element's byte width.
|
||||
if (descriptor.Stride == 0 && descriptor.OutOfBounds == 2 && descriptor.RecordCount != 0 &&
|
||||
VertexAttributeFormats.TryResolve(in descriptor, 4, out var format, out _))
|
||||
{
|
||||
minimumFetchBytes = Math.Max(minimumFetchBytes, Images.ViewFormatRules.BlockBytes(format));
|
||||
}
|
||||
}
|
||||
result[bufferIndex] = new VertexInputBuffer(buffer.Address, buffer.Stride, buffer.RecordCount, buffer.FetchIndex != 0)
|
||||
{
|
||||
MinimumFetchBytes = minimumFetchBytes,
|
||||
};
|
||||
foreach (var resourceIndex in buffer.AttributeIndices)
|
||||
{
|
||||
var resource = resources[resourceIndex];
|
||||
|
|
|
|||
|
|
@ -100,7 +100,9 @@ public readonly record struct DispatchThreadLimits(uint X, uint Y, uint Z);
|
|||
// The vertex buffer words of one fetch slot as the vertex program declares them.
|
||||
public readonly record struct VertexInputBuffer(ulong Address, uint Stride, uint RecordCount, bool PerInstance = false)
|
||||
{
|
||||
public ulong Size => Stride != 0 ? (ulong)Stride * RecordCount : RecordCount;
|
||||
public uint MinimumFetchBytes { get; init; }
|
||||
|
||||
public ulong Size => Math.Max(Stride != 0 ? (ulong)Stride * RecordCount : RecordCount, MinimumFetchBytes);
|
||||
}
|
||||
|
||||
// One attribute of the vertex tables: its buffer words, the registers it fills and its buffer slot.
|
||||
|
|
|
|||
|
|
@ -354,4 +354,36 @@ public sealed class VertexInputResolverTests : IDisposable
|
|||
Assert.Contains("records=4/5", fatal.Message);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(74u, 3, 12ul)]
|
||||
[InlineData(77u, 4, 16ul)]
|
||||
[InlineData(77u, 3, 16ul)]
|
||||
[InlineData(64u, 2, 8ul)]
|
||||
public void MergeBuffers_ConstantUncheckedStreamIncludesFullFormattedFetch(uint format, int components, ulong expectedSize)
|
||||
{
|
||||
var resource = Attribute(StreamBase, 0, 1, 0);
|
||||
resource = resource with
|
||||
{
|
||||
Descriptor = resource.Descriptor with { Word3 = IdentitySelect | (format << 12) | (2u << 28) },
|
||||
RegisterCount = components,
|
||||
};
|
||||
var buffer = Assert.Single(VertexInputResolver.MergeBuffers([resource], ShaderAddress));
|
||||
Assert.Equal(1u, buffer.RecordCount);
|
||||
Assert.Equal(0u, buffer.Stride);
|
||||
Assert.Equal(expectedSize, buffer.Size);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0u, 1u)]
|
||||
[InlineData(1u, 1u)]
|
||||
[InlineData(3u, 1u)]
|
||||
[InlineData(2u, 0u)]
|
||||
public void MergeBuffers_BoundedOrUnboundConstantStreamKeepsDeclaredFootprint(uint outOfBounds, uint records)
|
||||
{
|
||||
var resource = Attribute(StreamBase, 0, records, 0);
|
||||
resource = resource with { Descriptor = resource.Descriptor with { Word3 = resource.Descriptor.Word3 | (outOfBounds << 28) } };
|
||||
var buffer = Assert.Single(VertexInputResolver.MergeBuffers([resource], ShaderAddress));
|
||||
Assert.Equal((ulong)records, buffer.Size);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue