mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-22 22:46:41 +00:00
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:
+38
-1
@@ -341,7 +341,7 @@
|
|||||||
</para>
|
</para>
|
||||||
</content>
|
</content>
|
||||||
</section>
|
</section>
|
||||||
<section address="FAQ11">
|
<section address="FAQ16">
|
||||||
<title>RenderDoc is complaining about my OpenGL app in the overlay - what gives?</title>
|
<title>RenderDoc is complaining about my OpenGL app in the overlay - what gives?</title>
|
||||||
<content>
|
<content>
|
||||||
<para>
|
<para>
|
||||||
@@ -363,5 +363,42 @@
|
|||||||
</para>
|
</para>
|
||||||
</content>
|
</content>
|
||||||
</section>
|
</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>
|
</developerConceptualDocument>
|
||||||
</topic>
|
</topic>
|
||||||
|
|||||||
@@ -69,6 +69,24 @@ triggerFunc();
|
|||||||
perform precise refinements with the arrow keys to nudge the selection in each direction.</para></listItem>
|
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
|
<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>
|
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}), &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>
|
<listItem><para>More coming soon hopefully :).</para></listItem>
|
||||||
</list>
|
</list>
|
||||||
</para>
|
</para>
|
||||||
|
|||||||
@@ -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);
|
// 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 } };
|
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;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
if(riid == __uuidof(IDXGIDevice))
|
if(riid == __uuidof(IDXGIDevice))
|
||||||
@@ -668,6 +671,12 @@ HRESULT WrappedID3D11Device::QueryInterface(REFIID riid, void **ppvObject)
|
|||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(riid == IRenderDoc_uuid)
|
||||||
|
{
|
||||||
|
AddRef();
|
||||||
|
*ppvObject = this;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string guid = ToStr::Get(riid);
|
string guid = ToStr::Get(riid);
|
||||||
|
|||||||
@@ -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_STRIDE_EXT)
|
||||||
TOSTR_CASE_STRINGIZE_GLENUM(GL_VERTEX_WEIGHT_ARRAY_POINTER_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_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_IGNORE_BORDER_HP)
|
||||||
TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_SCALE_X_HP)
|
TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_SCALE_X_HP)
|
||||||
TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_SCALE_Y_HP)
|
TOSTR_CASE_STRINGIZE_GLENUM(GL_IMAGE_SCALE_Y_HP)
|
||||||
|
|||||||
@@ -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, ' ');
|
merge(ctxdata.glExts, ctxdata.glExtsString, ' ');
|
||||||
|
|
||||||
if(gl.glGetIntegerv)
|
if(gl.glGetIntegerv)
|
||||||
|
|||||||
@@ -3204,6 +3204,14 @@ enum RDCGLenum
|
|||||||
eGL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT = 0x850F,
|
eGL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT = 0x850F,
|
||||||
eGL_VERTEX_WEIGHT_ARRAY_POINTER_EXT = 0x8510,
|
eGL_VERTEX_WEIGHT_ARRAY_POINTER_EXT = 0x8510,
|
||||||
eGL_SYNC_X11_FENCE_EXT = 0x90E1,
|
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_IGNORE_BORDER_HP = 0x8150,
|
||||||
eGL_CONSTANT_BORDER_HP = 0x8151,
|
eGL_CONSTANT_BORDER_HP = 0x8151,
|
||||||
eGL_REPLICATE_BORDER_HP = 0x8153,
|
eGL_REPLICATE_BORDER_HP = 0x8153,
|
||||||
|
|||||||
@@ -8458,6 +8458,20 @@ GLAPI GLsync APIENTRY glImportSyncEXT (GLenum external_sync_type, GLintptr exter
|
|||||||
#endif
|
#endif
|
||||||
#endif /* GL_EXT_x11_sync_object */
|
#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
|
#ifndef GL_GREMEDY_frame_terminator
|
||||||
#define GL_GREMEDY_frame_terminator 1
|
#define GL_GREMEDY_frame_terminator 1
|
||||||
typedef void (APIENTRYP PFNGLFRAMETERMINATORGREMEDYPROC) (void);
|
typedef void (APIENTRYP PFNGLFRAMETERMINATORGREMEDYPROC) (void);
|
||||||
|
|||||||
@@ -59,6 +59,9 @@ void WrappedOpenGL::glFinish()
|
|||||||
|
|
||||||
GLboolean WrappedOpenGL::glIsEnabled(GLenum cap)
|
GLboolean WrappedOpenGL::glIsEnabled(GLenum cap)
|
||||||
{
|
{
|
||||||
|
if(cap == eGL_DEBUG_TOOL_EXT)
|
||||||
|
return true;
|
||||||
|
|
||||||
return m_Real.glIsEnabled(cap);
|
return m_Real.glIsEnabled(cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,6 +72,9 @@ GLboolean WrappedOpenGL::glIsTexture(GLuint texture)
|
|||||||
|
|
||||||
GLboolean WrappedOpenGL::glIsEnabledi(GLenum target, GLuint index)
|
GLboolean WrappedOpenGL::glIsEnabledi(GLenum target, GLuint index)
|
||||||
{
|
{
|
||||||
|
if(target == eGL_DEBUG_TOOL_EXT)
|
||||||
|
return true;
|
||||||
|
|
||||||
return m_Real.glIsEnabledi(target, index);
|
return m_Real.glIsEnabledi(target, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,12 +166,18 @@ void WrappedOpenGL::glGetIntegerv(GLenum pname, GLint *params)
|
|||||||
*params = (GLint)64;
|
*params = (GLint)64;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(pname == eGL_NUM_EXTENSIONS)
|
else if(pname == eGL_NUM_EXTENSIONS)
|
||||||
{
|
{
|
||||||
if(params)
|
if(params)
|
||||||
*params = (GLint)GetCtxData().glExts.size();
|
*params = (GLint)GetCtxData().glExts.size();
|
||||||
return;
|
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);
|
m_Real.glGetIntegerv(pname, params);
|
||||||
}
|
}
|
||||||
@@ -180,7 +192,13 @@ void WrappedOpenGL::glGetInteger64v(GLenum pname, GLint64 *data)
|
|||||||
if(pname == eGL_MIN_MAP_BUFFER_ALIGNMENT)
|
if(pname == eGL_MIN_MAP_BUFFER_ALIGNMENT)
|
||||||
{
|
{
|
||||||
if(data)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
m_Real.glGetInteger64v(pname, data);
|
m_Real.glGetInteger64v(pname, data);
|
||||||
@@ -199,6 +217,12 @@ void WrappedOpenGL::glGetIntegeri_v(GLenum pname, GLuint index, GLint *data)
|
|||||||
*data = (GLint)64;
|
*data = (GLint)64;
|
||||||
return;
|
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);
|
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(pname == eGL_MIN_MAP_BUFFER_ALIGNMENT)
|
||||||
{
|
{
|
||||||
if(data)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
m_Real.glGetInteger64i_v(pname, index, data);
|
m_Real.glGetInteger64i_v(pname, index, data);
|
||||||
@@ -477,6 +507,10 @@ const GLubyte *WrappedOpenGL::glGetString(GLenum name)
|
|||||||
{
|
{
|
||||||
return (const GLubyte *)GetCtxData().glExtsString.c_str();
|
return (const GLubyte *)GetCtxData().glExtsString.c_str();
|
||||||
}
|
}
|
||||||
|
else if(name == eGL_DEBUG_TOOL_NAME_EXT)
|
||||||
|
{
|
||||||
|
return (const GLubyte *)"RenderDoc";
|
||||||
|
}
|
||||||
return m_Real.glGetString(name);
|
return m_Real.glGetString(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,6 +523,10 @@ const GLubyte *WrappedOpenGL::glGetStringi(GLenum name, GLuint i)
|
|||||||
|
|
||||||
return (const GLubyte *)"";
|
return (const GLubyte *)"";
|
||||||
}
|
}
|
||||||
|
else if(name == eGL_DEBUG_TOOL_NAME_EXT)
|
||||||
|
{
|
||||||
|
return (const GLubyte *)"RenderDoc";
|
||||||
|
}
|
||||||
return m_Real.glGetStringi(name, i);
|
return m_Real.glGetStringi(name, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user