feat(rendering): add volumetric performance coverage
This commit is contained in:
@@ -25,6 +25,8 @@
|
||||
#include "../../RHI/integration/fixtures/RHIIntegrationFixture.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <chrono>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
@@ -41,6 +43,15 @@ constexpr uint32_t kFrameWidth = 1280;
|
||||
constexpr uint32_t kFrameHeight = 720;
|
||||
constexpr const char* kCloudVolumeRelativePath = "Res/Volumes/cloud.nvdb";
|
||||
|
||||
struct StableFrameStats {
|
||||
int warmupFrames = 0;
|
||||
int measuredFrames = 0;
|
||||
double averageFrameTimeMs = 0.0;
|
||||
double minFrameTimeMs = 0.0;
|
||||
double maxFrameTimeMs = 0.0;
|
||||
double averageFps = 0.0;
|
||||
};
|
||||
|
||||
inline Material* CreateVolumetricMaterial(
|
||||
const char* name,
|
||||
const char* path,
|
||||
@@ -50,7 +61,10 @@ inline Material* CreateVolumetricMaterial(
|
||||
float maxSteps = 2000.0f,
|
||||
float ambientStrength = 0.005f,
|
||||
const Vector3& lightDirection = Vector3(0.5f, 0.8f, 0.3f),
|
||||
float lightSamples = 8.0f) {
|
||||
float lightSamples = 8.0f,
|
||||
float enableEntryHdda = 1.0f,
|
||||
float enableEmptySpaceSkipping = 1.0f,
|
||||
float enableEarlyTermination = 1.0f) {
|
||||
auto* material = new Material();
|
||||
IResource::ConstructParams params = {};
|
||||
params.name = name;
|
||||
@@ -66,6 +80,9 @@ inline Material* CreateVolumetricMaterial(
|
||||
material->SetFloat("_AmbientStrength", ambientStrength);
|
||||
material->SetFloat4("_LightDirection", Vector4(lightDirection, 0.0f));
|
||||
material->SetFloat("_LightSamples", lightSamples);
|
||||
material->SetFloat("_EnableEntryHdda", enableEntryHdda);
|
||||
material->SetFloat("_EnableEmptySpaceSkipping", enableEmptySpaceSkipping);
|
||||
material->SetFloat("_EnableEarlyTermination", enableEarlyTermination);
|
||||
return material;
|
||||
}
|
||||
|
||||
@@ -250,6 +267,72 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
StableFrameStats RenderAndMeasureStableFrames(
|
||||
int warmupFrameCount,
|
||||
int measuredFrameCount,
|
||||
const char* screenshotFilename = nullptr) {
|
||||
StableFrameStats stats = {};
|
||||
stats.warmupFrames = warmupFrameCount;
|
||||
stats.measuredFrames = measuredFrameCount;
|
||||
|
||||
RHICommandQueue* commandQueue = GetCommandQueue();
|
||||
RHISwapChain* swapChain = GetSwapChain();
|
||||
if (commandQueue == nullptr || swapChain == nullptr) {
|
||||
ADD_FAILURE() << "RenderAndMeasureStableFrames requires a valid command queue and swap chain";
|
||||
return stats;
|
||||
}
|
||||
|
||||
auto renderPresentedFrame = [&]() {
|
||||
BeginRender();
|
||||
RenderFrame();
|
||||
swapChain->Present(0, 0);
|
||||
};
|
||||
|
||||
for (int frameIndex = 0; frameIndex < warmupFrameCount; ++frameIndex) {
|
||||
if (frameIndex > 0) {
|
||||
commandQueue->WaitForPreviousFrame();
|
||||
}
|
||||
renderPresentedFrame();
|
||||
}
|
||||
|
||||
if (warmupFrameCount > 0) {
|
||||
commandQueue->WaitForPreviousFrame();
|
||||
}
|
||||
|
||||
using Clock = std::chrono::steady_clock;
|
||||
double totalFrameTimeMs = 0.0;
|
||||
double minFrameTimeMs = std::numeric_limits<double>::max();
|
||||
double maxFrameTimeMs = 0.0;
|
||||
for (int frameIndex = 0; frameIndex < measuredFrameCount; ++frameIndex) {
|
||||
const Clock::time_point frameStart = Clock::now();
|
||||
renderPresentedFrame();
|
||||
commandQueue->WaitForPreviousFrame();
|
||||
const double frameTimeMs = std::chrono::duration<double, std::milli>(
|
||||
Clock::now() - frameStart).count();
|
||||
totalFrameTimeMs += frameTimeMs;
|
||||
minFrameTimeMs = (std::min)(minFrameTimeMs, frameTimeMs);
|
||||
maxFrameTimeMs = (std::max)(maxFrameTimeMs, frameTimeMs);
|
||||
}
|
||||
|
||||
if (measuredFrameCount > 0) {
|
||||
stats.averageFrameTimeMs = totalFrameTimeMs / static_cast<double>(measuredFrameCount);
|
||||
stats.minFrameTimeMs = minFrameTimeMs;
|
||||
stats.maxFrameTimeMs = maxFrameTimeMs;
|
||||
stats.averageFps = stats.averageFrameTimeMs > 0.0
|
||||
? 1000.0 / stats.averageFrameTimeMs
|
||||
: 0.0;
|
||||
}
|
||||
|
||||
if (screenshotFilename != nullptr && screenshotFilename[0] != '\0') {
|
||||
BeginRender();
|
||||
RenderFrame();
|
||||
commandQueue->WaitForIdle();
|
||||
EXPECT_TRUE(TakeScreenshot(screenshotFilename));
|
||||
}
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
RHIResourceView* GetCurrentBackBufferView() {
|
||||
const int backBufferIndex = GetCurrentBackBufferIndex();
|
||||
if (backBufferIndex < 0) {
|
||||
|
||||
Reference in New Issue
Block a user