Shader ownership change
This commit is contained in:
94
tests/RenderCadenceCompositorClockTests.cpp
Normal file
94
tests/RenderCadenceCompositorClockTests.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
#include "RenderCadenceClock.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
|
||||
namespace
|
||||
{
|
||||
int gFailures = 0;
|
||||
|
||||
void Expect(bool condition, const char* message)
|
||||
{
|
||||
if (condition)
|
||||
return;
|
||||
|
||||
std::cerr << "FAIL: " << message << "\n";
|
||||
++gFailures;
|
||||
}
|
||||
|
||||
void TestEarlyPollWaitsWithoutAdvancing()
|
||||
{
|
||||
using Clock = RenderCadenceClock::Clock;
|
||||
RenderCadenceClock cadence(16.0);
|
||||
const auto start = Clock::now();
|
||||
cadence.Reset(start);
|
||||
|
||||
const auto tick = cadence.Poll(start - std::chrono::milliseconds(1));
|
||||
Expect(!tick.due, "early poll is not due");
|
||||
Expect(tick.sleepFor > RenderCadenceClock::Duration::zero(), "early poll returns a sleep duration");
|
||||
Expect(cadence.OverrunCount() == 0, "early poll does not count overrun");
|
||||
Expect(cadence.SkippedFrameCount() == 0, "early poll does not skip frames");
|
||||
}
|
||||
|
||||
void TestDuePollRendersWithoutSkipping()
|
||||
{
|
||||
using Clock = RenderCadenceClock::Clock;
|
||||
RenderCadenceClock cadence(16.0);
|
||||
const auto start = Clock::now();
|
||||
cadence.Reset(start);
|
||||
|
||||
const auto tick = cadence.Poll(start);
|
||||
Expect(tick.due, "exact cadence time is due");
|
||||
Expect(tick.skippedFrames == 0, "exact cadence time skips no frames");
|
||||
Expect(cadence.OverrunCount() == 0, "exact cadence time is not an overrun");
|
||||
|
||||
cadence.MarkRendered(start);
|
||||
Expect(cadence.NextRenderTime() > start, "mark rendered advances next render time");
|
||||
}
|
||||
|
||||
void TestLatePollRecordsSkippedFrames()
|
||||
{
|
||||
using Clock = RenderCadenceClock::Clock;
|
||||
RenderCadenceClock cadence(10.0);
|
||||
const auto start = Clock::now();
|
||||
cadence.Reset(start);
|
||||
|
||||
const auto tick = cadence.Poll(start + std::chrono::milliseconds(35));
|
||||
Expect(tick.due, "late poll is due");
|
||||
Expect(tick.skippedFrames == 3, "late poll records skipped frame intervals");
|
||||
Expect(cadence.OverrunCount() == 1, "late poll records overrun");
|
||||
Expect(cadence.SkippedFrameCount() == 3, "late poll accumulates skipped frames");
|
||||
}
|
||||
|
||||
void TestMarkRenderedRebasesAfterLargeStall()
|
||||
{
|
||||
using Clock = RenderCadenceClock::Clock;
|
||||
RenderCadenceClock cadence(10.0);
|
||||
const auto start = Clock::now();
|
||||
cadence.Reset(start);
|
||||
|
||||
const auto stalled = start + std::chrono::milliseconds(100);
|
||||
cadence.MarkRendered(stalled);
|
||||
|
||||
const auto next = cadence.NextRenderTime();
|
||||
Expect(next > stalled, "large stall rebases next render time after now");
|
||||
Expect(next - stalled <= std::chrono::milliseconds(11), "large stall rebases to roughly one frame ahead");
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
TestEarlyPollWaitsWithoutAdvancing();
|
||||
TestDuePollRendersWithoutSkipping();
|
||||
TestLatePollRecordsSkippedFrames();
|
||||
TestMarkRenderedRebasesAfterLargeStall();
|
||||
|
||||
if (gFailures != 0)
|
||||
{
|
||||
std::cerr << gFailures << " cadence clock test failure(s).\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "RenderCadenceCompositor cadence clock tests passed.\n";
|
||||
return 0;
|
||||
}
|
||||
146
tests/RenderCadenceCompositorTelemetryTests.cpp
Normal file
146
tests/RenderCadenceCompositorTelemetryTests.cpp
Normal file
@@ -0,0 +1,146 @@
|
||||
#include "CadenceTelemetry.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
namespace
|
||||
{
|
||||
int gFailures = 0;
|
||||
|
||||
void Expect(bool condition, const char* message)
|
||||
{
|
||||
if (condition)
|
||||
return;
|
||||
|
||||
std::cerr << "FAIL: " << message << "\n";
|
||||
++gFailures;
|
||||
}
|
||||
|
||||
struct FakeExchangeMetrics
|
||||
{
|
||||
std::size_t freeCount = 0;
|
||||
std::size_t completedCount = 0;
|
||||
std::size_t scheduledCount = 0;
|
||||
uint64_t completedFrames = 0;
|
||||
uint64_t scheduledFrames = 0;
|
||||
};
|
||||
|
||||
struct FakeExchange
|
||||
{
|
||||
FakeExchangeMetrics metrics;
|
||||
FakeExchangeMetrics Metrics() const { return metrics; }
|
||||
};
|
||||
|
||||
struct FakeOutputThreadMetrics
|
||||
{
|
||||
uint64_t completedPollMisses = 0;
|
||||
uint64_t scheduleFailures = 0;
|
||||
};
|
||||
|
||||
struct FakeOutputThread
|
||||
{
|
||||
FakeOutputThreadMetrics metrics;
|
||||
FakeOutputThreadMetrics Metrics() const { return metrics; }
|
||||
};
|
||||
|
||||
struct FakeOutputMetrics
|
||||
{
|
||||
uint64_t completions = 0;
|
||||
uint64_t displayedLate = 0;
|
||||
uint64_t dropped = 0;
|
||||
uint64_t scheduleFailures = 0;
|
||||
bool actualBufferedFramesAvailable = false;
|
||||
uint64_t actualBufferedFrames = 0;
|
||||
double scheduleCallMilliseconds = 0.0;
|
||||
};
|
||||
|
||||
struct FakeOutput
|
||||
{
|
||||
FakeOutputMetrics metrics;
|
||||
FakeOutputMetrics Metrics() const { return metrics; }
|
||||
};
|
||||
|
||||
struct FakeRenderThreadMetrics
|
||||
{
|
||||
uint64_t shaderBuildsCommitted = 0;
|
||||
uint64_t shaderBuildFailures = 0;
|
||||
};
|
||||
|
||||
struct FakeRenderThread
|
||||
{
|
||||
FakeRenderThreadMetrics metrics;
|
||||
FakeRenderThreadMetrics GetMetrics() const { return metrics; }
|
||||
};
|
||||
|
||||
void TestTelemetrySamplesCompletedPollMissesAndShaderCounts()
|
||||
{
|
||||
RenderCadenceCompositor::CadenceTelemetry telemetry;
|
||||
FakeExchange exchange;
|
||||
exchange.metrics.freeCount = 7;
|
||||
exchange.metrics.completedCount = 1;
|
||||
exchange.metrics.scheduledCount = 4;
|
||||
exchange.metrics.completedFrames = 100;
|
||||
exchange.metrics.scheduledFrames = 96;
|
||||
|
||||
FakeOutput output;
|
||||
output.metrics.actualBufferedFramesAvailable = true;
|
||||
output.metrics.actualBufferedFrames = 4;
|
||||
|
||||
FakeOutputThread outputThread;
|
||||
outputThread.metrics.completedPollMisses = 12;
|
||||
outputThread.metrics.scheduleFailures = 0;
|
||||
|
||||
FakeRenderThread renderThread;
|
||||
renderThread.metrics.shaderBuildsCommitted = 1;
|
||||
renderThread.metrics.shaderBuildFailures = 0;
|
||||
|
||||
const auto snapshot = telemetry.Sample(exchange, output, outputThread, renderThread);
|
||||
Expect(snapshot.freeFrames == 7, "free frame count is sampled");
|
||||
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.shaderBuildsCommitted == 1, "shader committed count is sampled");
|
||||
Expect(snapshot.shaderBuildFailures == 0, "shader failure count is sampled");
|
||||
Expect(snapshot.deckLinkBufferedAvailable, "buffer telemetry availability is sampled");
|
||||
Expect(snapshot.deckLinkBuffered == 4, "buffer depth is sampled");
|
||||
}
|
||||
|
||||
void TestTelemetryComputesRatesFromDeltas()
|
||||
{
|
||||
RenderCadenceCompositor::CadenceTelemetry telemetry;
|
||||
FakeExchange exchange;
|
||||
FakeOutput output;
|
||||
FakeOutputThread outputThread;
|
||||
FakeRenderThread renderThread;
|
||||
|
||||
exchange.metrics.completedFrames = 10;
|
||||
exchange.metrics.scheduledFrames = 10;
|
||||
(void)telemetry.Sample(exchange, output, outputThread, renderThread);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||
|
||||
exchange.metrics.completedFrames = 20;
|
||||
exchange.metrics.scheduledFrames = 19;
|
||||
const auto snapshot = telemetry.Sample(exchange, output, outputThread, renderThread);
|
||||
Expect(snapshot.sampleSeconds > 0.0, "second telemetry sample has elapsed time");
|
||||
Expect(snapshot.renderFps > 0.0, "render fps is computed from completed frame delta");
|
||||
Expect(snapshot.scheduleFps > 0.0, "schedule fps is computed from scheduled frame delta");
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
TestTelemetrySamplesCompletedPollMissesAndShaderCounts();
|
||||
TestTelemetryComputesRatesFromDeltas();
|
||||
|
||||
if (gFailures != 0)
|
||||
{
|
||||
std::cerr << gFailures << " telemetry test failure(s).\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "RenderCadenceCompositor telemetry tests passed.\n";
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user