Fixed potential render scene time precision issues.
The timestamp was simply converted from GetTimeAtCurrentTick to a float. Since this value is backed by QueryPerformanceCounter which is 0 at boot, you could see broken animations on the GPU when your system has been on for a long time. So I simplified the RPI's time API (removed unused code), and subtracted the application start time each frame before converting the time value to a float.
Also moved FindShaderInputConstantIndex("m_time") to be called only once, instead of every frame.
Signed-off-by: santorac <55155825+santorac@users.noreply.github.com>
This commit is contained in:
@@ -96,8 +96,7 @@ namespace AZ
|
||||
// SystemTickBus::OnTick
|
||||
void OnSystemTick() override;
|
||||
|
||||
// Fill system time and game time information for simulation or rendering
|
||||
void FillTickTimeInfo();
|
||||
float GetCurrentTime();
|
||||
|
||||
// The set of core asset handlers registered by the system.
|
||||
AZStd::vector<AZStd::unique_ptr<Data::AssetHandler>> m_assetHandlers;
|
||||
@@ -123,8 +122,9 @@ namespace AZ
|
||||
// The job policy used for feature processor's rendering prepare
|
||||
RHI::JobPolicy m_prepareRenderJobPolicy = RHI::JobPolicy::Parallel;
|
||||
|
||||
TickTimeInfo m_tickTime;
|
||||
|
||||
ScriptTimePoint m_startTime;
|
||||
float m_currentSimulationTime = 0.0f;
|
||||
|
||||
RPISystemDescriptor m_descriptor;
|
||||
|
||||
// Reference to the shader asset that is used
|
||||
|
||||
@@ -32,7 +32,6 @@ namespace AZ
|
||||
namespace RPI
|
||||
{
|
||||
class Scene;
|
||||
struct TickTimeInfo;
|
||||
class ShaderResourceGroup;
|
||||
class AnyAsset;
|
||||
class WindowContext;
|
||||
@@ -203,7 +202,7 @@ namespace AZ
|
||||
void OnRemovedFromScene(Scene* scene);
|
||||
|
||||
// Called when this pipeline is about to be rendered
|
||||
void OnStartFrame(const TickTimeInfo& tick);
|
||||
void OnStartFrame(float time);
|
||||
|
||||
// Called when the rendering of current frame is finished.
|
||||
void OnFrameEnd();
|
||||
|
||||
@@ -47,14 +47,6 @@ namespace AZ
|
||||
// Callback function to modify values of a ShaderResourceGroup
|
||||
using ShaderResourceGroupCallback = AZStd::function<void(ShaderResourceGroup*)>;
|
||||
|
||||
//! A structure for ticks which contains system time and game time.
|
||||
struct TickTimeInfo
|
||||
{
|
||||
float m_currentGameTime;
|
||||
float m_gameDeltaTime = 0;
|
||||
};
|
||||
|
||||
|
||||
class Scene final
|
||||
: public SceneRequestBus::Handler
|
||||
{
|
||||
@@ -173,12 +165,14 @@ namespace AZ
|
||||
|
||||
// Cpu simulation which runs all active FeatureProcessor Simulate() functions.
|
||||
// @param jobPolicy if it's JobPolicy::Parallel, the function will spawn a job thread for each FeatureProcessor's simulation.
|
||||
void Simulate(const TickTimeInfo& tickInfo, RHI::JobPolicy jobPolicy);
|
||||
// @param simulationTime the number of seconds since the application started
|
||||
void Simulate(RHI::JobPolicy jobPolicy, float simulationTime);
|
||||
|
||||
// Collect DrawPackets from FeatureProcessors
|
||||
// @param jobPolicy if it's JobPolicy::Parallel, the function will spawn a job thread for each FeatureProcessor's
|
||||
// PrepareRender.
|
||||
void PrepareRender(const TickTimeInfo& tickInfo, RHI::JobPolicy jobPolicy);
|
||||
// @param simulationTime the number of seconds since the application started; this is the same time value that was passed to Simulate()
|
||||
void PrepareRender(RHI::JobPolicy jobPolicy, float simulationTime);
|
||||
|
||||
// Function called when the current frame is finished rendering.
|
||||
void OnFrameEnd();
|
||||
@@ -240,6 +234,7 @@ namespace AZ
|
||||
// Registry which allocates draw filter tag for RenderPipeline
|
||||
RHI::Ptr<RHI::DrawFilterTagRegistry> m_drawFilterTagRegistry;
|
||||
|
||||
RHI::ShaderInputConstantIndex m_timeInputIndex;
|
||||
float m_simulationTime;
|
||||
};
|
||||
|
||||
|
||||
@@ -249,23 +249,25 @@ namespace AZ
|
||||
|
||||
AssetInitBus::Broadcast(&AssetInitBus::Events::PostLoadInit);
|
||||
|
||||
// Update tick time info
|
||||
FillTickTimeInfo();
|
||||
m_currentSimulationTime = GetCurrentTime();
|
||||
|
||||
for (auto& scene : m_scenes)
|
||||
{
|
||||
scene->Simulate(m_tickTime, m_simulationJobPolicy);
|
||||
scene->Simulate(m_simulationJobPolicy, m_currentSimulationTime);
|
||||
}
|
||||
}
|
||||
|
||||
void RPISystem::FillTickTimeInfo()
|
||||
float RPISystem::GetCurrentTime()
|
||||
{
|
||||
AZ::TickRequestBus::BroadcastResult(m_tickTime.m_gameDeltaTime, &AZ::TickRequestBus::Events::GetTickDeltaTime);
|
||||
ScriptTimePoint currentTime;
|
||||
AZ::TickRequestBus::BroadcastResult(currentTime, &AZ::TickRequestBus::Events::GetTimeAtCurrentTick);
|
||||
m_tickTime.m_currentGameTime = static_cast<float>(currentTime.GetMilliseconds());
|
||||
}
|
||||
ScriptTimePoint timeAtCurrentTick;
|
||||
AZ::TickRequestBus::BroadcastResult(timeAtCurrentTick, &AZ::TickRequestBus::Events::GetTimeAtCurrentTick);
|
||||
|
||||
// We subtract the start time to maximize precision of the time value, since we will be converting it to a float.
|
||||
double currentTime = timeAtCurrentTick.GetSeconds() - m_startTime.GetSeconds();
|
||||
|
||||
return aznumeric_cast<float>(currentTime);
|
||||
}
|
||||
|
||||
void RPISystem::RenderTick()
|
||||
{
|
||||
if (!m_systemAssetsInitialized)
|
||||
@@ -282,7 +284,7 @@ namespace AZ
|
||||
// [GFX TODO] We may parallel scenes' prepare render.
|
||||
for (auto& scenePtr : m_scenes)
|
||||
{
|
||||
scenePtr->PrepareRender(m_tickTime, m_prepareRenderJobPolicy);
|
||||
scenePtr->PrepareRender(m_prepareRenderJobPolicy, m_currentSimulationTime);
|
||||
}
|
||||
|
||||
m_rhiSystem.FrameUpdate(
|
||||
|
||||
@@ -375,11 +375,11 @@ namespace AZ
|
||||
m_scene->RemoveRenderPipeline(m_nameId);
|
||||
}
|
||||
|
||||
void RenderPipeline::OnStartFrame(const TickTimeInfo& tick)
|
||||
void RenderPipeline::OnStartFrame(float time)
|
||||
{
|
||||
AZ_PROFILE_SCOPE(RPI, "RenderPipeline: OnStartFrame");
|
||||
|
||||
m_lastRenderStartTime = tick.m_currentGameTime;
|
||||
m_lastRenderStartTime = time;
|
||||
|
||||
OnPassModified();
|
||||
|
||||
|
||||
@@ -42,6 +42,9 @@ namespace AZ
|
||||
{
|
||||
auto shaderAsset = RPISystemInterface::Get()->GetCommonShaderAssetForSrgs();
|
||||
scene->m_srg = ShaderResourceGroup::Create(shaderAsset, sceneSrgLayout->GetName());
|
||||
|
||||
// Set value for constants defined in SceneTimeSrg.azsli
|
||||
scene->m_timeInputIndex = scene->m_srg->FindShaderInputConstantIndex(Name{ "m_time" });
|
||||
}
|
||||
|
||||
return ScenePtr(scene);
|
||||
@@ -346,11 +349,11 @@ namespace AZ
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Scene::Simulate([[maybe_unused]] const TickTimeInfo& tickInfo, RHI::JobPolicy jobPolicy)
|
||||
void Scene::Simulate(RHI::JobPolicy jobPolicy, float simulationTime)
|
||||
{
|
||||
AZ_PROFILE_SCOPE(RPI, "Scene: Simulate");
|
||||
|
||||
m_simulationTime = tickInfo.m_currentGameTime;
|
||||
m_simulationTime = simulationTime;
|
||||
|
||||
// If previous simulation job wasn't done, wait for it to finish.
|
||||
WaitAndCleanCompletionJob(m_simulationCompletion);
|
||||
@@ -404,11 +407,9 @@ namespace AZ
|
||||
{
|
||||
if (m_srg)
|
||||
{
|
||||
// Set value for constants defined in SceneTimeSrg.azsli
|
||||
RHI::ShaderInputConstantIndex timeIndex = m_srg->FindShaderInputConstantIndex(Name{ "m_time" });
|
||||
if (timeIndex.IsValid())
|
||||
if (m_timeInputIndex.IsValid())
|
||||
{
|
||||
m_srg->SetConstant(timeIndex, m_simulationTime);
|
||||
m_srg->SetConstant(m_timeInputIndex, m_simulationTime);
|
||||
}
|
||||
|
||||
// signal any handlers to update values for their partial scene srg
|
||||
@@ -418,7 +419,7 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::PrepareRender(const TickTimeInfo& tickInfo, RHI::JobPolicy jobPolicy)
|
||||
void Scene::PrepareRender(RHI::JobPolicy jobPolicy, float simulationTime)
|
||||
{
|
||||
AZ_PROFILE_SCOPE(RPI, "Scene: PrepareRender");
|
||||
|
||||
@@ -438,7 +439,7 @@ namespace AZ
|
||||
if (pipeline->NeedsRender())
|
||||
{
|
||||
activePipelines.push_back(pipeline);
|
||||
pipeline->OnStartFrame(tickInfo);
|
||||
pipeline->OnStartFrame(simulationTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user