Render timing

This commit is contained in:
Aiden
2026-05-12 22:18:27 +10:00
parent 13586c611a
commit 4a049a557a
15 changed files with 260 additions and 24 deletions

View File

@@ -154,6 +154,26 @@ void TestCompletedPollMissIsCounted()
SystemFrameExchangeMetrics metrics = exchange.Metrics();
Expect(metrics.completedPollMisses == 1, "completed poll miss is counted");
}
void TestStableCompletedDepthCanBeObserved()
{
SystemFrameExchange exchange(MakeConfig(1));
SystemFrame frame;
Expect(exchange.AcquireForRender(frame), "stable-depth frame can be acquired");
Expect(exchange.PublishCompleted(frame), "stable-depth frame can be completed");
Expect(
exchange.WaitForStableCompletedDepth(1, std::chrono::milliseconds(1), std::chrono::milliseconds(50)),
"stable completed depth can be observed");
}
void TestStableCompletedDepthTimesOut()
{
SystemFrameExchange exchange(MakeConfig(1));
Expect(
!exchange.WaitForStableCompletedDepth(1, std::chrono::milliseconds(1), std::chrono::milliseconds(1)),
"missing stable completed depth times out");
}
}
int main()
@@ -164,6 +184,8 @@ int main()
TestGenerationValidationRejectsStaleFrames();
TestPixelFormatAwareSizing();
TestCompletedPollMissIsCounted();
TestStableCompletedDepthCanBeObserved();
TestStableCompletedDepthTimesOut();
if (gFailures != 0)
{

View File

@@ -43,6 +43,13 @@ int main()
RenderCadenceCompositor::CadenceTelemetrySnapshot telemetry;
telemetry.renderFps = 59.94;
telemetry.renderFrameMilliseconds = 2.5;
telemetry.renderFrameBudgetUsedPercent = 15.0;
telemetry.renderFrameMaxMilliseconds = 4.0;
telemetry.readbackQueueMilliseconds = 0.6;
telemetry.completedReadbackCopyMilliseconds = 1.2;
telemetry.completedDrops = 3;
telemetry.acquireMisses = 4;
telemetry.shaderBuildsCommitted = 1;
const std::filesystem::path root = MakeTestRoot();
@@ -98,6 +105,13 @@ int main()
ExpectContains(json, "\"type\":\"color\"", "state JSON should serialize parameter types for the UI");
ExpectContains(json, "\"width\":1920", "state JSON should expose output width");
ExpectContains(json, "\"height\":1080", "state JSON should expose output height");
ExpectContains(json, "\"renderMs\":2.5", "state JSON should expose top-level render timing");
ExpectContains(json, "\"budgetUsedPercent\":15", "state JSON should expose top-level render budget percentage");
ExpectContains(json, "\"renderFrameMs\":2.5", "state JSON should expose cadence render timing");
ExpectContains(json, "\"readbackQueueMs\":0.6", "state JSON should expose readback queue timing");
ExpectContains(json, "\"completedReadbackCopyMs\":1.2", "state JSON should expose completed readback copy timing");
ExpectContains(json, "\"completedDrops\":3", "state JSON should expose completed drop count");
ExpectContains(json, "\"acquireMisses\":4", "state JSON should expose acquire miss count");
std::filesystem::remove_all(root);

View File

@@ -26,6 +26,8 @@ struct FakeExchangeMetrics
std::size_t scheduledCount = 0;
uint64_t completedFrames = 0;
uint64_t scheduledFrames = 0;
uint64_t completedDrops = 0;
uint64_t acquireMisses = 0;
};
struct FakeExchange
@@ -69,6 +71,11 @@ struct FakeRenderThreadMetrics
uint64_t skippedFrames = 0;
uint64_t shaderBuildsCommitted = 0;
uint64_t shaderBuildFailures = 0;
double renderFrameMilliseconds = 0.0;
double renderFrameBudgetUsedPercent = 0.0;
double renderFrameMaxMilliseconds = 0.0;
double readbackQueueMilliseconds = 0.0;
double completedReadbackCopyMilliseconds = 0.0;
uint64_t inputFramesReceived = 0;
uint64_t inputFramesDropped = 0;
uint64_t inputConsumeMisses = 0;
@@ -96,6 +103,8 @@ void TestTelemetrySamplesCompletedPollMissesAndShaderCounts()
exchange.metrics.scheduledCount = 4;
exchange.metrics.completedFrames = 100;
exchange.metrics.scheduledFrames = 96;
exchange.metrics.completedDrops = 2;
exchange.metrics.acquireMisses = 3;
FakeOutput output;
output.metrics.actualBufferedFramesAvailable = true;
@@ -110,6 +119,11 @@ void TestTelemetrySamplesCompletedPollMissesAndShaderCounts()
renderThread.metrics.skippedFrames = 8;
renderThread.metrics.shaderBuildsCommitted = 1;
renderThread.metrics.shaderBuildFailures = 0;
renderThread.metrics.renderFrameMilliseconds = 2.5;
renderThread.metrics.renderFrameBudgetUsedPercent = 15.0;
renderThread.metrics.renderFrameMaxMilliseconds = 4.0;
renderThread.metrics.readbackQueueMilliseconds = 0.6;
renderThread.metrics.completedReadbackCopyMilliseconds = 1.2;
renderThread.metrics.inputFramesReceived = 9;
renderThread.metrics.inputFramesDropped = 2;
renderThread.metrics.inputConsumeMisses = 3;
@@ -126,10 +140,17 @@ void TestTelemetrySamplesCompletedPollMissesAndShaderCounts()
Expect(snapshot.completedFrames == 1, "completed frame count is sampled");
Expect(snapshot.scheduledFrames == 4, "scheduled frame count is sampled");
Expect(snapshot.completedPollMisses == 12, "completed poll misses are sampled");
Expect(snapshot.completedDrops == 2, "completed drops are sampled");
Expect(snapshot.acquireMisses == 3, "acquire misses are sampled");
Expect(snapshot.clockOverruns == 5, "clock overrun count is sampled");
Expect(snapshot.clockSkippedFrames == 8, "clock skipped frame count is sampled");
Expect(snapshot.shaderBuildsCommitted == 1, "shader committed count is sampled");
Expect(snapshot.shaderBuildFailures == 0, "shader failure count is sampled");
Expect(snapshot.renderFrameMilliseconds == 2.5, "render frame timing is sampled");
Expect(snapshot.renderFrameBudgetUsedPercent == 15.0, "render budget percentage is sampled");
Expect(snapshot.renderFrameMaxMilliseconds == 4.0, "render frame max timing is sampled");
Expect(snapshot.readbackQueueMilliseconds == 0.6, "readback queue timing is sampled");
Expect(snapshot.completedReadbackCopyMilliseconds == 1.2, "completed readback copy timing is sampled");
Expect(snapshot.inputFramesReceived == 9, "input received count is sampled");
Expect(snapshot.inputFramesDropped == 2, "input dropped count is sampled");
Expect(snapshot.inputConsumeMisses == 3, "input consume miss count is sampled");
@@ -179,6 +200,8 @@ void TestTelemetrySerializesToJson()
snapshot.scheduledTotal = 118;
snapshot.completedPollMisses = 3;
snapshot.scheduleFailures = 0;
snapshot.completedDrops = 4;
snapshot.acquireMisses = 5;
snapshot.completions = 117;
snapshot.displayedLate = 1;
snapshot.dropped = 2;
@@ -186,6 +209,11 @@ void TestTelemetrySerializesToJson()
snapshot.clockSkippedFrames = 5;
snapshot.shaderBuildsCommitted = 1;
snapshot.shaderBuildFailures = 0;
snapshot.renderFrameMilliseconds = 2.5;
snapshot.renderFrameBudgetUsedPercent = 15.0;
snapshot.renderFrameMaxMilliseconds = 4.0;
snapshot.readbackQueueMilliseconds = 0.6;
snapshot.completedReadbackCopyMilliseconds = 1.2;
snapshot.inputFramesReceived = 10;
snapshot.inputFramesDropped = 1;
snapshot.inputConsumeMisses = 2;
@@ -213,10 +241,14 @@ void TestTelemetrySerializesToJson()
"\"free\":7,\"completed\":1,\"scheduled\":4,"
"\"renderedTotal\":120,\"scheduledTotal\":118,"
"\"completedPollMisses\":3,\"scheduleFailures\":0,"
"\"completedDrops\":4,\"acquireMisses\":5,"
"\"completions\":117,\"late\":1,\"dropped\":2,"
"\"clockOverruns\":3,\"clockSkippedFrames\":5,"
"\"clockOveruns\":3,\"clockSkipped\":5,"
"\"shaderCommitted\":1,\"shaderFailures\":0,"
"\"renderFrameMs\":2.5,\"renderFrameBudgetUsedPercent\":15,"
"\"renderFrameMaxMs\":4,\"readbackQueueMs\":0.6,"
"\"completedReadbackCopyMs\":1.2,"
"\"inputFramesReceived\":10,\"inputFramesDropped\":1,"
"\"inputConsumeMisses\":2,\"inputUploadMisses\":3,"
"\"inputReadyFrames\":1,\"inputReadingFrames\":0,"