Skip to content

Commit

Permalink
Debug API Rework (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheSpydog authored and flibitijibibo committed Jun 28, 2024
1 parent 6b92690 commit ff49898
Show file tree
Hide file tree
Showing 10 changed files with 223 additions and 51 deletions.
41 changes: 38 additions & 3 deletions include/SDL3/SDL_gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -990,17 +990,52 @@ extern SDL_DECLSPEC void SDLCALL SDL_GpuSetTextureName(
const char *text);

/**
* Sets an arbitrary string constant to label a section of a command buffer. Useful for debugging.
* Inserts an arbitrary string label into the command buffer callstream.
* Useful for debugging.
*
* \param commandBuffer a command buffer
* \param text a UTF-8 string constant to mark as the label
* \param text a UTF-8 string constant to insert as the label
*
* \since This function is available since SDL 3.x.x
*/
extern SDL_DECLSPEC void SDLCALL SDL_GpuSetStringMarker(
extern SDL_DECLSPEC void SDLCALL SDL_GpuInsertDebugLabel(
SDL_GpuCommandBuffer *commandBuffer,
const char *text);

/**
* Begins a debug group with an arbitary name.
* Used for denoting groups of calls when viewing the command buffer callstream
* in a graphics debugging tool.
*
* Each call to SDL_GpuPushDebugGroup must have a corresponding call to SDL_GpuPopDebugGroup.
*
* On some backends (e.g. Metal), pushing a debug group during a render/blit/compute pass
* will create a group that is scoped to the native pass rather than the command buffer.
* For best results, if you push a debug group during a pass, always pop it in the same pass.
*
* \param commandBuffer a command buffer
* \param name a UTF-8 string constant that names the group
*
* \since This function is available since SDL 3.x.x
*
* \sa SDL_GpuPopDebugGroup
*/
extern SDL_DECLSPEC void SDLCALL SDL_GpuPushDebugGroup(
SDL_GpuCommandBuffer *commandBuffer,
const char *name);

/**
* Ends the most-recently pushed debug group.
*
* \param commandBuffer a command buffer
*
* \since This function is available since SDL 3.x.x
*
* \sa SDL_GpuPushDebugGroup
*/
extern SDL_DECLSPEC void SDLCALL SDL_GpuPopDebugGroup(
SDL_GpuCommandBuffer *commandBuffer);

/* Disposal */

/**
Expand Down
4 changes: 3 additions & 1 deletion src/dynapi/SDL_dynapi.sym
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,9 @@ SDL3_0.0.0 {
SDL_GpuCreateTransferBuffer;
SDL_GpuSetBufferName;
SDL_GpuSetTextureName;
SDL_GpuSetStringMarker;
SDL_GpuInsertDebugLabel;
SDL_GpuPushDebugGroup;
SDL_GpuPopDebugGroup;
SDL_GpuReleaseTexture;
SDL_GpuReleaseSampler;
SDL_GpuReleaseBuffer;
Expand Down
4 changes: 3 additions & 1 deletion src/dynapi/SDL_dynapi_overrides.h
Original file line number Diff line number Diff line change
Expand Up @@ -1072,7 +1072,9 @@
#define SDL_GpuCreateTransferBuffer SDL_GpuCreateTransferBuffer_REAL
#define SDL_GpuSetBufferName SDL_GpuSetBufferName_REAL
#define SDL_GpuSetTextureName SDL_GpuSetTextureName_REAL
#define SDL_GpuSetStringMarker SDL_GpuSetStringMarker_REAL
#define SDL_GpuInsertDebugLabel SDL_GpuInsertDebugLabel_REAL
#define SDL_GpuPushDebugGroup SDL_GpuPushDebugGroup_REAL
#define SDL_GpuPopDebugGroup SDL_GpuPopDebugGroup_REAL
#define SDL_GpuReleaseTexture SDL_GpuReleaseTexture_REAL
#define SDL_GpuReleaseSampler SDL_GpuReleaseSampler_REAL
#define SDL_GpuReleaseBuffer SDL_GpuReleaseBuffer_REAL
Expand Down
4 changes: 3 additions & 1 deletion src/dynapi/SDL_dynapi_procs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1078,7 +1078,9 @@ SDL_DYNAPI_PROC(SDL_GpuBuffer*,SDL_GpuCreateBuffer,(SDL_GpuDevice *a, SDL_GpuBuf
SDL_DYNAPI_PROC(SDL_GpuTransferBuffer*,SDL_GpuCreateTransferBuffer,(SDL_GpuDevice *a, SDL_GpuTransferBufferUsage b, Uint32 c),(a,b,c),return)
SDL_DYNAPI_PROC(void,SDL_GpuSetBufferName,(SDL_GpuDevice *a, SDL_GpuBuffer *b, const char *c),(a,b,c),)
SDL_DYNAPI_PROC(void,SDL_GpuSetTextureName,(SDL_GpuDevice *a, SDL_GpuTexture *b, const char *c),(a,b,c),)
SDL_DYNAPI_PROC(void,SDL_GpuSetStringMarker,(SDL_GpuCommandBuffer *a, const char *b),(a,b),)
SDL_DYNAPI_PROC(void,SDL_GpuInsertDebugLabel,(SDL_GpuCommandBuffer *a, const char *b),(a,b),)
SDL_DYNAPI_PROC(void,SDL_GpuPushDebugGroup,(SDL_GpuCommandBuffer *a, const char *b),(a,b),)
SDL_DYNAPI_PROC(void,SDL_GpuPopDebugGroup,(SDL_GpuCommandBuffer *a),(a),)
SDL_DYNAPI_PROC(void,SDL_GpuReleaseTexture,(SDL_GpuDevice *a, SDL_GpuTexture *b),(a,b),)
SDL_DYNAPI_PROC(void,SDL_GpuReleaseSampler,(SDL_GpuDevice *a, SDL_GpuSampler *b),(a,b),)
SDL_DYNAPI_PROC(void,SDL_GpuReleaseBuffer,(SDL_GpuDevice *a, SDL_GpuBuffer *b),(a,b),)
Expand Down
22 changes: 20 additions & 2 deletions src/gpu/SDL_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,16 +484,34 @@ void SDL_GpuSetTextureName(
text);
}

void SDL_GpuSetStringMarker(
void SDL_GpuInsertDebugLabel(
SDL_GpuCommandBuffer *commandBuffer,
const char *text)
{
CHECK_COMMAND_BUFFER
COMMAND_BUFFER_DEVICE->SetStringMarker(
COMMAND_BUFFER_DEVICE->InsertDebugLabel(
commandBuffer,
text);
}

void SDL_GpuPushDebugGroup(
SDL_GpuCommandBuffer *commandBuffer,
const char *name)
{
CHECK_COMMAND_BUFFER
COMMAND_BUFFER_DEVICE->PushDebugGroup(
commandBuffer,
name);
}

void SDL_GpuPopDebugGroup(
SDL_GpuCommandBuffer *commandBuffer)
{
CHECK_COMMAND_BUFFER
COMMAND_BUFFER_DEVICE->PopDebugGroup(
commandBuffer);
}

/* Disposal */

void SDL_GpuReleaseTexture(
Expand Down
13 changes: 11 additions & 2 deletions src/gpu/SDL_gpu_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,17 @@ struct SDL_GpuDevice
SDL_GpuTexture *texture,
const char *text);

void (*SetStringMarker)(
void (*InsertDebugLabel)(
SDL_GpuCommandBuffer *commandBuffer,
const char *text);

void (*PushDebugGroup)(
SDL_GpuCommandBuffer *commandBuffer,
const char *name);

void (*PopDebugGroup)(
SDL_GpuCommandBuffer *commandBuffer);

/* Disposal */

void (*ReleaseTexture)(
Expand Down Expand Up @@ -608,7 +615,9 @@ struct SDL_GpuDevice
ASSIGN_DRIVER_FUNC(CreateTransferBuffer, name) \
ASSIGN_DRIVER_FUNC(SetBufferName, name) \
ASSIGN_DRIVER_FUNC(SetTextureName, name) \
ASSIGN_DRIVER_FUNC(SetStringMarker, name) \
ASSIGN_DRIVER_FUNC(InsertDebugLabel, name) \
ASSIGN_DRIVER_FUNC(PushDebugGroup, name) \
ASSIGN_DRIVER_FUNC(PopDebugGroup, name) \
ASSIGN_DRIVER_FUNC(ReleaseTexture, name) \
ASSIGN_DRIVER_FUNC(ReleaseSampler, name) \
ASSIGN_DRIVER_FUNC(ReleaseBuffer, name) \
Expand Down
113 changes: 75 additions & 38 deletions src/gpu/d3d11/SDL_gpu_d3d11.c
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,9 @@ typedef struct D3D11CommandBuffer
/* Compute Pass */
D3D11ComputePipeline *computePipeline;

/* Debug Annotation */
ID3DUserDefinedAnnotation *annotation;

/* Resource slot state */

SDL_bool needVertexSamplerBind;
Expand Down Expand Up @@ -761,7 +764,6 @@ struct D3D11Renderer
BOOL supportsTearing;
Uint8 supportsFlipDiscard;

ID3DUserDefinedAnnotation *annotation;
SDL_iconv_t iconv;

/* Blit */
Expand Down Expand Up @@ -970,6 +972,9 @@ static void D3D11_DestroyDevice(
/* Release command buffer infrastructure */
for (Uint32 i = 0; i < renderer->availableCommandBufferCount; i += 1) {
D3D11CommandBuffer *commandBuffer = renderer->availableCommandBuffers[i];
if (commandBuffer->annotation) {
ID3DUserDefinedAnnotation_Release(commandBuffer->annotation);
}
ID3D11DeviceContext_Release(commandBuffer->context);
SDL_free(commandBuffer->usedBuffers);
SDL_free(commandBuffer->usedTransferBuffers);
Expand Down Expand Up @@ -1005,10 +1010,7 @@ static void D3D11_DestroyDevice(
}
SDL_free(renderer->availableFences);

/* Release the annotation/iconv, if applicable */
if (renderer->annotation != NULL) {
ID3DUserDefinedAnnotation_Release(renderer->annotation);
}
/* Release the iconv, if applicable */
if (renderer->iconv != NULL) {
SDL_iconv_close(renderer->iconv);
}
Expand Down Expand Up @@ -1776,34 +1778,27 @@ static void D3D11_SetTextureName(
}
}

static void D3D11_SetStringMarker(
SDL_GpuCommandBuffer *commandBuffer,
const char *text)
static SDL_bool D3D11_INTERNAL_StrToWStr(
D3D11Renderer *renderer,
const char *str,
wchar_t *wstr,
size_t wstr_size)
{
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer *)commandBuffer;
D3D11Renderer *renderer = (D3D11Renderer *)d3d11CommandBuffer->renderer;

if (renderer->annotation == NULL) {
return;
}

wchar_t wstr[256];
wchar_t *out = wstr;
size_t inlen, outlen, result;
size_t inlen, result;
size_t outlen = wstr_size;

if (renderer->iconv == NULL) {
renderer->iconv = SDL_iconv_open("WCHAR_T", "UTF-8");
SDL_assert(renderer->iconv);
}

/* Convert... */
inlen = SDL_strlen(text) + 1;
outlen = sizeof(wstr);
inlen = SDL_strlen(str) + 1;
result = SDL_iconv(
renderer->iconv,
&text,
&str,
&inlen,
(char **)&out,
(char **)&wstr,
&outlen);

/* Check... */
Expand All @@ -1812,14 +1807,61 @@ static void D3D11_SetStringMarker(
case SDL_ICONV_E2BIG:
case SDL_ICONV_EILSEQ:
case SDL_ICONV_EINVAL:
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Failed to convert string marker to wchar_t!");
return;
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Failed to convert string to wchar_t!");
return SDL_FALSE;
default:
break;
}

/* Mark, finally. */
ID3DUserDefinedAnnotation_SetMarker(renderer->annotation, wstr);
return SDL_TRUE;
}

static void D3D11_InsertDebugLabel(
SDL_GpuCommandBuffer *commandBuffer,
const char *text)
{
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer *)commandBuffer;
D3D11Renderer *renderer = (D3D11Renderer *)d3d11CommandBuffer->renderer;

if (d3d11CommandBuffer->annotation == NULL) {
return;
}

wchar_t wstr[256];
if (!D3D11_INTERNAL_StrToWStr(renderer, text, wstr, sizeof(wstr))) {
return;
}

ID3DUserDefinedAnnotation_SetMarker(d3d11CommandBuffer->annotation, wstr);
}

static void D3D11_PushDebugGroup(
SDL_GpuCommandBuffer *commandBuffer,
const char *name)
{
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer *)commandBuffer;
D3D11Renderer *renderer = (D3D11Renderer *)d3d11CommandBuffer->renderer;

if (d3d11CommandBuffer->annotation == NULL) {
return;
}

wchar_t wstr[256];
if (!D3D11_INTERNAL_StrToWStr(renderer, name, wstr, sizeof(wstr))) {
return;
}

ID3DUserDefinedAnnotation_BeginEvent(d3d11CommandBuffer->annotation, wstr);
}

static void D3D11_PopDebugGroup(
SDL_GpuCommandBuffer *commandBuffer)
{
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer *)commandBuffer;
if (d3d11CommandBuffer->annotation == NULL) {
return;
}
ID3DUserDefinedAnnotation_EndEvent(d3d11CommandBuffer->annotation);
}

/* Resource Creation */
Expand Down Expand Up @@ -3219,7 +3261,7 @@ static void D3D11_INTERNAL_AllocateCommandBuffers(
sizeof(D3D11CommandBuffer *) * renderer->availableCommandBufferCapacity);

for (Uint32 i = 0; i < allocateCount; i += 1) {
commandBuffer = SDL_malloc(sizeof(D3D11CommandBuffer));
commandBuffer = SDL_calloc(1, sizeof(D3D11CommandBuffer));
commandBuffer->renderer = renderer;

/* Deferred Device Context */
Expand All @@ -3229,6 +3271,12 @@ static void D3D11_INTERNAL_AllocateCommandBuffers(
&commandBuffer->context);
ERROR_CHECK("Could not create deferred context");

/* Initialize debug annotation support, if available */
ID3D11DeviceContext_QueryInterface(
commandBuffer->context,
&D3D_IID_ID3DUserDefinedAnnotation,
(void **)&commandBuffer->annotation);

commandBuffer->initializedVertexUniformBufferCount = 0;
commandBuffer->initializedFragmentUniformBufferCount = 0;
commandBuffer->initializedComputeUniformBufferCount = 0;
Expand Down Expand Up @@ -6252,17 +6300,6 @@ static SDL_GpuDevice *D3D11_CreateDevice(SDL_bool debugMode)
/* Initialize miscellaneous renderer members */
renderer->debugMode = (flags & D3D11_CREATE_DEVICE_DEBUG);

/* Initialize SetStringMarker support, if available */
res = ID3D11DeviceContext_QueryInterface(
renderer->immediateContext,
&D3D_IID_ID3DUserDefinedAnnotation,
(void **)&renderer->annotation);

if (res < 0) {
D3D11_INTERNAL_LogError(renderer->device, "Could not get UserDefinedAnnotation", res);
renderer->annotation = NULL;
}

/* Create command buffer pool */
D3D11_INTERNAL_AllocateCommandBuffers(renderer, 2);

Expand Down
Loading

0 comments on commit ff49898

Please sign in to comment.