diff --git a/include/SDL3/SDL_gpu.h b/include/SDL3/SDL_gpu.h index b0a9cdf204..2db3a720c9 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 e24ad9b680..34905cea2c 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 85bad24434..98f4be9f85 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 c613e29bc7..39c8b62b6b 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 f87e9fcfca..411a29b29a 100644 --- a/src/gpu/metal/SDL_gpu_metal.m +++ b/src/gpu/metal/SDL_gpu_metal.m @@ -1043,7 +1043,15 @@ static SDL_GPUComputePipeline *METAL_CreateComputePipeline( 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 SDL_GPUGraphicsPipeline *METAL_CreateGraphicsPipeline( 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 = (MetalTextureContainer *)texture; - 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->textureCount; i += 1) { container->textures[i]->handle.label = @(text); @@ -1357,6 +1362,11 @@ static SDL_GPUSampler *METAL_CreateSampler( samplerDesc.maxAnisotropy = (NSUInteger)((createinfo->enable_anisotropy) ? createinfo->max_anisotropy : 1); samplerDesc.compareFunction = (createinfo->enable_compare) ? SDLToMetal_CompareOp[createinfo->compare_op] : MTLCompareFunctionAlways; + if (renderer->debugMode && SDL_HasProperty(createinfo->props, SDL_PROP_GPU_SAMPLER_CREATE_NAME_STRING)) { + const char *name = SDL_GetStringProperty(createinfo->props, SDL_PROP_GPU_SAMPLER_CREATE_NAME_STRING, NULL); + samplerDesc.label = @(name); + } + sampler = [renderer->device newSamplerStateWithDescriptor:samplerDesc]; if (sampler == NULL) { SET_STRING_ERROR_AND_RETURN("Failed to create sampler", NULL); @@ -1457,6 +1467,11 @@ static MetalTexture *METAL_INTERNAL_CreateTexture( metalTexture = (MetalTexture *)SDL_calloc(1, sizeof(MetalTexture)); metalTexture->handle = texture; SDL_SetAtomicInt(&metalTexture->referenceCount, 0); + + if (renderer->debugMode && SDL_HasProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING)) { + metalTexture->handle.label = @(SDL_GetStringProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING, NULL)); + } + return metalTexture; } @@ -1491,7 +1506,12 @@ static SDL_GPUTexture *METAL_CreateTexture( container = SDL_calloc(1, sizeof(MetalTextureContainer)); container->canBeCycled = 1; + + // 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->activeTexture = texture; container->textureCapacity = 1; container->textureCount = 1; @@ -1500,6 +1520,10 @@ static SDL_GPUTexture *METAL_CreateTexture( container->textures[0] = texture; 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)); + } + return (SDL_GPUTexture *)container; } } @@ -1534,10 +1558,6 @@ static MetalTexture *METAL_INTERNAL_PrepareTextureForWrite( container->textureCount += 1; container->activeTexture = container->textures[container->textureCount - 1]; - - if (renderer->debugMode && container->debugName != NULL) { - container->activeTexture->handle.label = @(container->debugName); - } } return container->activeTexture; @@ -1547,7 +1567,8 @@ static MetalTexture *METAL_INTERNAL_PrepareTextureForWrite( static MetalBuffer *METAL_INTERNAL_CreateBuffer( MetalRenderer *renderer, Uint32 size, - MTLResourceOptions resourceOptions) + MTLResourceOptions resourceOptions, + const char *debugName) { id bufferHandle; MetalBuffer *metalBuffer; @@ -1565,6 +1586,10 @@ static MetalBuffer *METAL_INTERNAL_CreateBuffer( metalBuffer->handle = bufferHandle; SDL_SetAtomicInt(&metalBuffer->referenceCount, 0); + if (debugName != NULL) { + metalBuffer->handle.label = @(debugName); + } + return metalBuffer; } @@ -1573,7 +1598,8 @@ static MetalBufferContainer *METAL_INTERNAL_CreateBufferContainer( MetalRenderer *renderer, Uint32 size, bool isPrivate, - bool isWriteOnly) + bool isWriteOnly, + const char *debugName) { MetalBufferContainer *container = SDL_calloc(1, sizeof(MetalBufferContainer)); MTLResourceOptions resourceOptions; @@ -1586,6 +1612,9 @@ static MetalBufferContainer *METAL_INTERNAL_CreateBufferContainer( container->isPrivate = isPrivate; container->isWriteOnly = isWriteOnly; container->debugName = NULL; + if (container->debugName != NULL) { + container->debugName = SDL_strdup(debugName); + } if (isPrivate) { resourceOptions = MTLResourceStorageModePrivate; @@ -1600,7 +1629,9 @@ static MetalBufferContainer *METAL_INTERNAL_CreateBufferContainer( container->buffers[0] = METAL_INTERNAL_CreateBuffer( renderer, size, - resourceOptions); + resourceOptions, + debugName); + container->activeBuffer = container->buffers[0]; return container; @@ -1609,28 +1640,32 @@ static MetalBufferContainer *METAL_INTERNAL_CreateBufferContainer( static SDL_GPUBuffer *METAL_CreateBuffer( SDL_GPURenderer *driverData, SDL_GPUBufferUsageFlags usage, - Uint32 size) + Uint32 size, + const char *debugName) { @autoreleasepool { return (SDL_GPUBuffer *)METAL_INTERNAL_CreateBufferContainer( (MetalRenderer *)driverData, size, true, - false); + false, + debugName); } } static SDL_GPUTransferBuffer *METAL_CreateTransferBuffer( SDL_GPURenderer *driverData, SDL_GPUTransferBufferUsage usage, - Uint32 size) + Uint32 size, + const char *debugName) { @autoreleasepool { return (SDL_GPUTransferBuffer *)METAL_INTERNAL_CreateBufferContainer( (MetalRenderer *)driverData, size, false, - usage == SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD); + usage == SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD, + debugName); } } @@ -1694,14 +1729,11 @@ static MetalBuffer *METAL_INTERNAL_PrepareBufferForWrite( container->buffers[container->bufferCount] = METAL_INTERNAL_CreateBuffer( renderer, container->size, - resourceOptions); + resourceOptions, + container->debugName); container->bufferCount += 1; container->activeBuffer = container->buffers[container->bufferCount - 1]; - - if (renderer->debugMode && container->debugName != NULL) { - container->activeBuffer->handle.label = @(container->debugName); - } } return container->activeBuffer; @@ -4386,6 +4418,7 @@ static SDL_GPUDevice *METAL_CreateDevice(bool debugMode, bool preferLowPower, SD } #ifdef SDL_PLATFORM_MACOS + hasHardwareSupport = true; if (@available(macOS 10.15, *)) { hasHardwareSupport = [device supportsFamily:MTLGPUFamilyMac2]; } else if (@available(macOS 10.14, *)) { diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index d04e89ec68..0037006320 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -4069,7 +4069,8 @@ static VulkanBuffer *VULKAN_INTERNAL_CreateBuffer( VkDeviceSize size, SDL_GPUBufferUsageFlags usageFlags, VulkanBufferType type, - bool dedicated) + bool dedicated, + const char *debugName) { VulkanBuffer *buffer; VkResult vulkanResult; @@ -4155,6 +4156,19 @@ static VulkanBuffer *VULKAN_INTERNAL_CreateBuffer( SDL_SetAtomicInt(&buffer->referenceCount, 0); + if (renderer->debugMode && renderer->supportsDebugUtils && debugName != NULL) { + VkDebugUtilsObjectNameInfoEXT nameInfo; + nameInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + nameInfo.pNext = NULL; + nameInfo.pObjectName = debugName; + nameInfo.objectType = VK_OBJECT_TYPE_BUFFER; + nameInfo.objectHandle = (uint64_t)buffer->buffer; + + renderer->vkSetDebugUtilsObjectNameEXT( + renderer->logicalDevice, + &nameInfo); + } + return buffer; } @@ -4163,7 +4177,8 @@ static VulkanBufferContainer *VULKAN_INTERNAL_CreateBufferContainer( VkDeviceSize size, SDL_GPUBufferUsageFlags usageFlags, VulkanBufferType type, - bool dedicated) + bool dedicated, + const char *debugName) { VulkanBufferContainer *bufferContainer; VulkanBuffer *buffer; @@ -4173,7 +4188,8 @@ static VulkanBufferContainer *VULKAN_INTERNAL_CreateBufferContainer( size, usageFlags, type, - dedicated); + dedicated, + debugName); if (buffer == NULL) { return NULL; @@ -4193,6 +4209,10 @@ static VulkanBufferContainer *VULKAN_INTERNAL_CreateBufferContainer( bufferContainer->dedicated = dedicated; bufferContainer->debugName = NULL; + if (debugName != NULL) { + bufferContainer->debugName = SDL_strdup(debugName); + } + return bufferContainer; } @@ -5763,6 +5783,20 @@ static VulkanTexture *VULKAN_INTERNAL_CreateTexture( } } + // Set debug name if applicable + if (renderer->debugMode && renderer->supportsDebugUtils && SDL_HasProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING)) { + VkDebugUtilsObjectNameInfoEXT nameInfo; + nameInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + nameInfo.pNext = NULL; + nameInfo.pObjectName = SDL_GetStringProperty(createinfo->props, SDL_PROP_GPU_TEXTURE_CREATE_NAME_STRING, NULL); + nameInfo.objectType = VK_OBJECT_TYPE_IMAGE; + nameInfo.objectHandle = (uint64_t)texture->image; + + renderer->vkSetDebugUtilsObjectNameEXT( + renderer->logicalDevice, + &nameInfo); + } + // Let's transition to the default barrier state, because for some reason Vulkan doesn't let us do that with initialLayout. VulkanCommandBuffer *barrierCommandBuffer = (VulkanCommandBuffer *)VULKAN_AcquireCommandBuffer((SDL_GPURenderer *)renderer); VULKAN_INTERNAL_TextureTransitionToDefaultUsage( @@ -5797,7 +5831,8 @@ static void VULKAN_INTERNAL_CycleActiveBuffer( container->activeBuffer->size, container->activeBuffer->usage, container->activeBuffer->type, - container->dedicated); + container->dedicated, + container->debugName); if (!buffer) { return; @@ -5816,13 +5851,6 @@ static void VULKAN_INTERNAL_CycleActiveBuffer( container->bufferCount += 1; container->activeBuffer = buffer; - - if (renderer->debugMode && renderer->supportsDebugUtils && container->debugName != NULL) { - VULKAN_INTERNAL_SetBufferName( - renderer, - container->activeBuffer, - container->debugName); - } } static void VULKAN_INTERNAL_CycleActiveTexture( @@ -5863,13 +5891,6 @@ static void VULKAN_INTERNAL_CycleActiveTexture( container->textureCount += 1; container->activeTexture = texture; - - if (renderer->debugMode && renderer->supportsDebugUtils && container->debugName != NULL) { - VULKAN_INTERNAL_SetTextureName( - renderer, - container->activeTexture, - container->debugName); - } } static VulkanBuffer *VULKAN_INTERNAL_PrepareBufferForWrite( @@ -6485,6 +6506,19 @@ static SDL_GPUGraphicsPipeline *VULKAN_CreateGraphicsPipeline( SDL_SetAtomicInt(&graphicsPipeline->referenceCount, 0); + if (renderer->debugMode && renderer->supportsDebugUtils && SDL_HasProperty(createinfo->props, SDL_PROP_GPU_GRAPHICSPIPELINE_CREATE_NAME_STRING)) { + VkDebugUtilsObjectNameInfoEXT nameInfo; + nameInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + nameInfo.pNext = NULL; + nameInfo.pObjectName = SDL_GetStringProperty(createinfo->props, SDL_PROP_GPU_GRAPHICSPIPELINE_CREATE_NAME_STRING, NULL); + nameInfo.objectType = VK_OBJECT_TYPE_PIPELINE; + nameInfo.objectHandle = (uint64_t)graphicsPipeline->pipeline; + + renderer->vkSetDebugUtilsObjectNameEXT( + renderer->logicalDevice, + &nameInfo); + } + return (SDL_GPUGraphicsPipeline *)graphicsPipeline; } @@ -6566,6 +6600,19 @@ static SDL_GPUComputePipeline *VULKAN_CreateComputePipeline( SDL_SetAtomicInt(&vulkanComputePipeline->referenceCount, 0); + if (renderer->debugMode && renderer->supportsDebugUtils && SDL_HasProperty(createinfo->props, SDL_PROP_GPU_COMPUTEPIPELINE_CREATE_NAME_STRING)) { + VkDebugUtilsObjectNameInfoEXT nameInfo; + nameInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + nameInfo.pNext = NULL; + nameInfo.pObjectName = SDL_GetStringProperty(createinfo->props, SDL_PROP_GPU_COMPUTEPIPELINE_CREATE_NAME_STRING, NULL); + nameInfo.objectType = VK_OBJECT_TYPE_PIPELINE; + nameInfo.objectHandle = (uint64_t)vulkanComputePipeline->pipeline; + + renderer->vkSetDebugUtilsObjectNameEXT( + renderer->logicalDevice, + &nameInfo); + } + return (SDL_GPUComputePipeline *)vulkanComputePipeline; } @@ -6610,6 +6657,19 @@ static SDL_GPUSampler *VULKAN_CreateSampler( SDL_SetAtomicInt(&vulkanSampler->referenceCount, 0); + if (renderer->debugMode && renderer->supportsDebugUtils && SDL_HasProperty(createinfo->props, SDL_PROP_GPU_SAMPLER_CREATE_NAME_STRING)) { + VkDebugUtilsObjectNameInfoEXT nameInfo; + nameInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + nameInfo.pNext = NULL; + nameInfo.pObjectName = SDL_GetStringProperty(createinfo->props, SDL_PROP_GPU_SAMPLER_CREATE_NAME_STRING, NULL); + nameInfo.objectType = VK_OBJECT_TYPE_SAMPLER; + nameInfo.objectHandle = (uint64_t)vulkanSampler->sampler; + + renderer->vkSetDebugUtilsObjectNameEXT( + renderer->logicalDevice, + &nameInfo); + } + return (SDL_GPUSampler *)vulkanSampler; } @@ -6653,6 +6713,19 @@ static SDL_GPUShader *VULKAN_CreateShader( SDL_SetAtomicInt(&vulkanShader->referenceCount, 0); + if (renderer->debugMode && SDL_HasProperty(createinfo->props, SDL_PROP_GPU_SHADER_CREATE_NAME_STRING)) { + VkDebugUtilsObjectNameInfoEXT nameInfo; + nameInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; + nameInfo.pNext = NULL; + nameInfo.pObjectName = SDL_GetStringProperty(createinfo->props, SDL_PROP_GPU_SHADER_CREATE_NAME_STRING, NULL); + nameInfo.objectType = VK_OBJECT_TYPE_SHADER_MODULE; + nameInfo.objectHandle = (uint64_t)vulkanShader->shaderModule; + + renderer->vkSetDebugUtilsObjectNameEXT( + renderer->logicalDevice, + &nameInfo); + } + return (SDL_GPUShader *)vulkanShader; } @@ -6684,7 +6757,12 @@ static SDL_GPUTexture *VULKAN_CreateTexture( } container = SDL_malloc(sizeof(VulkanTextureContainer)); + + // 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->canBeCycled = true; container->activeTexture = texture; container->textureCapacity = 1; @@ -6694,6 +6772,10 @@ static SDL_GPUTexture *VULKAN_CreateTexture( container->textures[0] = container->activeTexture; 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)); + } + texture->container = container; texture->containerIndex = 0; @@ -6703,14 +6785,16 @@ static SDL_GPUTexture *VULKAN_CreateTexture( static SDL_GPUBuffer *VULKAN_CreateBuffer( SDL_GPURenderer *driverData, SDL_GPUBufferUsageFlags usageFlags, - Uint32 size) + Uint32 size, + const char *debugName) { return (SDL_GPUBuffer *)VULKAN_INTERNAL_CreateBufferContainer( (VulkanRenderer *)driverData, (VkDeviceSize)size, usageFlags, VULKAN_BUFFER_TYPE_GPU, - false); + false, + debugName); } static VulkanUniformBuffer *VULKAN_INTERNAL_CreateUniformBuffer( @@ -6724,7 +6808,8 @@ static VulkanUniformBuffer *VULKAN_INTERNAL_CreateUniformBuffer( (VkDeviceSize)size, 0, VULKAN_BUFFER_TYPE_UNIFORM, - false); + false, + NULL); uniformBuffer->drawOffset = 0; uniformBuffer->writeOffset = 0; @@ -6736,7 +6821,8 @@ static VulkanUniformBuffer *VULKAN_INTERNAL_CreateUniformBuffer( static SDL_GPUTransferBuffer *VULKAN_CreateTransferBuffer( SDL_GPURenderer *driverData, SDL_GPUTransferBufferUsage usage, - Uint32 size) + Uint32 size, + const char *debugName) { // We use dedicated allocations for download buffers to avoid an issue // where a defrag is triggered after submitting a download but before @@ -6746,7 +6832,8 @@ static SDL_GPUTransferBuffer *VULKAN_CreateTransferBuffer( (VkDeviceSize)size, 0, VULKAN_BUFFER_TYPE_TRANSFER, - usage == SDL_GPU_TRANSFERBUFFERUSAGE_DOWNLOAD); + usage == SDL_GPU_TRANSFERBUFFERUSAGE_DOWNLOAD, + debugName); } static void VULKAN_INTERNAL_ReleaseTexture( @@ -9908,9 +9995,9 @@ static bool VULKAN_WaitAndAcquireSwapchainTexture( Uint32 *swapchain_texture_height ) { return VULKAN_INTERNAL_AcquireSwapchainTexture( - true, - command_buffer, - window, + true, + command_buffer, + window, swapchain_texture, swapchain_texture_width, swapchain_texture_height); @@ -10565,24 +10652,14 @@ static bool VULKAN_INTERNAL_DefragmentMemory( currentRegion->vulkanBuffer->size, currentRegion->vulkanBuffer->usage, currentRegion->vulkanBuffer->type, - false); + false, + currentRegion->vulkanBuffer->container != NULL ? currentRegion->vulkanBuffer->container->debugName : NULL); if (newBuffer == NULL) { SDL_UnlockMutex(renderer->allocatorLock); return false; } - if ( - renderer->debugMode && - renderer->supportsDebugUtils && - currentRegion->vulkanBuffer->container != NULL && - currentRegion->vulkanBuffer->container->debugName != NULL) { - VULKAN_INTERNAL_SetBufferName( - renderer, - newBuffer, - currentRegion->vulkanBuffer->container->debugName); - } - // Copy buffer contents if necessary if ( currentRegion->vulkanBuffer->type == VULKAN_BUFFER_TYPE_GPU && currentRegion->vulkanBuffer->transitioned) { @@ -10648,18 +10725,6 @@ static bool VULKAN_INTERNAL_DefragmentMemory( srcSubresource = ¤tRegion->vulkanTexture->subresources[subresourceIndex]; dstSubresource = &newTexture->subresources[subresourceIndex]; - // Set debug name if it exists - if ( - renderer->debugMode && - renderer->supportsDebugUtils && - srcSubresource->parent->container != NULL && - srcSubresource->parent->container->debugName != NULL) { - VULKAN_INTERNAL_SetTextureName( - renderer, - currentRegion->vulkanTexture, - srcSubresource->parent->container->debugName); - } - VULKAN_INTERNAL_TextureSubresourceTransitionFromDefaultUsage( renderer, commandBuffer, diff --git a/test/testgpu_spinning_cube.c b/test/testgpu_spinning_cube.c index 90e71bbc8e..ff9ece8138 100644 --- a/test/testgpu_spinning_cube.c +++ b/test/testgpu_spinning_cube.c @@ -538,23 +538,25 @@ init_render_state(int msaa) buffer_desc.usage = SDL_GPU_BUFFERUSAGE_VERTEX; buffer_desc.size = sizeof(vertex_data); - buffer_desc.props = 0; + buffer_desc.props = SDL_CreateProperties(); + SDL_SetStringProperty(buffer_desc.props, SDL_PROP_GPU_BUFFER_CREATE_NAME_STRING, "космонавт"); render_state.buf_vertex = SDL_CreateGPUBuffer( gpu_device, &buffer_desc ); CHECK_CREATE(render_state.buf_vertex, "Static vertex buffer") - - SDL_SetGPUBufferName(gpu_device, render_state.buf_vertex, "космонавт"); + SDL_DestroyProperties(buffer_desc.props); transfer_buffer_desc.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD; transfer_buffer_desc.size = sizeof(vertex_data); - transfer_buffer_desc.props = 0; + transfer_buffer_desc.props = SDL_CreateProperties(); + SDL_SetStringProperty(transfer_buffer_desc.props, SDL_PROP_GPU_TRANSFERBUFFER_CREATE_NAME_STRING, "Transfer Buffer"); buf_transfer = SDL_CreateGPUTransferBuffer( gpu_device, &transfer_buffer_desc ); CHECK_CREATE(buf_transfer, "Vertex transfer buffer") + SDL_DestroyProperties(transfer_buffer_desc.props); /* We just need to upload the static data once. */ map = SDL_MapGPUTransferBuffer(gpu_device, buf_transfer, false);