Add ways to detect RenderDoc being injected in D3D11 and OpenGL

* D3D11 you query for interface with UUID of
  {A7AA6116-9C8D-4BBA-9083-B4D816B71B78}. It's just IUnknown*
* GL implements GL_EXT_debug_tool with spec here:
  https://renderdoc.org/debug_tool.txt
  with DEBUG_TOOL_EXT #define'd to 0x6789, DEBUG_TOOL_NAME_EXT to 0x678A
  and DEBUG_TOOL_PURPOSE_EXT to 0x678B. For now, reporting this ext is
  enough to identify RenderDoc.
This commit is contained in:
baldurk
2015-04-24 22:12:30 +02:00
parent f576a80cf7
commit 2558b2cdea
8 changed files with 136 additions and 4 deletions
+38 -1
View File
@@ -341,7 +341,7 @@
</para>
</content>
</section>
<section address="FAQ11">
<section address="FAQ16">
<title>RenderDoc is complaining about my OpenGL app in the overlay - what gives?</title>
<content>
<para>
@@ -363,5 +363,42 @@
</para>
</content>
</section>
<section address="FAQ17">
<title>Can I tell via the graphics APIs if RenderDoc is present at runtime?</title>
<content>
<para>
Yes indeed. Some APIs offer ways to do this already - D3DPERF_GetStatus(),
ID3DUserDefinedAnnotation::GetStatus() and ID3D11DeviceContext2::IsAnnotationEnabled().
</para>
<para>
In addition to those:
</para>
<para>
Querying an ID3D11Device for UUID {A7AA6116-9C8D-4BBA-9083-B4D816B71B78}
will return an IUnknown* and S_OK when RenderDoc is present.
</para>
<para>
<externalLink>
<linkText>GL_EXT_debug_tool</linkText>
<linkAlternateText>GL_EXT_debug_tool</linkAlternateText>
<linkUri>https://renderdoc.org/debug_tool.txt</linkUri>
<linkTarget>_blank</linkTarget>
</externalLink>
is implemented on RenderDoc, which is an extension I've proposed for this purpose
(identifying when and which tool is injected in your program). It allows you to query
for the presence name and type of a debug tool that's currently hooked. At the
time of writing only RenderDoc implements this as I've only just proposed the
extension publicly, but in future you can use the queries described in that spec.
<alert class="note">
<para>Alert text</para> Until enumerants are assigned (if that ever happens):
<code language="cpp">
#define GL_DEBUG_TOOL_EXT 0x6789
#define GL_DEBUG_TOOL_NAME_EXT 0x678A
#define GL_DEBUG_TOOL_PURPOSE_EXT 0x678B</code>
</alert>
</para>
</content>
</section>
</developerConceptualDocument>
</topic>
+18
View File
@@ -69,6 +69,24 @@ triggerFunc();
perform precise refinements with the arrow keys to nudge the selection in each direction.</para></listItem>
<listItem><para>To get API debug or error messages, enable "Create Debug Device" when capturing
then check out the <link xlink:href="1f098896-0e60-485a-b879-900a4a320b80" /> window.</para></listItem>
<listItem><para>Detecting RenderDoc from your code can either be done by trying to load and
use the renderdoc in-program API, or through API specific ways:
<code language="cpp">
// For D3D11:
ID3D11Device *devicePointer = ...;
IUnknown *unk = NULL;
HRESULT hr = devicePointer->QueryInterface(MAKE_GUID({A7AA6116-9C8D-4BBA-9083-B4D816B71B78}), &amp;unk);
if(SUCCEEDED(hr)) { /* renderdoc is present; */ }
// For OpenGL:
// if GL_EXT_debug_tool is present (see https://renderdoc.org/debug_tool.txt)
glIsEnabled(GL_DEBUG_TOOL_EXT);
// Until enumerants are assigned (if that ever happens):
#define GL_DEBUG_TOOL_EXT 0x6789
#define GL_DEBUG_TOOL_NAME_EXT 0x678A
#define GL_DEBUG_TOOL_PURPOSE_EXT 0x678B
</code></para></listItem>
<listItem><para>More coming soon hopefully :).</para></listItem>
</list>
</para>
+9
View File
@@ -525,6 +525,9 @@ HRESULT WrappedID3D11Device::QueryInterface(REFIID riid, void **ppvObject)
// DEFINE_GUID(IID_IDirect3DDevice9, 0xd0223b96, 0xbf7a, 0x43fd, 0x92, 0xbd, 0xa4, 0x3b, 0xd, 0x82, 0xb9, 0xeb);
static const GUID IDirect3DDevice9_uuid = { 0xd0223b96, 0xbf7a, 0x43fd, { 0x92, 0xbd, 0xa4, 0x3b, 0xd, 0x82, 0xb9, 0xeb } };
// RenderDoc UUID {A7AA6116-9C8D-4BBA-9083-B4D816B71B78}
static const GUID IRenderDoc_uuid = { 0xa7aa6116, 0x9c8d, 0x4bba, { 0x90, 0x83, 0xb4, 0xd8, 0x16, 0xb7, 0x1b, 0x78 } };
HRESULT hr = S_OK;
if(riid == __uuidof(IDXGIDevice))
@@ -668,6 +671,12 @@ HRESULT WrappedID3D11Device::QueryInterface(REFIID riid, void **ppvObject)
return E_NOINTERFACE;
}
}
else if(riid == IRenderDoc_uuid)
{
AddRef();
*ppvObject = this;
return S_OK;
}
else
{
string guid = ToStr::Get(riid);
+3
View File
@@ -3993,6 +3993,9 @@ string ToStrHelper<false, RDCGLenum>::Get(const RDCGLenum &el)
TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT)
TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT)
TOSTR_CASE_STRINGIZE_GLENUM(GL_SYNC_X11_FENCE_EXT)
TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TOOL_EXT)
TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TOOL_NAME_EXT)
TOSTR_CASE_STRINGIZE_GLENUM(GL_DEBUG_TOOL_PURPOSE_EXT)
TOSTR_CASE_STRINGIZE_GLENUM(GL_IGNORE_BORDER_HP)
TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_SCALE_X_HP)
TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_SCALE_Y_HP)
+5
View File
@@ -1109,6 +1109,11 @@ void WrappedOpenGL::ActivateContext(GLWindowingData winData)
}
}
}
// this extension is something RenderDoc will support even if the impl
// doesn't. https://renderdoc.org/debug_tool.txt
ctxdata.glExts.push_back("GL_EXT_debug_tool");
merge(ctxdata.glExts, ctxdata.glExtsString, ' ');
if(gl.glGetIntegerv)
+8
View File
@@ -3204,6 +3204,14 @@ enum RDCGLenum
eGL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT = 0x850F,
eGL_VERTEX_WEIGHT_ARRAY_POINTER_EXT = 0x8510,
eGL_SYNC_X11_FENCE_EXT = 0x90E1,
eGL_DEBUG_TOOL_EXT = 0x6789,
eGL_DEBUG_TOOL_NAME_EXT = 0x678A,
eGL_DEBUG_TOOL_PURPOSE_EXT = 0x678B,
eGL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT = 0x0001,
eGL_DEBUG_TOOL_TRACE_CAPTURE_BIT_EXT = 0x0002,
eGL_DEBUG_TOOL_API_CALL_LOG_BIT_EXT = 0x0004,
eGL_DEBUG_TOOL_PROFILING_BIT_EXT = 0x0008,
eGL_DEBUG_TOOL_VALIDATION_BIT_EXT = 0x0010,
eGL_IGNORE_BORDER_HP = 0x8150,
eGL_CONSTANT_BORDER_HP = 0x8151,
eGL_REPLICATE_BORDER_HP = 0x8153,
+14
View File
@@ -8458,6 +8458,20 @@ GLAPI GLsync APIENTRY glImportSyncEXT (GLenum external_sync_type, GLintptr exter
#endif
#endif /* GL_EXT_x11_sync_object */
// Manually added for ease of running scripts on this header to generate
// prototypes/enum etc. https://renderdoc.org/debug_tool.txt
#ifndef GL_EXT_debug_tool
#define GL_EXT_debug_tool 1
#define GL_DEBUG_TOOL_EXT 0x6789
#define GL_DEBUG_TOOL_NAME_EXT 0x678A
#define GL_DEBUG_TOOL_PURPOSE_EXT 0x678B
#define GL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT 0x0001
#define GL_DEBUG_TOOL_TRACE_CAPTURE_BIT_EXT 0x0002
#define GL_DEBUG_TOOL_API_CALL_LOG_BIT_EXT 0x0004
#define GL_DEBUG_TOOL_PROFILING_BIT_EXT 0x0008
#define GL_DEBUG_TOOL_VALIDATION_BIT_EXT 0x0010
#endif /* GL_EXT_debug_tool */
#ifndef GL_GREMEDY_frame_terminator
#define GL_GREMEDY_frame_terminator 1
typedef void (APIENTRYP PFNGLFRAMETERMINATORGREMEDYPROC) (void);
+41 -3
View File
@@ -59,6 +59,9 @@ void WrappedOpenGL::glFinish()
GLboolean WrappedOpenGL::glIsEnabled(GLenum cap)
{
if(cap == eGL_DEBUG_TOOL_EXT)
return true;
return m_Real.glIsEnabled(cap);
}
@@ -69,6 +72,9 @@ GLboolean WrappedOpenGL::glIsTexture(GLuint texture)
GLboolean WrappedOpenGL::glIsEnabledi(GLenum target, GLuint index)
{
if(target == eGL_DEBUG_TOOL_EXT)
return true;
return m_Real.glIsEnabledi(target, index);
}
@@ -160,12 +166,18 @@ void WrappedOpenGL::glGetIntegerv(GLenum pname, GLint *params)
*params = (GLint)64;
return;
}
if(pname == eGL_NUM_EXTENSIONS)
else if(pname == eGL_NUM_EXTENSIONS)
{
if(params)
*params = (GLint)GetCtxData().glExts.size();
return;
}
else if(pname == eGL_DEBUG_TOOL_PURPOSE_EXT)
{
if(params)
*params = GLint(eGL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT);
return;
}
m_Real.glGetIntegerv(pname, params);
}
@@ -180,7 +192,13 @@ void WrappedOpenGL::glGetInteger64v(GLenum pname, GLint64 *data)
if(pname == eGL_MIN_MAP_BUFFER_ALIGNMENT)
{
if(data)
*data = (GLint)64;
*data = (GLint64)64;
return;
}
else if(pname == eGL_DEBUG_TOOL_PURPOSE_EXT)
{
if(data)
*data = GLint64(eGL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT);
return;
}
m_Real.glGetInteger64v(pname, data);
@@ -199,6 +217,12 @@ void WrappedOpenGL::glGetIntegeri_v(GLenum pname, GLuint index, GLint *data)
*data = (GLint)64;
return;
}
else if(pname == eGL_DEBUG_TOOL_PURPOSE_EXT)
{
if(data)
*data = GLint(eGL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT);
return;
}
m_Real.glGetIntegeri_v(pname, index, data);
}
@@ -217,7 +241,13 @@ void WrappedOpenGL::glGetInteger64i_v(GLenum pname, GLuint index, GLint64 *data)
if(pname == eGL_MIN_MAP_BUFFER_ALIGNMENT)
{
if(data)
*data = (GLint)64;
*data = (GLint64)64;
return;
}
else if(pname == eGL_DEBUG_TOOL_PURPOSE_EXT)
{
if(data)
*data = GLint64(eGL_DEBUG_TOOL_FRAME_CAPTURE_BIT_EXT);
return;
}
m_Real.glGetInteger64i_v(pname, index, data);
@@ -477,6 +507,10 @@ const GLubyte *WrappedOpenGL::glGetString(GLenum name)
{
return (const GLubyte *)GetCtxData().glExtsString.c_str();
}
else if(name == eGL_DEBUG_TOOL_NAME_EXT)
{
return (const GLubyte *)"RenderDoc";
}
return m_Real.glGetString(name);
}
@@ -489,6 +523,10 @@ const GLubyte *WrappedOpenGL::glGetStringi(GLenum name, GLuint i)
return (const GLubyte *)"";
}
else if(name == eGL_DEBUG_TOOL_NAME_EXT)
{
return (const GLubyte *)"RenderDoc";
}
return m_Real.glGetStringi(name, i);
}