From fb6df933848fdda0f204dd51925b42593ed177c6 Mon Sep 17 00:00:00 2001
From: Evan Hemsley <[EMAIL REDACTED]>
Date: Mon, 13 Jan 2025 17:29:08 -0800
Subject: [PATCH] GPU: Add name properties to resources (#11946)
---
include/SDL3/SDL_gpu.h | 56 ++++-
src/gpu/SDL_gpu.c | 10 +-
src/gpu/SDL_sysgpu.h | 6 +-
src/gpu/d3d12/SDL_gpu_d3d12.c | 392 ++++++++++++++++----------------
src/gpu/metal/SDL_gpu_metal.m | 103 ++++++---
src/gpu/vulkan/SDL_gpu_vulkan.c | 165 ++++++++++----
test/testgpu_spinning_cube.c | 10 +-
7 files changed, 441 insertions(+), 301 deletions(-)
diff --git a/include/SDL3/SDL_gpu.h b/include/SDL3/SDL_gpu.h
index b0a9cdf204dab..2db3a720c9cb3 100644
--- a/include/SDL3/SDL_gpu.h
+++ b/include/SDL3/SDL_gpu.h
@@ -334,7 +334,6 @@ typedef struct SDL_GPUDevice SDL_GPUDevice;
* \since This struct is available since SDL 3.1.3
*
* \sa SDL_CreateGPUBuffer
- * \sa SDL_SetGPUBufferName
* \sa SDL_UploadToGPUBuffer
* \sa SDL_DownloadFromGPUBuffer
* \sa SDL_CopyGPUBufferToBuffer
@@ -374,7 +373,6 @@ typedef struct SDL_GPUTransferBuffer SDL_GPUTransferBuffer;
* \since This struct is available since SDL 3.1.3
*
* \sa SDL_CreateGPUTexture
- * \sa SDL_SetGPUTextureName
* \sa SDL_UploadToGPUTexture
* \sa SDL_DownloadFromGPUTexture
* \sa SDL_CopyGPUTextureToTexture
@@ -2247,6 +2245,10 @@ extern SDL_DECLSPEC SDL_GPUShaderFormat SDLCALL SDL_GetGPUShaderFormats(SDL_GPUD
* - [[texture]]: Sampled textures, followed by read-only storage textures,
* followed by read-write storage textures
*
+ * There are optional properties that can be provided through `props`. These are the supported properties:
+ *
+ * - `SDL_PROP_GPU_COMPUTEPIPELINE_CREATE_NAME_STRING`: a name that can be displayed in debugging tools.
+ *
* \param device a GPU Context.
* \param createinfo a struct describing the state of the compute pipeline to
* create.
@@ -2262,9 +2264,15 @@ extern SDL_DECLSPEC SDL_GPUComputePipeline *SDLCALL SDL_CreateGPUComputePipeline
SDL_GPUDevice *device,
const SDL_GPUComputePipelineCreateInfo *createinfo);
+#define SDL_PROP_GPU_COMPUTEPIPELINE_CREATE_NAME_STRING "SDL.gpu.computepipeline.create.name"
+
/**
* Creates a pipeline object to be used in a graphics workflow.
*
+ * There are optional properties that can be provided through `props`. These are the supported properties:
+ *
+ * - `SDL_PROP_GPU_GRAPHICSPIPELINE_CREATE_NAME_STRING`: a name that can be displayed in debugging tools.
+ *
* \param device a GPU Context.
* \param createinfo a struct describing the state of the graphics pipeline to
* create.
@@ -2281,10 +2289,16 @@ extern SDL_DECLSPEC SDL_GPUGraphicsPipeline *SDLCALL SDL_CreateGPUGraphicsPipeli
SDL_GPUDevice *device,
const SDL_GPUGraphicsPipelineCreateInfo *createinfo);
+#define SDL_PROP_GPU_GRAPHICSPIPELINE_CREATE_NAME_STRING "SDL.gpu.graphicspipeline.create.name"
+
/**
* Creates a sampler object to be used when binding textures in a graphics
* workflow.
*
+ * There are optional properties that can be provided through `props`. These are the supported properties:
+ *
+ * - `SDL_PROP_GPU_SAMPLER_CREATE_NAME_STRING`: a name that can be displayed in debugging tools.
+ *
* \param device a GPU Context.
* \param createinfo a struct describing the state of the sampler to create.
* \returns a sampler object on success, or NULL on failure; call
@@ -2300,6 +2314,8 @@ extern SDL_DECLSPEC SDL_GPUSampler *SDLCALL SDL_CreateGPUSampler(
SDL_GPUDevice *device,
const SDL_GPUSamplerCreateInfo *createinfo);
+#define SDL_PROP_GPU_SAMPLER_CREATE_NAME_STRING "SDL.gpu.sampler.create.name"
+
/**
* Creates a shader to be used when creating a graphics pipeline.
*
@@ -2357,6 +2373,10 @@ extern SDL_DECLSPEC SDL_GPUSampler *SDLCALL SDL_CreateGPUSampler(
* SDL_PROP_GPU_DEVICE_CREATE_D3D12_SEMANTIC_NAME_STRING with
* SDL_CreateGPUDeviceWithProperties().
*
+ * There are optional properties that can be provided through `props`. These are the supported properties:
+ *
+ * - `SDL_PROP_GPU_SHADER_CREATE_NAME_STRING`: a name that can be displayed in debugging tools.
+ *
* \param device a GPU Context.
* \param createinfo a struct describing the state of the shader to create.
* \returns a shader object on success, or NULL on failure; call
@@ -2371,6 +2391,8 @@ extern SDL_DECLSPEC SDL_GPUShader *SDLCALL SDL_CreateGPUShader(
SDL_GPUDevice *device,
const SDL_GPUShaderCreateInfo *createinfo);
+#define SDL_PROP_GPU_SHADER_CREATE_NAME_STRING "SDL.gpu.shader.create.name"
+
/**
* Creates a texture object to be used in graphics or compute workflows.
*
@@ -2408,6 +2430,7 @@ extern SDL_DECLSPEC SDL_GPUShader *SDLCALL SDL_CreateGPUShader(
* - `SDL_PROP_GPU_CREATETEXTURE_D3D12_CLEAR_STENCIL_UINT8`: (Direct3D 12
* only) if the texture usage is SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET,
* clear the texture to a stencil of this value. Defaults to zero.
+ * - `SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING`: a name that can be displayed in debugging tools.
*
* \param device a GPU Context.
* \param createinfo a struct describing the state of the texture to create.
@@ -2437,7 +2460,7 @@ extern SDL_DECLSPEC SDL_GPUTexture *SDLCALL SDL_CreateGPUTexture(
#define SDL_PROP_GPU_CREATETEXTURE_D3D12_CLEAR_A_FLOAT "SDL.gpu.createtexture.d3d12.clear.a"
#define SDL_PROP_GPU_CREATETEXTURE_D3D12_CLEAR_DEPTH_FLOAT "SDL.gpu.createtexture.d3d12.clear.depth"
#define SDL_PROP_GPU_CREATETEXTURE_D3D12_CLEAR_STENCIL_UINT8 "SDL.gpu.createtexture.d3d12.clear.stencil"
-
+#define SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING "SDL.gpu.texture.create.name"
/**
* Creates a buffer object to be used in graphics or compute workflows.
@@ -2453,6 +2476,10 @@ extern SDL_DECLSPEC SDL_GPUTexture *SDLCALL SDL_CreateGPUTexture(
* [this blog post](https://moonside.games/posts/sdl-gpu-concepts-cycling/)
* .
*
+ * There are optional properties that can be provided through `props`. These are the supported properties:
+ *
+ * - `SDL_PROP_GPU_BUFFER_CREATE_NAME_STRING`: a name that can be displayed in debugging tools.
+ *
* \param device a GPU Context.
* \param createinfo a struct describing the state of the buffer to create.
* \returns a buffer object on success, or NULL on failure; call
@@ -2460,7 +2487,6 @@ extern SDL_DECLSPEC SDL_GPUTexture *SDLCALL SDL_CreateGPUTexture(
*
* \since This function is available since SDL 3.1.3.
*
- * \sa SDL_SetGPUBufferName
* \sa SDL_UploadToGPUBuffer
* \sa SDL_DownloadFromGPUBuffer
* \sa SDL_CopyGPUBufferToBuffer
@@ -2478,6 +2504,8 @@ extern SDL_DECLSPEC SDL_GPUBuffer *SDLCALL SDL_CreateGPUBuffer(
SDL_GPUDevice *device,
const SDL_GPUBufferCreateInfo *createinfo);
+#define SDL_PROP_GPU_BUFFER_CREATE_NAME_STRING "SDL.gpu.buffer.create.name"
+
/**
* Creates a transfer buffer to be used when uploading to or downloading from
* graphics resources.
@@ -2485,6 +2513,10 @@ extern SDL_DECLSPEC SDL_GPUBuffer *SDLCALL SDL_CreateGPUBuffer(
* Download buffers can be particularly expensive to create, so it is good
* practice to reuse them if data will be downloaded regularly.
*
+ * There are optional properties that can be provided through `props`. These are the supported properties:
+ *
+ * - `SDL_PROP_GPU_TRANSFERBUFFER_CREATE_NAME_STRING`: a name that can be displayed in debugging tools.
+ *
* \param device a GPU Context.
* \param createinfo a struct describing the state of the transfer buffer to
* create.
@@ -2503,21 +2535,24 @@ extern SDL_DECLSPEC SDL_GPUTransferBuffer *SDLCALL SDL_CreateGPUTransferBuffer(
SDL_GPUDevice *device,
const SDL_GPUTransferBufferCreateInfo *createinfo);
+#define SDL_PROP_GPU_TRANSFERBUFFER_CREATE_NAME_STRING "SDL.gpu.transferbuffer.create.name"
+
/* Debug Naming */
/**
* Sets an arbitrary string constant to label a buffer.
*
- * Useful for debugging.
+ * You should use SDL_PROP_GPU_BUFFER_CREATE_NAME_STRING with SDL_CreateGPUBuffer instead of this function to avoid thread safety issues.
*
* \param device a GPU Context.
* \param buffer a buffer to attach the name to.
* \param text a UTF-8 string constant to mark as the name of the buffer.
*
- * \threadsafety This function is not thread safe, you must synchronize calls
- * to this function.
+ * \threadsafety This function is not thread safe, you must make sure the buffer is not simultaneously used by any other thread.
*
* \since This function is available since SDL 3.1.3.
+ *
+ * \sa SDL_CreateGPUBuffer
*/
extern SDL_DECLSPEC void SDLCALL SDL_SetGPUBufferName(
SDL_GPUDevice *device,
@@ -2527,16 +2562,17 @@ extern SDL_DECLSPEC void SDLCALL SDL_SetGPUBufferName(
/**
* Sets an arbitrary string constant to label a texture.
*
- * Useful for debugging.
+ * You should use SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING with SDL_CreateGPUTexture instead of this function to avoid thread safety issues.
*
* \param device a GPU Context.
* \param texture a texture to attach the name to.
* \param text a UTF-8 string constant to mark as the name of the texture.
*
- * \threadsafety This function is not thread safe, you must synchronize calls
- * to this function.
+ * \threadsafety This function is not thread safe, you must make sure the texture is not simultaneously used by any other thread.
*
* \since This function is available since SDL 3.1.3.
+ *
+ * \sa SDL_CreateGPUTexture
*/
extern SDL_DECLSPEC void SDLCALL SDL_SetGPUTextureName(
SDL_GPUDevice *device,
diff --git a/src/gpu/SDL_gpu.c b/src/gpu/SDL_gpu.c
index e24ad9b680c82..34905cea2ce36 100644
--- a/src/gpu/SDL_gpu.c
+++ b/src/gpu/SDL_gpu.c
@@ -1055,10 +1055,13 @@ SDL_GPUBuffer *SDL_CreateGPUBuffer(
return NULL;
}
+ const char *debugName = SDL_GetStringProperty(createinfo->props, SDL_PROP_GPU_BUFFER_CREATE_NAME_STRING, NULL);
+
return device->CreateBuffer(
device->driverData,
createinfo->usage,
- createinfo->size);
+ createinfo->size,
+ debugName);
}
SDL_GPUTransferBuffer *SDL_CreateGPUTransferBuffer(
@@ -1071,10 +1074,13 @@ SDL_GPUTransferBuffer *SDL_CreateGPUTransferBuffer(
return NULL;
}
+ const char *debugName = SDL_GetStringProperty(createinfo->props, SDL_PROP_GPU_TRANSFERBUFFER_CREATE_NAME_STRING, NULL);
+
return device->CreateTransferBuffer(
device->driverData,
createinfo->usage,
- createinfo->size);
+ createinfo->size,
+ debugName);
}
// Debug Naming
diff --git a/src/gpu/SDL_sysgpu.h b/src/gpu/SDL_sysgpu.h
index 85bad24434a4b..98f4be9f8574e 100644
--- a/src/gpu/SDL_sysgpu.h
+++ b/src/gpu/SDL_sysgpu.h
@@ -474,12 +474,14 @@ struct SDL_GPUDevice
SDL_GPUBuffer *(*CreateBuffer)(
SDL_GPURenderer *driverData,
SDL_GPUBufferUsageFlags usageFlags,
- Uint32 size);
+ Uint32 size,
+ const char *debugName);
SDL_GPUTransferBuffer *(*CreateTransferBuffer)(
SDL_GPURenderer *driverData,
SDL_GPUTransferBufferUsage usage,
- Uint32 size);
+ Uint32 size,
+ const char *debugName);
// Debug Naming
diff --git a/src/gpu/d3d12/SDL_gpu_d3d12.c b/src/gpu/d3d12/SDL_gpu_d3d12.c
index c613e29bc7805..39c8b62b6be67 100644
--- a/src/gpu/d3d12/SDL_gpu_d3d12.c
+++ b/src/gpu/d3d12/SDL_gpu_d3d12.c
@@ -160,7 +160,6 @@ static const IID D3D_IID_IDXGIDebug = { 0x119e7452, 0xde9e, 0x40fe, { 0x88, 0x06
static const IID D3D_IID_IDXGIInfoQueue = { 0xd67441c7, 0x672a, 0x476f, { 0x9e, 0x82, 0xcd, 0x55, 0xb4, 0x49, 0x49, 0xce } };
#endif
static const GUID D3D_IID_DXGI_DEBUG_ALL = { 0xe48ae283, 0xda80, 0x490b, { 0x87, 0xe6, 0x43, 0xe9, 0xa9, 0xcf, 0xda, 0x08 } };
-static const GUID D3D_IID_D3DDebugObjectName = { 0x429b8c22, 0x9188, 0x4b0c, { 0x87, 0x42, 0xac, 0xb0, 0xbf, 0x85, 0xc2, 0x00 } };
static const IID D3D_IID_ID3D12Device = { 0x189819f1, 0x1db6, 0x4b57, { 0xbe, 0x54, 0x18, 0x21, 0x33, 0x9b, 0x85, 0xf7 } };
static const IID D3D_IID_ID3D12CommandQueue = { 0x0ec870a6, 0x5d7e, 0x4c22, { 0x8c, 0xfc, 0x5b, 0xaa, 0xe0, 0x76, 0x16, 0xed } };
@@ -1177,22 +1176,6 @@ static void D3D12_INTERNAL_SetError(
SDL_SetError("%s! Error Code: %s " HRESULT_FMT, msg, wszMsgBuff, res);
}
-// Debug Naming
-
-static void D3D12_INTERNAL_SetResourceName(
- D3D12Renderer *renderer,
- ID3D12Resource *resource,
- const char *text)
-{
- if (renderer->debug_mode) {
- ID3D12DeviceChild_SetPrivateData(
- resource,
- D3D_GUID(D3D_IID_D3DDebugObjectName),
- (UINT)SDL_strlen(text),
- text);
- }
-}
-
// Release / Cleanup
static void D3D12_INTERNAL_ReleaseStagingDescriptorHandle(
@@ -1952,6 +1935,127 @@ static void D3D12_INTERNAL_TrackComputePipeline(
#undef TRACK_RESOURCE
+// Debug Naming
+
+static void D3D12_INTERNAL_SetPipelineStateName(
+ D3D12Renderer *renderer,
+ ID3D12PipelineState *pipelineState,
+ const char *text
+) {
+ if (renderer->debug_mode && text != NULL) {
+ WCHAR *wchar_text = WIN_UTF8ToStringW(text);
+ ID3D12PipelineState_SetName(
+ pipelineState,
+ wchar_text);
+ SDL_free(wchar_text);
+ }
+}
+
+static void D3D12_INTERNAL_SetResourceName(
+ D3D12Renderer *renderer,
+ ID3D12Resource *resource,
+ const char *text
+) {
+ if (renderer->debug_mode && text != NULL) {
+ WCHAR *wchar_text = WIN_UTF8ToStringW(text);
+ ID3D12Resource_SetName(
+ resource,
+ wchar_text);
+ SDL_free(wchar_text);
+ }
+}
+
+static void D3D12_SetBufferName(
+ SDL_GPURenderer *driverData,
+ SDL_GPUBuffer *buffer,
+ const char *text)
+{
+ D3D12Renderer *renderer = (D3D12Renderer *)driverData;
+ D3D12BufferContainer *container = (D3D12BufferContainer *)buffer;
+
+ if (renderer->debug_mode && text != NULL) {
+ if (container->debugName != NULL) {
+ SDL_free(container->debugName);
+ }
+
+ container->debugName = SDL_strdup(text);
+
+ for (Uint32 i = 0; i < container->bufferCount; i += 1) {
+ D3D12_INTERNAL_SetResourceName(
+ renderer,
+ container->buffers[i]->handle,
+ text);
+ }
+ }
+}
+
+static void D3D12_SetTextureName(
+ SDL_GPURenderer *driverData,
+ SDL_GPUTexture *texture,
+ const char *text)
+{
+ D3D12Renderer *renderer = (D3D12Renderer *)driverData;
+ D3D12TextureContainer *container = (D3D12TextureContainer *)texture;
+
+ if (renderer->debug_mode && text != NULL) {
+ if (container->debugName != NULL) {
+ SDL_free(container->debugName);
+ }
+
+ container->debugName = SDL_strdup(text);
+
+ for (Uint32 i = 0; i < container->textureCount; i += 1) {
+ D3D12_INTERNAL_SetResourceName(
+ renderer,
+ container->textures[i]->resource,
+ text);
+ }
+ }
+}
+
+/* These debug functions are all marked as "for internal usage only"
+ * on D3D12... works on renderdoc!
+ */
+
+static void D3D12_InsertDebugLabel(
+ SDL_GPUCommandBuffer *commandBuffer,
+ const char *text)
+{
+ D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
+ WCHAR *wchar_text = WIN_UTF8ToStringW(text);
+
+ ID3D12GraphicsCommandList_SetMarker(
+ d3d12CommandBuffer->graphicsCommandList,
+ 0,
+ wchar_text,
+ (UINT)SDL_wcslen(wchar_text));
+
+ SDL_free(wchar_text);
+}
+
+static void D3D12_PushDebugGroup(
+ SDL_GPUCommandBuffer *commandBuffer,
+ const char *name)
+{
+ D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
+ WCHAR *wchar_text = WIN_UTF8ToStringW(name);
+
+ ID3D12GraphicsCommandList_BeginEvent(
+ d3d12CommandBuffer->graphicsCommandList,
+ 0,
+ wchar_text,
+ (UINT)SDL_wcslen(wchar_text));
+
+ SDL_free(wchar_text);
+}
+
+static void D3D12_PopDebugGroup(
+ SDL_GPUCommandBuffer *commandBuffer)
+{
+ D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
+ ID3D12GraphicsCommandList_EndEvent(d3d12CommandBuffer->graphicsCommandList);
+}
+
// State Creation
static D3D12DescriptorHeap *D3D12_INTERNAL_CreateDescriptorHeap(
@@ -2681,6 +2785,13 @@ static SDL_GPUComputePipeline *D3D12_CreateComputePipeline(
computePipeline->numUniformBuffers = createinfo->num_uniform_buffers;
SDL_SetAtomicInt(&computePipeline->referenceCount, 0);
+ if (renderer->debug_mode && SDL_HasProperty(createinfo->props, SDL_PROP_GPU_COMPUTEPIPELINE_CREATE_NAME_STRING)) {
+ D3D12_INTERNAL_SetPipelineStateName(
+ renderer,
+ computePipeline->pipelineState,
+ SDL_GetStringProperty(createinfo->props, SDL_PROP_GPU_COMPUTEPIPELINE_CREATE_NAME_STRING, NULL));
+ }
+
return (SDL_GPUComputePipeline *)computePipeline;
}
@@ -2965,6 +3076,14 @@ static SDL_GPUGraphicsPipeline *D3D12_CreateGraphicsPipeline(
pipeline->fragmentUniformBufferCount = fragShader->numUniformBuffers;
SDL_SetAtomicInt(&pipeline->referenceCount, 0);
+
+ if (renderer->debug_mode && SDL_HasProperty(createinfo->props, SDL_PROP_GPU_GRAPHICSPIPELINE_CREATE_NAME_STRING)) {
+ D3D12_INTERNAL_SetPipelineStateName(
+ renderer,
+ pipeline->pipelineState,
+ SDL_GetStringProperty(createinfo->props, SDL_PROP_GPU_GRAPHICSPIPELINE_CREATE_NAME_STRING, NULL));
+ }
+
return (SDL_GPUGraphicsPipeline *)pipeline;
}
@@ -3010,6 +3129,9 @@ static SDL_GPUSampler *D3D12_CreateSampler(
sampler->createInfo = *createinfo;
SDL_SetAtomicInt(&sampler->referenceCount, 0);
+
+ // Ignore name property because it is not applicable to D3D12.
+
return (SDL_GPUSampler *)sampler;
}
@@ -3047,13 +3169,16 @@ static SDL_GPUShader *D3D12_CreateShader(
shader->bytecode = bytecode;
shader->bytecodeSize = bytecodeSize;
+ // Ignore name property because it is not applicable to D3D12.
+
return (SDL_GPUShader *)shader;
}
static D3D12Texture *D3D12_INTERNAL_CreateTexture(
D3D12Renderer *renderer,
const SDL_GPUTextureCreateInfo *createinfo,
- bool isSwapchainTexture)
+ bool isSwapchainTexture,
+ const char *debugName)
{
D3D12Texture *texture;
ID3D12Resource *handle;
@@ -3340,6 +3465,11 @@ static D3D12Texture *D3D12_INTERNAL_CreateTexture(
}
}
+ D3D12_INTERNAL_SetResourceName(
+ renderer,
+ texture->resource,
+ debugName);
+
return texture;
}
@@ -3352,7 +3482,11 @@ static SDL_GPUTexture *D3D12_CreateTexture(
return NULL;
}
+ // Copy properties so we don't lose information when the client destroys them
container->header.info = *createinfo;
+ container->header.info.props = SDL_CreateProperties();
+ SDL_CopyProperties(createinfo->props, container->header.info.props);
+
container->textureCapacity = 1;
container->textureCount = 1;
container->textures = (D3D12Texture **)SDL_calloc(
@@ -3364,12 +3498,17 @@ static SDL_GPUTexture *D3D12_CreateTexture(
}
container->debugName = NULL;
+ if (SDL_HasProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING)) {
+ container->debugName = SDL_strdup(SDL_GetStringProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING, NULL));
+ }
+
container->canBeCycled = true;
D3D12Texture *texture = D3D12_INTERNAL_CreateTexture(
(D3D12Renderer *)driverData,
createinfo,
- false);
+ false,
+ container->debugName);
if (!texture) {
SDL_free(container->textures);
@@ -3390,7 +3529,8 @@ static D3D12Buffer *D3D12_INTERNAL_CreateBuffer(
D3D12Renderer *renderer,
SDL_GPUBufferUsageFlags usageFlags,
Uint32 size,
- D3D12BufferType type)
+ D3D12BufferType type,
+ const char *debugName)
{
D3D12Buffer *buffer;
ID3D12Resource *handle;
@@ -3579,6 +3719,12 @@ static D3D12Buffer *D3D12_INTERNAL_CreateBuffer(
buffer->transitioned = initialState != D3D12_RESOURCE_STATE_COMMON;
SDL_SetAtomicInt(&buffer->referenceCount, 0);
+
+ D3D12_INTERNAL_SetResourceName(
+ renderer,
+ buffer->handle,
+ debugName);
+
return buffer;
}
@@ -3586,7 +3732,8 @@ static D3D12BufferContainer *D3D12_INTERNAL_CreateBufferContainer(
D3D12Renderer *renderer,
SDL_GPUBufferUsageFlags usageFlags,
Uint32 size,
- D3D12BufferType type)
+ D3D12BufferType type,
+ const char *debugName)
{
D3D12BufferContainer *container;
D3D12Buffer *buffer;
@@ -3614,7 +3761,8 @@ static D3D12BufferContainer *D3D12_INTERNAL_CreateBufferContainer(
renderer,
usageFlags,
size,
- type);
+ type,
+ debugName);
if (buffer == NULL) {
SDL_free(container->buffers);
@@ -3627,190 +3775,39 @@ static D3D12BufferContainer *D3D12_INTERNAL_CreateBufferContainer(
buffer->container = container;
buffer->containerIndex = 0;
+ if (debugName != NULL) {
+ container->debugName = SDL_strdup(debugName);
+ }
+
return container;
}
static SDL_GPUBuffer *D3D12_CreateBuffer(
SDL_GPURenderer *driverData,
SDL_GPUBufferUsageFlags usageFlags,
- Uint32 size)
+ Uint32 size,
+ const char *debugName)
{
return (SDL_GPUBuffer *)D3D12_INTERNAL_CreateBufferContainer(
(D3D12Renderer *)driverData,
usageFlags,
size,
- D3D12_BUFFER_TYPE_GPU);
+ D3D12_BUFFER_TYPE_GPU,
+ debugName);
}
static SDL_GPUTransferBuffer *D3D12_CreateTransferBuffer(
SDL_GPURenderer *driverData,
SDL_GPUTransferBufferUsage usage,
- Uint32 size)
+ Uint32 size,
+ const char *debugName)
{
return (SDL_GPUTransferBuffer *)D3D12_INTERNAL_CreateBufferContainer(
(D3D12Renderer *)driverData,
0,
size,
- usage == SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD ? D3D12_BUFFER_TYPE_UPLOAD : D3D12_BUFFER_TYPE_DOWNLOAD);
-}
-
-// Debug Naming
-
-static void D3D12_SetBufferName(
- SDL_GPURenderer *driverData,
- SDL_GPUBuffer *buffer,
- const char *text)
-{
- D3D12Renderer *renderer = (D3D12Renderer *)driverData;
- D3D12BufferContainer *container = (D3D12BufferContainer *)buffer;
- size_t textLength = SDL_strlen(text) + 1;
-
- if (renderer->debug_mode) {
- container->debugName = (char *)SDL_realloc(
- container->debugName,
- textLength);
-
- SDL_utf8strlcpy(
- container->debugName,
- text,
- textLength);
-
- for (Uint32 i = 0; i < container->bufferCount; i += 1) {
- D3D12_INTERNAL_SetResourceName(
- renderer,
- container->buffers[i]->handle,
- text);
- }
- }
-}
-
-static void D3D12_SetTextureName(
- SDL_GPURenderer *driverData,
- SDL_GPUTexture *texture,
- const char *text)
-{
- D3D12Renderer *renderer = (D3D12Renderer *)driverData;
- D3D12TextureContainer *container = (D3D12TextureContainer *)texture;
- size_t textLength = SDL_strlen(text) + 1;
-
- if (renderer->debug_mode) {
- container->debugName = (char *)SDL_realloc(
- container->debugName,
- textLength);
-
- SDL_utf8strlcpy(
- container->debugName,
- text,
- textLength);
-
- for (Uint32 i = 0; i < container->textureCount; i += 1) {
- D3D12_INTERNAL_SetResourceName(
- renderer,
- container->textures[i]->resource,
- text);
- }
- }
-}
-
-/* These debug functions are all marked as "for internal usage only"
- * on D3D12... works on renderdoc!
- */
-
-static bool D3D12_INTERNAL_StrToWStr(
- D3D12Renderer *renderer,
- const char *str,
- wchar_t *wstr,
- size_t wstrSize,
- Uint32 *outSize)
-{
- size_t inlen, result;
- size_t outBytesLeft = wstrSize;
- *outSize = 0;
-
- if (renderer->iconv == NULL) {
- renderer->iconv = SDL_iconv_open("WCHAR_T", "UTF-8");
- SDL_assert(renderer->iconv);
- }
-
- // Convert...
- inlen = SDL_strlen(str) + 1;
- result = SDL_iconv(
- renderer->iconv,
- &str,
- &inlen,
- (char **)&wstr,
- &outBytesLeft);
-
-
- // Check...
- switch (result) {
- case SDL_ICONV_ERROR:
- case SDL_ICONV_E2BIG:
- case SDL_ICONV_EILSEQ:
- case SDL_ICONV_EINVAL:
- SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "Failed to convert string to wchar_t!");
- return false;
- default:
- break;
- }
-
- *outSize = (Uint32)(wstrSize - outBytesLeft);
- return true;
-}
-
-static void D3D12_InsertDebugLabel(
- SDL_GPUCommandBuffer *commandBuffer,
- const char *text)
-{
- D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
- wchar_t wstr[256];
- Uint32 convSize;
-
- if (!D3D12_INTERNAL_StrToWStr(
- d3d12CommandBuffer->renderer,
- text,
- wstr,
- sizeof(wstr),
- &convSize)) {
- return;
- }
-
- ID3D12GraphicsCommandList_SetMarker(
- d3d12CommandBuffer->graphicsCommandList,
- 0,
- wstr,
- convSize);
-}
-
-static void D3D12_PushDebugGroup(
- SDL_GPUCommandBuffer *commandBuffer,
- const char *name)
-{
- D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
- wchar_t wstr[256];
- Uint32 convSize;
-
- if (!D3D12_INTERNAL_StrToWStr(
- d3d12CommandBuffer->renderer,
- name,
- wstr,
- sizeof(wstr),
- &convSize)) {
- return;
- }
-
- ID3D12GraphicsCommandList_BeginEvent(
- d3d12CommandBuffer->graphicsCommandList,
- 0,
- wstr,
- convSize);
-}
-
-static void D3D12_PopDebugGroup(
- SDL_GPUCommandBuffer *commandBuffer)
-{
- D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
- ID3D12GraphicsCommandList_EndEvent(d3d12CommandBuffer->graphicsCommandList);
+ usage == SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD ? D3D12_BUFFER_TYPE_UPLOAD : D3D12_BUFFER_TYPE_DOWNLOAD,
+ debugName);
}
// Disposal
@@ -4028,7 +4025,8 @@ static void D3D12_INTERNAL_CycleActiveTexture(
texture = D3D12_INTERNAL_CreateTexture(
renderer,
&container->header.info,
- false);
+ false,
+ container->debugName);
if (!texture) {
return;
@@ -4047,13 +4045,6 @@ static void D3D12_INTERNAL_CycleActiveTexture(
container->textureCount += 1;
container->activeTexture = texture;
-
- if (renderer->debug_mode && container->debugName != NULL) {
- D3D12_INTERNAL_SetResourceName(
- renderer,
- container->activeTexture->resource,
- container->debugName);
- }
}
static D3D12TextureSubresource *D3D12_INTERNAL_PrepareTextureSubresourceForWrite(
@@ -4109,7 +4100,8 @@ static void D3D12_INTERNAL_CycleActiveBuffer(
renderer,
container->usage,
container->size,
- container->type);
+ container->type,
+ container->debugName);
if (!buffer) {
return;
@@ -4383,7 +4375,8 @@ static D3D12UniformBuffer *D3D12_INTERNAL_AcquireUniformBufferFromPool(
renderer,
0,
UNIFORM_BUFFER_SIZE,
- D3D12_BUFFER_TYPE_UNIFORM);
+ D3D12_BUFFER_TYPE_UNIFORM,
+ NULL);
if (!uniformBuffer->buffer) {
SDL_UnlockMutex(renderer->acquireUniformBufferLock);
return NULL;
@@ -5762,7 +5755,8 @@ static void D3D12_UploadToTexture(
d3d12CommandBuffer->renderer,
0,
alignedRowPitch * destination->h * destination->d,
- D3D12_BUFFER_TYPE_UPLOAD);
+ D3D12_BUFFER_TYPE_UPLOAD,
+ NULL);
if (!temporaryBuffer) {
return;
@@ -5808,7 +5802,8 @@ static void D3D12_UploadToTexture(
d3d12CommandBuffer->renderer,
0,
alignedRowPitch * destination->h * destination->d,
- D3D12_BUFFER_TYPE_UPLOAD);
+ D3D12_BUFFER_TYPE_UPLOAD,
+ NULL);
if (!temporaryBuffer) {
return;
@@ -6091,7 +6086,8 @@ static void D3D12_DownloadFromTexture(
d3d12CommandBuffer->renderer,
0,
alignedRowPitch * rowsPerSlice * source->d,
- D3D12_BUFFER_TYPE_DOWNLOAD);
+ D3D12_BUFFER_TYPE_DOWNLOAD,
+ NULL);
if (!textureDownload->temporaryBuffer) {
SDL_free(textureDownload);
diff --git a/src/gpu/metal/SDL_gpu_metal.m b/src/gpu/metal/SDL_gpu_metal.m
index f87e9fcfcab83..411a29b29a941 100644
--- a/src/gpu/metal/SDL_gpu_metal.m
+++ b/src/gpu/metal/SDL_gpu_metal.m
@@ -1043,7 +1043,15 @@ static void METAL_ReleaseGraphicsPipeline(
return NULL;
}
- handle = [renderer->device newComputePipelineStateWithFunction:libraryFunction.function error:&error];
+ MTLComputePipelineDescriptor *descriptor = [MTLComputePipelineDescriptor new];
+ descriptor.computeFunction = libraryFunction.function;
+
+ if (renderer->debugMode && SDL_HasProperty(createinfo->props, SDL_PROP_GPU_COMPUTEPIPELINE_CREATE_NAME_STRING)) {
+ const char *name = SDL_GetStringProperty(createinfo->props, SDL_PROP_GPU_COMPUTEPIPELINE_CREATE_NAME_STRING, NULL);
+ descriptor.label = @(name);
+ }
+
+ handle = [renderer->device newComputePipelineStateWithDescriptor:descriptor options:MTLPipelineOptionNone reflection: nil error:&error];
if (error != NULL) {
SET_ERROR_AND_RETURN("Creating compute pipeline failed: %s", [[error description] UTF8String], NULL);
}
@@ -1183,6 +1191,11 @@ static void METAL_ReleaseGraphicsPipeline(
pipelineDescriptor.vertexDescriptor = vertexDescriptor;
}
+ if (renderer->debugMode && SDL_HasProperty(createinfo->props, SDL_PROP_GPU_GRAPHICSPIPELINE_CREATE_NAME_STRING)) {
+ const char *name = SDL_GetStringProperty(createinfo->props, SDL_PROP_GPU_GRAPHICSPIPELINE_CREATE_NAME_STRING, NULL);
+ pipelineDescriptor.label = @(name);
+ }
+
// Create the graphics pipeline
pipelineState = [renderer->device newRenderPipelineStateWithDescriptor:pipelineDescriptor error:&error];
@@ -1222,17 +1235,13 @@ static void METAL_SetBufferName(
@autoreleasepool {
MetalRenderer *renderer = (MetalRenderer *)driverData;
MetalBufferContainer *container = (MetalBufferContainer *)buffer;
- size_t textLength = SDL_strlen(text) + 1;
- if (renderer->debugMode) {
- container->debugName = SDL_realloc(
- container->debugName,
- textLength);
+ if (renderer->debugMode && text != NULL) {
+ if (container->debugName != NULL) {
+ SDL_free(container->debugName);
+ }
- SDL_utf8strlcpy(
- container->debugName,
- text,
- textLength);
+ container->debugName = SDL_strdup(text);
for (Uint32 i = 0; i < container->bufferCount; i += 1) {
container->buffers[i]->handle.label = @(text);
@@ -1249,17 +1258,13 @@ static void METAL_SetTextureName(
@autoreleasepool {
MetalRenderer *renderer = (MetalRenderer *)driverData;
MetalTextureContainer *container = (MetalT
(Patch may be truncated, please check the link at the top of this post.)