[Gpu] Keep fallback occlusion results coherent and conservatively visible
This commit is contained in:
parent
aaed66bf83
commit
428c03eb32
|
|
@ -435,15 +435,21 @@ public sealed partial class GpuCommandInterpreter
|
|||
throw _host.Fatal($"The occlusion-counter dump is invalid: index=0x{eventIndex:X8} address=0x{eventAddress:X16}.");
|
||||
}
|
||||
|
||||
// Publish visible occlusion results for each depth block.
|
||||
// Until real sample queries are implemented, conservatively report visibility.
|
||||
// A one-sample delta can disappear when the guest scales or reduces the counts.
|
||||
const ulong visibleCounterStep = 0x2FFFFFF;
|
||||
const ulong readyBit = 1UL << 63;
|
||||
var result = readyBit | SyntheticOcclusionCounter;
|
||||
for (var depthBlock = 0u; depthBlock < 16u; depthBlock++)
|
||||
{
|
||||
WriteQword(eventAddress + ((ulong)depthBlock * 2 * sizeof(ulong)), result);
|
||||
// Query reducers can read a GPU-cached copy of this range. Use the same
|
||||
// ordered transfer path as clears instead of changing only CPU backing.
|
||||
var destination = eventAddress + ((ulong)depthBlock * 2 * sizeof(ulong));
|
||||
_host.FillBuffer(destination, sizeof(uint), (uint)result, false);
|
||||
_host.FillBuffer(destination + sizeof(uint), sizeof(uint), (uint)(result >> 32), false);
|
||||
}
|
||||
|
||||
SyntheticOcclusionCounter = (SyntheticOcclusionCounter + 1) & (readyBit - 1);
|
||||
SyntheticOcclusionCounter = (SyntheticOcclusionCounter + visibleCounterStep) & (readyBit - 1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -325,12 +325,16 @@ public sealed class GpuCommandInterpreterLabelTests
|
|||
Assert.Contains("event type is unknown", runner.RunExpectingFatal(StreamRunner.Packet(PacketOpcode.EventWrite, 0x3F)).Message);
|
||||
|
||||
runner.Run(StreamRunner.Packet(PacketOpcode.EventWrite, 0x39 | (1u << 8), StreamRunner.Low(Label), StreamRunner.High(Label)));
|
||||
// CPU-only stores leave GPU query-reduction inputs stale. Require the
|
||||
// host transfer path for both words of every counter, including ready.
|
||||
Assert.Equal(32, runner.Host.Calls.Count);
|
||||
Assert.All(runner.Host.Calls, call => Assert.StartsWith("fill ", call));
|
||||
Assert.Equal(1UL << 63, runner.Host.ReadQword(Label));
|
||||
Assert.Equal(1UL << 63, runner.Host.ReadQword(Label + 15 * 16));
|
||||
Assert.Equal(0UL, runner.Host.ReadQword(Label + 8));
|
||||
|
||||
runner.Run(StreamRunner.Packet(PacketOpcode.EventWrite, 0x39 | (1u << 8), StreamRunner.Low(Label), StreamRunner.High(Label)));
|
||||
Assert.Equal((1UL << 63) | 1, runner.Host.ReadQword(Label));
|
||||
Assert.Equal((1UL << 63) | 0x2FFFFFFUL, runner.Host.ReadQword(Label));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
Loading…
Reference in New Issue