libobs/graphics: Support debug markers

Add support for debug markers via D3DPERF API and KHR_debug. This makes
it easier to understand RenderDoc captures.

D3DPERF is preferred to ID3DUserDefinedAnnotation because it supports
colors. d3d9.lib is now linked in to support this.

This feature is disabled by default, and is controlled by
GS_USE_DEBUG_MARKERS.

From: obsproject/obs-studio#1799
master
James Park 2019-04-02 23:22:19 -07:00 committed by jp9000
parent a3e5344cce
commit 2996a6c06b
8 changed files with 117 additions and 0 deletions

View File

@ -30,6 +30,7 @@ set_target_properties(libobs-d3d11
PREFIX "")
target_link_libraries(libobs-d3d11
libobs
d3d9
d3d11
dxgi)

View File

@ -21,6 +21,7 @@
#include <util/dstr.h>
#include <util/util.hpp>
#include <graphics/matrix3.h>
#include <d3d9.h>
#include "d3d11-subsystem.hpp"
struct UnsupportedHWError : HRError {
@ -2217,6 +2218,24 @@ extern "C" EXPORT bool device_nv12_available(gs_device_t *device)
return device->nv12Supported;
}
extern "C" EXPORT void device_debug_marker_begin(gs_device_t *,
const char *markername, const float color[4])
{
D3DCOLOR bgra = D3DCOLOR_ARGB((DWORD)(255.0f * color[3]),
(DWORD)(255.0f * color[0]), (DWORD)(255.0f * color[1]),
(DWORD)(255.0f * color[2]));
wchar_t wide[64];
os_utf8_to_wcs(markername, 0, wide, _countof(wide));
D3DPERF_BeginEvent(bgra, wide);
}
extern "C" EXPORT void device_debug_marker_end(gs_device_t *)
{
D3DPERF_EndEvent();
}
extern "C" EXPORT gs_texture_t *device_texture_create_gdi(gs_device_t *device,
uint32_t width, uint32_t height)
{

View File

@ -1341,6 +1341,22 @@ void device_projection_pop(gs_device_t *device)
da_pop_back(device->proj_stack);
}
void device_debug_marker_begin(gs_device_t *device,
const char *markername, const float color[4])
{
UNUSED_PARAMETER(device);
UNUSED_PARAMETER(color);
glPushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION, 0, -1, markername);
}
void device_debug_marker_end(gs_device_t *device)
{
UNUSED_PARAMETER(device);
glPopDebugGroupKHR();
}
void gs_swapchain_destroy(gs_swapchain_t *swapchain)
{
if (!swapchain)

View File

@ -142,6 +142,9 @@ EXPORT void device_frustum(gs_device_t *device, float left, float right,
float top, float bottom, float znear, float zfar);
EXPORT void device_projection_push(gs_device_t *device);
EXPORT void device_projection_pop(gs_device_t *device);
EXPORT void device_debug_marker_begin(gs_device_t *device,
const char *markername, const float color[4]);
EXPORT void device_debug_marker_end(gs_device_t *device);
#ifdef __cplusplus
}

View File

@ -173,6 +173,9 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
GRAPHICS_IMPORT_OPTIONAL(device_nv12_available);
GRAPHICS_IMPORT(device_debug_marker_begin);
GRAPHICS_IMPORT(device_debug_marker_end);
/* OSX/Cocoa specific functions */
#ifdef __APPLE__
GRAPHICS_IMPORT_OPTIONAL(device_texture_create_from_iosurface);

View File

@ -234,6 +234,10 @@ struct gs_exports {
bool (*device_nv12_available)(gs_device_t *device);
void (*device_debug_marker_begin)(gs_device_t *device,
const char *markername, const float color[4]);
void (*device_debug_marker_end)(gs_device_t *device);
#ifdef __APPLE__
/* OSX/Cocoa specific functions */
gs_texture_t *(*device_texture_create_from_iosurface)(gs_device_t *dev,

View File

@ -2557,6 +2557,49 @@ bool gs_nv12_available(void)
thread_graphics->device);
}
void gs_debug_marker_begin(const float color[4],
const char *markername)
{
if (!gs_valid("gs_debug_marker_begin"))
return;
if (!markername)
markername = "(null)";
thread_graphics->exports.device_debug_marker_begin(
thread_graphics->device, markername,
color);
}
void gs_debug_marker_begin_format(const float color[4],
const char *format, ...)
{
if (!gs_valid("gs_debug_marker_begin"))
return;
if (format) {
char markername[64];
va_list args;
va_start(args, format);
vsnprintf(markername, sizeof(markername), format, args);
va_end(args);
thread_graphics->exports.device_debug_marker_begin(
thread_graphics->device, markername,
color);
} else {
gs_debug_marker_begin(color, NULL);
}
}
void gs_debug_marker_end(void)
{
if (!gs_valid("gs_debug_marker_end"))
return;
thread_graphics->exports.device_debug_marker_end(
thread_graphics->device);
}
#ifdef __APPLE__
/** Platform specific functions */

View File

@ -761,6 +761,34 @@ EXPORT enum gs_index_type gs_indexbuffer_get_type(
EXPORT bool gs_nv12_available(void);
#define GS_USE_DEBUG_MARKERS 0
#if GS_USE_DEBUG_MARKERS
static const float GS_DEBUG_COLOR_DEFAULT[] = { 0.5f, 0.5f, 0.5f, 1.0f };
static const float GS_DEBUG_COLOR_RENDER_VIDEO[] = { 0.0f, 0.5f, 0.0f, 1.0f };
static const float GS_DEBUG_COLOR_MAIN_TEXTURE[] = { 0.0f, 0.25f, 0.0f, 1.0f };
static const float GS_DEBUG_COLOR_DISPLAY[] = { 0.0f, 0.5f, 0.5f, 1.0f };
static const float GS_DEBUG_COLOR_SOURCE[] = { 0.0f, 0.5f, 5.0f, 1.0f };
static const float GS_DEBUG_COLOR_ITEM[] = { 0.5f, 0.0f, 0.0f, 1.0f };
static const float GS_DEBUG_COLOR_ITEM_TEXTURE[] = { 0.25f, 0.0f, 0.0f, 1.0f };
static const float GS_DEBUG_COLOR_CONVERT_FORMAT[] = { 0.5f, 0.5f, 0.0f, 1.0f };
#define GS_DEBUG_MARKER_BEGIN(color, markername) \
gs_debug_marker_begin(color, markername)
#define GS_DEBUG_MARKER_BEGIN_FORMAT(color, format, ...) \
gs_debug_marker_begin_format(color, format, \
__VA_ARGS__)
#define GS_DEBUG_MARKER_END() gs_debug_marker_end()
#else
#define GS_DEBUG_MARKER_BEGIN(color, markername) ((void)0)
#define GS_DEBUG_MARKER_BEGIN_FORMAT(color, format, ...) ((void)0)
#define GS_DEBUG_MARKER_END() ((void)0)
#endif
EXPORT void gs_debug_marker_begin(const float color[4],
const char *markername);
EXPORT void gs_debug_marker_begin_format(const float color[4],
const char *format, ...);
EXPORT void gs_debug_marker_end(void);
#ifdef __APPLE__
/** platform specific function for creating (GL_TEXTURE_RECTANGLE) textures