mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-04 17:10:47 +00:00
Show message in connection window for unsupported API capture
* This is helpful when the normal overlay is not available or visible such as in VR headsets
This commit is contained in:
@@ -654,6 +654,8 @@ void LiveCapture::updateAPIStatus()
|
||||
if(!m_APIs[api].supported)
|
||||
{
|
||||
apiStatus += tr(", %1 (Unsupported)").arg(api);
|
||||
if(!m_APIs[api].supportMessage.isEmpty())
|
||||
apiStatus += lit("\n") + m_APIs[api].supportMessage;
|
||||
}
|
||||
else if(!m_APIs[api].presenting)
|
||||
{
|
||||
@@ -665,6 +667,8 @@ void LiveCapture::updateAPIStatus()
|
||||
// remove the redundant starting ", "
|
||||
apiStatus.remove(0, 2);
|
||||
|
||||
apiStatus.replace(QLatin1Char('\n'), lit("<br>"));
|
||||
|
||||
ui->apiStatus->setText(apiStatus);
|
||||
|
||||
ui->apiIcon->setVisible(nonpresenting);
|
||||
@@ -1344,13 +1348,11 @@ void LiveCapture::connectionThreadEntry()
|
||||
|
||||
if(msg.type == TargetControlMessageType::RegisterAPI)
|
||||
{
|
||||
QString api = msg.apiUse.name;
|
||||
bool presenting = msg.apiUse.presenting;
|
||||
bool supported = msg.apiUse.supported;
|
||||
GUIInvoke::call(this, [this, api, presenting, supported]() {
|
||||
m_APIs[api] = APIStatus(presenting, supported);
|
||||
GUIInvoke::call(this, [this, msg]() {
|
||||
m_APIs[msg.apiUse.name] =
|
||||
APIStatus(msg.apiUse.presenting, msg.apiUse.supported, msg.apiUse.supportMessage);
|
||||
|
||||
if(presenting && supported)
|
||||
if(msg.apiUse.presenting && msg.apiUse.supported)
|
||||
{
|
||||
ui->triggerImmediateCapture->setEnabled(true);
|
||||
ui->triggerDelayedCapture->setEnabled(true);
|
||||
|
||||
@@ -127,9 +127,10 @@ private:
|
||||
struct APIStatus
|
||||
{
|
||||
APIStatus() = default;
|
||||
APIStatus(bool p, bool s) : presenting(p), supported(s) {}
|
||||
APIStatus(bool p, bool s, rdcstr m) : presenting(p), supported(s), supportMessage(m) {}
|
||||
bool presenting = false;
|
||||
bool supported = false;
|
||||
rdcstr supportMessage;
|
||||
};
|
||||
|
||||
Capture *GetCapture(QListWidgetItem *item);
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
<string>API:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -562,6 +562,12 @@ struct APIUseData
|
||||
|
||||
DOCUMENT("``True`` if the API can be captured.");
|
||||
bool supported = false;
|
||||
|
||||
DOCUMENT(R"(A string message if the API is unsupported explaining why.
|
||||
|
||||
:type: str
|
||||
)");
|
||||
rdcstr supportMessage;
|
||||
};
|
||||
|
||||
DECLARE_REFLECTION_STRUCT(APIUseData);
|
||||
|
||||
+23
-6
@@ -1669,7 +1669,16 @@ void RenderDoc::AddActiveDriver(RDCDriver driver, bool present)
|
||||
}
|
||||
}
|
||||
|
||||
std::map<RDCDriver, bool> RenderDoc::GetActiveDrivers()
|
||||
void RenderDoc::SetDriverUnsupportedMessage(RDCDriver driver, rdcstr message)
|
||||
{
|
||||
if(driver == RDCDriver::Unknown)
|
||||
return;
|
||||
|
||||
SCOPED_LOCK(m_DriverLock);
|
||||
m_APISupportMessages[driver] = message;
|
||||
}
|
||||
|
||||
std::map<RDCDriver, RDCDriverStatus> RenderDoc::GetActiveDrivers()
|
||||
{
|
||||
std::map<RDCDriver, uint64_t> drivers;
|
||||
|
||||
@@ -1678,20 +1687,28 @@ std::map<RDCDriver, bool> RenderDoc::GetActiveDrivers()
|
||||
drivers = m_ActiveDrivers;
|
||||
}
|
||||
|
||||
std::map<RDCDriver, bool> ret;
|
||||
std::map<RDCDriver, RDCDriverStatus> ret;
|
||||
|
||||
for(auto it = drivers.begin(); it != drivers.end(); ++it)
|
||||
{
|
||||
RDCDriverStatus &status = ret[it->first];
|
||||
// driver is presenting if the timestamp is greater than 0 and less than 10 seconds ago (gives a
|
||||
// little leeway for loading screens or something where the presentation stops temporarily).
|
||||
// we also assume that during a capture if it was presenting, then it's still capturing.
|
||||
// Otherwise a long capture would temporarily set it as not presenting.
|
||||
bool presenting = it->second > 0;
|
||||
status.presenting = it->second > 0;
|
||||
|
||||
if(presenting && !IsFrameCapturing() && it->second < Timing::GetUnixTimestamp() - 10)
|
||||
presenting = false;
|
||||
if(status.presenting && !IsFrameCapturing() && it->second < Timing::GetUnixTimestamp() - 10)
|
||||
status.presenting = false;
|
||||
|
||||
ret[it->first] = presenting;
|
||||
status.supported = (HasRemoteDriver(it->first) || HasReplayDriver(it->first)) &&
|
||||
HasActiveFrameCapturer(it->first);
|
||||
|
||||
if(!status.supported)
|
||||
{
|
||||
SCOPED_LOCK(m_DriverLock);
|
||||
status.supportMessage = m_APISupportMessages[it->first];
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
+17
-1
@@ -236,6 +236,20 @@ enum class RDCDriver : uint32_t
|
||||
|
||||
DECLARE_REFLECTION_ENUM(RDCDriver);
|
||||
|
||||
struct RDCDriverStatus
|
||||
{
|
||||
bool presenting = false;
|
||||
bool supported = false;
|
||||
rdcstr supportMessage;
|
||||
|
||||
bool operator==(const RDCDriverStatus &o) const
|
||||
{
|
||||
return presenting == o.presenting && supported == o.supported &&
|
||||
supportMessage == o.supportMessage;
|
||||
}
|
||||
bool operator!=(const RDCDriverStatus &o) const { return !(*this == o); }
|
||||
};
|
||||
|
||||
enum ReplayLogType
|
||||
{
|
||||
eReplay_Full,
|
||||
@@ -547,7 +561,8 @@ public:
|
||||
bool HasRemoteDriver(RDCDriver driver) const;
|
||||
|
||||
void AddActiveDriver(RDCDriver driver, bool present);
|
||||
std::map<RDCDriver, bool> GetActiveDrivers();
|
||||
void SetDriverUnsupportedMessage(RDCDriver driver, rdcstr message);
|
||||
std::map<RDCDriver, RDCDriverStatus> GetActiveDrivers();
|
||||
|
||||
uint32_t GetTargetControlIdent() const { return m_RemoteIdent; }
|
||||
bool IsTargetControlConnected();
|
||||
@@ -644,6 +659,7 @@ private:
|
||||
int32_t m_MarkerIndentLevel;
|
||||
Threading::CriticalSection m_DriverLock;
|
||||
std::map<RDCDriver, uint64_t> m_ActiveDrivers;
|
||||
std::map<RDCDriver, rdcstr> m_APISupportMessages;
|
||||
|
||||
Threading::ThreadHandle m_AvailableGPUThread = 0;
|
||||
rdcarray<GPUDevice> m_AvailableGPUs;
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "replay/replay_driver.h"
|
||||
#include "serialise/serialiser.h"
|
||||
|
||||
static const uint32_t TargetControlProtocolVersion = 7;
|
||||
static const uint32_t TargetControlProtocolVersion = 8;
|
||||
|
||||
static bool IsProtocolVersionSupported(const uint32_t protocolVersion)
|
||||
{
|
||||
@@ -56,6 +56,10 @@ static bool IsProtocolVersionSupported(const uint32_t protocolVersion)
|
||||
if(protocolVersion == 6)
|
||||
return true;
|
||||
|
||||
// 7 -> 8 add custom message for unsupported APIs
|
||||
if(protocolVersion == 7)
|
||||
return true;
|
||||
|
||||
if(protocolVersion == TargetControlProtocolVersion)
|
||||
return true;
|
||||
|
||||
@@ -156,7 +160,7 @@ void RenderDoc::TargetControlClientThread(uint32_t version, Network::Socket *cli
|
||||
|
||||
rdcarray<CaptureData> captures;
|
||||
rdcarray<rdcpair<uint32_t, uint32_t> > children;
|
||||
std::map<RDCDriver, bool> drivers;
|
||||
std::map<RDCDriver, RDCDriverStatus> drivers;
|
||||
float prevCaptureProgress = captureProgress;
|
||||
uint32_t prevWindows = 0;
|
||||
|
||||
@@ -171,7 +175,7 @@ void RenderDoc::TargetControlClientThread(uint32_t version, Network::Socket *cli
|
||||
Threading::Sleep(ticktime);
|
||||
curtime += ticktime;
|
||||
|
||||
std::map<RDCDriver, bool> curdrivers = RenderDoc::Inst().GetActiveDrivers();
|
||||
std::map<RDCDriver, RDCDriverStatus> curdrivers = RenderDoc::Inst().GetActiveDrivers();
|
||||
|
||||
rdcarray<CaptureData> caps = RenderDoc::Inst().GetCaptures();
|
||||
rdcarray<rdcpair<uint32_t, uint32_t> > childprocs = RenderDoc::Inst().GetChildProcesses();
|
||||
@@ -182,7 +186,7 @@ void RenderDoc::TargetControlClientThread(uint32_t version, Network::Socket *cli
|
||||
{
|
||||
// find the first difference, either a new key or a key with a different value, and send it.
|
||||
RDCDriver driver = RDCDriver::Unknown;
|
||||
bool presenting = false;
|
||||
RDCDriverStatus status;
|
||||
|
||||
// search for new drivers
|
||||
for(auto it = curdrivers.begin(); it != curdrivers.end(); it++)
|
||||
@@ -190,7 +194,7 @@ void RenderDoc::TargetControlClientThread(uint32_t version, Network::Socket *cli
|
||||
if(drivers.find(it->first) == drivers.end() || drivers[it->first] != it->second)
|
||||
{
|
||||
driver = it->first;
|
||||
presenting = it->second;
|
||||
status = it->second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -198,19 +202,18 @@ void RenderDoc::TargetControlClientThread(uint32_t version, Network::Socket *cli
|
||||
RDCASSERTNOTEQUAL(driver, RDCDriver::Unknown);
|
||||
|
||||
if(driver != RDCDriver::Unknown)
|
||||
drivers[driver] = presenting;
|
||||
|
||||
bool supported =
|
||||
RenderDoc::Inst().HasRemoteDriver(driver) || RenderDoc::Inst().HasReplayDriver(driver);
|
||||
|
||||
supported &= RenderDoc::Inst().HasActiveFrameCapturer(driver);
|
||||
drivers[driver] = status;
|
||||
|
||||
WRITE_DATA_SCOPE();
|
||||
{
|
||||
SCOPED_SERIALISE_CHUNK(ePacket_APIUse);
|
||||
SERIALISE_ELEMENT(driver);
|
||||
SERIALISE_ELEMENT(presenting);
|
||||
SERIALISE_ELEMENT(supported);
|
||||
SERIALISE_ELEMENT(status.presenting);
|
||||
SERIALISE_ELEMENT(status.supported);
|
||||
if(version >= 8)
|
||||
{
|
||||
SERIALISE_ELEMENT(status.supportMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(caps.size() != captures.size())
|
||||
@@ -843,15 +846,21 @@ public:
|
||||
RDCDriver driver = RDCDriver::Unknown;
|
||||
bool presenting = false;
|
||||
bool supported = false;
|
||||
rdcstr supportMessage;
|
||||
|
||||
READ_DATA_SCOPE();
|
||||
SERIALISE_ELEMENT(driver);
|
||||
SERIALISE_ELEMENT(presenting);
|
||||
SERIALISE_ELEMENT(supported);
|
||||
if(m_Version >= 8)
|
||||
{
|
||||
SERIALISE_ELEMENT(supportMessage);
|
||||
}
|
||||
|
||||
msg.apiUse.name = ToStr(driver);
|
||||
msg.apiUse.presenting = presenting;
|
||||
msg.apiUse.supported = supported;
|
||||
msg.apiUse.supportMessage = supportMessage;
|
||||
|
||||
if(presenting)
|
||||
m_API = ToStr(driver);
|
||||
@@ -859,6 +868,8 @@ public:
|
||||
RDCLOG("Used API: %s (%s & %s)", msg.apiUse.name.c_str(),
|
||||
presenting ? "Presenting" : "Not presenting",
|
||||
supported ? "supported" : "not supported");
|
||||
if(!supportMessage.empty())
|
||||
RDCLOG("Support: %s", supportMessage.c_str());
|
||||
|
||||
reader.EndChunk();
|
||||
return msg;
|
||||
|
||||
@@ -283,6 +283,7 @@ HRESULT __stdcall WrappedD3DDevice8::Present(CONST RECT *pSourceRect, CONST RECT
|
||||
}
|
||||
|
||||
RenderDoc::Inst().AddActiveDriver(RDCDriver::D3D8, true);
|
||||
RenderDoc::Inst().SetDriverUnsupportedMessage(RDCDriver::D3D8, "D3D8 is not a supported API");
|
||||
|
||||
return m_device->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
|
||||
}
|
||||
|
||||
@@ -257,6 +257,7 @@ HRESULT __stdcall WrappedD3DDevice9::Present(CONST RECT *pSourceRect, CONST RECT
|
||||
}
|
||||
|
||||
RenderDoc::Inst().AddActiveDriver(RDCDriver::D3D9, true);
|
||||
RenderDoc::Inst().SetDriverUnsupportedMessage(RDCDriver::D3D9, "D3D9 is not a supported API");
|
||||
|
||||
return m_device->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
|
||||
}
|
||||
|
||||
@@ -1027,7 +1027,28 @@ void WrappedOpenGL::UseUnusedSupportedFunction(const char *name)
|
||||
}
|
||||
}
|
||||
|
||||
size_t sz = m_UnsupportedFunctions.size();
|
||||
m_UnsupportedFunctions.insert(name);
|
||||
|
||||
if(sz != m_UnsupportedFunctions.size())
|
||||
{
|
||||
RDCERR("Unsupported function %s used", name);
|
||||
|
||||
rdcstr unsupportedStatus = StringFormat::Fmt(
|
||||
"Unsupported %s used:\n", m_UnsupportedFunctions.size() == 1 ? "function" : "functions");
|
||||
size_t i = 0;
|
||||
for(const char *func : m_UnsupportedFunctions)
|
||||
{
|
||||
i++;
|
||||
if(i > 4)
|
||||
break;
|
||||
unsupportedStatus += StringFormat::Fmt(" - %s\n", func);
|
||||
}
|
||||
if(m_UnsupportedFunctions.size() > i)
|
||||
unsupportedStatus += " - ...\n";
|
||||
|
||||
RenderDoc::Inst().SetDriverUnsupportedMessage(RDCDriver::OpenGL, unsupportedStatus);
|
||||
}
|
||||
}
|
||||
|
||||
void WrappedOpenGL::CheckImplicitThread()
|
||||
@@ -2073,7 +2094,9 @@ void WrappedOpenGL::SwapBuffers(WindowingSystem winSystem, void *windowHandle)
|
||||
// print the unsupported functions (up to a handful) to show
|
||||
if(!m_UnsupportedFunctions.empty())
|
||||
{
|
||||
overlayText += "Captures disabled.\nUnsupported function used:\n";
|
||||
overlayText +=
|
||||
StringFormat::Fmt("Captures disabled.\nUnsupported %s used:\n",
|
||||
m_UnsupportedFunctions.size() == 1 ? "function" : "functions");
|
||||
size_t i = 0;
|
||||
for(const char *func : m_UnsupportedFunctions)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user