[d3d11,d3d9,util] Add a config option for reproducible VK output

It ensures that for the same D3D commands the output VK commands
don't change between runs.

Useful for comparative benchmarking, can negatively affect performance.

Signed-off-by: Danylo Piliaiev <dpiliaiev@igalia.com>
This commit is contained in:
Danylo Piliaiev 2024-05-16 13:50:37 +02:00 committed by Philip Rebohle
parent 61bd62c327
commit 58d8ea2d31
9 changed files with 41 additions and 0 deletions

View File

@ -312,6 +312,20 @@
# d3d11.exposeDriverCommandLists = True
# Reproducible Command Stream
#
# Ensure that for the same D3D commands the output VK commands
# don't change between runs. Useful for comparative benchmarking,
# can negatively affect performance and can break some games
# that don't use queries correctly.
#
# Supported values:
# - True/False
# d3d11.reproducibleCommandStream = False
# d3d9.reproducibleCommandStream = False
# Sets number of pipeline compiler threads.
#
# If the graphics pipeline library feature is enabled, the given

View File

@ -19,6 +19,7 @@ namespace dxvk {
m_csThread(Device, Device->createContext(DxvkContextType::Primary)),
m_maxImplicitDiscardSize(pParent->GetOptions()->maxImplicitDiscardSize),
m_submissionFence(new sync::CallbackFence()),
m_flushTracker(pParent->GetOptions()->reproducibleCommandStream),
m_multithread(this, false, pParent->GetOptions()->enableContextLock),
m_videoContext(this, Device) {
EmitCs([

View File

@ -33,6 +33,7 @@ namespace dxvk {
this->maxFrameRate = config.getOption<int32_t>("dxgi.maxFrameRate", 0);
this->exposeDriverCommandLists = config.getOption<bool>("d3d11.exposeDriverCommandLists", true);
this->longMad = config.getOption<bool>("d3d11.longMad", false);
this->reproducibleCommandStream = config.getOption<bool>("d3d11.reproducibleCommandStream", false);
// Clamp LOD bias so that people don't abuse this in unintended ways
this->samplerLodBias = dxvk::fclamp(this->samplerLodBias, -2.0f, 1.0f);

View File

@ -123,6 +123,11 @@ namespace dxvk {
/// Should we make our Mads a FFma or do it the long way with an FMul and an FAdd?
bool longMad;
/// Ensure that for the same D3D commands the output VK commands
/// don't change between runs. Useful for comparative benchmarking,
/// can negatively affect performance.
bool reproducibleCommandStream;
};
}

View File

@ -56,6 +56,7 @@ namespace dxvk {
, m_csThread ( dxvkDevice, dxvkDevice->createContext(DxvkContextType::Primary) )
, m_csChunk ( AllocCsChunk() )
, m_submissionFence (new sync::Fence())
, m_flushTracker (m_d3d9Options.reproducibleCommandStream)
, m_d3d9Interop ( this )
, m_d3d9On12 ( this )
, m_d3d8Bridge ( this ) {

View File

@ -77,6 +77,7 @@ namespace dxvk {
this->samplerLodBias = config.getOption<float> ("d3d9.samplerLodBias", 0.0f);
this->clampNegativeLodBias = config.getOption<bool> ("d3d9.clampNegativeLodBias", false);
this->countLosableResources = config.getOption<bool> ("d3d9.countLosableResources", true);
this->reproducibleCommandStream = config.getOption<bool> ("d3d9.reproducibleCommandStream", false);
// Clamp LOD bias so that people don't abuse this in unintended ways
this->samplerLodBias = dxvk::fclamp(this->samplerLodBias, -2.0f, 1.0f);

View File

@ -155,6 +155,11 @@ namespace dxvk {
/// Disable counting losable resources and rejecting calls to Reset() if any are still alive
bool countLosableResources;
/// Ensure that for the same D3D commands the output VK commands
/// don't change between runs. Useful for comparative benchmarking,
/// can negatively affect performance.
bool reproducibleCommandStream;
};
}

View File

@ -2,6 +2,12 @@
namespace dxvk {
GpuFlushTracker::GpuFlushTracker(
bool ensureReproducibleHeuristic)
: m_ensureReproducibleHeuristic(ensureReproducibleHeuristic) {
}
bool GpuFlushTracker::considerFlush(
GpuFlushType flushType,
uint64_t chunkId,
@ -17,6 +23,9 @@ namespace dxvk {
if (!chunkCount)
return false;
if (m_ensureReproducibleHeuristic && flushType != GpuFlushType::ExplicitFlush)
return false;
// Take any earlier missed flush with a stronger hint into account, so
// that we still flush those as soon as possible. Ignore synchronization
// commands since they will either perform a flush or not need it at all.

View File

@ -34,6 +34,8 @@ namespace dxvk {
public:
GpuFlushTracker(bool ensureReproducibleHeuristic);
/**
* \brief Checks whether a context flush should be performed
*
@ -61,6 +63,8 @@ namespace dxvk {
private:
bool m_ensureReproducibleHeuristic;
GpuFlushType m_lastMissedType = GpuFlushType::ImplicitWeakHint;
uint64_t m_lastFlushChunkId = 0ull;