Add ReplayOptions struct to contain replay-time configuration

* Not currently exposed to the UI or used by the drivers, we just pass the
  default object through
This commit is contained in:
baldurk
2019-08-27 18:51:56 +01:00
parent 878acd4ad9
commit 20be9f3d52
27 changed files with 250 additions and 71 deletions
+9 -8
View File
@@ -681,8 +681,8 @@ void CaptureContext::CleanMenu(QAction *action)
delete menu;
}
void CaptureContext::LoadCapture(const rdcstr &captureFile, const rdcstr &origFilename,
bool temporary, bool local)
void CaptureContext::LoadCapture(const rdcstr &captureFile, const ReplayOptions &opts,
const rdcstr &origFilename, bool temporary, bool local)
{
CloseCapture();
@@ -696,9 +696,10 @@ void CaptureContext::LoadCapture(const rdcstr &captureFile, const rdcstr &origFi
bool newCapture = (!temporary && !Config().RecentCaptureFiles.contains(origFilename));
LambdaThread *thread = new LambdaThread([this, captureFile, origFilename, temporary, local]() {
LoadCaptureThreaded(captureFile, origFilename, temporary, local);
});
LambdaThread *thread =
new LambdaThread([this, captureFile, opts, origFilename, temporary, local]() {
LoadCaptureThreaded(captureFile, opts, origFilename, temporary, local);
});
thread->selfDelete(true);
thread->start();
@@ -775,8 +776,8 @@ float CaptureContext::UpdateLoadProgress()
return val;
}
void CaptureContext::LoadCaptureThreaded(const QString &captureFile, const QString &origFilename,
bool temporary, bool local)
void CaptureContext::LoadCaptureThreaded(const QString &captureFile, const ReplayOptions &opts,
const QString &origFilename, bool temporary, bool local)
{
m_CaptureFile = origFilename;
@@ -788,7 +789,7 @@ void CaptureContext::LoadCaptureThreaded(const QString &captureFile, const QStri
m_PostloadProgress = 0.0f;
// this function call will block until the capture is either loaded, or there's some failure
m_Replay.OpenCapture(captureFile, [this](float p) { m_LoadProgress = p; });
m_Replay.OpenCapture(captureFile, opts, [this](float p) { m_LoadProgress = p; });
// if the renderer isn't running, we hit a failure case so display an error message
if(!m_Replay.IsRunning())
+4 -4
View File
@@ -102,8 +102,8 @@ public:
//////////////////////////////////////////////////////////////////////////////
// Control functions
void LoadCapture(const rdcstr &captureFile, const rdcstr &origFilename, bool temporary,
bool local) override;
void LoadCapture(const rdcstr &captureFile, const ReplayOptions &opts, const rdcstr &origFilename,
bool temporary, bool local) override;
bool SaveCaptureTo(const rdcstr &captureFile) override;
void RecompressCapture() override;
void CloseCapture() override;
@@ -305,8 +305,8 @@ private:
float m_PostloadProgress = 0.0f;
float UpdateLoadProgress();
void LoadCaptureThreaded(const QString &captureFile, const QString &origFilename, bool temporary,
bool local);
void LoadCaptureThreaded(const QString &captureFile, const ReplayOptions &opts,
const QString &origFilename, bool temporary, bool local);
void AddSortedMenuItem(QMenu *menu, bool rootMenu, const rdcarray<rdcstr> &items,
std::function<void()> callback);
+3 -2
View File
@@ -1083,13 +1083,14 @@ data.
DOCUMENT(R"(Open a capture file for replay.
:param str captureFile: The actual path to the capture file.
:param ReplayOptions opts: The options controlling how the capture should be replayed.
:param str origFilename: The original filename, if the capture was copied remotely for replay.
:param bool temporary: ``True`` if this is a temporary capture which should prompt the user for
either save or delete on close.
:param bool local: ``True`` if ``captureFile`` refers to a file on the local machine.
)");
virtual void LoadCapture(const rdcstr &captureFile, const rdcstr &origFilename, bool temporary,
bool local) = 0;
virtual void LoadCapture(const rdcstr &captureFile, const ReplayOptions &opts,
const rdcstr &origFilename, bool temporary, bool local) = 0;
DOCUMENT(R"(Saves the current capture file to a given path.
+7 -6
View File
@@ -42,7 +42,8 @@ ReplayManager::~ReplayManager()
RENDERDOC_UnregisterMemoryRegion(this);
}
void ReplayManager::OpenCapture(const QString &capturefile, RENDERDOC_ProgressCallback progress)
void ReplayManager::OpenCapture(const QString &capturefile, const ReplayOptions &opts,
RENDERDOC_ProgressCallback progress)
{
if(m_Running)
return;
@@ -50,8 +51,8 @@ void ReplayManager::OpenCapture(const QString &capturefile, RENDERDOC_ProgressCa
// TODO maybe we could expose this choice to the user?
int proxyRenderer = -1;
m_Thread = new LambdaThread([this, proxyRenderer, capturefile, progress]() {
run(proxyRenderer, capturefile, progress);
m_Thread = new LambdaThread([this, proxyRenderer, capturefile, opts, progress]() {
run(proxyRenderer, capturefile, opts, progress);
});
m_Thread->start(QThread::HighestPriority);
@@ -416,7 +417,7 @@ void ReplayManager::PushInvoke(ReplayManager::InvokeHandle *cmd)
m_RenderCondition.wakeAll();
}
void ReplayManager::run(int proxyRenderer, const QString &capturefile,
void ReplayManager::run(int proxyRenderer, const QString &capturefile, const ReplayOptions &opts,
RENDERDOC_ProgressCallback progress)
{
m_Renderer = NULL;
@@ -424,7 +425,7 @@ void ReplayManager::run(int proxyRenderer, const QString &capturefile,
if(m_Remote)
{
rdctie(m_CreateStatus, m_Renderer) =
m_Remote->OpenCapture(proxyRenderer, capturefile.toUtf8().data(), progress);
m_Remote->OpenCapture(proxyRenderer, capturefile.toUtf8().data(), opts, progress);
}
else
{
@@ -433,7 +434,7 @@ void ReplayManager::run(int proxyRenderer, const QString &capturefile,
m_CreateStatus = m_CaptureFile->OpenFile(capturefile.toUtf8().data(), "rdc", NULL);
if(m_CreateStatus == ReplayStatus::Succeeded)
rdctie(m_CreateStatus, m_Renderer) = m_CaptureFile->OpenCapture(progress);
rdctie(m_CreateStatus, m_Renderer) = m_CaptureFile->OpenCapture(opts, progress);
}
if(m_Renderer == NULL)
+4 -2
View File
@@ -48,7 +48,8 @@ public:
ReplayManager();
~ReplayManager();
void OpenCapture(const QString &capturefile, RENDERDOC_ProgressCallback progress);
void OpenCapture(const QString &capturefile, const ReplayOptions &opts,
RENDERDOC_ProgressCallback progress);
void DeleteCapture(const rdcstr &capturefile, bool local);
bool IsRunning();
@@ -113,7 +114,8 @@ private:
bool selfdelete;
};
void run(int proxyRenderer, const QString &capturefile, RENDERDOC_ProgressCallback progress);
void run(int proxyRenderer, const QString &capturefile, const ReplayOptions &opts,
RENDERDOC_ProgressCallback progress);
QMutex m_TimerLock;
QElapsedTimer m_CommandTimer;
+1 -1
View File
@@ -760,7 +760,7 @@ void LiveCapture::openCapture(Capture *cap)
return;
}
m_Main->LoadCapture(cap->path, !cap->saved, cap->local);
m_Main->LoadCapture(cap->path, ReplayOptions(), !cap->saved, cap->local);
}
bool LiveCapture::saveCapture(Capture *cap, QString path)
+6 -5
View File
@@ -487,7 +487,7 @@ void MainWindow::LoadFromFilename(const QString &filename, bool temporary)
if(ext == lit("rdc"))
{
LoadCapture(filename, temporary, true);
LoadCapture(filename, ReplayOptions(), temporary, true);
}
else if(ext == lit("cap"))
{
@@ -500,7 +500,7 @@ void MainWindow::LoadFromFilename(const QString &filename, bool temporary)
else
{
// not a recognised filetype, see if we can load it anyway
LoadCapture(filename, temporary, true);
LoadCapture(filename, ReplayOptions(), temporary, true);
}
}
@@ -633,7 +633,8 @@ void MainWindow::OnInjectTrigger(uint32_t PID, const rdcarray<EnvironmentModific
th->deleteLater();
}
void MainWindow::LoadCapture(const QString &filename, bool temporary, bool local)
void MainWindow::LoadCapture(const QString &filename, const ReplayOptions &opts, bool temporary,
bool local)
{
if(PromptCloseCapture())
{
@@ -800,7 +801,7 @@ void MainWindow::LoadCapture(const QString &filename, bool temporary, bool local
ANALYTIC_SET(UIFeatures.ImageViewer, true);
}
m_Ctx.LoadCapture(fileToLoad, origFilename, temporary, local);
m_Ctx.LoadCapture(fileToLoad, opts, origFilename, temporary, local);
}
if(local && !temporary)
@@ -1506,7 +1507,7 @@ void MainWindow::recentCaptureFile(const QString &filename)
{
if(QFileInfo::exists(filename))
{
LoadCapture(filename, false, true);
LoadCapture(filename, ReplayOptions(), false, true);
}
else
{
+1 -1
View File
@@ -77,7 +77,7 @@ public:
void takeCaptureOwnership() { m_OwnTempCapture = true; }
void captureModified();
void LoadFromFilename(const QString &filename, bool temporary);
void LoadCapture(const QString &filename, bool temporary, bool local);
void LoadCapture(const QString &filename, const ReplayOptions &opts, bool temporary, bool local);
void CloseCapture();
QString GetSavePath(QString title = QString(), QString filter = QString());
+3 -3
View File
@@ -173,10 +173,10 @@ struct CaptureContextInvoker : ICaptureContext
{
return InvokeRetFunction<WindowingData>(&ICaptureContext::CreateWindowingData, window);
}
virtual void LoadCapture(const rdcstr &capture, const rdcstr &origFilename, bool temporary,
bool local) override
virtual void LoadCapture(const rdcstr &capture, const ReplayOptions &opts,
const rdcstr &origFilename, bool temporary, bool local) override
{
InvokeVoidFunction(&ICaptureContext::LoadCapture, capture, origFilename, temporary, local);
InvokeVoidFunction(&ICaptureContext::LoadCapture, capture, opts, origFilename, temporary, local);
}
virtual bool SaveCaptureTo(const rdcstr &capture) override
{
+3 -2
View File
@@ -461,13 +461,14 @@ struct AndroidRemoteServer : public RemoteServer
}
virtual rdcpair<ReplayStatus, IReplayController *> OpenCapture(
uint32_t proxyid, const char *filename, RENDERDOC_ProgressCallback progress) override
uint32_t proxyid, const char *filename, const ReplayOptions &opts,
RENDERDOC_ProgressCallback progress) override
{
ResetAndroidSettings();
LazilyStartLogcatThread();
return RemoteServer::OpenCapture(proxyid, filename, progress);
return RemoteServer::OpenCapture(proxyid, filename, opts, progress);
}
virtual rdcstr GetHomeFolder() override { return ""; }
+71
View File
@@ -698,3 +698,74 @@ struct GPUDevice
};
DECLARE_REFLECTION_STRUCT(GPUDevice);
DOCUMENT("The options controlling how replay of a capture should be performed");
struct ReplayOptions
{
DOCUMENT("");
ReplayOptions() = default;
ReplayOptions(const ReplayOptions &) = default;
DOCUMENT(R"(Replay with API validation enabled and use debug messages from there, ignoring any
that may be contained in the capture.
The default is not to do any validation.
.. note:: RenderDoc does not handle invalid API use in the general case so validation should still
be performed at runtime in your program for ground truth results.
)");
bool apiValidation = false;
DOCUMENT(R"(Force the selection of a GPU by vendor ID. This allows overriding which GPU is used to
replay on, even if a different GPU would be the best match for the capture.
When set to :data:`GPUVendor.Unknown`, specifies no particular vendor.
See also :data:`forceGPUDeviceID` and :data:`forceGPUDriverName`. Available GPUs can be enumerated
using :meth:`CaptureAccess.GetAvailableGPUs`.
The default is not to do any override. The capture contains information about what GPU was used, and
the closest matching GPU is used on replay.
.. note::
If a GPU is forced that is not available or not supported for a given capture, such as when GPUs
are only available for some APIs and not others, the default GPU selection will be used. If a GPU
is available for a capture but fails to open however then there is no fallback to a default GPU.
OpenGL does not support GPU selection so the default method (which effectively does nothing) will
always be used.
)");
GPUVendor forceGPUVendor = GPUVendor::Unknown;
DOCUMENT(R"(Force the selection of a GPU by device ID. This allows overriding which GPU is used to
replay on.
When set to 0, specifies no particular device.
See :data:`forceGPUDeviceID` for a full explanation of GPU selection override.
)");
uint32_t forceGPUDeviceID = 0;
DOCUMENT(R"(Force the selection of a GPU by driver name. This allows overriding which GPU is used
to replay on.
When set to an empty string, specifies no particular driver.
See :data:`forceGPUDeviceID` for a full explanation of GPU selection override.
)");
rdcstr forceGPUDriverName;
DOCUMENT(R"(How much optimisation should be done, potentially at the cost of correctness.
The default is :data:`ReplayOptimisationLevel.Balanced`.
)");
ReplayOptimisationLevel optimisation = ReplayOptimisationLevel::Balanced;
// helpers for Qt, define constructor and cast. These will be defined in Qt code
#if defined(RENDERDOC_QT_COMPAT)
ReplayOptions(const QVariant &var);
operator QVariant() const;
#endif
};
DECLARE_REFLECTION_STRUCT(ReplayOptions);
+6 -2
View File
@@ -1690,6 +1690,7 @@ or an error has occurred.
or :data:`NoPreference` to indicate no preference for any proxy.
:param str logfile: The path on the remote system where the file is. If the file is only available
locally you can use :meth:`CopyCaptureToRemote` to transfer it over the remote connection.
:param ReplayOptions opts: The options controlling how the capture should be replayed.
:param ProgressCallback progress: A callback that will be repeatedly called with an updated progress
value for the opening. Can be ``None`` if no progress is desired.
:return: A tuple containing the status of opening the capture, whether success or failure, and the
@@ -1697,7 +1698,8 @@ or an error has occurred.
:rtype: ``tuple`` of :class:`ReplayStatus` and :class:`ReplayController`
)");
virtual rdcpair<ReplayStatus, IReplayController *> OpenCapture(
uint32_t proxyid, const char *logfile, RENDERDOC_ProgressCallback progress) = 0;
uint32_t proxyid, const char *logfile, const ReplayOptions &opts,
RENDERDOC_ProgressCallback progress) = 0;
DOCUMENT(R"(Close a capture analysis handle previously opened by :meth:`OpenCapture`.
@@ -1854,13 +1856,15 @@ This function will block until the capture is fully loaded and ready.
Once the replay is created, this :class:`CaptureFile` can be shut down, there is no dependency on it
by the :class:`ReplayController`.
:param ReplayOptions opts: The options controlling how the capture should be replayed.
:param ProgressCallback progress: A callback that will be repeatedly called with an updated progress
value for the opening. Can be ``None`` if no progress is desired.
:return: A tuple containing the status of opening the capture, whether success or failure, and the
resulting :class:`ReplayController` handle if successful.
:rtype: ``tuple`` of :class:`ReplayStatus` and :class:`ReplayController`.
)");
virtual rdcpair<ReplayStatus, IReplayController *> OpenCapture(RENDERDOC_ProgressCallback progress) = 0;
virtual rdcpair<ReplayStatus, IReplayController *> OpenCapture(
const ReplayOptions &opts, RENDERDOC_ProgressCallback progress) = 0;
DOCUMENT(R"(Returns the structured data for this capture.
+13
View File
@@ -948,6 +948,19 @@ rdcstr DoStringise(const SectionType &el)
END_ENUM_STRINGISE();
}
template <>
rdcstr DoStringise(const ReplayOptimisationLevel &el)
{
BEGIN_ENUM_STRINGISE(ReplayOptimisationLevel);
{
STRINGISE_ENUM_CLASS_NAMED(NoOptimisation, "No Optimisation");
STRINGISE_ENUM_CLASS(Conservative);
STRINGISE_ENUM_CLASS(Balanced);
STRINGISE_ENUM_CLASS(Fastest);
}
END_ENUM_STRINGISE();
}
template <>
rdcstr DoStringise(const D3DBufferViewFlags &el)
{
+35
View File
@@ -3436,6 +3436,41 @@ DECLARE_REFLECTION_ENUM(LogType);
ITERABLE_OPERATORS(LogType);
DOCUMENT(R"(The level of optimisation used in
.. data:: NoOptimisation
Completely disabled, no optimisation will be used at all.
.. data:: Conservative
Optimisation is used when it doesn't interfere with replay correctness.
.. data:: Balanced
Optimisation is used when it has minimal impact on replay correctness. This could include e.g.
resources appearing cleared instead of containing contents from prior frames where those resources
are written to before being read.
.. data:: Fastest
All possible optimisations are enabled as long as they do not cause invalid/incorrect replay.
This could result in side-effects like data from one replay being visible early in another replay,
if it's known that the data will be overwritten before being used.
)");
enum class ReplayOptimisationLevel : int32_t
{
NoOptimisation,
First = NoOptimisation,
Conservative,
Balanced,
Fastest,
Count,
};
DECLARE_REFLECTION_ENUM(ReplayOptimisationLevel);
ITERABLE_OPERATORS(ReplayOptimisationLevel);
#if defined(ENABLE_PYTHON_FLAG_ENUMS)
ENABLE_PYTHON_FLAG_ENUMS;
+29 -8
View File
@@ -43,6 +43,25 @@
#include "replay/renderdoc_serialise.inl"
void LogReplayOptions(const ReplayOptions &opts)
{
RDCLOG("%s API validation during replay", (opts.apiValidation ? "Enabling" : "Not enabling"));
if(opts.forceGPUVendor == GPUVendor::Unknown && opts.forceGPUDeviceID == 0 &&
opts.forceGPUDriverName.empty())
{
RDCLOG("Using default GPU replay selection algorithm");
}
else
{
RDCLOG("Overriding GPU replay selection:");
RDCLOG(" Vendor %s, device %u, driver \"%s\"", ToStr(opts.forceGPUVendor).c_str(),
opts.forceGPUDeviceID, opts.forceGPUDriverName.c_str());
}
RDCLOG("Replay optimisation level: %s", ToStr(opts.optimisation).c_str());
}
// this one is done by hand as we format it
template <>
rdcstr DoStringise(const ResourceId &el)
@@ -1260,17 +1279,18 @@ ReplayStatus RenderDoc::CreateProxyReplayDriver(RDCDriver proxyDriver, IReplayDr
if(proxyDriver == RDCDriver::Unknown)
{
if(!m_ReplayDriverProviders.empty())
return m_ReplayDriverProviders.begin()->second(NULL, driver);
return m_ReplayDriverProviders.begin()->second(NULL, ReplayOptions(), driver);
}
if(m_ReplayDriverProviders.find(proxyDriver) != m_ReplayDriverProviders.end())
return m_ReplayDriverProviders[proxyDriver](NULL, driver);
return m_ReplayDriverProviders[proxyDriver](NULL, ReplayOptions(), driver);
RDCERR("Unsupported replay driver requested: %s", ToStr(proxyDriver).c_str());
return ReplayStatus::APIUnsupported;
}
ReplayStatus RenderDoc::CreateReplayDriver(RDCFile *rdc, IReplayDriver **driver)
ReplayStatus RenderDoc::CreateReplayDriver(RDCFile *rdc, const ReplayOptions &opts,
IReplayDriver **driver)
{
if(driver == NULL)
return ReplayStatus::InternalError;
@@ -1279,7 +1299,7 @@ ReplayStatus RenderDoc::CreateReplayDriver(RDCFile *rdc, IReplayDriver **driver)
if(rdc == NULL)
{
if(!m_ReplayDriverProviders.empty())
return m_ReplayDriverProviders.begin()->second(NULL, driver);
return m_ReplayDriverProviders.begin()->second(NULL, opts, driver);
RDCERR("Request for proxy replay device, but no replay providers are available.");
return ReplayStatus::InternalError;
@@ -1292,13 +1312,14 @@ ReplayStatus RenderDoc::CreateReplayDriver(RDCFile *rdc, IReplayDriver **driver)
return IMG_CreateReplayDevice(rdc, driver);
if(m_ReplayDriverProviders.find(driverType) != m_ReplayDriverProviders.end())
return m_ReplayDriverProviders[driverType](rdc, driver);
return m_ReplayDriverProviders[driverType](rdc, opts, driver);
RDCERR("Unsupported replay driver requested: %s", ToStr(driverType).c_str());
return ReplayStatus::APIUnsupported;
}
ReplayStatus RenderDoc::CreateRemoteDriver(RDCFile *rdc, IRemoteDriver **driver)
ReplayStatus RenderDoc::CreateRemoteDriver(RDCFile *rdc, const ReplayOptions &opts,
IRemoteDriver **driver)
{
if(rdc == NULL || driver == NULL)
return ReplayStatus::InternalError;
@@ -1306,13 +1327,13 @@ ReplayStatus RenderDoc::CreateRemoteDriver(RDCFile *rdc, IRemoteDriver **driver)
RDCDriver driverType = rdc->GetDriver();
if(m_RemoteDriverProviders.find(driverType) != m_RemoteDriverProviders.end())
return m_RemoteDriverProviders[driverType](rdc, driver);
return m_RemoteDriverProviders[driverType](rdc, opts, driver);
// replay drivers are remote drivers, fall back and try them
if(m_ReplayDriverProviders.find(driverType) != m_ReplayDriverProviders.end())
{
IReplayDriver *dr = NULL;
ReplayStatus status = m_ReplayDriverProviders[driverType](rdc, &dr);
ReplayStatus status = m_ReplayDriverProviders[driverType](rdc, opts, &dr);
if(status == ReplayStatus::Succeeded)
*driver = (IRemoteDriver *)dr;
+7 -4
View File
@@ -43,6 +43,7 @@ struct RDCThumb;
// not provided by tinyexr, just do by hand
bool is_exr_file(FILE *f);
void LogReplayOptions(const ReplayOptions &opts);
struct ICrashHandler
{
@@ -336,8 +337,10 @@ class IReplayDriver;
class StreamReader;
class RDCFile;
typedef ReplayStatus (*RemoteDriverProvider)(RDCFile *rdc, IRemoteDriver **driver);
typedef ReplayStatus (*ReplayDriverProvider)(RDCFile *rdc, IReplayDriver **driver);
typedef ReplayStatus (*RemoteDriverProvider)(RDCFile *rdc, const ReplayOptions &opts,
IRemoteDriver **driver);
typedef ReplayStatus (*ReplayDriverProvider)(RDCFile *rdc, const ReplayOptions &opts,
IReplayDriver **driver);
typedef void (*StructuredProcessor)(RDCFile *rdc, SDFile &structData);
@@ -522,8 +525,8 @@ public:
bool IsDarkTheme() { return m_DarkTheme; }
void SetDarkTheme(bool dark) { m_DarkTheme = dark; }
ReplayStatus CreateProxyReplayDriver(RDCDriver proxyDriver, IReplayDriver **driver);
ReplayStatus CreateReplayDriver(RDCFile *rdc, IReplayDriver **driver);
ReplayStatus CreateRemoteDriver(RDCFile *rdc, IRemoteDriver **driver);
ReplayStatus CreateReplayDriver(RDCFile *rdc, const ReplayOptions &opts, IReplayDriver **driver);
ReplayStatus CreateRemoteDriver(RDCFile *rdc, const ReplayOptions &opts, IRemoteDriver **driver);
bool HasReplaySupport(RDCDriver driverType);
+9 -3
View File
@@ -397,10 +397,12 @@ static void ActiveRemoteClientThread(ClientThread *threadData,
else if(type == eRemoteServer_OpenLog)
{
std::string path;
ReplayOptions opts;
{
READ_DATA_SCOPE();
SERIALISE_ELEMENT(path);
SERIALISE_ELEMENT(opts);
}
reader.EndChunk();
@@ -450,13 +452,13 @@ static void ActiveRemoteClientThread(ClientThread *threadData,
// if we have a replay driver, try to create it so we can display a local preview e.g.
if(RenderDoc::Inst().HasReplayDriver(rdc->GetDriver()))
{
status = RenderDoc::Inst().CreateReplayDriver(rdc, &replayDriver);
status = RenderDoc::Inst().CreateReplayDriver(rdc, opts, &replayDriver);
if(replayDriver)
remoteDriver = replayDriver;
}
else
{
status = RenderDoc::Inst().CreateRemoteDriver(rdc, &remoteDriver);
status = RenderDoc::Inst().CreateRemoteDriver(rdc, opts, &remoteDriver);
}
if(status != ReplayStatus::Succeeded || remoteDriver == NULL)
@@ -1434,7 +1436,8 @@ void RemoteServer::TakeOwnershipCapture(const char *filename)
}
rdcpair<ReplayStatus, IReplayController *> RemoteServer::OpenCapture(
uint32_t proxyid, const char *filename, RENDERDOC_ProgressCallback progress)
uint32_t proxyid, const char *filename, const ReplayOptions &opts,
RENDERDOC_ProgressCallback progress)
{
rdcpair<ReplayStatus, IReplayController *> ret;
ret.first = ReplayStatus::InternalError;
@@ -1449,6 +1452,8 @@ rdcpair<ReplayStatus, IReplayController *> RemoteServer::OpenCapture(
RDCLOG("Opening capture remotely");
LogReplayOptions(opts);
// if the proxy id is ~0U, then we just don't care so let RenderDoc pick the most
// appropriate supported proxy for the current platform.
RDCDriver proxydrivertype = proxyid == ~0U ? RDCDriver::Unknown : m_Proxies[proxyid].first;
@@ -1457,6 +1462,7 @@ rdcpair<ReplayStatus, IReplayController *> RemoteServer::OpenCapture(
WRITE_DATA_SCOPE();
SCOPED_SERIALISE_CHUNK(eRemoteServer_OpenLog);
SERIALISE_ELEMENT(filename);
SERIALISE_ELEMENT(opts);
}
RemoteServerPacket type = eRemoteServer_Noop;
+1
View File
@@ -71,6 +71,7 @@ public:
virtual rdcpair<ReplayStatus, IReplayController *> OpenCapture(uint32_t proxyid,
const char *filename,
const ReplayOptions &opts,
RENDERDOC_ProgressCallback progress);
virtual void CloseCapture(IReplayController *rend);
+1 -1
View File
@@ -3625,7 +3625,7 @@ void D3D11Replay::SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSi
ID3DDevice *GetD3D11DeviceIfAlloc(IUnknown *dev);
ReplayStatus D3D11_CreateReplayDevice(RDCFile *rdc, IReplayDriver **driver)
ReplayStatus D3D11_CreateReplayDevice(RDCFile *rdc, const ReplayOptions &opts, IReplayDriver **driver)
{
RDCDEBUG("Creating a D3D11 replay device");
+1 -1
View File
@@ -3617,7 +3617,7 @@ void D3D12Replay::SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSi
#pragma endregion
ReplayStatus D3D12_CreateReplayDevice(RDCFile *rdc, IReplayDriver **driver)
ReplayStatus D3D12_CreateReplayDevice(RDCFile *rdc, const ReplayOptions &opts, IReplayDriver **driver)
{
RDCDEBUG("Creating a D3D12 replay device");
+10 -9
View File
@@ -3363,8 +3363,8 @@ void GLReplay::CloseReplayContext()
m_pDriver->m_Platform.DeleteReplayContext(m_ReplayCtx);
}
ReplayStatus CreateReplayDevice(RDCDriver rdcdriver, RDCFile *rdc, GLPlatform &platform,
IReplayDriver **&driver)
ReplayStatus CreateReplayDevice(RDCDriver rdcdriver, RDCFile *rdc, const ReplayOptions &opts,
GLPlatform &platform, IReplayDriver **&driver)
{
GLInitParams initParams;
uint64_t ver = GLInitParams::CurrentVersion;
@@ -3512,7 +3512,7 @@ std::vector<GLVersion> GetReplayVersions(RDCDriver api)
#if defined(RENDERDOC_SUPPORT_GL)
ReplayStatus GL_CreateReplayDevice(RDCFile *rdc, IReplayDriver **driver)
ReplayStatus GL_CreateReplayDevice(RDCFile *rdc, const ReplayOptions &opts, IReplayDriver **driver)
{
RDCDEBUG("Creating an OpenGL replay device");
@@ -3524,7 +3524,8 @@ ReplayStatus GL_CreateReplayDevice(RDCFile *rdc, IReplayDriver **driver)
return ReplayStatus::APIInitFailed;
}
return CreateReplayDevice(rdc ? rdc->GetDriver() : RDCDriver::OpenGL, rdc, GetGLPlatform(), driver);
return CreateReplayDevice(rdc ? rdc->GetDriver() : RDCDriver::OpenGL, rdc, opts, GetGLPlatform(),
driver);
}
static DriverRegistration GLDriverRegistration(RDCDriver::OpenGL, &GL_CreateReplayDevice);
@@ -3533,7 +3534,7 @@ static DriverRegistration GLDriverRegistration(RDCDriver::OpenGL, &GL_CreateRepl
#if defined(RENDERDOC_SUPPORT_GLES)
ReplayStatus GLES_CreateReplayDevice(RDCFile *rdc, IReplayDriver **driver)
ReplayStatus GLES_CreateReplayDevice(RDCFile *rdc, const ReplayOptions &opts, IReplayDriver **driver)
{
RDCLOG("Creating an OpenGL ES replay device");
@@ -3551,8 +3552,8 @@ ReplayStatus GLES_CreateReplayDevice(RDCFile *rdc, IReplayDriver **driver)
RDCLOG("Initialising GLES replay via libEGL");
return CreateReplayDevice(rdc ? rdc->GetDriver() : RDCDriver::OpenGLES, rdc, GetEGLPlatform(),
driver);
return CreateReplayDevice(rdc ? rdc->GetDriver() : RDCDriver::OpenGLES, rdc, opts,
GetEGLPlatform(), driver);
}
#if defined(RENDERDOC_SUPPORT_GL)
else if(GetGLPlatform().CanCreateGLESContext())
@@ -3567,8 +3568,8 @@ ReplayStatus GLES_CreateReplayDevice(RDCFile *rdc, IReplayDriver **driver)
return ReplayStatus::APIInitFailed;
}
return CreateReplayDevice(rdc ? rdc->GetDriver() : RDCDriver::OpenGLES, rdc, GetGLPlatform(),
driver);
return CreateReplayDevice(rdc ? rdc->GetDriver() : RDCDriver::OpenGLES, rdc, opts,
GetGLPlatform(), driver);
}
RDCERR(
+1 -1
View File
@@ -4129,7 +4129,7 @@ void VulkanReplay::SetProxyBufferData(ResourceId bufid, byte *data, size_t dataS
VULKANNOTIMP("SetProxyTextureData");
}
ReplayStatus Vulkan_CreateReplayDevice(RDCFile *rdc, IReplayDriver **driver)
ReplayStatus Vulkan_CreateReplayDevice(RDCFile *rdc, const ReplayOptions &opts, IReplayDriver **driver)
{
RDCDEBUG("Creating a VulkanReplay replay device");
+7 -3
View File
@@ -122,7 +122,8 @@ public:
ReplaySupport LocalReplaySupport() { return m_Support; }
rdcstr DriverName() { return m_DriverName; }
const char *RecordedMachineIdent() { return m_Ident.c_str(); }
rdcpair<ReplayStatus, IReplayController *> OpenCapture(RENDERDOC_ProgressCallback progress);
rdcpair<ReplayStatus, IReplayController *> OpenCapture(const ReplayOptions &opts,
RENDERDOC_ProgressCallback progress);
void SetMetadata(const char *driverName, uint64_t machineIdent, FileType thumbType,
uint32_t thumbWidth, uint32_t thumbHeight, const bytebuf &thumbData);
@@ -353,7 +354,8 @@ void CaptureFile::InitStructuredData(RENDERDOC_ProgressCallback progress /*= REN
}
}
rdcpair<ReplayStatus, IReplayController *> CaptureFile::OpenCapture(RENDERDOC_ProgressCallback progress)
rdcpair<ReplayStatus, IReplayController *> CaptureFile::OpenCapture(const ReplayOptions &opts,
RENDERDOC_ProgressCallback progress)
{
if(!m_RDC || m_RDC->ErrorCode() != ContainerError::NoError)
return rdcpair<ReplayStatus, IReplayController *>(ReplayStatus::InternalError, NULL);
@@ -361,9 +363,11 @@ rdcpair<ReplayStatus, IReplayController *> CaptureFile::OpenCapture(RENDERDOC_Pr
ReplayController *render = new ReplayController();
ReplayStatus ret;
LogReplayOptions(opts);
RenderDoc::Inst().SetProgressCallback<LoadProgress>(progress);
ret = render->CreateDevice(m_RDC);
ret = render->CreateDevice(m_RDC, opts);
RenderDoc::Inst().SetProgressCallback<LoadProgress>(RENDERDOC_ProgressCallback());
+13
View File
@@ -891,6 +891,18 @@ void DoSerialise(SerialiserType &ser, GPUDevice &el)
SIZE_CHECK(80);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, ReplayOptions &el)
{
SERIALISE_MEMBER(apiValidation);
SERIALISE_MEMBER(forceGPUVendor);
SERIALISE_MEMBER(forceGPUDeviceID);
SERIALISE_MEMBER(forceGPUDriverName);
SERIALISE_MEMBER(optimisation);
SIZE_CHECK(48);
}
#pragma region Common pipeline state
template <typename SerialiserType>
@@ -2256,6 +2268,7 @@ INSTANTIATE_SERIALISE_TYPE(EventUsage)
INSTANTIATE_SERIALISE_TYPE(CounterResult)
INSTANTIATE_SERIALISE_TYPE(CounterValue)
INSTANTIATE_SERIALISE_TYPE(GPUDevice)
INSTANTIATE_SERIALISE_TYPE(ReplayOptions)
INSTANTIATE_SERIALISE_TYPE(D3D11Pipe::Layout)
INSTANTIATE_SERIALISE_TYPE(D3D11Pipe::InputAssembly)
INSTANTIATE_SERIALISE_TYPE(D3D11Pipe::View)
+2 -2
View File
@@ -2032,12 +2032,12 @@ void ReplayController::RemoveReplacement(ResourceId id)
m_Outputs[i]->Display();
}
ReplayStatus ReplayController::CreateDevice(RDCFile *rdc)
ReplayStatus ReplayController::CreateDevice(RDCFile *rdc, const ReplayOptions &opts)
{
CHECK_REPLAY_THREAD();
IReplayDriver *driver = NULL;
ReplayStatus status = RenderDoc::Inst().CreateReplayDriver(rdc, &driver);
ReplayStatus status = RenderDoc::Inst().CreateReplayDriver(rdc, opts, &driver);
if(driver && status == ReplayStatus::Succeeded)
{
+1 -1
View File
@@ -137,7 +137,7 @@ public:
APIProperties GetAPIProperties();
ReplayStatus CreateDevice(RDCFile *rdc);
ReplayStatus CreateDevice(RDCFile *rdc, const ReplayOptions &opts);
ReplayStatus SetDevice(IReplayDriver *device);
void FileChanged();
+2 -2
View File
@@ -566,7 +566,7 @@ struct ReplayCommand : public Command
rdcstr remotePath = remote->CopyCaptureToRemote(filename.c_str(), NULL);
IReplayController *renderer = NULL;
rdctie(status, renderer) = remote->OpenCapture(~0U, remotePath.c_str(), NULL);
rdctie(status, renderer) = remote->OpenCapture(~0U, remotePath.c_str(), ReplayOptions(), NULL);
if(status == ReplayStatus::Succeeded)
{
@@ -596,7 +596,7 @@ struct ReplayCommand : public Command
IReplayController *renderer = NULL;
ReplayStatus status = ReplayStatus::InternalError;
rdctie(status, renderer) = file->OpenCapture(NULL);
rdctie(status, renderer) = file->OpenCapture(ReplayOptions(), NULL);
file->Shutdown();